diff --git a/docs-website/reference/integrations-api/agent_pack.md b/docs-website/reference/integrations-api/agent_pack.md new file mode 100644 index 0000000000..2921c4d640 --- /dev/null +++ b/docs-website/reference/integrations-api/agent_pack.md @@ -0,0 +1,463 @@ +--- +title: "Agent Pack" +id: integrations-agent-pack +description: "Agent Pack integration for Haystack" +slug: "/integrations-agent-pack" +--- + + +## haystack_integrations.agent_pack.advanced_rag.agent + +### create_advanced_rag_agent + +```python +create_advanced_rag_agent( + *, + document_store: DocumentStore, + retriever: TextRetriever | Pipeline | None = None, + retrieval_pipeline_input_mapping: dict[str, list[str]] | None = None, + retrieval_pipeline_output_mapping: dict[str, str] | None = None, + llm: ChatGenerator | None = None, + backup_answer_llm: ChatGenerator | None = None, + system_prompt: str | None = None, + max_agent_steps: int = 20, + max_fetched_docs: int = 10, + extra_tools: ToolsType | None = None, + state_schema: dict[str, Any] | None = None, + hooks: dict[HookPoint, list[Hook]] | None = None, + raise_on_tool_invocation_failure: bool = False, + tool_concurrency_limit: int = 4 +) -> Agent +``` + +Create the advanced RAG agent. + +The agent answers questions from documents it retrieves out of the document store. Instead of guessing which +metadata fields exist, it can inspect the store (fields, values, ranges) and construct a Haystack filter to +narrow its retrieval when metadata helps — plain, unfiltered retrieval remains available when it doesn't. The +answer cites the retrieved documents. + +The required `retriever` becomes the `search_documents` tool; `document_store` additionally feeds the three +metadata inspection tools and must implement the metadata introspection methods (`get_metadata_fields_info`, +`get_metadata_field_unique_values`, `get_metadata_field_min_max`). + +**Parameters:** + +- **document_store** (DocumentStore) – The document store the metadata inspection tools and the `fetch_documents_by_filter` tool + run against. +- **retriever** (TextRetriever | Pipeline | None) – What retrieves for the `search_documents` tool (required). Either a standalone retriever + component following the `TextRetriever` protocol, i.e. its `run` method accepts `query` and `filters` + (e.g. `InMemoryBM25Retriever`, or an embedding retriever wrapped in `TextEmbeddingRetriever`), or a custom + retrieval `Pipeline` (e.g. embedder -> retriever, or hybrid retrieval) — a pipeline additionally requires + `retrieval_pipeline_input_mapping`. It should retrieve by relevance scoring (keyword or embedding-based) — + direct, unscored fetching is already covered by the built-in `fetch_documents_by_filter` tool. +- **retrieval_pipeline_input_mapping** (dict\[str, list\[str\]\] | None) – Required when `retriever` is a `Pipeline`: maps the tool inputs to + pipeline input sockets; must have exactly the keys "query" and "filters", + e.g. `{"query": ["embedder.text"], "filters": ["retriever.filters"]}`. +- **retrieval_pipeline_output_mapping** (dict\[str, str\] | None) – Optional when `retriever` is a `Pipeline`: maps pipeline output sockets + to tool outputs, e.g. `{"retriever.documents": "documents"}`. +- **llm** (ChatGenerator | None) – LLM that drives the agent loop. Defaults to `OpenAIResponsesChatGenerator("gpt-5.4")` with low + reasoning effort. +- **backup_answer_llm** (ChatGenerator | None) – LLM the built-in `BackupAnswerHook` uses to write a best-effort answer when the run + is cut off by `max_agent_steps`. Defaults to a separate `OpenAIResponsesChatGenerator("gpt-5.4")` with low + reasoning effort. +- **system_prompt** (str | None) – Overrides the pre-made system prompt. +- **max_agent_steps** (int) – Maximum steps for the agent loop. If the loop is cut off by this limit before writing an + answer, an `after_run` hook (`BackupAnswerHook`) makes one extra LLM call to produce a best-effort answer from + the evidence gathered so far, so `last_message` always carries a text answer. +- **max_fetched_docs** (int) – Maximum number of documents `fetch_documents_by_filter` shows per fetch. A filter fetch is + not bounded by a retriever's `top_k`, so this caps the tool result instead; the scored `search_documents` tool + is bounded by the `top_k` configured on your retrieval components. +- **extra_tools** (ToolsType | None) – Additional tools (or toolsets) for the agent, appended after the built-in document-store + toolset and the retrieval tool. +- **state_schema** (dict\[str, Any\] | None) – Additional entries merged into the agent's state schema. The built-in `documents` entry + (the accumulated retrieved documents) always takes precedence. +- **hooks** (dict\[HookPoint, list\[Hook\]\] | None) – Additional hooks per hook point, merged with the built-in hooks. For `after_run`, the built-in + backup-answer hook runs first, so custom hooks see the final answer. +- **raise_on_tool_invocation_failure** (bool) – If True, a failing tool call raises instead of being returned to the LLM + as an error message it can recover from (the default). +- **tool_concurrency_limit** (int) – Maximum number of tool calls executed in parallel within one agent step. + +**Returns:** + +- Agent – The advanced RAG `Agent`. Call it with the question as a user message, + `agent.run(messages=[ChatMessage.from_user(question)])`; the answer is in `last_message` (a `ChatMessage`) and + `documents` carries every document the agent retrieved during the run (deduplicated by id, in first-retrieved + order) — the answer cites them by the first 8 characters of their id, e.g. `[doc a1b2c3d4]`. The standard Agent + outputs `messages`, `step_count`, `token_usage` and `tool_call_counts` are also returned. + +## haystack_integrations.agent_pack.advanced_rag.hooks + +### BackupAnswerHook + +Produce a final answer when the agent run ends without one. Runs as an `after_run` hook. + +When the agent exhausts `max_agent_steps` mid-investigation, the run ends on a tool call or tool result instead of +an assistant text answer (and only `after_run` hooks run in this situation). This hook detects that case and makes +one LLM call over the conversation so far to produce a best-effort answer from the already-gathered evidence. + +#### __init__ + +```python +__init__(chat_generator: ChatGenerator) -> None +``` + +Create the hook. + +**Parameters:** + +- **chat_generator** (ChatGenerator) – LLM that writes the backup answer from the gathered evidence. + +#### warm_up + +```python +warm_up() -> None +``` + +Prepare the hook's generator for use; called from the Agent's `warm_up`. + +#### close + +```python +close() -> None +``` + +Release the hook's generator resources; called from the Agent's `close`. + +#### to_dict + +```python +to_dict() -> dict +``` + +Serialize the hook to a dictionary. + +**Returns:** + +- dict – Dictionary with serialized data. + +#### from_dict + +```python +from_dict(data: dict) -> BackupAnswerHook +``` + +Deserialize the hook from a dictionary. + +**Parameters:** + +- **data** (dict) – Dictionary to deserialize from. + +**Returns:** + +- BackupAnswerHook – Deserialized hook. + +#### run + +```python +run(state: State) -> None +``` + +Append a best-effort final answer when the run ended without one (e.g. step exhaustion). + +**Parameters:** + +- **state** (State) – The agent run's state. + +## haystack_integrations.agent_pack.advanced_rag.tools + +### ListMetadataFieldsTool + +Bases: Tool + +Tool that lists all metadata fields and their types from a document store. + +#### __init__ + +```python +__init__(document_store: DocumentStore) -> None +``` + +Create the tool. + +**Parameters:** + +- **document_store** (DocumentStore) – The document store to inspect. Must implement `get_metadata_fields_info`. + +**Raises:** + +- ValueError – If the store does not implement `get_metadata_fields_info`. + +#### to_dict + +```python +to_dict() -> dict[str, Any] +``` + +Serialize the tool to a dictionary. + +#### from_dict + +```python +from_dict(data: dict[str, Any]) -> ListMetadataFieldsTool +``` + +Deserialize the tool from a dictionary. + +**Parameters:** + +- **data** (dict\[str, Any\]) – The dictionary produced by `to_dict`. + +**Returns:** + +- ListMetadataFieldsTool – The deserialized tool. + +### GetMetadataFieldValuesTool + +Bases: Tool + +Tool that returns the distinct values of a metadata field from a document store. + +#### __init__ + +```python +__init__(document_store: DocumentStore) -> None +``` + +Create the tool. + +**Parameters:** + +- **document_store** (DocumentStore) – The document store to inspect. Must implement `get_metadata_field_unique_values`. + +**Raises:** + +- ValueError – If the store does not implement `get_metadata_field_unique_values`. + +#### to_dict + +```python +to_dict() -> dict[str, Any] +``` + +Serialize the tool to a dictionary. + +#### from_dict + +```python +from_dict(data: dict[str, Any]) -> GetMetadataFieldValuesTool +``` + +Deserialize the tool from a dictionary. + +**Parameters:** + +- **data** (dict\[str, Any\]) – The dictionary produced by `to_dict`. + +**Returns:** + +- GetMetadataFieldValuesTool – The deserialized tool. + +### GetMetadataFieldRangeTool + +Bases: Tool + +Tool that returns the minimum and maximum values of a metadata field from a document store. + +#### __init__ + +```python +__init__(document_store: DocumentStore) -> None +``` + +Create the tool. + +**Parameters:** + +- **document_store** (DocumentStore) – The document store to inspect. Must implement `get_metadata_field_min_max`. + +**Raises:** + +- ValueError – If the store does not implement `get_metadata_field_min_max`. + +#### to_dict + +```python +to_dict() -> dict[str, Any] +``` + +Serialize the tool to a dictionary. + +#### from_dict + +```python +from_dict(data: dict[str, Any]) -> GetMetadataFieldRangeTool +``` + +Deserialize the tool from a dictionary. + +**Parameters:** + +- **data** (dict\[str, Any\]) – The dictionary produced by `to_dict`. + +**Returns:** + +- GetMetadataFieldRangeTool – The deserialized tool. + +### FetchDocumentsByFilterTool + +Bases: Tool + +Tool that fetches documents directly from a document store by metadata filter. + +Unlike a scored retrieval tool, this fetches without any relevance ranking, so an agent can grab specific documents +(e.g. a known title or source file) without going through a relevance search. The fetched documents are put into +reading order first: grouped by their parent file (`file_name`/`file_path`/`source_id`) and sorted by their +position within it (`split_id`/`split_idx_start`/`page_number`), using whichever of those metadata fields the +documents carry. Match sets larger than `max_docs` are paged: each call returns one page plus the total match +count, and the tool's `offset` input continues where the previous page ended. + +#### __init__ + +```python +__init__( + document_store: DocumentStore, + max_docs: int = 10, + max_fetch_factor: int = 10, +) -> None +``` + +Create the tool. + +**Parameters:** + +- **document_store** (DocumentStore) – The document store to fetch documents from. +- **max_docs** (int) – Ceiling on the number of documents shown to the agent per fetch. Unlike scored retrieval, a + filter fetch is not bounded by a retriever's `top_k`, so this caps the tool result instead. The LLM can + request fewer via the tool's optional `max_docs` input, but never more. +- **max_fetch_factor** (int) – How many times the `max_docs` ceiling a filter may match before the fetch is + refused outright (when the store supports `count_documents_by_filter`) — the refusal is surfaced to the + LLM as an error it can recover from by narrowing the filter. + +#### to_dict + +```python +to_dict() -> dict[str, Any] +``` + +Serialize the tool to a dictionary. + +#### from_dict + +```python +from_dict(data: dict[str, Any]) -> FetchDocumentsByFilterTool +``` + +Deserialize the tool from a dictionary. + +**Parameters:** + +- **data** (dict\[str, Any\]) – The dictionary produced by `to_dict`. + +**Returns:** + +- FetchDocumentsByFilterTool – The deserialized tool. + +### DocumentStoreToolset + +Bases: Toolset + +All document-store-backed tools as one unit. + +Bundles the three metadata inspection tools (`ListMetadataFieldsTool`, `GetMetadataFieldValuesTool`, +`GetMetadataFieldRangeTool`) and the direct `FetchDocumentsByFilterTool`, so they can be handed to an `Agent` +(or combined with a retrieval tool) as a single object. + +#### __init__ + +```python +__init__(document_store: DocumentStore, max_fetched_docs: int = 10) -> None +``` + +Create the toolset. + +**Parameters:** + +- **document_store** (DocumentStore) – The document store all tools run against. Must implement the metadata introspection + methods (`get_metadata_fields_info`, `get_metadata_field_unique_values`, `get_metadata_field_min_max`). +- **max_fetched_docs** (int) – Maximum number of documents `fetch_documents_by_filter` shows per fetch (see + `FetchDocumentsByFilterTool.max_docs`). + +#### to_dict + +```python +to_dict() -> dict[str, Any] +``` + +Serialize the toolset to a dictionary. + +#### from_dict + +```python +from_dict(data: dict[str, Any]) -> DocumentStoreToolset +``` + +Deserialize the toolset from a dictionary. + +**Parameters:** + +- **data** (dict\[str, Any\]) – The dictionary produced by `to_dict`. + +**Returns:** + +- DocumentStoreToolset – The deserialized toolset. + +## haystack_integrations.agent_pack.deep_research.agent + +### create_deep_research_agent + +```python +create_deep_research_agent( + *, + scope_llm: ChatGenerator | None = None, + orchestrator_llm: ChatGenerator | None = None, + researcher_llm: ChatGenerator | None = None, + summarizer_llm: ChatGenerator | None = None, + writer_llm: ChatGenerator | None = None, + max_subtopics: int = 5, + max_concurrent_researchers: int = 5, + max_orchestrator_steps: int = 8, + max_researcher_steps: int = 20, + max_search_results: int = 10, + max_content_length: int = 50000 +) -> Agent +``` + +Create the deep research agent. + +**Parameters:** + +- **scope_llm** (ChatGenerator | None) – LLM that rewrites the user query into a focused research brief. + Defaults to `OpenAIResponsesChatGenerator("gpt-5.4")`. +- **orchestrator_llm** (ChatGenerator | None) – LLM that plans the investigation and delegates the sub-questions. + Defaults to `OpenAIResponsesChatGenerator("gpt-5.4")`. +- **researcher_llm** (ChatGenerator | None) – LLM that drives each sub-researcher's search/read/think loop. + Defaults to `OpenAIResponsesChatGenerator("gpt-5.4-mini")`. +- **summarizer_llm** (ChatGenerator | None) – LLM used inside the `read_url` tool to summarize a fetched page toward + the question. Defaults to `OpenAIResponsesChatGenerator("gpt-5.4-mini")`. +- **writer_llm** (ChatGenerator | None) – LLM that turns the brief plus collected notes into the final report. + Defaults to `OpenAIResponsesChatGenerator("gpt-5.4")`. +- **max_subtopics** (int) – Maximum number of sub-questions the orchestrator may delegate (breadth). +- **max_concurrent_researchers** (int) – Maximum number of sub-researchers that run at the same time. +- **max_orchestrator_steps** (int) – Maximum steps for the orchestrator's agent loop (reflect -> delegate rounds). +- **max_researcher_steps** (int) – Maximum steps for each sub-researcher's agent loop. +- **max_search_results** (int) – Number of results returned per `web_search` call. +- **max_content_length** (int) – Maximum raw page characters fed to the summarizer, before summarization. + +**Returns:** + +- Agent – The deep research `Agent`. Call it with the question as a user message, + `agent.run(messages=[ChatMessage.from_user(question)])`; it returns a dict whose main output is + `report` (the final markdown report, a `str`). The dict also carries the intermediate `brief` + (`str`) and `notes` (`list[str]`), plus the standard Agent outputs `messages`, `last_message`, + `step_count`, `token_usage` and `tool_call_counts`. diff --git a/docs-website/reference_versioned_docs/version-2.18/integrations-api/agent_pack.md b/docs-website/reference_versioned_docs/version-2.18/integrations-api/agent_pack.md new file mode 100644 index 0000000000..2921c4d640 --- /dev/null +++ b/docs-website/reference_versioned_docs/version-2.18/integrations-api/agent_pack.md @@ -0,0 +1,463 @@ +--- +title: "Agent Pack" +id: integrations-agent-pack +description: "Agent Pack integration for Haystack" +slug: "/integrations-agent-pack" +--- + + +## haystack_integrations.agent_pack.advanced_rag.agent + +### create_advanced_rag_agent + +```python +create_advanced_rag_agent( + *, + document_store: DocumentStore, + retriever: TextRetriever | Pipeline | None = None, + retrieval_pipeline_input_mapping: dict[str, list[str]] | None = None, + retrieval_pipeline_output_mapping: dict[str, str] | None = None, + llm: ChatGenerator | None = None, + backup_answer_llm: ChatGenerator | None = None, + system_prompt: str | None = None, + max_agent_steps: int = 20, + max_fetched_docs: int = 10, + extra_tools: ToolsType | None = None, + state_schema: dict[str, Any] | None = None, + hooks: dict[HookPoint, list[Hook]] | None = None, + raise_on_tool_invocation_failure: bool = False, + tool_concurrency_limit: int = 4 +) -> Agent +``` + +Create the advanced RAG agent. + +The agent answers questions from documents it retrieves out of the document store. Instead of guessing which +metadata fields exist, it can inspect the store (fields, values, ranges) and construct a Haystack filter to +narrow its retrieval when metadata helps — plain, unfiltered retrieval remains available when it doesn't. The +answer cites the retrieved documents. + +The required `retriever` becomes the `search_documents` tool; `document_store` additionally feeds the three +metadata inspection tools and must implement the metadata introspection methods (`get_metadata_fields_info`, +`get_metadata_field_unique_values`, `get_metadata_field_min_max`). + +**Parameters:** + +- **document_store** (DocumentStore) – The document store the metadata inspection tools and the `fetch_documents_by_filter` tool + run against. +- **retriever** (TextRetriever | Pipeline | None) – What retrieves for the `search_documents` tool (required). Either a standalone retriever + component following the `TextRetriever` protocol, i.e. its `run` method accepts `query` and `filters` + (e.g. `InMemoryBM25Retriever`, or an embedding retriever wrapped in `TextEmbeddingRetriever`), or a custom + retrieval `Pipeline` (e.g. embedder -> retriever, or hybrid retrieval) — a pipeline additionally requires + `retrieval_pipeline_input_mapping`. It should retrieve by relevance scoring (keyword or embedding-based) — + direct, unscored fetching is already covered by the built-in `fetch_documents_by_filter` tool. +- **retrieval_pipeline_input_mapping** (dict\[str, list\[str\]\] | None) – Required when `retriever` is a `Pipeline`: maps the tool inputs to + pipeline input sockets; must have exactly the keys "query" and "filters", + e.g. `{"query": ["embedder.text"], "filters": ["retriever.filters"]}`. +- **retrieval_pipeline_output_mapping** (dict\[str, str\] | None) – Optional when `retriever` is a `Pipeline`: maps pipeline output sockets + to tool outputs, e.g. `{"retriever.documents": "documents"}`. +- **llm** (ChatGenerator | None) – LLM that drives the agent loop. Defaults to `OpenAIResponsesChatGenerator("gpt-5.4")` with low + reasoning effort. +- **backup_answer_llm** (ChatGenerator | None) – LLM the built-in `BackupAnswerHook` uses to write a best-effort answer when the run + is cut off by `max_agent_steps`. Defaults to a separate `OpenAIResponsesChatGenerator("gpt-5.4")` with low + reasoning effort. +- **system_prompt** (str | None) – Overrides the pre-made system prompt. +- **max_agent_steps** (int) – Maximum steps for the agent loop. If the loop is cut off by this limit before writing an + answer, an `after_run` hook (`BackupAnswerHook`) makes one extra LLM call to produce a best-effort answer from + the evidence gathered so far, so `last_message` always carries a text answer. +- **max_fetched_docs** (int) – Maximum number of documents `fetch_documents_by_filter` shows per fetch. A filter fetch is + not bounded by a retriever's `top_k`, so this caps the tool result instead; the scored `search_documents` tool + is bounded by the `top_k` configured on your retrieval components. +- **extra_tools** (ToolsType | None) – Additional tools (or toolsets) for the agent, appended after the built-in document-store + toolset and the retrieval tool. +- **state_schema** (dict\[str, Any\] | None) – Additional entries merged into the agent's state schema. The built-in `documents` entry + (the accumulated retrieved documents) always takes precedence. +- **hooks** (dict\[HookPoint, list\[Hook\]\] | None) – Additional hooks per hook point, merged with the built-in hooks. For `after_run`, the built-in + backup-answer hook runs first, so custom hooks see the final answer. +- **raise_on_tool_invocation_failure** (bool) – If True, a failing tool call raises instead of being returned to the LLM + as an error message it can recover from (the default). +- **tool_concurrency_limit** (int) – Maximum number of tool calls executed in parallel within one agent step. + +**Returns:** + +- Agent – The advanced RAG `Agent`. Call it with the question as a user message, + `agent.run(messages=[ChatMessage.from_user(question)])`; the answer is in `last_message` (a `ChatMessage`) and + `documents` carries every document the agent retrieved during the run (deduplicated by id, in first-retrieved + order) — the answer cites them by the first 8 characters of their id, e.g. `[doc a1b2c3d4]`. The standard Agent + outputs `messages`, `step_count`, `token_usage` and `tool_call_counts` are also returned. + +## haystack_integrations.agent_pack.advanced_rag.hooks + +### BackupAnswerHook + +Produce a final answer when the agent run ends without one. Runs as an `after_run` hook. + +When the agent exhausts `max_agent_steps` mid-investigation, the run ends on a tool call or tool result instead of +an assistant text answer (and only `after_run` hooks run in this situation). This hook detects that case and makes +one LLM call over the conversation so far to produce a best-effort answer from the already-gathered evidence. + +#### __init__ + +```python +__init__(chat_generator: ChatGenerator) -> None +``` + +Create the hook. + +**Parameters:** + +- **chat_generator** (ChatGenerator) – LLM that writes the backup answer from the gathered evidence. + +#### warm_up + +```python +warm_up() -> None +``` + +Prepare the hook's generator for use; called from the Agent's `warm_up`. + +#### close + +```python +close() -> None +``` + +Release the hook's generator resources; called from the Agent's `close`. + +#### to_dict + +```python +to_dict() -> dict +``` + +Serialize the hook to a dictionary. + +**Returns:** + +- dict – Dictionary with serialized data. + +#### from_dict + +```python +from_dict(data: dict) -> BackupAnswerHook +``` + +Deserialize the hook from a dictionary. + +**Parameters:** + +- **data** (dict) – Dictionary to deserialize from. + +**Returns:** + +- BackupAnswerHook – Deserialized hook. + +#### run + +```python +run(state: State) -> None +``` + +Append a best-effort final answer when the run ended without one (e.g. step exhaustion). + +**Parameters:** + +- **state** (State) – The agent run's state. + +## haystack_integrations.agent_pack.advanced_rag.tools + +### ListMetadataFieldsTool + +Bases: Tool + +Tool that lists all metadata fields and their types from a document store. + +#### __init__ + +```python +__init__(document_store: DocumentStore) -> None +``` + +Create the tool. + +**Parameters:** + +- **document_store** (DocumentStore) – The document store to inspect. Must implement `get_metadata_fields_info`. + +**Raises:** + +- ValueError – If the store does not implement `get_metadata_fields_info`. + +#### to_dict + +```python +to_dict() -> dict[str, Any] +``` + +Serialize the tool to a dictionary. + +#### from_dict + +```python +from_dict(data: dict[str, Any]) -> ListMetadataFieldsTool +``` + +Deserialize the tool from a dictionary. + +**Parameters:** + +- **data** (dict\[str, Any\]) – The dictionary produced by `to_dict`. + +**Returns:** + +- ListMetadataFieldsTool – The deserialized tool. + +### GetMetadataFieldValuesTool + +Bases: Tool + +Tool that returns the distinct values of a metadata field from a document store. + +#### __init__ + +```python +__init__(document_store: DocumentStore) -> None +``` + +Create the tool. + +**Parameters:** + +- **document_store** (DocumentStore) – The document store to inspect. Must implement `get_metadata_field_unique_values`. + +**Raises:** + +- ValueError – If the store does not implement `get_metadata_field_unique_values`. + +#### to_dict + +```python +to_dict() -> dict[str, Any] +``` + +Serialize the tool to a dictionary. + +#### from_dict + +```python +from_dict(data: dict[str, Any]) -> GetMetadataFieldValuesTool +``` + +Deserialize the tool from a dictionary. + +**Parameters:** + +- **data** (dict\[str, Any\]) – The dictionary produced by `to_dict`. + +**Returns:** + +- GetMetadataFieldValuesTool – The deserialized tool. + +### GetMetadataFieldRangeTool + +Bases: Tool + +Tool that returns the minimum and maximum values of a metadata field from a document store. + +#### __init__ + +```python +__init__(document_store: DocumentStore) -> None +``` + +Create the tool. + +**Parameters:** + +- **document_store** (DocumentStore) – The document store to inspect. Must implement `get_metadata_field_min_max`. + +**Raises:** + +- ValueError – If the store does not implement `get_metadata_field_min_max`. + +#### to_dict + +```python +to_dict() -> dict[str, Any] +``` + +Serialize the tool to a dictionary. + +#### from_dict + +```python +from_dict(data: dict[str, Any]) -> GetMetadataFieldRangeTool +``` + +Deserialize the tool from a dictionary. + +**Parameters:** + +- **data** (dict\[str, Any\]) – The dictionary produced by `to_dict`. + +**Returns:** + +- GetMetadataFieldRangeTool – The deserialized tool. + +### FetchDocumentsByFilterTool + +Bases: Tool + +Tool that fetches documents directly from a document store by metadata filter. + +Unlike a scored retrieval tool, this fetches without any relevance ranking, so an agent can grab specific documents +(e.g. a known title or source file) without going through a relevance search. The fetched documents are put into +reading order first: grouped by their parent file (`file_name`/`file_path`/`source_id`) and sorted by their +position within it (`split_id`/`split_idx_start`/`page_number`), using whichever of those metadata fields the +documents carry. Match sets larger than `max_docs` are paged: each call returns one page plus the total match +count, and the tool's `offset` input continues where the previous page ended. + +#### __init__ + +```python +__init__( + document_store: DocumentStore, + max_docs: int = 10, + max_fetch_factor: int = 10, +) -> None +``` + +Create the tool. + +**Parameters:** + +- **document_store** (DocumentStore) – The document store to fetch documents from. +- **max_docs** (int) – Ceiling on the number of documents shown to the agent per fetch. Unlike scored retrieval, a + filter fetch is not bounded by a retriever's `top_k`, so this caps the tool result instead. The LLM can + request fewer via the tool's optional `max_docs` input, but never more. +- **max_fetch_factor** (int) – How many times the `max_docs` ceiling a filter may match before the fetch is + refused outright (when the store supports `count_documents_by_filter`) — the refusal is surfaced to the + LLM as an error it can recover from by narrowing the filter. + +#### to_dict + +```python +to_dict() -> dict[str, Any] +``` + +Serialize the tool to a dictionary. + +#### from_dict + +```python +from_dict(data: dict[str, Any]) -> FetchDocumentsByFilterTool +``` + +Deserialize the tool from a dictionary. + +**Parameters:** + +- **data** (dict\[str, Any\]) – The dictionary produced by `to_dict`. + +**Returns:** + +- FetchDocumentsByFilterTool – The deserialized tool. + +### DocumentStoreToolset + +Bases: Toolset + +All document-store-backed tools as one unit. + +Bundles the three metadata inspection tools (`ListMetadataFieldsTool`, `GetMetadataFieldValuesTool`, +`GetMetadataFieldRangeTool`) and the direct `FetchDocumentsByFilterTool`, so they can be handed to an `Agent` +(or combined with a retrieval tool) as a single object. + +#### __init__ + +```python +__init__(document_store: DocumentStore, max_fetched_docs: int = 10) -> None +``` + +Create the toolset. + +**Parameters:** + +- **document_store** (DocumentStore) – The document store all tools run against. Must implement the metadata introspection + methods (`get_metadata_fields_info`, `get_metadata_field_unique_values`, `get_metadata_field_min_max`). +- **max_fetched_docs** (int) – Maximum number of documents `fetch_documents_by_filter` shows per fetch (see + `FetchDocumentsByFilterTool.max_docs`). + +#### to_dict + +```python +to_dict() -> dict[str, Any] +``` + +Serialize the toolset to a dictionary. + +#### from_dict + +```python +from_dict(data: dict[str, Any]) -> DocumentStoreToolset +``` + +Deserialize the toolset from a dictionary. + +**Parameters:** + +- **data** (dict\[str, Any\]) – The dictionary produced by `to_dict`. + +**Returns:** + +- DocumentStoreToolset – The deserialized toolset. + +## haystack_integrations.agent_pack.deep_research.agent + +### create_deep_research_agent + +```python +create_deep_research_agent( + *, + scope_llm: ChatGenerator | None = None, + orchestrator_llm: ChatGenerator | None = None, + researcher_llm: ChatGenerator | None = None, + summarizer_llm: ChatGenerator | None = None, + writer_llm: ChatGenerator | None = None, + max_subtopics: int = 5, + max_concurrent_researchers: int = 5, + max_orchestrator_steps: int = 8, + max_researcher_steps: int = 20, + max_search_results: int = 10, + max_content_length: int = 50000 +) -> Agent +``` + +Create the deep research agent. + +**Parameters:** + +- **scope_llm** (ChatGenerator | None) – LLM that rewrites the user query into a focused research brief. + Defaults to `OpenAIResponsesChatGenerator("gpt-5.4")`. +- **orchestrator_llm** (ChatGenerator | None) – LLM that plans the investigation and delegates the sub-questions. + Defaults to `OpenAIResponsesChatGenerator("gpt-5.4")`. +- **researcher_llm** (ChatGenerator | None) – LLM that drives each sub-researcher's search/read/think loop. + Defaults to `OpenAIResponsesChatGenerator("gpt-5.4-mini")`. +- **summarizer_llm** (ChatGenerator | None) – LLM used inside the `read_url` tool to summarize a fetched page toward + the question. Defaults to `OpenAIResponsesChatGenerator("gpt-5.4-mini")`. +- **writer_llm** (ChatGenerator | None) – LLM that turns the brief plus collected notes into the final report. + Defaults to `OpenAIResponsesChatGenerator("gpt-5.4")`. +- **max_subtopics** (int) – Maximum number of sub-questions the orchestrator may delegate (breadth). +- **max_concurrent_researchers** (int) – Maximum number of sub-researchers that run at the same time. +- **max_orchestrator_steps** (int) – Maximum steps for the orchestrator's agent loop (reflect -> delegate rounds). +- **max_researcher_steps** (int) – Maximum steps for each sub-researcher's agent loop. +- **max_search_results** (int) – Number of results returned per `web_search` call. +- **max_content_length** (int) – Maximum raw page characters fed to the summarizer, before summarization. + +**Returns:** + +- Agent – The deep research `Agent`. Call it with the question as a user message, + `agent.run(messages=[ChatMessage.from_user(question)])`; it returns a dict whose main output is + `report` (the final markdown report, a `str`). The dict also carries the intermediate `brief` + (`str`) and `notes` (`list[str]`), plus the standard Agent outputs `messages`, `last_message`, + `step_count`, `token_usage` and `tool_call_counts`. diff --git a/docs-website/reference_versioned_docs/version-2.19/integrations-api/agent_pack.md b/docs-website/reference_versioned_docs/version-2.19/integrations-api/agent_pack.md new file mode 100644 index 0000000000..2921c4d640 --- /dev/null +++ b/docs-website/reference_versioned_docs/version-2.19/integrations-api/agent_pack.md @@ -0,0 +1,463 @@ +--- +title: "Agent Pack" +id: integrations-agent-pack +description: "Agent Pack integration for Haystack" +slug: "/integrations-agent-pack" +--- + + +## haystack_integrations.agent_pack.advanced_rag.agent + +### create_advanced_rag_agent + +```python +create_advanced_rag_agent( + *, + document_store: DocumentStore, + retriever: TextRetriever | Pipeline | None = None, + retrieval_pipeline_input_mapping: dict[str, list[str]] | None = None, + retrieval_pipeline_output_mapping: dict[str, str] | None = None, + llm: ChatGenerator | None = None, + backup_answer_llm: ChatGenerator | None = None, + system_prompt: str | None = None, + max_agent_steps: int = 20, + max_fetched_docs: int = 10, + extra_tools: ToolsType | None = None, + state_schema: dict[str, Any] | None = None, + hooks: dict[HookPoint, list[Hook]] | None = None, + raise_on_tool_invocation_failure: bool = False, + tool_concurrency_limit: int = 4 +) -> Agent +``` + +Create the advanced RAG agent. + +The agent answers questions from documents it retrieves out of the document store. Instead of guessing which +metadata fields exist, it can inspect the store (fields, values, ranges) and construct a Haystack filter to +narrow its retrieval when metadata helps — plain, unfiltered retrieval remains available when it doesn't. The +answer cites the retrieved documents. + +The required `retriever` becomes the `search_documents` tool; `document_store` additionally feeds the three +metadata inspection tools and must implement the metadata introspection methods (`get_metadata_fields_info`, +`get_metadata_field_unique_values`, `get_metadata_field_min_max`). + +**Parameters:** + +- **document_store** (DocumentStore) – The document store the metadata inspection tools and the `fetch_documents_by_filter` tool + run against. +- **retriever** (TextRetriever | Pipeline | None) – What retrieves for the `search_documents` tool (required). Either a standalone retriever + component following the `TextRetriever` protocol, i.e. its `run` method accepts `query` and `filters` + (e.g. `InMemoryBM25Retriever`, or an embedding retriever wrapped in `TextEmbeddingRetriever`), or a custom + retrieval `Pipeline` (e.g. embedder -> retriever, or hybrid retrieval) — a pipeline additionally requires + `retrieval_pipeline_input_mapping`. It should retrieve by relevance scoring (keyword or embedding-based) — + direct, unscored fetching is already covered by the built-in `fetch_documents_by_filter` tool. +- **retrieval_pipeline_input_mapping** (dict\[str, list\[str\]\] | None) – Required when `retriever` is a `Pipeline`: maps the tool inputs to + pipeline input sockets; must have exactly the keys "query" and "filters", + e.g. `{"query": ["embedder.text"], "filters": ["retriever.filters"]}`. +- **retrieval_pipeline_output_mapping** (dict\[str, str\] | None) – Optional when `retriever` is a `Pipeline`: maps pipeline output sockets + to tool outputs, e.g. `{"retriever.documents": "documents"}`. +- **llm** (ChatGenerator | None) – LLM that drives the agent loop. Defaults to `OpenAIResponsesChatGenerator("gpt-5.4")` with low + reasoning effort. +- **backup_answer_llm** (ChatGenerator | None) – LLM the built-in `BackupAnswerHook` uses to write a best-effort answer when the run + is cut off by `max_agent_steps`. Defaults to a separate `OpenAIResponsesChatGenerator("gpt-5.4")` with low + reasoning effort. +- **system_prompt** (str | None) – Overrides the pre-made system prompt. +- **max_agent_steps** (int) – Maximum steps for the agent loop. If the loop is cut off by this limit before writing an + answer, an `after_run` hook (`BackupAnswerHook`) makes one extra LLM call to produce a best-effort answer from + the evidence gathered so far, so `last_message` always carries a text answer. +- **max_fetched_docs** (int) – Maximum number of documents `fetch_documents_by_filter` shows per fetch. A filter fetch is + not bounded by a retriever's `top_k`, so this caps the tool result instead; the scored `search_documents` tool + is bounded by the `top_k` configured on your retrieval components. +- **extra_tools** (ToolsType | None) – Additional tools (or toolsets) for the agent, appended after the built-in document-store + toolset and the retrieval tool. +- **state_schema** (dict\[str, Any\] | None) – Additional entries merged into the agent's state schema. The built-in `documents` entry + (the accumulated retrieved documents) always takes precedence. +- **hooks** (dict\[HookPoint, list\[Hook\]\] | None) – Additional hooks per hook point, merged with the built-in hooks. For `after_run`, the built-in + backup-answer hook runs first, so custom hooks see the final answer. +- **raise_on_tool_invocation_failure** (bool) – If True, a failing tool call raises instead of being returned to the LLM + as an error message it can recover from (the default). +- **tool_concurrency_limit** (int) – Maximum number of tool calls executed in parallel within one agent step. + +**Returns:** + +- Agent – The advanced RAG `Agent`. Call it with the question as a user message, + `agent.run(messages=[ChatMessage.from_user(question)])`; the answer is in `last_message` (a `ChatMessage`) and + `documents` carries every document the agent retrieved during the run (deduplicated by id, in first-retrieved + order) — the answer cites them by the first 8 characters of their id, e.g. `[doc a1b2c3d4]`. The standard Agent + outputs `messages`, `step_count`, `token_usage` and `tool_call_counts` are also returned. + +## haystack_integrations.agent_pack.advanced_rag.hooks + +### BackupAnswerHook + +Produce a final answer when the agent run ends without one. Runs as an `after_run` hook. + +When the agent exhausts `max_agent_steps` mid-investigation, the run ends on a tool call or tool result instead of +an assistant text answer (and only `after_run` hooks run in this situation). This hook detects that case and makes +one LLM call over the conversation so far to produce a best-effort answer from the already-gathered evidence. + +#### __init__ + +```python +__init__(chat_generator: ChatGenerator) -> None +``` + +Create the hook. + +**Parameters:** + +- **chat_generator** (ChatGenerator) – LLM that writes the backup answer from the gathered evidence. + +#### warm_up + +```python +warm_up() -> None +``` + +Prepare the hook's generator for use; called from the Agent's `warm_up`. + +#### close + +```python +close() -> None +``` + +Release the hook's generator resources; called from the Agent's `close`. + +#### to_dict + +```python +to_dict() -> dict +``` + +Serialize the hook to a dictionary. + +**Returns:** + +- dict – Dictionary with serialized data. + +#### from_dict + +```python +from_dict(data: dict) -> BackupAnswerHook +``` + +Deserialize the hook from a dictionary. + +**Parameters:** + +- **data** (dict) – Dictionary to deserialize from. + +**Returns:** + +- BackupAnswerHook – Deserialized hook. + +#### run + +```python +run(state: State) -> None +``` + +Append a best-effort final answer when the run ended without one (e.g. step exhaustion). + +**Parameters:** + +- **state** (State) – The agent run's state. + +## haystack_integrations.agent_pack.advanced_rag.tools + +### ListMetadataFieldsTool + +Bases: Tool + +Tool that lists all metadata fields and their types from a document store. + +#### __init__ + +```python +__init__(document_store: DocumentStore) -> None +``` + +Create the tool. + +**Parameters:** + +- **document_store** (DocumentStore) – The document store to inspect. Must implement `get_metadata_fields_info`. + +**Raises:** + +- ValueError – If the store does not implement `get_metadata_fields_info`. + +#### to_dict + +```python +to_dict() -> dict[str, Any] +``` + +Serialize the tool to a dictionary. + +#### from_dict + +```python +from_dict(data: dict[str, Any]) -> ListMetadataFieldsTool +``` + +Deserialize the tool from a dictionary. + +**Parameters:** + +- **data** (dict\[str, Any\]) – The dictionary produced by `to_dict`. + +**Returns:** + +- ListMetadataFieldsTool – The deserialized tool. + +### GetMetadataFieldValuesTool + +Bases: Tool + +Tool that returns the distinct values of a metadata field from a document store. + +#### __init__ + +```python +__init__(document_store: DocumentStore) -> None +``` + +Create the tool. + +**Parameters:** + +- **document_store** (DocumentStore) – The document store to inspect. Must implement `get_metadata_field_unique_values`. + +**Raises:** + +- ValueError – If the store does not implement `get_metadata_field_unique_values`. + +#### to_dict + +```python +to_dict() -> dict[str, Any] +``` + +Serialize the tool to a dictionary. + +#### from_dict + +```python +from_dict(data: dict[str, Any]) -> GetMetadataFieldValuesTool +``` + +Deserialize the tool from a dictionary. + +**Parameters:** + +- **data** (dict\[str, Any\]) – The dictionary produced by `to_dict`. + +**Returns:** + +- GetMetadataFieldValuesTool – The deserialized tool. + +### GetMetadataFieldRangeTool + +Bases: Tool + +Tool that returns the minimum and maximum values of a metadata field from a document store. + +#### __init__ + +```python +__init__(document_store: DocumentStore) -> None +``` + +Create the tool. + +**Parameters:** + +- **document_store** (DocumentStore) – The document store to inspect. Must implement `get_metadata_field_min_max`. + +**Raises:** + +- ValueError – If the store does not implement `get_metadata_field_min_max`. + +#### to_dict + +```python +to_dict() -> dict[str, Any] +``` + +Serialize the tool to a dictionary. + +#### from_dict + +```python +from_dict(data: dict[str, Any]) -> GetMetadataFieldRangeTool +``` + +Deserialize the tool from a dictionary. + +**Parameters:** + +- **data** (dict\[str, Any\]) – The dictionary produced by `to_dict`. + +**Returns:** + +- GetMetadataFieldRangeTool – The deserialized tool. + +### FetchDocumentsByFilterTool + +Bases: Tool + +Tool that fetches documents directly from a document store by metadata filter. + +Unlike a scored retrieval tool, this fetches without any relevance ranking, so an agent can grab specific documents +(e.g. a known title or source file) without going through a relevance search. The fetched documents are put into +reading order first: grouped by their parent file (`file_name`/`file_path`/`source_id`) and sorted by their +position within it (`split_id`/`split_idx_start`/`page_number`), using whichever of those metadata fields the +documents carry. Match sets larger than `max_docs` are paged: each call returns one page plus the total match +count, and the tool's `offset` input continues where the previous page ended. + +#### __init__ + +```python +__init__( + document_store: DocumentStore, + max_docs: int = 10, + max_fetch_factor: int = 10, +) -> None +``` + +Create the tool. + +**Parameters:** + +- **document_store** (DocumentStore) – The document store to fetch documents from. +- **max_docs** (int) – Ceiling on the number of documents shown to the agent per fetch. Unlike scored retrieval, a + filter fetch is not bounded by a retriever's `top_k`, so this caps the tool result instead. The LLM can + request fewer via the tool's optional `max_docs` input, but never more. +- **max_fetch_factor** (int) – How many times the `max_docs` ceiling a filter may match before the fetch is + refused outright (when the store supports `count_documents_by_filter`) — the refusal is surfaced to the + LLM as an error it can recover from by narrowing the filter. + +#### to_dict + +```python +to_dict() -> dict[str, Any] +``` + +Serialize the tool to a dictionary. + +#### from_dict + +```python +from_dict(data: dict[str, Any]) -> FetchDocumentsByFilterTool +``` + +Deserialize the tool from a dictionary. + +**Parameters:** + +- **data** (dict\[str, Any\]) – The dictionary produced by `to_dict`. + +**Returns:** + +- FetchDocumentsByFilterTool – The deserialized tool. + +### DocumentStoreToolset + +Bases: Toolset + +All document-store-backed tools as one unit. + +Bundles the three metadata inspection tools (`ListMetadataFieldsTool`, `GetMetadataFieldValuesTool`, +`GetMetadataFieldRangeTool`) and the direct `FetchDocumentsByFilterTool`, so they can be handed to an `Agent` +(or combined with a retrieval tool) as a single object. + +#### __init__ + +```python +__init__(document_store: DocumentStore, max_fetched_docs: int = 10) -> None +``` + +Create the toolset. + +**Parameters:** + +- **document_store** (DocumentStore) – The document store all tools run against. Must implement the metadata introspection + methods (`get_metadata_fields_info`, `get_metadata_field_unique_values`, `get_metadata_field_min_max`). +- **max_fetched_docs** (int) – Maximum number of documents `fetch_documents_by_filter` shows per fetch (see + `FetchDocumentsByFilterTool.max_docs`). + +#### to_dict + +```python +to_dict() -> dict[str, Any] +``` + +Serialize the toolset to a dictionary. + +#### from_dict + +```python +from_dict(data: dict[str, Any]) -> DocumentStoreToolset +``` + +Deserialize the toolset from a dictionary. + +**Parameters:** + +- **data** (dict\[str, Any\]) – The dictionary produced by `to_dict`. + +**Returns:** + +- DocumentStoreToolset – The deserialized toolset. + +## haystack_integrations.agent_pack.deep_research.agent + +### create_deep_research_agent + +```python +create_deep_research_agent( + *, + scope_llm: ChatGenerator | None = None, + orchestrator_llm: ChatGenerator | None = None, + researcher_llm: ChatGenerator | None = None, + summarizer_llm: ChatGenerator | None = None, + writer_llm: ChatGenerator | None = None, + max_subtopics: int = 5, + max_concurrent_researchers: int = 5, + max_orchestrator_steps: int = 8, + max_researcher_steps: int = 20, + max_search_results: int = 10, + max_content_length: int = 50000 +) -> Agent +``` + +Create the deep research agent. + +**Parameters:** + +- **scope_llm** (ChatGenerator | None) – LLM that rewrites the user query into a focused research brief. + Defaults to `OpenAIResponsesChatGenerator("gpt-5.4")`. +- **orchestrator_llm** (ChatGenerator | None) – LLM that plans the investigation and delegates the sub-questions. + Defaults to `OpenAIResponsesChatGenerator("gpt-5.4")`. +- **researcher_llm** (ChatGenerator | None) – LLM that drives each sub-researcher's search/read/think loop. + Defaults to `OpenAIResponsesChatGenerator("gpt-5.4-mini")`. +- **summarizer_llm** (ChatGenerator | None) – LLM used inside the `read_url` tool to summarize a fetched page toward + the question. Defaults to `OpenAIResponsesChatGenerator("gpt-5.4-mini")`. +- **writer_llm** (ChatGenerator | None) – LLM that turns the brief plus collected notes into the final report. + Defaults to `OpenAIResponsesChatGenerator("gpt-5.4")`. +- **max_subtopics** (int) – Maximum number of sub-questions the orchestrator may delegate (breadth). +- **max_concurrent_researchers** (int) – Maximum number of sub-researchers that run at the same time. +- **max_orchestrator_steps** (int) – Maximum steps for the orchestrator's agent loop (reflect -> delegate rounds). +- **max_researcher_steps** (int) – Maximum steps for each sub-researcher's agent loop. +- **max_search_results** (int) – Number of results returned per `web_search` call. +- **max_content_length** (int) – Maximum raw page characters fed to the summarizer, before summarization. + +**Returns:** + +- Agent – The deep research `Agent`. Call it with the question as a user message, + `agent.run(messages=[ChatMessage.from_user(question)])`; it returns a dict whose main output is + `report` (the final markdown report, a `str`). The dict also carries the intermediate `brief` + (`str`) and `notes` (`list[str]`), plus the standard Agent outputs `messages`, `last_message`, + `step_count`, `token_usage` and `tool_call_counts`. diff --git a/docs-website/reference_versioned_docs/version-2.20/integrations-api/agent_pack.md b/docs-website/reference_versioned_docs/version-2.20/integrations-api/agent_pack.md new file mode 100644 index 0000000000..2921c4d640 --- /dev/null +++ b/docs-website/reference_versioned_docs/version-2.20/integrations-api/agent_pack.md @@ -0,0 +1,463 @@ +--- +title: "Agent Pack" +id: integrations-agent-pack +description: "Agent Pack integration for Haystack" +slug: "/integrations-agent-pack" +--- + + +## haystack_integrations.agent_pack.advanced_rag.agent + +### create_advanced_rag_agent + +```python +create_advanced_rag_agent( + *, + document_store: DocumentStore, + retriever: TextRetriever | Pipeline | None = None, + retrieval_pipeline_input_mapping: dict[str, list[str]] | None = None, + retrieval_pipeline_output_mapping: dict[str, str] | None = None, + llm: ChatGenerator | None = None, + backup_answer_llm: ChatGenerator | None = None, + system_prompt: str | None = None, + max_agent_steps: int = 20, + max_fetched_docs: int = 10, + extra_tools: ToolsType | None = None, + state_schema: dict[str, Any] | None = None, + hooks: dict[HookPoint, list[Hook]] | None = None, + raise_on_tool_invocation_failure: bool = False, + tool_concurrency_limit: int = 4 +) -> Agent +``` + +Create the advanced RAG agent. + +The agent answers questions from documents it retrieves out of the document store. Instead of guessing which +metadata fields exist, it can inspect the store (fields, values, ranges) and construct a Haystack filter to +narrow its retrieval when metadata helps — plain, unfiltered retrieval remains available when it doesn't. The +answer cites the retrieved documents. + +The required `retriever` becomes the `search_documents` tool; `document_store` additionally feeds the three +metadata inspection tools and must implement the metadata introspection methods (`get_metadata_fields_info`, +`get_metadata_field_unique_values`, `get_metadata_field_min_max`). + +**Parameters:** + +- **document_store** (DocumentStore) – The document store the metadata inspection tools and the `fetch_documents_by_filter` tool + run against. +- **retriever** (TextRetriever | Pipeline | None) – What retrieves for the `search_documents` tool (required). Either a standalone retriever + component following the `TextRetriever` protocol, i.e. its `run` method accepts `query` and `filters` + (e.g. `InMemoryBM25Retriever`, or an embedding retriever wrapped in `TextEmbeddingRetriever`), or a custom + retrieval `Pipeline` (e.g. embedder -> retriever, or hybrid retrieval) — a pipeline additionally requires + `retrieval_pipeline_input_mapping`. It should retrieve by relevance scoring (keyword or embedding-based) — + direct, unscored fetching is already covered by the built-in `fetch_documents_by_filter` tool. +- **retrieval_pipeline_input_mapping** (dict\[str, list\[str\]\] | None) – Required when `retriever` is a `Pipeline`: maps the tool inputs to + pipeline input sockets; must have exactly the keys "query" and "filters", + e.g. `{"query": ["embedder.text"], "filters": ["retriever.filters"]}`. +- **retrieval_pipeline_output_mapping** (dict\[str, str\] | None) – Optional when `retriever` is a `Pipeline`: maps pipeline output sockets + to tool outputs, e.g. `{"retriever.documents": "documents"}`. +- **llm** (ChatGenerator | None) – LLM that drives the agent loop. Defaults to `OpenAIResponsesChatGenerator("gpt-5.4")` with low + reasoning effort. +- **backup_answer_llm** (ChatGenerator | None) – LLM the built-in `BackupAnswerHook` uses to write a best-effort answer when the run + is cut off by `max_agent_steps`. Defaults to a separate `OpenAIResponsesChatGenerator("gpt-5.4")` with low + reasoning effort. +- **system_prompt** (str | None) – Overrides the pre-made system prompt. +- **max_agent_steps** (int) – Maximum steps for the agent loop. If the loop is cut off by this limit before writing an + answer, an `after_run` hook (`BackupAnswerHook`) makes one extra LLM call to produce a best-effort answer from + the evidence gathered so far, so `last_message` always carries a text answer. +- **max_fetched_docs** (int) – Maximum number of documents `fetch_documents_by_filter` shows per fetch. A filter fetch is + not bounded by a retriever's `top_k`, so this caps the tool result instead; the scored `search_documents` tool + is bounded by the `top_k` configured on your retrieval components. +- **extra_tools** (ToolsType | None) – Additional tools (or toolsets) for the agent, appended after the built-in document-store + toolset and the retrieval tool. +- **state_schema** (dict\[str, Any\] | None) – Additional entries merged into the agent's state schema. The built-in `documents` entry + (the accumulated retrieved documents) always takes precedence. +- **hooks** (dict\[HookPoint, list\[Hook\]\] | None) – Additional hooks per hook point, merged with the built-in hooks. For `after_run`, the built-in + backup-answer hook runs first, so custom hooks see the final answer. +- **raise_on_tool_invocation_failure** (bool) – If True, a failing tool call raises instead of being returned to the LLM + as an error message it can recover from (the default). +- **tool_concurrency_limit** (int) – Maximum number of tool calls executed in parallel within one agent step. + +**Returns:** + +- Agent – The advanced RAG `Agent`. Call it with the question as a user message, + `agent.run(messages=[ChatMessage.from_user(question)])`; the answer is in `last_message` (a `ChatMessage`) and + `documents` carries every document the agent retrieved during the run (deduplicated by id, in first-retrieved + order) — the answer cites them by the first 8 characters of their id, e.g. `[doc a1b2c3d4]`. The standard Agent + outputs `messages`, `step_count`, `token_usage` and `tool_call_counts` are also returned. + +## haystack_integrations.agent_pack.advanced_rag.hooks + +### BackupAnswerHook + +Produce a final answer when the agent run ends without one. Runs as an `after_run` hook. + +When the agent exhausts `max_agent_steps` mid-investigation, the run ends on a tool call or tool result instead of +an assistant text answer (and only `after_run` hooks run in this situation). This hook detects that case and makes +one LLM call over the conversation so far to produce a best-effort answer from the already-gathered evidence. + +#### __init__ + +```python +__init__(chat_generator: ChatGenerator) -> None +``` + +Create the hook. + +**Parameters:** + +- **chat_generator** (ChatGenerator) – LLM that writes the backup answer from the gathered evidence. + +#### warm_up + +```python +warm_up() -> None +``` + +Prepare the hook's generator for use; called from the Agent's `warm_up`. + +#### close + +```python +close() -> None +``` + +Release the hook's generator resources; called from the Agent's `close`. + +#### to_dict + +```python +to_dict() -> dict +``` + +Serialize the hook to a dictionary. + +**Returns:** + +- dict – Dictionary with serialized data. + +#### from_dict + +```python +from_dict(data: dict) -> BackupAnswerHook +``` + +Deserialize the hook from a dictionary. + +**Parameters:** + +- **data** (dict) – Dictionary to deserialize from. + +**Returns:** + +- BackupAnswerHook – Deserialized hook. + +#### run + +```python +run(state: State) -> None +``` + +Append a best-effort final answer when the run ended without one (e.g. step exhaustion). + +**Parameters:** + +- **state** (State) – The agent run's state. + +## haystack_integrations.agent_pack.advanced_rag.tools + +### ListMetadataFieldsTool + +Bases: Tool + +Tool that lists all metadata fields and their types from a document store. + +#### __init__ + +```python +__init__(document_store: DocumentStore) -> None +``` + +Create the tool. + +**Parameters:** + +- **document_store** (DocumentStore) – The document store to inspect. Must implement `get_metadata_fields_info`. + +**Raises:** + +- ValueError – If the store does not implement `get_metadata_fields_info`. + +#### to_dict + +```python +to_dict() -> dict[str, Any] +``` + +Serialize the tool to a dictionary. + +#### from_dict + +```python +from_dict(data: dict[str, Any]) -> ListMetadataFieldsTool +``` + +Deserialize the tool from a dictionary. + +**Parameters:** + +- **data** (dict\[str, Any\]) – The dictionary produced by `to_dict`. + +**Returns:** + +- ListMetadataFieldsTool – The deserialized tool. + +### GetMetadataFieldValuesTool + +Bases: Tool + +Tool that returns the distinct values of a metadata field from a document store. + +#### __init__ + +```python +__init__(document_store: DocumentStore) -> None +``` + +Create the tool. + +**Parameters:** + +- **document_store** (DocumentStore) – The document store to inspect. Must implement `get_metadata_field_unique_values`. + +**Raises:** + +- ValueError – If the store does not implement `get_metadata_field_unique_values`. + +#### to_dict + +```python +to_dict() -> dict[str, Any] +``` + +Serialize the tool to a dictionary. + +#### from_dict + +```python +from_dict(data: dict[str, Any]) -> GetMetadataFieldValuesTool +``` + +Deserialize the tool from a dictionary. + +**Parameters:** + +- **data** (dict\[str, Any\]) – The dictionary produced by `to_dict`. + +**Returns:** + +- GetMetadataFieldValuesTool – The deserialized tool. + +### GetMetadataFieldRangeTool + +Bases: Tool + +Tool that returns the minimum and maximum values of a metadata field from a document store. + +#### __init__ + +```python +__init__(document_store: DocumentStore) -> None +``` + +Create the tool. + +**Parameters:** + +- **document_store** (DocumentStore) – The document store to inspect. Must implement `get_metadata_field_min_max`. + +**Raises:** + +- ValueError – If the store does not implement `get_metadata_field_min_max`. + +#### to_dict + +```python +to_dict() -> dict[str, Any] +``` + +Serialize the tool to a dictionary. + +#### from_dict + +```python +from_dict(data: dict[str, Any]) -> GetMetadataFieldRangeTool +``` + +Deserialize the tool from a dictionary. + +**Parameters:** + +- **data** (dict\[str, Any\]) – The dictionary produced by `to_dict`. + +**Returns:** + +- GetMetadataFieldRangeTool – The deserialized tool. + +### FetchDocumentsByFilterTool + +Bases: Tool + +Tool that fetches documents directly from a document store by metadata filter. + +Unlike a scored retrieval tool, this fetches without any relevance ranking, so an agent can grab specific documents +(e.g. a known title or source file) without going through a relevance search. The fetched documents are put into +reading order first: grouped by their parent file (`file_name`/`file_path`/`source_id`) and sorted by their +position within it (`split_id`/`split_idx_start`/`page_number`), using whichever of those metadata fields the +documents carry. Match sets larger than `max_docs` are paged: each call returns one page plus the total match +count, and the tool's `offset` input continues where the previous page ended. + +#### __init__ + +```python +__init__( + document_store: DocumentStore, + max_docs: int = 10, + max_fetch_factor: int = 10, +) -> None +``` + +Create the tool. + +**Parameters:** + +- **document_store** (DocumentStore) – The document store to fetch documents from. +- **max_docs** (int) – Ceiling on the number of documents shown to the agent per fetch. Unlike scored retrieval, a + filter fetch is not bounded by a retriever's `top_k`, so this caps the tool result instead. The LLM can + request fewer via the tool's optional `max_docs` input, but never more. +- **max_fetch_factor** (int) – How many times the `max_docs` ceiling a filter may match before the fetch is + refused outright (when the store supports `count_documents_by_filter`) — the refusal is surfaced to the + LLM as an error it can recover from by narrowing the filter. + +#### to_dict + +```python +to_dict() -> dict[str, Any] +``` + +Serialize the tool to a dictionary. + +#### from_dict + +```python +from_dict(data: dict[str, Any]) -> FetchDocumentsByFilterTool +``` + +Deserialize the tool from a dictionary. + +**Parameters:** + +- **data** (dict\[str, Any\]) – The dictionary produced by `to_dict`. + +**Returns:** + +- FetchDocumentsByFilterTool – The deserialized tool. + +### DocumentStoreToolset + +Bases: Toolset + +All document-store-backed tools as one unit. + +Bundles the three metadata inspection tools (`ListMetadataFieldsTool`, `GetMetadataFieldValuesTool`, +`GetMetadataFieldRangeTool`) and the direct `FetchDocumentsByFilterTool`, so they can be handed to an `Agent` +(or combined with a retrieval tool) as a single object. + +#### __init__ + +```python +__init__(document_store: DocumentStore, max_fetched_docs: int = 10) -> None +``` + +Create the toolset. + +**Parameters:** + +- **document_store** (DocumentStore) – The document store all tools run against. Must implement the metadata introspection + methods (`get_metadata_fields_info`, `get_metadata_field_unique_values`, `get_metadata_field_min_max`). +- **max_fetched_docs** (int) – Maximum number of documents `fetch_documents_by_filter` shows per fetch (see + `FetchDocumentsByFilterTool.max_docs`). + +#### to_dict + +```python +to_dict() -> dict[str, Any] +``` + +Serialize the toolset to a dictionary. + +#### from_dict + +```python +from_dict(data: dict[str, Any]) -> DocumentStoreToolset +``` + +Deserialize the toolset from a dictionary. + +**Parameters:** + +- **data** (dict\[str, Any\]) – The dictionary produced by `to_dict`. + +**Returns:** + +- DocumentStoreToolset – The deserialized toolset. + +## haystack_integrations.agent_pack.deep_research.agent + +### create_deep_research_agent + +```python +create_deep_research_agent( + *, + scope_llm: ChatGenerator | None = None, + orchestrator_llm: ChatGenerator | None = None, + researcher_llm: ChatGenerator | None = None, + summarizer_llm: ChatGenerator | None = None, + writer_llm: ChatGenerator | None = None, + max_subtopics: int = 5, + max_concurrent_researchers: int = 5, + max_orchestrator_steps: int = 8, + max_researcher_steps: int = 20, + max_search_results: int = 10, + max_content_length: int = 50000 +) -> Agent +``` + +Create the deep research agent. + +**Parameters:** + +- **scope_llm** (ChatGenerator | None) – LLM that rewrites the user query into a focused research brief. + Defaults to `OpenAIResponsesChatGenerator("gpt-5.4")`. +- **orchestrator_llm** (ChatGenerator | None) – LLM that plans the investigation and delegates the sub-questions. + Defaults to `OpenAIResponsesChatGenerator("gpt-5.4")`. +- **researcher_llm** (ChatGenerator | None) – LLM that drives each sub-researcher's search/read/think loop. + Defaults to `OpenAIResponsesChatGenerator("gpt-5.4-mini")`. +- **summarizer_llm** (ChatGenerator | None) – LLM used inside the `read_url` tool to summarize a fetched page toward + the question. Defaults to `OpenAIResponsesChatGenerator("gpt-5.4-mini")`. +- **writer_llm** (ChatGenerator | None) – LLM that turns the brief plus collected notes into the final report. + Defaults to `OpenAIResponsesChatGenerator("gpt-5.4")`. +- **max_subtopics** (int) – Maximum number of sub-questions the orchestrator may delegate (breadth). +- **max_concurrent_researchers** (int) – Maximum number of sub-researchers that run at the same time. +- **max_orchestrator_steps** (int) – Maximum steps for the orchestrator's agent loop (reflect -> delegate rounds). +- **max_researcher_steps** (int) – Maximum steps for each sub-researcher's agent loop. +- **max_search_results** (int) – Number of results returned per `web_search` call. +- **max_content_length** (int) – Maximum raw page characters fed to the summarizer, before summarization. + +**Returns:** + +- Agent – The deep research `Agent`. Call it with the question as a user message, + `agent.run(messages=[ChatMessage.from_user(question)])`; it returns a dict whose main output is + `report` (the final markdown report, a `str`). The dict also carries the intermediate `brief` + (`str`) and `notes` (`list[str]`), plus the standard Agent outputs `messages`, `last_message`, + `step_count`, `token_usage` and `tool_call_counts`. diff --git a/docs-website/reference_versioned_docs/version-2.21/integrations-api/agent_pack.md b/docs-website/reference_versioned_docs/version-2.21/integrations-api/agent_pack.md new file mode 100644 index 0000000000..2921c4d640 --- /dev/null +++ b/docs-website/reference_versioned_docs/version-2.21/integrations-api/agent_pack.md @@ -0,0 +1,463 @@ +--- +title: "Agent Pack" +id: integrations-agent-pack +description: "Agent Pack integration for Haystack" +slug: "/integrations-agent-pack" +--- + + +## haystack_integrations.agent_pack.advanced_rag.agent + +### create_advanced_rag_agent + +```python +create_advanced_rag_agent( + *, + document_store: DocumentStore, + retriever: TextRetriever | Pipeline | None = None, + retrieval_pipeline_input_mapping: dict[str, list[str]] | None = None, + retrieval_pipeline_output_mapping: dict[str, str] | None = None, + llm: ChatGenerator | None = None, + backup_answer_llm: ChatGenerator | None = None, + system_prompt: str | None = None, + max_agent_steps: int = 20, + max_fetched_docs: int = 10, + extra_tools: ToolsType | None = None, + state_schema: dict[str, Any] | None = None, + hooks: dict[HookPoint, list[Hook]] | None = None, + raise_on_tool_invocation_failure: bool = False, + tool_concurrency_limit: int = 4 +) -> Agent +``` + +Create the advanced RAG agent. + +The agent answers questions from documents it retrieves out of the document store. Instead of guessing which +metadata fields exist, it can inspect the store (fields, values, ranges) and construct a Haystack filter to +narrow its retrieval when metadata helps — plain, unfiltered retrieval remains available when it doesn't. The +answer cites the retrieved documents. + +The required `retriever` becomes the `search_documents` tool; `document_store` additionally feeds the three +metadata inspection tools and must implement the metadata introspection methods (`get_metadata_fields_info`, +`get_metadata_field_unique_values`, `get_metadata_field_min_max`). + +**Parameters:** + +- **document_store** (DocumentStore) – The document store the metadata inspection tools and the `fetch_documents_by_filter` tool + run against. +- **retriever** (TextRetriever | Pipeline | None) – What retrieves for the `search_documents` tool (required). Either a standalone retriever + component following the `TextRetriever` protocol, i.e. its `run` method accepts `query` and `filters` + (e.g. `InMemoryBM25Retriever`, or an embedding retriever wrapped in `TextEmbeddingRetriever`), or a custom + retrieval `Pipeline` (e.g. embedder -> retriever, or hybrid retrieval) — a pipeline additionally requires + `retrieval_pipeline_input_mapping`. It should retrieve by relevance scoring (keyword or embedding-based) — + direct, unscored fetching is already covered by the built-in `fetch_documents_by_filter` tool. +- **retrieval_pipeline_input_mapping** (dict\[str, list\[str\]\] | None) – Required when `retriever` is a `Pipeline`: maps the tool inputs to + pipeline input sockets; must have exactly the keys "query" and "filters", + e.g. `{"query": ["embedder.text"], "filters": ["retriever.filters"]}`. +- **retrieval_pipeline_output_mapping** (dict\[str, str\] | None) – Optional when `retriever` is a `Pipeline`: maps pipeline output sockets + to tool outputs, e.g. `{"retriever.documents": "documents"}`. +- **llm** (ChatGenerator | None) – LLM that drives the agent loop. Defaults to `OpenAIResponsesChatGenerator("gpt-5.4")` with low + reasoning effort. +- **backup_answer_llm** (ChatGenerator | None) – LLM the built-in `BackupAnswerHook` uses to write a best-effort answer when the run + is cut off by `max_agent_steps`. Defaults to a separate `OpenAIResponsesChatGenerator("gpt-5.4")` with low + reasoning effort. +- **system_prompt** (str | None) – Overrides the pre-made system prompt. +- **max_agent_steps** (int) – Maximum steps for the agent loop. If the loop is cut off by this limit before writing an + answer, an `after_run` hook (`BackupAnswerHook`) makes one extra LLM call to produce a best-effort answer from + the evidence gathered so far, so `last_message` always carries a text answer. +- **max_fetched_docs** (int) – Maximum number of documents `fetch_documents_by_filter` shows per fetch. A filter fetch is + not bounded by a retriever's `top_k`, so this caps the tool result instead; the scored `search_documents` tool + is bounded by the `top_k` configured on your retrieval components. +- **extra_tools** (ToolsType | None) – Additional tools (or toolsets) for the agent, appended after the built-in document-store + toolset and the retrieval tool. +- **state_schema** (dict\[str, Any\] | None) – Additional entries merged into the agent's state schema. The built-in `documents` entry + (the accumulated retrieved documents) always takes precedence. +- **hooks** (dict\[HookPoint, list\[Hook\]\] | None) – Additional hooks per hook point, merged with the built-in hooks. For `after_run`, the built-in + backup-answer hook runs first, so custom hooks see the final answer. +- **raise_on_tool_invocation_failure** (bool) – If True, a failing tool call raises instead of being returned to the LLM + as an error message it can recover from (the default). +- **tool_concurrency_limit** (int) – Maximum number of tool calls executed in parallel within one agent step. + +**Returns:** + +- Agent – The advanced RAG `Agent`. Call it with the question as a user message, + `agent.run(messages=[ChatMessage.from_user(question)])`; the answer is in `last_message` (a `ChatMessage`) and + `documents` carries every document the agent retrieved during the run (deduplicated by id, in first-retrieved + order) — the answer cites them by the first 8 characters of their id, e.g. `[doc a1b2c3d4]`. The standard Agent + outputs `messages`, `step_count`, `token_usage` and `tool_call_counts` are also returned. + +## haystack_integrations.agent_pack.advanced_rag.hooks + +### BackupAnswerHook + +Produce a final answer when the agent run ends without one. Runs as an `after_run` hook. + +When the agent exhausts `max_agent_steps` mid-investigation, the run ends on a tool call or tool result instead of +an assistant text answer (and only `after_run` hooks run in this situation). This hook detects that case and makes +one LLM call over the conversation so far to produce a best-effort answer from the already-gathered evidence. + +#### __init__ + +```python +__init__(chat_generator: ChatGenerator) -> None +``` + +Create the hook. + +**Parameters:** + +- **chat_generator** (ChatGenerator) – LLM that writes the backup answer from the gathered evidence. + +#### warm_up + +```python +warm_up() -> None +``` + +Prepare the hook's generator for use; called from the Agent's `warm_up`. + +#### close + +```python +close() -> None +``` + +Release the hook's generator resources; called from the Agent's `close`. + +#### to_dict + +```python +to_dict() -> dict +``` + +Serialize the hook to a dictionary. + +**Returns:** + +- dict – Dictionary with serialized data. + +#### from_dict + +```python +from_dict(data: dict) -> BackupAnswerHook +``` + +Deserialize the hook from a dictionary. + +**Parameters:** + +- **data** (dict) – Dictionary to deserialize from. + +**Returns:** + +- BackupAnswerHook – Deserialized hook. + +#### run + +```python +run(state: State) -> None +``` + +Append a best-effort final answer when the run ended without one (e.g. step exhaustion). + +**Parameters:** + +- **state** (State) – The agent run's state. + +## haystack_integrations.agent_pack.advanced_rag.tools + +### ListMetadataFieldsTool + +Bases: Tool + +Tool that lists all metadata fields and their types from a document store. + +#### __init__ + +```python +__init__(document_store: DocumentStore) -> None +``` + +Create the tool. + +**Parameters:** + +- **document_store** (DocumentStore) – The document store to inspect. Must implement `get_metadata_fields_info`. + +**Raises:** + +- ValueError – If the store does not implement `get_metadata_fields_info`. + +#### to_dict + +```python +to_dict() -> dict[str, Any] +``` + +Serialize the tool to a dictionary. + +#### from_dict + +```python +from_dict(data: dict[str, Any]) -> ListMetadataFieldsTool +``` + +Deserialize the tool from a dictionary. + +**Parameters:** + +- **data** (dict\[str, Any\]) – The dictionary produced by `to_dict`. + +**Returns:** + +- ListMetadataFieldsTool – The deserialized tool. + +### GetMetadataFieldValuesTool + +Bases: Tool + +Tool that returns the distinct values of a metadata field from a document store. + +#### __init__ + +```python +__init__(document_store: DocumentStore) -> None +``` + +Create the tool. + +**Parameters:** + +- **document_store** (DocumentStore) – The document store to inspect. Must implement `get_metadata_field_unique_values`. + +**Raises:** + +- ValueError – If the store does not implement `get_metadata_field_unique_values`. + +#### to_dict + +```python +to_dict() -> dict[str, Any] +``` + +Serialize the tool to a dictionary. + +#### from_dict + +```python +from_dict(data: dict[str, Any]) -> GetMetadataFieldValuesTool +``` + +Deserialize the tool from a dictionary. + +**Parameters:** + +- **data** (dict\[str, Any\]) – The dictionary produced by `to_dict`. + +**Returns:** + +- GetMetadataFieldValuesTool – The deserialized tool. + +### GetMetadataFieldRangeTool + +Bases: Tool + +Tool that returns the minimum and maximum values of a metadata field from a document store. + +#### __init__ + +```python +__init__(document_store: DocumentStore) -> None +``` + +Create the tool. + +**Parameters:** + +- **document_store** (DocumentStore) – The document store to inspect. Must implement `get_metadata_field_min_max`. + +**Raises:** + +- ValueError – If the store does not implement `get_metadata_field_min_max`. + +#### to_dict + +```python +to_dict() -> dict[str, Any] +``` + +Serialize the tool to a dictionary. + +#### from_dict + +```python +from_dict(data: dict[str, Any]) -> GetMetadataFieldRangeTool +``` + +Deserialize the tool from a dictionary. + +**Parameters:** + +- **data** (dict\[str, Any\]) – The dictionary produced by `to_dict`. + +**Returns:** + +- GetMetadataFieldRangeTool – The deserialized tool. + +### FetchDocumentsByFilterTool + +Bases: Tool + +Tool that fetches documents directly from a document store by metadata filter. + +Unlike a scored retrieval tool, this fetches without any relevance ranking, so an agent can grab specific documents +(e.g. a known title or source file) without going through a relevance search. The fetched documents are put into +reading order first: grouped by their parent file (`file_name`/`file_path`/`source_id`) and sorted by their +position within it (`split_id`/`split_idx_start`/`page_number`), using whichever of those metadata fields the +documents carry. Match sets larger than `max_docs` are paged: each call returns one page plus the total match +count, and the tool's `offset` input continues where the previous page ended. + +#### __init__ + +```python +__init__( + document_store: DocumentStore, + max_docs: int = 10, + max_fetch_factor: int = 10, +) -> None +``` + +Create the tool. + +**Parameters:** + +- **document_store** (DocumentStore) – The document store to fetch documents from. +- **max_docs** (int) – Ceiling on the number of documents shown to the agent per fetch. Unlike scored retrieval, a + filter fetch is not bounded by a retriever's `top_k`, so this caps the tool result instead. The LLM can + request fewer via the tool's optional `max_docs` input, but never more. +- **max_fetch_factor** (int) – How many times the `max_docs` ceiling a filter may match before the fetch is + refused outright (when the store supports `count_documents_by_filter`) — the refusal is surfaced to the + LLM as an error it can recover from by narrowing the filter. + +#### to_dict + +```python +to_dict() -> dict[str, Any] +``` + +Serialize the tool to a dictionary. + +#### from_dict + +```python +from_dict(data: dict[str, Any]) -> FetchDocumentsByFilterTool +``` + +Deserialize the tool from a dictionary. + +**Parameters:** + +- **data** (dict\[str, Any\]) – The dictionary produced by `to_dict`. + +**Returns:** + +- FetchDocumentsByFilterTool – The deserialized tool. + +### DocumentStoreToolset + +Bases: Toolset + +All document-store-backed tools as one unit. + +Bundles the three metadata inspection tools (`ListMetadataFieldsTool`, `GetMetadataFieldValuesTool`, +`GetMetadataFieldRangeTool`) and the direct `FetchDocumentsByFilterTool`, so they can be handed to an `Agent` +(or combined with a retrieval tool) as a single object. + +#### __init__ + +```python +__init__(document_store: DocumentStore, max_fetched_docs: int = 10) -> None +``` + +Create the toolset. + +**Parameters:** + +- **document_store** (DocumentStore) – The document store all tools run against. Must implement the metadata introspection + methods (`get_metadata_fields_info`, `get_metadata_field_unique_values`, `get_metadata_field_min_max`). +- **max_fetched_docs** (int) – Maximum number of documents `fetch_documents_by_filter` shows per fetch (see + `FetchDocumentsByFilterTool.max_docs`). + +#### to_dict + +```python +to_dict() -> dict[str, Any] +``` + +Serialize the toolset to a dictionary. + +#### from_dict + +```python +from_dict(data: dict[str, Any]) -> DocumentStoreToolset +``` + +Deserialize the toolset from a dictionary. + +**Parameters:** + +- **data** (dict\[str, Any\]) – The dictionary produced by `to_dict`. + +**Returns:** + +- DocumentStoreToolset – The deserialized toolset. + +## haystack_integrations.agent_pack.deep_research.agent + +### create_deep_research_agent + +```python +create_deep_research_agent( + *, + scope_llm: ChatGenerator | None = None, + orchestrator_llm: ChatGenerator | None = None, + researcher_llm: ChatGenerator | None = None, + summarizer_llm: ChatGenerator | None = None, + writer_llm: ChatGenerator | None = None, + max_subtopics: int = 5, + max_concurrent_researchers: int = 5, + max_orchestrator_steps: int = 8, + max_researcher_steps: int = 20, + max_search_results: int = 10, + max_content_length: int = 50000 +) -> Agent +``` + +Create the deep research agent. + +**Parameters:** + +- **scope_llm** (ChatGenerator | None) – LLM that rewrites the user query into a focused research brief. + Defaults to `OpenAIResponsesChatGenerator("gpt-5.4")`. +- **orchestrator_llm** (ChatGenerator | None) – LLM that plans the investigation and delegates the sub-questions. + Defaults to `OpenAIResponsesChatGenerator("gpt-5.4")`. +- **researcher_llm** (ChatGenerator | None) – LLM that drives each sub-researcher's search/read/think loop. + Defaults to `OpenAIResponsesChatGenerator("gpt-5.4-mini")`. +- **summarizer_llm** (ChatGenerator | None) – LLM used inside the `read_url` tool to summarize a fetched page toward + the question. Defaults to `OpenAIResponsesChatGenerator("gpt-5.4-mini")`. +- **writer_llm** (ChatGenerator | None) – LLM that turns the brief plus collected notes into the final report. + Defaults to `OpenAIResponsesChatGenerator("gpt-5.4")`. +- **max_subtopics** (int) – Maximum number of sub-questions the orchestrator may delegate (breadth). +- **max_concurrent_researchers** (int) – Maximum number of sub-researchers that run at the same time. +- **max_orchestrator_steps** (int) – Maximum steps for the orchestrator's agent loop (reflect -> delegate rounds). +- **max_researcher_steps** (int) – Maximum steps for each sub-researcher's agent loop. +- **max_search_results** (int) – Number of results returned per `web_search` call. +- **max_content_length** (int) – Maximum raw page characters fed to the summarizer, before summarization. + +**Returns:** + +- Agent – The deep research `Agent`. Call it with the question as a user message, + `agent.run(messages=[ChatMessage.from_user(question)])`; it returns a dict whose main output is + `report` (the final markdown report, a `str`). The dict also carries the intermediate `brief` + (`str`) and `notes` (`list[str]`), plus the standard Agent outputs `messages`, `last_message`, + `step_count`, `token_usage` and `tool_call_counts`. diff --git a/docs-website/reference_versioned_docs/version-2.22/integrations-api/agent_pack.md b/docs-website/reference_versioned_docs/version-2.22/integrations-api/agent_pack.md new file mode 100644 index 0000000000..2921c4d640 --- /dev/null +++ b/docs-website/reference_versioned_docs/version-2.22/integrations-api/agent_pack.md @@ -0,0 +1,463 @@ +--- +title: "Agent Pack" +id: integrations-agent-pack +description: "Agent Pack integration for Haystack" +slug: "/integrations-agent-pack" +--- + + +## haystack_integrations.agent_pack.advanced_rag.agent + +### create_advanced_rag_agent + +```python +create_advanced_rag_agent( + *, + document_store: DocumentStore, + retriever: TextRetriever | Pipeline | None = None, + retrieval_pipeline_input_mapping: dict[str, list[str]] | None = None, + retrieval_pipeline_output_mapping: dict[str, str] | None = None, + llm: ChatGenerator | None = None, + backup_answer_llm: ChatGenerator | None = None, + system_prompt: str | None = None, + max_agent_steps: int = 20, + max_fetched_docs: int = 10, + extra_tools: ToolsType | None = None, + state_schema: dict[str, Any] | None = None, + hooks: dict[HookPoint, list[Hook]] | None = None, + raise_on_tool_invocation_failure: bool = False, + tool_concurrency_limit: int = 4 +) -> Agent +``` + +Create the advanced RAG agent. + +The agent answers questions from documents it retrieves out of the document store. Instead of guessing which +metadata fields exist, it can inspect the store (fields, values, ranges) and construct a Haystack filter to +narrow its retrieval when metadata helps — plain, unfiltered retrieval remains available when it doesn't. The +answer cites the retrieved documents. + +The required `retriever` becomes the `search_documents` tool; `document_store` additionally feeds the three +metadata inspection tools and must implement the metadata introspection methods (`get_metadata_fields_info`, +`get_metadata_field_unique_values`, `get_metadata_field_min_max`). + +**Parameters:** + +- **document_store** (DocumentStore) – The document store the metadata inspection tools and the `fetch_documents_by_filter` tool + run against. +- **retriever** (TextRetriever | Pipeline | None) – What retrieves for the `search_documents` tool (required). Either a standalone retriever + component following the `TextRetriever` protocol, i.e. its `run` method accepts `query` and `filters` + (e.g. `InMemoryBM25Retriever`, or an embedding retriever wrapped in `TextEmbeddingRetriever`), or a custom + retrieval `Pipeline` (e.g. embedder -> retriever, or hybrid retrieval) — a pipeline additionally requires + `retrieval_pipeline_input_mapping`. It should retrieve by relevance scoring (keyword or embedding-based) — + direct, unscored fetching is already covered by the built-in `fetch_documents_by_filter` tool. +- **retrieval_pipeline_input_mapping** (dict\[str, list\[str\]\] | None) – Required when `retriever` is a `Pipeline`: maps the tool inputs to + pipeline input sockets; must have exactly the keys "query" and "filters", + e.g. `{"query": ["embedder.text"], "filters": ["retriever.filters"]}`. +- **retrieval_pipeline_output_mapping** (dict\[str, str\] | None) – Optional when `retriever` is a `Pipeline`: maps pipeline output sockets + to tool outputs, e.g. `{"retriever.documents": "documents"}`. +- **llm** (ChatGenerator | None) – LLM that drives the agent loop. Defaults to `OpenAIResponsesChatGenerator("gpt-5.4")` with low + reasoning effort. +- **backup_answer_llm** (ChatGenerator | None) – LLM the built-in `BackupAnswerHook` uses to write a best-effort answer when the run + is cut off by `max_agent_steps`. Defaults to a separate `OpenAIResponsesChatGenerator("gpt-5.4")` with low + reasoning effort. +- **system_prompt** (str | None) – Overrides the pre-made system prompt. +- **max_agent_steps** (int) – Maximum steps for the agent loop. If the loop is cut off by this limit before writing an + answer, an `after_run` hook (`BackupAnswerHook`) makes one extra LLM call to produce a best-effort answer from + the evidence gathered so far, so `last_message` always carries a text answer. +- **max_fetched_docs** (int) – Maximum number of documents `fetch_documents_by_filter` shows per fetch. A filter fetch is + not bounded by a retriever's `top_k`, so this caps the tool result instead; the scored `search_documents` tool + is bounded by the `top_k` configured on your retrieval components. +- **extra_tools** (ToolsType | None) – Additional tools (or toolsets) for the agent, appended after the built-in document-store + toolset and the retrieval tool. +- **state_schema** (dict\[str, Any\] | None) – Additional entries merged into the agent's state schema. The built-in `documents` entry + (the accumulated retrieved documents) always takes precedence. +- **hooks** (dict\[HookPoint, list\[Hook\]\] | None) – Additional hooks per hook point, merged with the built-in hooks. For `after_run`, the built-in + backup-answer hook runs first, so custom hooks see the final answer. +- **raise_on_tool_invocation_failure** (bool) – If True, a failing tool call raises instead of being returned to the LLM + as an error message it can recover from (the default). +- **tool_concurrency_limit** (int) – Maximum number of tool calls executed in parallel within one agent step. + +**Returns:** + +- Agent – The advanced RAG `Agent`. Call it with the question as a user message, + `agent.run(messages=[ChatMessage.from_user(question)])`; the answer is in `last_message` (a `ChatMessage`) and + `documents` carries every document the agent retrieved during the run (deduplicated by id, in first-retrieved + order) — the answer cites them by the first 8 characters of their id, e.g. `[doc a1b2c3d4]`. The standard Agent + outputs `messages`, `step_count`, `token_usage` and `tool_call_counts` are also returned. + +## haystack_integrations.agent_pack.advanced_rag.hooks + +### BackupAnswerHook + +Produce a final answer when the agent run ends without one. Runs as an `after_run` hook. + +When the agent exhausts `max_agent_steps` mid-investigation, the run ends on a tool call or tool result instead of +an assistant text answer (and only `after_run` hooks run in this situation). This hook detects that case and makes +one LLM call over the conversation so far to produce a best-effort answer from the already-gathered evidence. + +#### __init__ + +```python +__init__(chat_generator: ChatGenerator) -> None +``` + +Create the hook. + +**Parameters:** + +- **chat_generator** (ChatGenerator) – LLM that writes the backup answer from the gathered evidence. + +#### warm_up + +```python +warm_up() -> None +``` + +Prepare the hook's generator for use; called from the Agent's `warm_up`. + +#### close + +```python +close() -> None +``` + +Release the hook's generator resources; called from the Agent's `close`. + +#### to_dict + +```python +to_dict() -> dict +``` + +Serialize the hook to a dictionary. + +**Returns:** + +- dict – Dictionary with serialized data. + +#### from_dict + +```python +from_dict(data: dict) -> BackupAnswerHook +``` + +Deserialize the hook from a dictionary. + +**Parameters:** + +- **data** (dict) – Dictionary to deserialize from. + +**Returns:** + +- BackupAnswerHook – Deserialized hook. + +#### run + +```python +run(state: State) -> None +``` + +Append a best-effort final answer when the run ended without one (e.g. step exhaustion). + +**Parameters:** + +- **state** (State) – The agent run's state. + +## haystack_integrations.agent_pack.advanced_rag.tools + +### ListMetadataFieldsTool + +Bases: Tool + +Tool that lists all metadata fields and their types from a document store. + +#### __init__ + +```python +__init__(document_store: DocumentStore) -> None +``` + +Create the tool. + +**Parameters:** + +- **document_store** (DocumentStore) – The document store to inspect. Must implement `get_metadata_fields_info`. + +**Raises:** + +- ValueError – If the store does not implement `get_metadata_fields_info`. + +#### to_dict + +```python +to_dict() -> dict[str, Any] +``` + +Serialize the tool to a dictionary. + +#### from_dict + +```python +from_dict(data: dict[str, Any]) -> ListMetadataFieldsTool +``` + +Deserialize the tool from a dictionary. + +**Parameters:** + +- **data** (dict\[str, Any\]) – The dictionary produced by `to_dict`. + +**Returns:** + +- ListMetadataFieldsTool – The deserialized tool. + +### GetMetadataFieldValuesTool + +Bases: Tool + +Tool that returns the distinct values of a metadata field from a document store. + +#### __init__ + +```python +__init__(document_store: DocumentStore) -> None +``` + +Create the tool. + +**Parameters:** + +- **document_store** (DocumentStore) – The document store to inspect. Must implement `get_metadata_field_unique_values`. + +**Raises:** + +- ValueError – If the store does not implement `get_metadata_field_unique_values`. + +#### to_dict + +```python +to_dict() -> dict[str, Any] +``` + +Serialize the tool to a dictionary. + +#### from_dict + +```python +from_dict(data: dict[str, Any]) -> GetMetadataFieldValuesTool +``` + +Deserialize the tool from a dictionary. + +**Parameters:** + +- **data** (dict\[str, Any\]) – The dictionary produced by `to_dict`. + +**Returns:** + +- GetMetadataFieldValuesTool – The deserialized tool. + +### GetMetadataFieldRangeTool + +Bases: Tool + +Tool that returns the minimum and maximum values of a metadata field from a document store. + +#### __init__ + +```python +__init__(document_store: DocumentStore) -> None +``` + +Create the tool. + +**Parameters:** + +- **document_store** (DocumentStore) – The document store to inspect. Must implement `get_metadata_field_min_max`. + +**Raises:** + +- ValueError – If the store does not implement `get_metadata_field_min_max`. + +#### to_dict + +```python +to_dict() -> dict[str, Any] +``` + +Serialize the tool to a dictionary. + +#### from_dict + +```python +from_dict(data: dict[str, Any]) -> GetMetadataFieldRangeTool +``` + +Deserialize the tool from a dictionary. + +**Parameters:** + +- **data** (dict\[str, Any\]) – The dictionary produced by `to_dict`. + +**Returns:** + +- GetMetadataFieldRangeTool – The deserialized tool. + +### FetchDocumentsByFilterTool + +Bases: Tool + +Tool that fetches documents directly from a document store by metadata filter. + +Unlike a scored retrieval tool, this fetches without any relevance ranking, so an agent can grab specific documents +(e.g. a known title or source file) without going through a relevance search. The fetched documents are put into +reading order first: grouped by their parent file (`file_name`/`file_path`/`source_id`) and sorted by their +position within it (`split_id`/`split_idx_start`/`page_number`), using whichever of those metadata fields the +documents carry. Match sets larger than `max_docs` are paged: each call returns one page plus the total match +count, and the tool's `offset` input continues where the previous page ended. + +#### __init__ + +```python +__init__( + document_store: DocumentStore, + max_docs: int = 10, + max_fetch_factor: int = 10, +) -> None +``` + +Create the tool. + +**Parameters:** + +- **document_store** (DocumentStore) – The document store to fetch documents from. +- **max_docs** (int) – Ceiling on the number of documents shown to the agent per fetch. Unlike scored retrieval, a + filter fetch is not bounded by a retriever's `top_k`, so this caps the tool result instead. The LLM can + request fewer via the tool's optional `max_docs` input, but never more. +- **max_fetch_factor** (int) – How many times the `max_docs` ceiling a filter may match before the fetch is + refused outright (when the store supports `count_documents_by_filter`) — the refusal is surfaced to the + LLM as an error it can recover from by narrowing the filter. + +#### to_dict + +```python +to_dict() -> dict[str, Any] +``` + +Serialize the tool to a dictionary. + +#### from_dict + +```python +from_dict(data: dict[str, Any]) -> FetchDocumentsByFilterTool +``` + +Deserialize the tool from a dictionary. + +**Parameters:** + +- **data** (dict\[str, Any\]) – The dictionary produced by `to_dict`. + +**Returns:** + +- FetchDocumentsByFilterTool – The deserialized tool. + +### DocumentStoreToolset + +Bases: Toolset + +All document-store-backed tools as one unit. + +Bundles the three metadata inspection tools (`ListMetadataFieldsTool`, `GetMetadataFieldValuesTool`, +`GetMetadataFieldRangeTool`) and the direct `FetchDocumentsByFilterTool`, so they can be handed to an `Agent` +(or combined with a retrieval tool) as a single object. + +#### __init__ + +```python +__init__(document_store: DocumentStore, max_fetched_docs: int = 10) -> None +``` + +Create the toolset. + +**Parameters:** + +- **document_store** (DocumentStore) – The document store all tools run against. Must implement the metadata introspection + methods (`get_metadata_fields_info`, `get_metadata_field_unique_values`, `get_metadata_field_min_max`). +- **max_fetched_docs** (int) – Maximum number of documents `fetch_documents_by_filter` shows per fetch (see + `FetchDocumentsByFilterTool.max_docs`). + +#### to_dict + +```python +to_dict() -> dict[str, Any] +``` + +Serialize the toolset to a dictionary. + +#### from_dict + +```python +from_dict(data: dict[str, Any]) -> DocumentStoreToolset +``` + +Deserialize the toolset from a dictionary. + +**Parameters:** + +- **data** (dict\[str, Any\]) – The dictionary produced by `to_dict`. + +**Returns:** + +- DocumentStoreToolset – The deserialized toolset. + +## haystack_integrations.agent_pack.deep_research.agent + +### create_deep_research_agent + +```python +create_deep_research_agent( + *, + scope_llm: ChatGenerator | None = None, + orchestrator_llm: ChatGenerator | None = None, + researcher_llm: ChatGenerator | None = None, + summarizer_llm: ChatGenerator | None = None, + writer_llm: ChatGenerator | None = None, + max_subtopics: int = 5, + max_concurrent_researchers: int = 5, + max_orchestrator_steps: int = 8, + max_researcher_steps: int = 20, + max_search_results: int = 10, + max_content_length: int = 50000 +) -> Agent +``` + +Create the deep research agent. + +**Parameters:** + +- **scope_llm** (ChatGenerator | None) – LLM that rewrites the user query into a focused research brief. + Defaults to `OpenAIResponsesChatGenerator("gpt-5.4")`. +- **orchestrator_llm** (ChatGenerator | None) – LLM that plans the investigation and delegates the sub-questions. + Defaults to `OpenAIResponsesChatGenerator("gpt-5.4")`. +- **researcher_llm** (ChatGenerator | None) – LLM that drives each sub-researcher's search/read/think loop. + Defaults to `OpenAIResponsesChatGenerator("gpt-5.4-mini")`. +- **summarizer_llm** (ChatGenerator | None) – LLM used inside the `read_url` tool to summarize a fetched page toward + the question. Defaults to `OpenAIResponsesChatGenerator("gpt-5.4-mini")`. +- **writer_llm** (ChatGenerator | None) – LLM that turns the brief plus collected notes into the final report. + Defaults to `OpenAIResponsesChatGenerator("gpt-5.4")`. +- **max_subtopics** (int) – Maximum number of sub-questions the orchestrator may delegate (breadth). +- **max_concurrent_researchers** (int) – Maximum number of sub-researchers that run at the same time. +- **max_orchestrator_steps** (int) – Maximum steps for the orchestrator's agent loop (reflect -> delegate rounds). +- **max_researcher_steps** (int) – Maximum steps for each sub-researcher's agent loop. +- **max_search_results** (int) – Number of results returned per `web_search` call. +- **max_content_length** (int) – Maximum raw page characters fed to the summarizer, before summarization. + +**Returns:** + +- Agent – The deep research `Agent`. Call it with the question as a user message, + `agent.run(messages=[ChatMessage.from_user(question)])`; it returns a dict whose main output is + `report` (the final markdown report, a `str`). The dict also carries the intermediate `brief` + (`str`) and `notes` (`list[str]`), plus the standard Agent outputs `messages`, `last_message`, + `step_count`, `token_usage` and `tool_call_counts`. diff --git a/docs-website/reference_versioned_docs/version-2.23/integrations-api/agent_pack.md b/docs-website/reference_versioned_docs/version-2.23/integrations-api/agent_pack.md new file mode 100644 index 0000000000..2921c4d640 --- /dev/null +++ b/docs-website/reference_versioned_docs/version-2.23/integrations-api/agent_pack.md @@ -0,0 +1,463 @@ +--- +title: "Agent Pack" +id: integrations-agent-pack +description: "Agent Pack integration for Haystack" +slug: "/integrations-agent-pack" +--- + + +## haystack_integrations.agent_pack.advanced_rag.agent + +### create_advanced_rag_agent + +```python +create_advanced_rag_agent( + *, + document_store: DocumentStore, + retriever: TextRetriever | Pipeline | None = None, + retrieval_pipeline_input_mapping: dict[str, list[str]] | None = None, + retrieval_pipeline_output_mapping: dict[str, str] | None = None, + llm: ChatGenerator | None = None, + backup_answer_llm: ChatGenerator | None = None, + system_prompt: str | None = None, + max_agent_steps: int = 20, + max_fetched_docs: int = 10, + extra_tools: ToolsType | None = None, + state_schema: dict[str, Any] | None = None, + hooks: dict[HookPoint, list[Hook]] | None = None, + raise_on_tool_invocation_failure: bool = False, + tool_concurrency_limit: int = 4 +) -> Agent +``` + +Create the advanced RAG agent. + +The agent answers questions from documents it retrieves out of the document store. Instead of guessing which +metadata fields exist, it can inspect the store (fields, values, ranges) and construct a Haystack filter to +narrow its retrieval when metadata helps — plain, unfiltered retrieval remains available when it doesn't. The +answer cites the retrieved documents. + +The required `retriever` becomes the `search_documents` tool; `document_store` additionally feeds the three +metadata inspection tools and must implement the metadata introspection methods (`get_metadata_fields_info`, +`get_metadata_field_unique_values`, `get_metadata_field_min_max`). + +**Parameters:** + +- **document_store** (DocumentStore) – The document store the metadata inspection tools and the `fetch_documents_by_filter` tool + run against. +- **retriever** (TextRetriever | Pipeline | None) – What retrieves for the `search_documents` tool (required). Either a standalone retriever + component following the `TextRetriever` protocol, i.e. its `run` method accepts `query` and `filters` + (e.g. `InMemoryBM25Retriever`, or an embedding retriever wrapped in `TextEmbeddingRetriever`), or a custom + retrieval `Pipeline` (e.g. embedder -> retriever, or hybrid retrieval) — a pipeline additionally requires + `retrieval_pipeline_input_mapping`. It should retrieve by relevance scoring (keyword or embedding-based) — + direct, unscored fetching is already covered by the built-in `fetch_documents_by_filter` tool. +- **retrieval_pipeline_input_mapping** (dict\[str, list\[str\]\] | None) – Required when `retriever` is a `Pipeline`: maps the tool inputs to + pipeline input sockets; must have exactly the keys "query" and "filters", + e.g. `{"query": ["embedder.text"], "filters": ["retriever.filters"]}`. +- **retrieval_pipeline_output_mapping** (dict\[str, str\] | None) – Optional when `retriever` is a `Pipeline`: maps pipeline output sockets + to tool outputs, e.g. `{"retriever.documents": "documents"}`. +- **llm** (ChatGenerator | None) – LLM that drives the agent loop. Defaults to `OpenAIResponsesChatGenerator("gpt-5.4")` with low + reasoning effort. +- **backup_answer_llm** (ChatGenerator | None) – LLM the built-in `BackupAnswerHook` uses to write a best-effort answer when the run + is cut off by `max_agent_steps`. Defaults to a separate `OpenAIResponsesChatGenerator("gpt-5.4")` with low + reasoning effort. +- **system_prompt** (str | None) – Overrides the pre-made system prompt. +- **max_agent_steps** (int) – Maximum steps for the agent loop. If the loop is cut off by this limit before writing an + answer, an `after_run` hook (`BackupAnswerHook`) makes one extra LLM call to produce a best-effort answer from + the evidence gathered so far, so `last_message` always carries a text answer. +- **max_fetched_docs** (int) – Maximum number of documents `fetch_documents_by_filter` shows per fetch. A filter fetch is + not bounded by a retriever's `top_k`, so this caps the tool result instead; the scored `search_documents` tool + is bounded by the `top_k` configured on your retrieval components. +- **extra_tools** (ToolsType | None) – Additional tools (or toolsets) for the agent, appended after the built-in document-store + toolset and the retrieval tool. +- **state_schema** (dict\[str, Any\] | None) – Additional entries merged into the agent's state schema. The built-in `documents` entry + (the accumulated retrieved documents) always takes precedence. +- **hooks** (dict\[HookPoint, list\[Hook\]\] | None) – Additional hooks per hook point, merged with the built-in hooks. For `after_run`, the built-in + backup-answer hook runs first, so custom hooks see the final answer. +- **raise_on_tool_invocation_failure** (bool) – If True, a failing tool call raises instead of being returned to the LLM + as an error message it can recover from (the default). +- **tool_concurrency_limit** (int) – Maximum number of tool calls executed in parallel within one agent step. + +**Returns:** + +- Agent – The advanced RAG `Agent`. Call it with the question as a user message, + `agent.run(messages=[ChatMessage.from_user(question)])`; the answer is in `last_message` (a `ChatMessage`) and + `documents` carries every document the agent retrieved during the run (deduplicated by id, in first-retrieved + order) — the answer cites them by the first 8 characters of their id, e.g. `[doc a1b2c3d4]`. The standard Agent + outputs `messages`, `step_count`, `token_usage` and `tool_call_counts` are also returned. + +## haystack_integrations.agent_pack.advanced_rag.hooks + +### BackupAnswerHook + +Produce a final answer when the agent run ends without one. Runs as an `after_run` hook. + +When the agent exhausts `max_agent_steps` mid-investigation, the run ends on a tool call or tool result instead of +an assistant text answer (and only `after_run` hooks run in this situation). This hook detects that case and makes +one LLM call over the conversation so far to produce a best-effort answer from the already-gathered evidence. + +#### __init__ + +```python +__init__(chat_generator: ChatGenerator) -> None +``` + +Create the hook. + +**Parameters:** + +- **chat_generator** (ChatGenerator) – LLM that writes the backup answer from the gathered evidence. + +#### warm_up + +```python +warm_up() -> None +``` + +Prepare the hook's generator for use; called from the Agent's `warm_up`. + +#### close + +```python +close() -> None +``` + +Release the hook's generator resources; called from the Agent's `close`. + +#### to_dict + +```python +to_dict() -> dict +``` + +Serialize the hook to a dictionary. + +**Returns:** + +- dict – Dictionary with serialized data. + +#### from_dict + +```python +from_dict(data: dict) -> BackupAnswerHook +``` + +Deserialize the hook from a dictionary. + +**Parameters:** + +- **data** (dict) – Dictionary to deserialize from. + +**Returns:** + +- BackupAnswerHook – Deserialized hook. + +#### run + +```python +run(state: State) -> None +``` + +Append a best-effort final answer when the run ended without one (e.g. step exhaustion). + +**Parameters:** + +- **state** (State) – The agent run's state. + +## haystack_integrations.agent_pack.advanced_rag.tools + +### ListMetadataFieldsTool + +Bases: Tool + +Tool that lists all metadata fields and their types from a document store. + +#### __init__ + +```python +__init__(document_store: DocumentStore) -> None +``` + +Create the tool. + +**Parameters:** + +- **document_store** (DocumentStore) – The document store to inspect. Must implement `get_metadata_fields_info`. + +**Raises:** + +- ValueError – If the store does not implement `get_metadata_fields_info`. + +#### to_dict + +```python +to_dict() -> dict[str, Any] +``` + +Serialize the tool to a dictionary. + +#### from_dict + +```python +from_dict(data: dict[str, Any]) -> ListMetadataFieldsTool +``` + +Deserialize the tool from a dictionary. + +**Parameters:** + +- **data** (dict\[str, Any\]) – The dictionary produced by `to_dict`. + +**Returns:** + +- ListMetadataFieldsTool – The deserialized tool. + +### GetMetadataFieldValuesTool + +Bases: Tool + +Tool that returns the distinct values of a metadata field from a document store. + +#### __init__ + +```python +__init__(document_store: DocumentStore) -> None +``` + +Create the tool. + +**Parameters:** + +- **document_store** (DocumentStore) – The document store to inspect. Must implement `get_metadata_field_unique_values`. + +**Raises:** + +- ValueError – If the store does not implement `get_metadata_field_unique_values`. + +#### to_dict + +```python +to_dict() -> dict[str, Any] +``` + +Serialize the tool to a dictionary. + +#### from_dict + +```python +from_dict(data: dict[str, Any]) -> GetMetadataFieldValuesTool +``` + +Deserialize the tool from a dictionary. + +**Parameters:** + +- **data** (dict\[str, Any\]) – The dictionary produced by `to_dict`. + +**Returns:** + +- GetMetadataFieldValuesTool – The deserialized tool. + +### GetMetadataFieldRangeTool + +Bases: Tool + +Tool that returns the minimum and maximum values of a metadata field from a document store. + +#### __init__ + +```python +__init__(document_store: DocumentStore) -> None +``` + +Create the tool. + +**Parameters:** + +- **document_store** (DocumentStore) – The document store to inspect. Must implement `get_metadata_field_min_max`. + +**Raises:** + +- ValueError – If the store does not implement `get_metadata_field_min_max`. + +#### to_dict + +```python +to_dict() -> dict[str, Any] +``` + +Serialize the tool to a dictionary. + +#### from_dict + +```python +from_dict(data: dict[str, Any]) -> GetMetadataFieldRangeTool +``` + +Deserialize the tool from a dictionary. + +**Parameters:** + +- **data** (dict\[str, Any\]) – The dictionary produced by `to_dict`. + +**Returns:** + +- GetMetadataFieldRangeTool – The deserialized tool. + +### FetchDocumentsByFilterTool + +Bases: Tool + +Tool that fetches documents directly from a document store by metadata filter. + +Unlike a scored retrieval tool, this fetches without any relevance ranking, so an agent can grab specific documents +(e.g. a known title or source file) without going through a relevance search. The fetched documents are put into +reading order first: grouped by their parent file (`file_name`/`file_path`/`source_id`) and sorted by their +position within it (`split_id`/`split_idx_start`/`page_number`), using whichever of those metadata fields the +documents carry. Match sets larger than `max_docs` are paged: each call returns one page plus the total match +count, and the tool's `offset` input continues where the previous page ended. + +#### __init__ + +```python +__init__( + document_store: DocumentStore, + max_docs: int = 10, + max_fetch_factor: int = 10, +) -> None +``` + +Create the tool. + +**Parameters:** + +- **document_store** (DocumentStore) – The document store to fetch documents from. +- **max_docs** (int) – Ceiling on the number of documents shown to the agent per fetch. Unlike scored retrieval, a + filter fetch is not bounded by a retriever's `top_k`, so this caps the tool result instead. The LLM can + request fewer via the tool's optional `max_docs` input, but never more. +- **max_fetch_factor** (int) – How many times the `max_docs` ceiling a filter may match before the fetch is + refused outright (when the store supports `count_documents_by_filter`) — the refusal is surfaced to the + LLM as an error it can recover from by narrowing the filter. + +#### to_dict + +```python +to_dict() -> dict[str, Any] +``` + +Serialize the tool to a dictionary. + +#### from_dict + +```python +from_dict(data: dict[str, Any]) -> FetchDocumentsByFilterTool +``` + +Deserialize the tool from a dictionary. + +**Parameters:** + +- **data** (dict\[str, Any\]) – The dictionary produced by `to_dict`. + +**Returns:** + +- FetchDocumentsByFilterTool – The deserialized tool. + +### DocumentStoreToolset + +Bases: Toolset + +All document-store-backed tools as one unit. + +Bundles the three metadata inspection tools (`ListMetadataFieldsTool`, `GetMetadataFieldValuesTool`, +`GetMetadataFieldRangeTool`) and the direct `FetchDocumentsByFilterTool`, so they can be handed to an `Agent` +(or combined with a retrieval tool) as a single object. + +#### __init__ + +```python +__init__(document_store: DocumentStore, max_fetched_docs: int = 10) -> None +``` + +Create the toolset. + +**Parameters:** + +- **document_store** (DocumentStore) – The document store all tools run against. Must implement the metadata introspection + methods (`get_metadata_fields_info`, `get_metadata_field_unique_values`, `get_metadata_field_min_max`). +- **max_fetched_docs** (int) – Maximum number of documents `fetch_documents_by_filter` shows per fetch (see + `FetchDocumentsByFilterTool.max_docs`). + +#### to_dict + +```python +to_dict() -> dict[str, Any] +``` + +Serialize the toolset to a dictionary. + +#### from_dict + +```python +from_dict(data: dict[str, Any]) -> DocumentStoreToolset +``` + +Deserialize the toolset from a dictionary. + +**Parameters:** + +- **data** (dict\[str, Any\]) – The dictionary produced by `to_dict`. + +**Returns:** + +- DocumentStoreToolset – The deserialized toolset. + +## haystack_integrations.agent_pack.deep_research.agent + +### create_deep_research_agent + +```python +create_deep_research_agent( + *, + scope_llm: ChatGenerator | None = None, + orchestrator_llm: ChatGenerator | None = None, + researcher_llm: ChatGenerator | None = None, + summarizer_llm: ChatGenerator | None = None, + writer_llm: ChatGenerator | None = None, + max_subtopics: int = 5, + max_concurrent_researchers: int = 5, + max_orchestrator_steps: int = 8, + max_researcher_steps: int = 20, + max_search_results: int = 10, + max_content_length: int = 50000 +) -> Agent +``` + +Create the deep research agent. + +**Parameters:** + +- **scope_llm** (ChatGenerator | None) – LLM that rewrites the user query into a focused research brief. + Defaults to `OpenAIResponsesChatGenerator("gpt-5.4")`. +- **orchestrator_llm** (ChatGenerator | None) – LLM that plans the investigation and delegates the sub-questions. + Defaults to `OpenAIResponsesChatGenerator("gpt-5.4")`. +- **researcher_llm** (ChatGenerator | None) – LLM that drives each sub-researcher's search/read/think loop. + Defaults to `OpenAIResponsesChatGenerator("gpt-5.4-mini")`. +- **summarizer_llm** (ChatGenerator | None) – LLM used inside the `read_url` tool to summarize a fetched page toward + the question. Defaults to `OpenAIResponsesChatGenerator("gpt-5.4-mini")`. +- **writer_llm** (ChatGenerator | None) – LLM that turns the brief plus collected notes into the final report. + Defaults to `OpenAIResponsesChatGenerator("gpt-5.4")`. +- **max_subtopics** (int) – Maximum number of sub-questions the orchestrator may delegate (breadth). +- **max_concurrent_researchers** (int) – Maximum number of sub-researchers that run at the same time. +- **max_orchestrator_steps** (int) – Maximum steps for the orchestrator's agent loop (reflect -> delegate rounds). +- **max_researcher_steps** (int) – Maximum steps for each sub-researcher's agent loop. +- **max_search_results** (int) – Number of results returned per `web_search` call. +- **max_content_length** (int) – Maximum raw page characters fed to the summarizer, before summarization. + +**Returns:** + +- Agent – The deep research `Agent`. Call it with the question as a user message, + `agent.run(messages=[ChatMessage.from_user(question)])`; it returns a dict whose main output is + `report` (the final markdown report, a `str`). The dict also carries the intermediate `brief` + (`str`) and `notes` (`list[str]`), plus the standard Agent outputs `messages`, `last_message`, + `step_count`, `token_usage` and `tool_call_counts`. diff --git a/docs-website/reference_versioned_docs/version-2.24/integrations-api/agent_pack.md b/docs-website/reference_versioned_docs/version-2.24/integrations-api/agent_pack.md new file mode 100644 index 0000000000..2921c4d640 --- /dev/null +++ b/docs-website/reference_versioned_docs/version-2.24/integrations-api/agent_pack.md @@ -0,0 +1,463 @@ +--- +title: "Agent Pack" +id: integrations-agent-pack +description: "Agent Pack integration for Haystack" +slug: "/integrations-agent-pack" +--- + + +## haystack_integrations.agent_pack.advanced_rag.agent + +### create_advanced_rag_agent + +```python +create_advanced_rag_agent( + *, + document_store: DocumentStore, + retriever: TextRetriever | Pipeline | None = None, + retrieval_pipeline_input_mapping: dict[str, list[str]] | None = None, + retrieval_pipeline_output_mapping: dict[str, str] | None = None, + llm: ChatGenerator | None = None, + backup_answer_llm: ChatGenerator | None = None, + system_prompt: str | None = None, + max_agent_steps: int = 20, + max_fetched_docs: int = 10, + extra_tools: ToolsType | None = None, + state_schema: dict[str, Any] | None = None, + hooks: dict[HookPoint, list[Hook]] | None = None, + raise_on_tool_invocation_failure: bool = False, + tool_concurrency_limit: int = 4 +) -> Agent +``` + +Create the advanced RAG agent. + +The agent answers questions from documents it retrieves out of the document store. Instead of guessing which +metadata fields exist, it can inspect the store (fields, values, ranges) and construct a Haystack filter to +narrow its retrieval when metadata helps — plain, unfiltered retrieval remains available when it doesn't. The +answer cites the retrieved documents. + +The required `retriever` becomes the `search_documents` tool; `document_store` additionally feeds the three +metadata inspection tools and must implement the metadata introspection methods (`get_metadata_fields_info`, +`get_metadata_field_unique_values`, `get_metadata_field_min_max`). + +**Parameters:** + +- **document_store** (DocumentStore) – The document store the metadata inspection tools and the `fetch_documents_by_filter` tool + run against. +- **retriever** (TextRetriever | Pipeline | None) – What retrieves for the `search_documents` tool (required). Either a standalone retriever + component following the `TextRetriever` protocol, i.e. its `run` method accepts `query` and `filters` + (e.g. `InMemoryBM25Retriever`, or an embedding retriever wrapped in `TextEmbeddingRetriever`), or a custom + retrieval `Pipeline` (e.g. embedder -> retriever, or hybrid retrieval) — a pipeline additionally requires + `retrieval_pipeline_input_mapping`. It should retrieve by relevance scoring (keyword or embedding-based) — + direct, unscored fetching is already covered by the built-in `fetch_documents_by_filter` tool. +- **retrieval_pipeline_input_mapping** (dict\[str, list\[str\]\] | None) – Required when `retriever` is a `Pipeline`: maps the tool inputs to + pipeline input sockets; must have exactly the keys "query" and "filters", + e.g. `{"query": ["embedder.text"], "filters": ["retriever.filters"]}`. +- **retrieval_pipeline_output_mapping** (dict\[str, str\] | None) – Optional when `retriever` is a `Pipeline`: maps pipeline output sockets + to tool outputs, e.g. `{"retriever.documents": "documents"}`. +- **llm** (ChatGenerator | None) – LLM that drives the agent loop. Defaults to `OpenAIResponsesChatGenerator("gpt-5.4")` with low + reasoning effort. +- **backup_answer_llm** (ChatGenerator | None) – LLM the built-in `BackupAnswerHook` uses to write a best-effort answer when the run + is cut off by `max_agent_steps`. Defaults to a separate `OpenAIResponsesChatGenerator("gpt-5.4")` with low + reasoning effort. +- **system_prompt** (str | None) – Overrides the pre-made system prompt. +- **max_agent_steps** (int) – Maximum steps for the agent loop. If the loop is cut off by this limit before writing an + answer, an `after_run` hook (`BackupAnswerHook`) makes one extra LLM call to produce a best-effort answer from + the evidence gathered so far, so `last_message` always carries a text answer. +- **max_fetched_docs** (int) – Maximum number of documents `fetch_documents_by_filter` shows per fetch. A filter fetch is + not bounded by a retriever's `top_k`, so this caps the tool result instead; the scored `search_documents` tool + is bounded by the `top_k` configured on your retrieval components. +- **extra_tools** (ToolsType | None) – Additional tools (or toolsets) for the agent, appended after the built-in document-store + toolset and the retrieval tool. +- **state_schema** (dict\[str, Any\] | None) – Additional entries merged into the agent's state schema. The built-in `documents` entry + (the accumulated retrieved documents) always takes precedence. +- **hooks** (dict\[HookPoint, list\[Hook\]\] | None) – Additional hooks per hook point, merged with the built-in hooks. For `after_run`, the built-in + backup-answer hook runs first, so custom hooks see the final answer. +- **raise_on_tool_invocation_failure** (bool) – If True, a failing tool call raises instead of being returned to the LLM + as an error message it can recover from (the default). +- **tool_concurrency_limit** (int) – Maximum number of tool calls executed in parallel within one agent step. + +**Returns:** + +- Agent – The advanced RAG `Agent`. Call it with the question as a user message, + `agent.run(messages=[ChatMessage.from_user(question)])`; the answer is in `last_message` (a `ChatMessage`) and + `documents` carries every document the agent retrieved during the run (deduplicated by id, in first-retrieved + order) — the answer cites them by the first 8 characters of their id, e.g. `[doc a1b2c3d4]`. The standard Agent + outputs `messages`, `step_count`, `token_usage` and `tool_call_counts` are also returned. + +## haystack_integrations.agent_pack.advanced_rag.hooks + +### BackupAnswerHook + +Produce a final answer when the agent run ends without one. Runs as an `after_run` hook. + +When the agent exhausts `max_agent_steps` mid-investigation, the run ends on a tool call or tool result instead of +an assistant text answer (and only `after_run` hooks run in this situation). This hook detects that case and makes +one LLM call over the conversation so far to produce a best-effort answer from the already-gathered evidence. + +#### __init__ + +```python +__init__(chat_generator: ChatGenerator) -> None +``` + +Create the hook. + +**Parameters:** + +- **chat_generator** (ChatGenerator) – LLM that writes the backup answer from the gathered evidence. + +#### warm_up + +```python +warm_up() -> None +``` + +Prepare the hook's generator for use; called from the Agent's `warm_up`. + +#### close + +```python +close() -> None +``` + +Release the hook's generator resources; called from the Agent's `close`. + +#### to_dict + +```python +to_dict() -> dict +``` + +Serialize the hook to a dictionary. + +**Returns:** + +- dict – Dictionary with serialized data. + +#### from_dict + +```python +from_dict(data: dict) -> BackupAnswerHook +``` + +Deserialize the hook from a dictionary. + +**Parameters:** + +- **data** (dict) – Dictionary to deserialize from. + +**Returns:** + +- BackupAnswerHook – Deserialized hook. + +#### run + +```python +run(state: State) -> None +``` + +Append a best-effort final answer when the run ended without one (e.g. step exhaustion). + +**Parameters:** + +- **state** (State) – The agent run's state. + +## haystack_integrations.agent_pack.advanced_rag.tools + +### ListMetadataFieldsTool + +Bases: Tool + +Tool that lists all metadata fields and their types from a document store. + +#### __init__ + +```python +__init__(document_store: DocumentStore) -> None +``` + +Create the tool. + +**Parameters:** + +- **document_store** (DocumentStore) – The document store to inspect. Must implement `get_metadata_fields_info`. + +**Raises:** + +- ValueError – If the store does not implement `get_metadata_fields_info`. + +#### to_dict + +```python +to_dict() -> dict[str, Any] +``` + +Serialize the tool to a dictionary. + +#### from_dict + +```python +from_dict(data: dict[str, Any]) -> ListMetadataFieldsTool +``` + +Deserialize the tool from a dictionary. + +**Parameters:** + +- **data** (dict\[str, Any\]) – The dictionary produced by `to_dict`. + +**Returns:** + +- ListMetadataFieldsTool – The deserialized tool. + +### GetMetadataFieldValuesTool + +Bases: Tool + +Tool that returns the distinct values of a metadata field from a document store. + +#### __init__ + +```python +__init__(document_store: DocumentStore) -> None +``` + +Create the tool. + +**Parameters:** + +- **document_store** (DocumentStore) – The document store to inspect. Must implement `get_metadata_field_unique_values`. + +**Raises:** + +- ValueError – If the store does not implement `get_metadata_field_unique_values`. + +#### to_dict + +```python +to_dict() -> dict[str, Any] +``` + +Serialize the tool to a dictionary. + +#### from_dict + +```python +from_dict(data: dict[str, Any]) -> GetMetadataFieldValuesTool +``` + +Deserialize the tool from a dictionary. + +**Parameters:** + +- **data** (dict\[str, Any\]) – The dictionary produced by `to_dict`. + +**Returns:** + +- GetMetadataFieldValuesTool – The deserialized tool. + +### GetMetadataFieldRangeTool + +Bases: Tool + +Tool that returns the minimum and maximum values of a metadata field from a document store. + +#### __init__ + +```python +__init__(document_store: DocumentStore) -> None +``` + +Create the tool. + +**Parameters:** + +- **document_store** (DocumentStore) – The document store to inspect. Must implement `get_metadata_field_min_max`. + +**Raises:** + +- ValueError – If the store does not implement `get_metadata_field_min_max`. + +#### to_dict + +```python +to_dict() -> dict[str, Any] +``` + +Serialize the tool to a dictionary. + +#### from_dict + +```python +from_dict(data: dict[str, Any]) -> GetMetadataFieldRangeTool +``` + +Deserialize the tool from a dictionary. + +**Parameters:** + +- **data** (dict\[str, Any\]) – The dictionary produced by `to_dict`. + +**Returns:** + +- GetMetadataFieldRangeTool – The deserialized tool. + +### FetchDocumentsByFilterTool + +Bases: Tool + +Tool that fetches documents directly from a document store by metadata filter. + +Unlike a scored retrieval tool, this fetches without any relevance ranking, so an agent can grab specific documents +(e.g. a known title or source file) without going through a relevance search. The fetched documents are put into +reading order first: grouped by their parent file (`file_name`/`file_path`/`source_id`) and sorted by their +position within it (`split_id`/`split_idx_start`/`page_number`), using whichever of those metadata fields the +documents carry. Match sets larger than `max_docs` are paged: each call returns one page plus the total match +count, and the tool's `offset` input continues where the previous page ended. + +#### __init__ + +```python +__init__( + document_store: DocumentStore, + max_docs: int = 10, + max_fetch_factor: int = 10, +) -> None +``` + +Create the tool. + +**Parameters:** + +- **document_store** (DocumentStore) – The document store to fetch documents from. +- **max_docs** (int) – Ceiling on the number of documents shown to the agent per fetch. Unlike scored retrieval, a + filter fetch is not bounded by a retriever's `top_k`, so this caps the tool result instead. The LLM can + request fewer via the tool's optional `max_docs` input, but never more. +- **max_fetch_factor** (int) – How many times the `max_docs` ceiling a filter may match before the fetch is + refused outright (when the store supports `count_documents_by_filter`) — the refusal is surfaced to the + LLM as an error it can recover from by narrowing the filter. + +#### to_dict + +```python +to_dict() -> dict[str, Any] +``` + +Serialize the tool to a dictionary. + +#### from_dict + +```python +from_dict(data: dict[str, Any]) -> FetchDocumentsByFilterTool +``` + +Deserialize the tool from a dictionary. + +**Parameters:** + +- **data** (dict\[str, Any\]) – The dictionary produced by `to_dict`. + +**Returns:** + +- FetchDocumentsByFilterTool – The deserialized tool. + +### DocumentStoreToolset + +Bases: Toolset + +All document-store-backed tools as one unit. + +Bundles the three metadata inspection tools (`ListMetadataFieldsTool`, `GetMetadataFieldValuesTool`, +`GetMetadataFieldRangeTool`) and the direct `FetchDocumentsByFilterTool`, so they can be handed to an `Agent` +(or combined with a retrieval tool) as a single object. + +#### __init__ + +```python +__init__(document_store: DocumentStore, max_fetched_docs: int = 10) -> None +``` + +Create the toolset. + +**Parameters:** + +- **document_store** (DocumentStore) – The document store all tools run against. Must implement the metadata introspection + methods (`get_metadata_fields_info`, `get_metadata_field_unique_values`, `get_metadata_field_min_max`). +- **max_fetched_docs** (int) – Maximum number of documents `fetch_documents_by_filter` shows per fetch (see + `FetchDocumentsByFilterTool.max_docs`). + +#### to_dict + +```python +to_dict() -> dict[str, Any] +``` + +Serialize the toolset to a dictionary. + +#### from_dict + +```python +from_dict(data: dict[str, Any]) -> DocumentStoreToolset +``` + +Deserialize the toolset from a dictionary. + +**Parameters:** + +- **data** (dict\[str, Any\]) – The dictionary produced by `to_dict`. + +**Returns:** + +- DocumentStoreToolset – The deserialized toolset. + +## haystack_integrations.agent_pack.deep_research.agent + +### create_deep_research_agent + +```python +create_deep_research_agent( + *, + scope_llm: ChatGenerator | None = None, + orchestrator_llm: ChatGenerator | None = None, + researcher_llm: ChatGenerator | None = None, + summarizer_llm: ChatGenerator | None = None, + writer_llm: ChatGenerator | None = None, + max_subtopics: int = 5, + max_concurrent_researchers: int = 5, + max_orchestrator_steps: int = 8, + max_researcher_steps: int = 20, + max_search_results: int = 10, + max_content_length: int = 50000 +) -> Agent +``` + +Create the deep research agent. + +**Parameters:** + +- **scope_llm** (ChatGenerator | None) – LLM that rewrites the user query into a focused research brief. + Defaults to `OpenAIResponsesChatGenerator("gpt-5.4")`. +- **orchestrator_llm** (ChatGenerator | None) – LLM that plans the investigation and delegates the sub-questions. + Defaults to `OpenAIResponsesChatGenerator("gpt-5.4")`. +- **researcher_llm** (ChatGenerator | None) – LLM that drives each sub-researcher's search/read/think loop. + Defaults to `OpenAIResponsesChatGenerator("gpt-5.4-mini")`. +- **summarizer_llm** (ChatGenerator | None) – LLM used inside the `read_url` tool to summarize a fetched page toward + the question. Defaults to `OpenAIResponsesChatGenerator("gpt-5.4-mini")`. +- **writer_llm** (ChatGenerator | None) – LLM that turns the brief plus collected notes into the final report. + Defaults to `OpenAIResponsesChatGenerator("gpt-5.4")`. +- **max_subtopics** (int) – Maximum number of sub-questions the orchestrator may delegate (breadth). +- **max_concurrent_researchers** (int) – Maximum number of sub-researchers that run at the same time. +- **max_orchestrator_steps** (int) – Maximum steps for the orchestrator's agent loop (reflect -> delegate rounds). +- **max_researcher_steps** (int) – Maximum steps for each sub-researcher's agent loop. +- **max_search_results** (int) – Number of results returned per `web_search` call. +- **max_content_length** (int) – Maximum raw page characters fed to the summarizer, before summarization. + +**Returns:** + +- Agent – The deep research `Agent`. Call it with the question as a user message, + `agent.run(messages=[ChatMessage.from_user(question)])`; it returns a dict whose main output is + `report` (the final markdown report, a `str`). The dict also carries the intermediate `brief` + (`str`) and `notes` (`list[str]`), plus the standard Agent outputs `messages`, `last_message`, + `step_count`, `token_usage` and `tool_call_counts`. diff --git a/docs-website/reference_versioned_docs/version-2.25/integrations-api/agent_pack.md b/docs-website/reference_versioned_docs/version-2.25/integrations-api/agent_pack.md new file mode 100644 index 0000000000..2921c4d640 --- /dev/null +++ b/docs-website/reference_versioned_docs/version-2.25/integrations-api/agent_pack.md @@ -0,0 +1,463 @@ +--- +title: "Agent Pack" +id: integrations-agent-pack +description: "Agent Pack integration for Haystack" +slug: "/integrations-agent-pack" +--- + + +## haystack_integrations.agent_pack.advanced_rag.agent + +### create_advanced_rag_agent + +```python +create_advanced_rag_agent( + *, + document_store: DocumentStore, + retriever: TextRetriever | Pipeline | None = None, + retrieval_pipeline_input_mapping: dict[str, list[str]] | None = None, + retrieval_pipeline_output_mapping: dict[str, str] | None = None, + llm: ChatGenerator | None = None, + backup_answer_llm: ChatGenerator | None = None, + system_prompt: str | None = None, + max_agent_steps: int = 20, + max_fetched_docs: int = 10, + extra_tools: ToolsType | None = None, + state_schema: dict[str, Any] | None = None, + hooks: dict[HookPoint, list[Hook]] | None = None, + raise_on_tool_invocation_failure: bool = False, + tool_concurrency_limit: int = 4 +) -> Agent +``` + +Create the advanced RAG agent. + +The agent answers questions from documents it retrieves out of the document store. Instead of guessing which +metadata fields exist, it can inspect the store (fields, values, ranges) and construct a Haystack filter to +narrow its retrieval when metadata helps — plain, unfiltered retrieval remains available when it doesn't. The +answer cites the retrieved documents. + +The required `retriever` becomes the `search_documents` tool; `document_store` additionally feeds the three +metadata inspection tools and must implement the metadata introspection methods (`get_metadata_fields_info`, +`get_metadata_field_unique_values`, `get_metadata_field_min_max`). + +**Parameters:** + +- **document_store** (DocumentStore) – The document store the metadata inspection tools and the `fetch_documents_by_filter` tool + run against. +- **retriever** (TextRetriever | Pipeline | None) – What retrieves for the `search_documents` tool (required). Either a standalone retriever + component following the `TextRetriever` protocol, i.e. its `run` method accepts `query` and `filters` + (e.g. `InMemoryBM25Retriever`, or an embedding retriever wrapped in `TextEmbeddingRetriever`), or a custom + retrieval `Pipeline` (e.g. embedder -> retriever, or hybrid retrieval) — a pipeline additionally requires + `retrieval_pipeline_input_mapping`. It should retrieve by relevance scoring (keyword or embedding-based) — + direct, unscored fetching is already covered by the built-in `fetch_documents_by_filter` tool. +- **retrieval_pipeline_input_mapping** (dict\[str, list\[str\]\] | None) – Required when `retriever` is a `Pipeline`: maps the tool inputs to + pipeline input sockets; must have exactly the keys "query" and "filters", + e.g. `{"query": ["embedder.text"], "filters": ["retriever.filters"]}`. +- **retrieval_pipeline_output_mapping** (dict\[str, str\] | None) – Optional when `retriever` is a `Pipeline`: maps pipeline output sockets + to tool outputs, e.g. `{"retriever.documents": "documents"}`. +- **llm** (ChatGenerator | None) – LLM that drives the agent loop. Defaults to `OpenAIResponsesChatGenerator("gpt-5.4")` with low + reasoning effort. +- **backup_answer_llm** (ChatGenerator | None) – LLM the built-in `BackupAnswerHook` uses to write a best-effort answer when the run + is cut off by `max_agent_steps`. Defaults to a separate `OpenAIResponsesChatGenerator("gpt-5.4")` with low + reasoning effort. +- **system_prompt** (str | None) – Overrides the pre-made system prompt. +- **max_agent_steps** (int) – Maximum steps for the agent loop. If the loop is cut off by this limit before writing an + answer, an `after_run` hook (`BackupAnswerHook`) makes one extra LLM call to produce a best-effort answer from + the evidence gathered so far, so `last_message` always carries a text answer. +- **max_fetched_docs** (int) – Maximum number of documents `fetch_documents_by_filter` shows per fetch. A filter fetch is + not bounded by a retriever's `top_k`, so this caps the tool result instead; the scored `search_documents` tool + is bounded by the `top_k` configured on your retrieval components. +- **extra_tools** (ToolsType | None) – Additional tools (or toolsets) for the agent, appended after the built-in document-store + toolset and the retrieval tool. +- **state_schema** (dict\[str, Any\] | None) – Additional entries merged into the agent's state schema. The built-in `documents` entry + (the accumulated retrieved documents) always takes precedence. +- **hooks** (dict\[HookPoint, list\[Hook\]\] | None) – Additional hooks per hook point, merged with the built-in hooks. For `after_run`, the built-in + backup-answer hook runs first, so custom hooks see the final answer. +- **raise_on_tool_invocation_failure** (bool) – If True, a failing tool call raises instead of being returned to the LLM + as an error message it can recover from (the default). +- **tool_concurrency_limit** (int) – Maximum number of tool calls executed in parallel within one agent step. + +**Returns:** + +- Agent – The advanced RAG `Agent`. Call it with the question as a user message, + `agent.run(messages=[ChatMessage.from_user(question)])`; the answer is in `last_message` (a `ChatMessage`) and + `documents` carries every document the agent retrieved during the run (deduplicated by id, in first-retrieved + order) — the answer cites them by the first 8 characters of their id, e.g. `[doc a1b2c3d4]`. The standard Agent + outputs `messages`, `step_count`, `token_usage` and `tool_call_counts` are also returned. + +## haystack_integrations.agent_pack.advanced_rag.hooks + +### BackupAnswerHook + +Produce a final answer when the agent run ends without one. Runs as an `after_run` hook. + +When the agent exhausts `max_agent_steps` mid-investigation, the run ends on a tool call or tool result instead of +an assistant text answer (and only `after_run` hooks run in this situation). This hook detects that case and makes +one LLM call over the conversation so far to produce a best-effort answer from the already-gathered evidence. + +#### __init__ + +```python +__init__(chat_generator: ChatGenerator) -> None +``` + +Create the hook. + +**Parameters:** + +- **chat_generator** (ChatGenerator) – LLM that writes the backup answer from the gathered evidence. + +#### warm_up + +```python +warm_up() -> None +``` + +Prepare the hook's generator for use; called from the Agent's `warm_up`. + +#### close + +```python +close() -> None +``` + +Release the hook's generator resources; called from the Agent's `close`. + +#### to_dict + +```python +to_dict() -> dict +``` + +Serialize the hook to a dictionary. + +**Returns:** + +- dict – Dictionary with serialized data. + +#### from_dict + +```python +from_dict(data: dict) -> BackupAnswerHook +``` + +Deserialize the hook from a dictionary. + +**Parameters:** + +- **data** (dict) – Dictionary to deserialize from. + +**Returns:** + +- BackupAnswerHook – Deserialized hook. + +#### run + +```python +run(state: State) -> None +``` + +Append a best-effort final answer when the run ended without one (e.g. step exhaustion). + +**Parameters:** + +- **state** (State) – The agent run's state. + +## haystack_integrations.agent_pack.advanced_rag.tools + +### ListMetadataFieldsTool + +Bases: Tool + +Tool that lists all metadata fields and their types from a document store. + +#### __init__ + +```python +__init__(document_store: DocumentStore) -> None +``` + +Create the tool. + +**Parameters:** + +- **document_store** (DocumentStore) – The document store to inspect. Must implement `get_metadata_fields_info`. + +**Raises:** + +- ValueError – If the store does not implement `get_metadata_fields_info`. + +#### to_dict + +```python +to_dict() -> dict[str, Any] +``` + +Serialize the tool to a dictionary. + +#### from_dict + +```python +from_dict(data: dict[str, Any]) -> ListMetadataFieldsTool +``` + +Deserialize the tool from a dictionary. + +**Parameters:** + +- **data** (dict\[str, Any\]) – The dictionary produced by `to_dict`. + +**Returns:** + +- ListMetadataFieldsTool – The deserialized tool. + +### GetMetadataFieldValuesTool + +Bases: Tool + +Tool that returns the distinct values of a metadata field from a document store. + +#### __init__ + +```python +__init__(document_store: DocumentStore) -> None +``` + +Create the tool. + +**Parameters:** + +- **document_store** (DocumentStore) – The document store to inspect. Must implement `get_metadata_field_unique_values`. + +**Raises:** + +- ValueError – If the store does not implement `get_metadata_field_unique_values`. + +#### to_dict + +```python +to_dict() -> dict[str, Any] +``` + +Serialize the tool to a dictionary. + +#### from_dict + +```python +from_dict(data: dict[str, Any]) -> GetMetadataFieldValuesTool +``` + +Deserialize the tool from a dictionary. + +**Parameters:** + +- **data** (dict\[str, Any\]) – The dictionary produced by `to_dict`. + +**Returns:** + +- GetMetadataFieldValuesTool – The deserialized tool. + +### GetMetadataFieldRangeTool + +Bases: Tool + +Tool that returns the minimum and maximum values of a metadata field from a document store. + +#### __init__ + +```python +__init__(document_store: DocumentStore) -> None +``` + +Create the tool. + +**Parameters:** + +- **document_store** (DocumentStore) – The document store to inspect. Must implement `get_metadata_field_min_max`. + +**Raises:** + +- ValueError – If the store does not implement `get_metadata_field_min_max`. + +#### to_dict + +```python +to_dict() -> dict[str, Any] +``` + +Serialize the tool to a dictionary. + +#### from_dict + +```python +from_dict(data: dict[str, Any]) -> GetMetadataFieldRangeTool +``` + +Deserialize the tool from a dictionary. + +**Parameters:** + +- **data** (dict\[str, Any\]) – The dictionary produced by `to_dict`. + +**Returns:** + +- GetMetadataFieldRangeTool – The deserialized tool. + +### FetchDocumentsByFilterTool + +Bases: Tool + +Tool that fetches documents directly from a document store by metadata filter. + +Unlike a scored retrieval tool, this fetches without any relevance ranking, so an agent can grab specific documents +(e.g. a known title or source file) without going through a relevance search. The fetched documents are put into +reading order first: grouped by their parent file (`file_name`/`file_path`/`source_id`) and sorted by their +position within it (`split_id`/`split_idx_start`/`page_number`), using whichever of those metadata fields the +documents carry. Match sets larger than `max_docs` are paged: each call returns one page plus the total match +count, and the tool's `offset` input continues where the previous page ended. + +#### __init__ + +```python +__init__( + document_store: DocumentStore, + max_docs: int = 10, + max_fetch_factor: int = 10, +) -> None +``` + +Create the tool. + +**Parameters:** + +- **document_store** (DocumentStore) – The document store to fetch documents from. +- **max_docs** (int) – Ceiling on the number of documents shown to the agent per fetch. Unlike scored retrieval, a + filter fetch is not bounded by a retriever's `top_k`, so this caps the tool result instead. The LLM can + request fewer via the tool's optional `max_docs` input, but never more. +- **max_fetch_factor** (int) – How many times the `max_docs` ceiling a filter may match before the fetch is + refused outright (when the store supports `count_documents_by_filter`) — the refusal is surfaced to the + LLM as an error it can recover from by narrowing the filter. + +#### to_dict + +```python +to_dict() -> dict[str, Any] +``` + +Serialize the tool to a dictionary. + +#### from_dict + +```python +from_dict(data: dict[str, Any]) -> FetchDocumentsByFilterTool +``` + +Deserialize the tool from a dictionary. + +**Parameters:** + +- **data** (dict\[str, Any\]) – The dictionary produced by `to_dict`. + +**Returns:** + +- FetchDocumentsByFilterTool – The deserialized tool. + +### DocumentStoreToolset + +Bases: Toolset + +All document-store-backed tools as one unit. + +Bundles the three metadata inspection tools (`ListMetadataFieldsTool`, `GetMetadataFieldValuesTool`, +`GetMetadataFieldRangeTool`) and the direct `FetchDocumentsByFilterTool`, so they can be handed to an `Agent` +(or combined with a retrieval tool) as a single object. + +#### __init__ + +```python +__init__(document_store: DocumentStore, max_fetched_docs: int = 10) -> None +``` + +Create the toolset. + +**Parameters:** + +- **document_store** (DocumentStore) – The document store all tools run against. Must implement the metadata introspection + methods (`get_metadata_fields_info`, `get_metadata_field_unique_values`, `get_metadata_field_min_max`). +- **max_fetched_docs** (int) – Maximum number of documents `fetch_documents_by_filter` shows per fetch (see + `FetchDocumentsByFilterTool.max_docs`). + +#### to_dict + +```python +to_dict() -> dict[str, Any] +``` + +Serialize the toolset to a dictionary. + +#### from_dict + +```python +from_dict(data: dict[str, Any]) -> DocumentStoreToolset +``` + +Deserialize the toolset from a dictionary. + +**Parameters:** + +- **data** (dict\[str, Any\]) – The dictionary produced by `to_dict`. + +**Returns:** + +- DocumentStoreToolset – The deserialized toolset. + +## haystack_integrations.agent_pack.deep_research.agent + +### create_deep_research_agent + +```python +create_deep_research_agent( + *, + scope_llm: ChatGenerator | None = None, + orchestrator_llm: ChatGenerator | None = None, + researcher_llm: ChatGenerator | None = None, + summarizer_llm: ChatGenerator | None = None, + writer_llm: ChatGenerator | None = None, + max_subtopics: int = 5, + max_concurrent_researchers: int = 5, + max_orchestrator_steps: int = 8, + max_researcher_steps: int = 20, + max_search_results: int = 10, + max_content_length: int = 50000 +) -> Agent +``` + +Create the deep research agent. + +**Parameters:** + +- **scope_llm** (ChatGenerator | None) – LLM that rewrites the user query into a focused research brief. + Defaults to `OpenAIResponsesChatGenerator("gpt-5.4")`. +- **orchestrator_llm** (ChatGenerator | None) – LLM that plans the investigation and delegates the sub-questions. + Defaults to `OpenAIResponsesChatGenerator("gpt-5.4")`. +- **researcher_llm** (ChatGenerator | None) – LLM that drives each sub-researcher's search/read/think loop. + Defaults to `OpenAIResponsesChatGenerator("gpt-5.4-mini")`. +- **summarizer_llm** (ChatGenerator | None) – LLM used inside the `read_url` tool to summarize a fetched page toward + the question. Defaults to `OpenAIResponsesChatGenerator("gpt-5.4-mini")`. +- **writer_llm** (ChatGenerator | None) – LLM that turns the brief plus collected notes into the final report. + Defaults to `OpenAIResponsesChatGenerator("gpt-5.4")`. +- **max_subtopics** (int) – Maximum number of sub-questions the orchestrator may delegate (breadth). +- **max_concurrent_researchers** (int) – Maximum number of sub-researchers that run at the same time. +- **max_orchestrator_steps** (int) – Maximum steps for the orchestrator's agent loop (reflect -> delegate rounds). +- **max_researcher_steps** (int) – Maximum steps for each sub-researcher's agent loop. +- **max_search_results** (int) – Number of results returned per `web_search` call. +- **max_content_length** (int) – Maximum raw page characters fed to the summarizer, before summarization. + +**Returns:** + +- Agent – The deep research `Agent`. Call it with the question as a user message, + `agent.run(messages=[ChatMessage.from_user(question)])`; it returns a dict whose main output is + `report` (the final markdown report, a `str`). The dict also carries the intermediate `brief` + (`str`) and `notes` (`list[str]`), plus the standard Agent outputs `messages`, `last_message`, + `step_count`, `token_usage` and `tool_call_counts`. diff --git a/docs-website/reference_versioned_docs/version-2.26/integrations-api/agent_pack.md b/docs-website/reference_versioned_docs/version-2.26/integrations-api/agent_pack.md new file mode 100644 index 0000000000..2921c4d640 --- /dev/null +++ b/docs-website/reference_versioned_docs/version-2.26/integrations-api/agent_pack.md @@ -0,0 +1,463 @@ +--- +title: "Agent Pack" +id: integrations-agent-pack +description: "Agent Pack integration for Haystack" +slug: "/integrations-agent-pack" +--- + + +## haystack_integrations.agent_pack.advanced_rag.agent + +### create_advanced_rag_agent + +```python +create_advanced_rag_agent( + *, + document_store: DocumentStore, + retriever: TextRetriever | Pipeline | None = None, + retrieval_pipeline_input_mapping: dict[str, list[str]] | None = None, + retrieval_pipeline_output_mapping: dict[str, str] | None = None, + llm: ChatGenerator | None = None, + backup_answer_llm: ChatGenerator | None = None, + system_prompt: str | None = None, + max_agent_steps: int = 20, + max_fetched_docs: int = 10, + extra_tools: ToolsType | None = None, + state_schema: dict[str, Any] | None = None, + hooks: dict[HookPoint, list[Hook]] | None = None, + raise_on_tool_invocation_failure: bool = False, + tool_concurrency_limit: int = 4 +) -> Agent +``` + +Create the advanced RAG agent. + +The agent answers questions from documents it retrieves out of the document store. Instead of guessing which +metadata fields exist, it can inspect the store (fields, values, ranges) and construct a Haystack filter to +narrow its retrieval when metadata helps — plain, unfiltered retrieval remains available when it doesn't. The +answer cites the retrieved documents. + +The required `retriever` becomes the `search_documents` tool; `document_store` additionally feeds the three +metadata inspection tools and must implement the metadata introspection methods (`get_metadata_fields_info`, +`get_metadata_field_unique_values`, `get_metadata_field_min_max`). + +**Parameters:** + +- **document_store** (DocumentStore) – The document store the metadata inspection tools and the `fetch_documents_by_filter` tool + run against. +- **retriever** (TextRetriever | Pipeline | None) – What retrieves for the `search_documents` tool (required). Either a standalone retriever + component following the `TextRetriever` protocol, i.e. its `run` method accepts `query` and `filters` + (e.g. `InMemoryBM25Retriever`, or an embedding retriever wrapped in `TextEmbeddingRetriever`), or a custom + retrieval `Pipeline` (e.g. embedder -> retriever, or hybrid retrieval) — a pipeline additionally requires + `retrieval_pipeline_input_mapping`. It should retrieve by relevance scoring (keyword or embedding-based) — + direct, unscored fetching is already covered by the built-in `fetch_documents_by_filter` tool. +- **retrieval_pipeline_input_mapping** (dict\[str, list\[str\]\] | None) – Required when `retriever` is a `Pipeline`: maps the tool inputs to + pipeline input sockets; must have exactly the keys "query" and "filters", + e.g. `{"query": ["embedder.text"], "filters": ["retriever.filters"]}`. +- **retrieval_pipeline_output_mapping** (dict\[str, str\] | None) – Optional when `retriever` is a `Pipeline`: maps pipeline output sockets + to tool outputs, e.g. `{"retriever.documents": "documents"}`. +- **llm** (ChatGenerator | None) – LLM that drives the agent loop. Defaults to `OpenAIResponsesChatGenerator("gpt-5.4")` with low + reasoning effort. +- **backup_answer_llm** (ChatGenerator | None) – LLM the built-in `BackupAnswerHook` uses to write a best-effort answer when the run + is cut off by `max_agent_steps`. Defaults to a separate `OpenAIResponsesChatGenerator("gpt-5.4")` with low + reasoning effort. +- **system_prompt** (str | None) – Overrides the pre-made system prompt. +- **max_agent_steps** (int) – Maximum steps for the agent loop. If the loop is cut off by this limit before writing an + answer, an `after_run` hook (`BackupAnswerHook`) makes one extra LLM call to produce a best-effort answer from + the evidence gathered so far, so `last_message` always carries a text answer. +- **max_fetched_docs** (int) – Maximum number of documents `fetch_documents_by_filter` shows per fetch. A filter fetch is + not bounded by a retriever's `top_k`, so this caps the tool result instead; the scored `search_documents` tool + is bounded by the `top_k` configured on your retrieval components. +- **extra_tools** (ToolsType | None) – Additional tools (or toolsets) for the agent, appended after the built-in document-store + toolset and the retrieval tool. +- **state_schema** (dict\[str, Any\] | None) – Additional entries merged into the agent's state schema. The built-in `documents` entry + (the accumulated retrieved documents) always takes precedence. +- **hooks** (dict\[HookPoint, list\[Hook\]\] | None) – Additional hooks per hook point, merged with the built-in hooks. For `after_run`, the built-in + backup-answer hook runs first, so custom hooks see the final answer. +- **raise_on_tool_invocation_failure** (bool) – If True, a failing tool call raises instead of being returned to the LLM + as an error message it can recover from (the default). +- **tool_concurrency_limit** (int) – Maximum number of tool calls executed in parallel within one agent step. + +**Returns:** + +- Agent – The advanced RAG `Agent`. Call it with the question as a user message, + `agent.run(messages=[ChatMessage.from_user(question)])`; the answer is in `last_message` (a `ChatMessage`) and + `documents` carries every document the agent retrieved during the run (deduplicated by id, in first-retrieved + order) — the answer cites them by the first 8 characters of their id, e.g. `[doc a1b2c3d4]`. The standard Agent + outputs `messages`, `step_count`, `token_usage` and `tool_call_counts` are also returned. + +## haystack_integrations.agent_pack.advanced_rag.hooks + +### BackupAnswerHook + +Produce a final answer when the agent run ends without one. Runs as an `after_run` hook. + +When the agent exhausts `max_agent_steps` mid-investigation, the run ends on a tool call or tool result instead of +an assistant text answer (and only `after_run` hooks run in this situation). This hook detects that case and makes +one LLM call over the conversation so far to produce a best-effort answer from the already-gathered evidence. + +#### __init__ + +```python +__init__(chat_generator: ChatGenerator) -> None +``` + +Create the hook. + +**Parameters:** + +- **chat_generator** (ChatGenerator) – LLM that writes the backup answer from the gathered evidence. + +#### warm_up + +```python +warm_up() -> None +``` + +Prepare the hook's generator for use; called from the Agent's `warm_up`. + +#### close + +```python +close() -> None +``` + +Release the hook's generator resources; called from the Agent's `close`. + +#### to_dict + +```python +to_dict() -> dict +``` + +Serialize the hook to a dictionary. + +**Returns:** + +- dict – Dictionary with serialized data. + +#### from_dict + +```python +from_dict(data: dict) -> BackupAnswerHook +``` + +Deserialize the hook from a dictionary. + +**Parameters:** + +- **data** (dict) – Dictionary to deserialize from. + +**Returns:** + +- BackupAnswerHook – Deserialized hook. + +#### run + +```python +run(state: State) -> None +``` + +Append a best-effort final answer when the run ended without one (e.g. step exhaustion). + +**Parameters:** + +- **state** (State) – The agent run's state. + +## haystack_integrations.agent_pack.advanced_rag.tools + +### ListMetadataFieldsTool + +Bases: Tool + +Tool that lists all metadata fields and their types from a document store. + +#### __init__ + +```python +__init__(document_store: DocumentStore) -> None +``` + +Create the tool. + +**Parameters:** + +- **document_store** (DocumentStore) – The document store to inspect. Must implement `get_metadata_fields_info`. + +**Raises:** + +- ValueError – If the store does not implement `get_metadata_fields_info`. + +#### to_dict + +```python +to_dict() -> dict[str, Any] +``` + +Serialize the tool to a dictionary. + +#### from_dict + +```python +from_dict(data: dict[str, Any]) -> ListMetadataFieldsTool +``` + +Deserialize the tool from a dictionary. + +**Parameters:** + +- **data** (dict\[str, Any\]) – The dictionary produced by `to_dict`. + +**Returns:** + +- ListMetadataFieldsTool – The deserialized tool. + +### GetMetadataFieldValuesTool + +Bases: Tool + +Tool that returns the distinct values of a metadata field from a document store. + +#### __init__ + +```python +__init__(document_store: DocumentStore) -> None +``` + +Create the tool. + +**Parameters:** + +- **document_store** (DocumentStore) – The document store to inspect. Must implement `get_metadata_field_unique_values`. + +**Raises:** + +- ValueError – If the store does not implement `get_metadata_field_unique_values`. + +#### to_dict + +```python +to_dict() -> dict[str, Any] +``` + +Serialize the tool to a dictionary. + +#### from_dict + +```python +from_dict(data: dict[str, Any]) -> GetMetadataFieldValuesTool +``` + +Deserialize the tool from a dictionary. + +**Parameters:** + +- **data** (dict\[str, Any\]) – The dictionary produced by `to_dict`. + +**Returns:** + +- GetMetadataFieldValuesTool – The deserialized tool. + +### GetMetadataFieldRangeTool + +Bases: Tool + +Tool that returns the minimum and maximum values of a metadata field from a document store. + +#### __init__ + +```python +__init__(document_store: DocumentStore) -> None +``` + +Create the tool. + +**Parameters:** + +- **document_store** (DocumentStore) – The document store to inspect. Must implement `get_metadata_field_min_max`. + +**Raises:** + +- ValueError – If the store does not implement `get_metadata_field_min_max`. + +#### to_dict + +```python +to_dict() -> dict[str, Any] +``` + +Serialize the tool to a dictionary. + +#### from_dict + +```python +from_dict(data: dict[str, Any]) -> GetMetadataFieldRangeTool +``` + +Deserialize the tool from a dictionary. + +**Parameters:** + +- **data** (dict\[str, Any\]) – The dictionary produced by `to_dict`. + +**Returns:** + +- GetMetadataFieldRangeTool – The deserialized tool. + +### FetchDocumentsByFilterTool + +Bases: Tool + +Tool that fetches documents directly from a document store by metadata filter. + +Unlike a scored retrieval tool, this fetches without any relevance ranking, so an agent can grab specific documents +(e.g. a known title or source file) without going through a relevance search. The fetched documents are put into +reading order first: grouped by their parent file (`file_name`/`file_path`/`source_id`) and sorted by their +position within it (`split_id`/`split_idx_start`/`page_number`), using whichever of those metadata fields the +documents carry. Match sets larger than `max_docs` are paged: each call returns one page plus the total match +count, and the tool's `offset` input continues where the previous page ended. + +#### __init__ + +```python +__init__( + document_store: DocumentStore, + max_docs: int = 10, + max_fetch_factor: int = 10, +) -> None +``` + +Create the tool. + +**Parameters:** + +- **document_store** (DocumentStore) – The document store to fetch documents from. +- **max_docs** (int) – Ceiling on the number of documents shown to the agent per fetch. Unlike scored retrieval, a + filter fetch is not bounded by a retriever's `top_k`, so this caps the tool result instead. The LLM can + request fewer via the tool's optional `max_docs` input, but never more. +- **max_fetch_factor** (int) – How many times the `max_docs` ceiling a filter may match before the fetch is + refused outright (when the store supports `count_documents_by_filter`) — the refusal is surfaced to the + LLM as an error it can recover from by narrowing the filter. + +#### to_dict + +```python +to_dict() -> dict[str, Any] +``` + +Serialize the tool to a dictionary. + +#### from_dict + +```python +from_dict(data: dict[str, Any]) -> FetchDocumentsByFilterTool +``` + +Deserialize the tool from a dictionary. + +**Parameters:** + +- **data** (dict\[str, Any\]) – The dictionary produced by `to_dict`. + +**Returns:** + +- FetchDocumentsByFilterTool – The deserialized tool. + +### DocumentStoreToolset + +Bases: Toolset + +All document-store-backed tools as one unit. + +Bundles the three metadata inspection tools (`ListMetadataFieldsTool`, `GetMetadataFieldValuesTool`, +`GetMetadataFieldRangeTool`) and the direct `FetchDocumentsByFilterTool`, so they can be handed to an `Agent` +(or combined with a retrieval tool) as a single object. + +#### __init__ + +```python +__init__(document_store: DocumentStore, max_fetched_docs: int = 10) -> None +``` + +Create the toolset. + +**Parameters:** + +- **document_store** (DocumentStore) – The document store all tools run against. Must implement the metadata introspection + methods (`get_metadata_fields_info`, `get_metadata_field_unique_values`, `get_metadata_field_min_max`). +- **max_fetched_docs** (int) – Maximum number of documents `fetch_documents_by_filter` shows per fetch (see + `FetchDocumentsByFilterTool.max_docs`). + +#### to_dict + +```python +to_dict() -> dict[str, Any] +``` + +Serialize the toolset to a dictionary. + +#### from_dict + +```python +from_dict(data: dict[str, Any]) -> DocumentStoreToolset +``` + +Deserialize the toolset from a dictionary. + +**Parameters:** + +- **data** (dict\[str, Any\]) – The dictionary produced by `to_dict`. + +**Returns:** + +- DocumentStoreToolset – The deserialized toolset. + +## haystack_integrations.agent_pack.deep_research.agent + +### create_deep_research_agent + +```python +create_deep_research_agent( + *, + scope_llm: ChatGenerator | None = None, + orchestrator_llm: ChatGenerator | None = None, + researcher_llm: ChatGenerator | None = None, + summarizer_llm: ChatGenerator | None = None, + writer_llm: ChatGenerator | None = None, + max_subtopics: int = 5, + max_concurrent_researchers: int = 5, + max_orchestrator_steps: int = 8, + max_researcher_steps: int = 20, + max_search_results: int = 10, + max_content_length: int = 50000 +) -> Agent +``` + +Create the deep research agent. + +**Parameters:** + +- **scope_llm** (ChatGenerator | None) – LLM that rewrites the user query into a focused research brief. + Defaults to `OpenAIResponsesChatGenerator("gpt-5.4")`. +- **orchestrator_llm** (ChatGenerator | None) – LLM that plans the investigation and delegates the sub-questions. + Defaults to `OpenAIResponsesChatGenerator("gpt-5.4")`. +- **researcher_llm** (ChatGenerator | None) – LLM that drives each sub-researcher's search/read/think loop. + Defaults to `OpenAIResponsesChatGenerator("gpt-5.4-mini")`. +- **summarizer_llm** (ChatGenerator | None) – LLM used inside the `read_url` tool to summarize a fetched page toward + the question. Defaults to `OpenAIResponsesChatGenerator("gpt-5.4-mini")`. +- **writer_llm** (ChatGenerator | None) – LLM that turns the brief plus collected notes into the final report. + Defaults to `OpenAIResponsesChatGenerator("gpt-5.4")`. +- **max_subtopics** (int) – Maximum number of sub-questions the orchestrator may delegate (breadth). +- **max_concurrent_researchers** (int) – Maximum number of sub-researchers that run at the same time. +- **max_orchestrator_steps** (int) – Maximum steps for the orchestrator's agent loop (reflect -> delegate rounds). +- **max_researcher_steps** (int) – Maximum steps for each sub-researcher's agent loop. +- **max_search_results** (int) – Number of results returned per `web_search` call. +- **max_content_length** (int) – Maximum raw page characters fed to the summarizer, before summarization. + +**Returns:** + +- Agent – The deep research `Agent`. Call it with the question as a user message, + `agent.run(messages=[ChatMessage.from_user(question)])`; it returns a dict whose main output is + `report` (the final markdown report, a `str`). The dict also carries the intermediate `brief` + (`str`) and `notes` (`list[str]`), plus the standard Agent outputs `messages`, `last_message`, + `step_count`, `token_usage` and `tool_call_counts`. diff --git a/docs-website/reference_versioned_docs/version-2.27/integrations-api/agent_pack.md b/docs-website/reference_versioned_docs/version-2.27/integrations-api/agent_pack.md new file mode 100644 index 0000000000..2921c4d640 --- /dev/null +++ b/docs-website/reference_versioned_docs/version-2.27/integrations-api/agent_pack.md @@ -0,0 +1,463 @@ +--- +title: "Agent Pack" +id: integrations-agent-pack +description: "Agent Pack integration for Haystack" +slug: "/integrations-agent-pack" +--- + + +## haystack_integrations.agent_pack.advanced_rag.agent + +### create_advanced_rag_agent + +```python +create_advanced_rag_agent( + *, + document_store: DocumentStore, + retriever: TextRetriever | Pipeline | None = None, + retrieval_pipeline_input_mapping: dict[str, list[str]] | None = None, + retrieval_pipeline_output_mapping: dict[str, str] | None = None, + llm: ChatGenerator | None = None, + backup_answer_llm: ChatGenerator | None = None, + system_prompt: str | None = None, + max_agent_steps: int = 20, + max_fetched_docs: int = 10, + extra_tools: ToolsType | None = None, + state_schema: dict[str, Any] | None = None, + hooks: dict[HookPoint, list[Hook]] | None = None, + raise_on_tool_invocation_failure: bool = False, + tool_concurrency_limit: int = 4 +) -> Agent +``` + +Create the advanced RAG agent. + +The agent answers questions from documents it retrieves out of the document store. Instead of guessing which +metadata fields exist, it can inspect the store (fields, values, ranges) and construct a Haystack filter to +narrow its retrieval when metadata helps — plain, unfiltered retrieval remains available when it doesn't. The +answer cites the retrieved documents. + +The required `retriever` becomes the `search_documents` tool; `document_store` additionally feeds the three +metadata inspection tools and must implement the metadata introspection methods (`get_metadata_fields_info`, +`get_metadata_field_unique_values`, `get_metadata_field_min_max`). + +**Parameters:** + +- **document_store** (DocumentStore) – The document store the metadata inspection tools and the `fetch_documents_by_filter` tool + run against. +- **retriever** (TextRetriever | Pipeline | None) – What retrieves for the `search_documents` tool (required). Either a standalone retriever + component following the `TextRetriever` protocol, i.e. its `run` method accepts `query` and `filters` + (e.g. `InMemoryBM25Retriever`, or an embedding retriever wrapped in `TextEmbeddingRetriever`), or a custom + retrieval `Pipeline` (e.g. embedder -> retriever, or hybrid retrieval) — a pipeline additionally requires + `retrieval_pipeline_input_mapping`. It should retrieve by relevance scoring (keyword or embedding-based) — + direct, unscored fetching is already covered by the built-in `fetch_documents_by_filter` tool. +- **retrieval_pipeline_input_mapping** (dict\[str, list\[str\]\] | None) – Required when `retriever` is a `Pipeline`: maps the tool inputs to + pipeline input sockets; must have exactly the keys "query" and "filters", + e.g. `{"query": ["embedder.text"], "filters": ["retriever.filters"]}`. +- **retrieval_pipeline_output_mapping** (dict\[str, str\] | None) – Optional when `retriever` is a `Pipeline`: maps pipeline output sockets + to tool outputs, e.g. `{"retriever.documents": "documents"}`. +- **llm** (ChatGenerator | None) – LLM that drives the agent loop. Defaults to `OpenAIResponsesChatGenerator("gpt-5.4")` with low + reasoning effort. +- **backup_answer_llm** (ChatGenerator | None) – LLM the built-in `BackupAnswerHook` uses to write a best-effort answer when the run + is cut off by `max_agent_steps`. Defaults to a separate `OpenAIResponsesChatGenerator("gpt-5.4")` with low + reasoning effort. +- **system_prompt** (str | None) – Overrides the pre-made system prompt. +- **max_agent_steps** (int) – Maximum steps for the agent loop. If the loop is cut off by this limit before writing an + answer, an `after_run` hook (`BackupAnswerHook`) makes one extra LLM call to produce a best-effort answer from + the evidence gathered so far, so `last_message` always carries a text answer. +- **max_fetched_docs** (int) – Maximum number of documents `fetch_documents_by_filter` shows per fetch. A filter fetch is + not bounded by a retriever's `top_k`, so this caps the tool result instead; the scored `search_documents` tool + is bounded by the `top_k` configured on your retrieval components. +- **extra_tools** (ToolsType | None) – Additional tools (or toolsets) for the agent, appended after the built-in document-store + toolset and the retrieval tool. +- **state_schema** (dict\[str, Any\] | None) – Additional entries merged into the agent's state schema. The built-in `documents` entry + (the accumulated retrieved documents) always takes precedence. +- **hooks** (dict\[HookPoint, list\[Hook\]\] | None) – Additional hooks per hook point, merged with the built-in hooks. For `after_run`, the built-in + backup-answer hook runs first, so custom hooks see the final answer. +- **raise_on_tool_invocation_failure** (bool) – If True, a failing tool call raises instead of being returned to the LLM + as an error message it can recover from (the default). +- **tool_concurrency_limit** (int) – Maximum number of tool calls executed in parallel within one agent step. + +**Returns:** + +- Agent – The advanced RAG `Agent`. Call it with the question as a user message, + `agent.run(messages=[ChatMessage.from_user(question)])`; the answer is in `last_message` (a `ChatMessage`) and + `documents` carries every document the agent retrieved during the run (deduplicated by id, in first-retrieved + order) — the answer cites them by the first 8 characters of their id, e.g. `[doc a1b2c3d4]`. The standard Agent + outputs `messages`, `step_count`, `token_usage` and `tool_call_counts` are also returned. + +## haystack_integrations.agent_pack.advanced_rag.hooks + +### BackupAnswerHook + +Produce a final answer when the agent run ends without one. Runs as an `after_run` hook. + +When the agent exhausts `max_agent_steps` mid-investigation, the run ends on a tool call or tool result instead of +an assistant text answer (and only `after_run` hooks run in this situation). This hook detects that case and makes +one LLM call over the conversation so far to produce a best-effort answer from the already-gathered evidence. + +#### __init__ + +```python +__init__(chat_generator: ChatGenerator) -> None +``` + +Create the hook. + +**Parameters:** + +- **chat_generator** (ChatGenerator) – LLM that writes the backup answer from the gathered evidence. + +#### warm_up + +```python +warm_up() -> None +``` + +Prepare the hook's generator for use; called from the Agent's `warm_up`. + +#### close + +```python +close() -> None +``` + +Release the hook's generator resources; called from the Agent's `close`. + +#### to_dict + +```python +to_dict() -> dict +``` + +Serialize the hook to a dictionary. + +**Returns:** + +- dict – Dictionary with serialized data. + +#### from_dict + +```python +from_dict(data: dict) -> BackupAnswerHook +``` + +Deserialize the hook from a dictionary. + +**Parameters:** + +- **data** (dict) – Dictionary to deserialize from. + +**Returns:** + +- BackupAnswerHook – Deserialized hook. + +#### run + +```python +run(state: State) -> None +``` + +Append a best-effort final answer when the run ended without one (e.g. step exhaustion). + +**Parameters:** + +- **state** (State) – The agent run's state. + +## haystack_integrations.agent_pack.advanced_rag.tools + +### ListMetadataFieldsTool + +Bases: Tool + +Tool that lists all metadata fields and their types from a document store. + +#### __init__ + +```python +__init__(document_store: DocumentStore) -> None +``` + +Create the tool. + +**Parameters:** + +- **document_store** (DocumentStore) – The document store to inspect. Must implement `get_metadata_fields_info`. + +**Raises:** + +- ValueError – If the store does not implement `get_metadata_fields_info`. + +#### to_dict + +```python +to_dict() -> dict[str, Any] +``` + +Serialize the tool to a dictionary. + +#### from_dict + +```python +from_dict(data: dict[str, Any]) -> ListMetadataFieldsTool +``` + +Deserialize the tool from a dictionary. + +**Parameters:** + +- **data** (dict\[str, Any\]) – The dictionary produced by `to_dict`. + +**Returns:** + +- ListMetadataFieldsTool – The deserialized tool. + +### GetMetadataFieldValuesTool + +Bases: Tool + +Tool that returns the distinct values of a metadata field from a document store. + +#### __init__ + +```python +__init__(document_store: DocumentStore) -> None +``` + +Create the tool. + +**Parameters:** + +- **document_store** (DocumentStore) – The document store to inspect. Must implement `get_metadata_field_unique_values`. + +**Raises:** + +- ValueError – If the store does not implement `get_metadata_field_unique_values`. + +#### to_dict + +```python +to_dict() -> dict[str, Any] +``` + +Serialize the tool to a dictionary. + +#### from_dict + +```python +from_dict(data: dict[str, Any]) -> GetMetadataFieldValuesTool +``` + +Deserialize the tool from a dictionary. + +**Parameters:** + +- **data** (dict\[str, Any\]) – The dictionary produced by `to_dict`. + +**Returns:** + +- GetMetadataFieldValuesTool – The deserialized tool. + +### GetMetadataFieldRangeTool + +Bases: Tool + +Tool that returns the minimum and maximum values of a metadata field from a document store. + +#### __init__ + +```python +__init__(document_store: DocumentStore) -> None +``` + +Create the tool. + +**Parameters:** + +- **document_store** (DocumentStore) – The document store to inspect. Must implement `get_metadata_field_min_max`. + +**Raises:** + +- ValueError – If the store does not implement `get_metadata_field_min_max`. + +#### to_dict + +```python +to_dict() -> dict[str, Any] +``` + +Serialize the tool to a dictionary. + +#### from_dict + +```python +from_dict(data: dict[str, Any]) -> GetMetadataFieldRangeTool +``` + +Deserialize the tool from a dictionary. + +**Parameters:** + +- **data** (dict\[str, Any\]) – The dictionary produced by `to_dict`. + +**Returns:** + +- GetMetadataFieldRangeTool – The deserialized tool. + +### FetchDocumentsByFilterTool + +Bases: Tool + +Tool that fetches documents directly from a document store by metadata filter. + +Unlike a scored retrieval tool, this fetches without any relevance ranking, so an agent can grab specific documents +(e.g. a known title or source file) without going through a relevance search. The fetched documents are put into +reading order first: grouped by their parent file (`file_name`/`file_path`/`source_id`) and sorted by their +position within it (`split_id`/`split_idx_start`/`page_number`), using whichever of those metadata fields the +documents carry. Match sets larger than `max_docs` are paged: each call returns one page plus the total match +count, and the tool's `offset` input continues where the previous page ended. + +#### __init__ + +```python +__init__( + document_store: DocumentStore, + max_docs: int = 10, + max_fetch_factor: int = 10, +) -> None +``` + +Create the tool. + +**Parameters:** + +- **document_store** (DocumentStore) – The document store to fetch documents from. +- **max_docs** (int) – Ceiling on the number of documents shown to the agent per fetch. Unlike scored retrieval, a + filter fetch is not bounded by a retriever's `top_k`, so this caps the tool result instead. The LLM can + request fewer via the tool's optional `max_docs` input, but never more. +- **max_fetch_factor** (int) – How many times the `max_docs` ceiling a filter may match before the fetch is + refused outright (when the store supports `count_documents_by_filter`) — the refusal is surfaced to the + LLM as an error it can recover from by narrowing the filter. + +#### to_dict + +```python +to_dict() -> dict[str, Any] +``` + +Serialize the tool to a dictionary. + +#### from_dict + +```python +from_dict(data: dict[str, Any]) -> FetchDocumentsByFilterTool +``` + +Deserialize the tool from a dictionary. + +**Parameters:** + +- **data** (dict\[str, Any\]) – The dictionary produced by `to_dict`. + +**Returns:** + +- FetchDocumentsByFilterTool – The deserialized tool. + +### DocumentStoreToolset + +Bases: Toolset + +All document-store-backed tools as one unit. + +Bundles the three metadata inspection tools (`ListMetadataFieldsTool`, `GetMetadataFieldValuesTool`, +`GetMetadataFieldRangeTool`) and the direct `FetchDocumentsByFilterTool`, so they can be handed to an `Agent` +(or combined with a retrieval tool) as a single object. + +#### __init__ + +```python +__init__(document_store: DocumentStore, max_fetched_docs: int = 10) -> None +``` + +Create the toolset. + +**Parameters:** + +- **document_store** (DocumentStore) – The document store all tools run against. Must implement the metadata introspection + methods (`get_metadata_fields_info`, `get_metadata_field_unique_values`, `get_metadata_field_min_max`). +- **max_fetched_docs** (int) – Maximum number of documents `fetch_documents_by_filter` shows per fetch (see + `FetchDocumentsByFilterTool.max_docs`). + +#### to_dict + +```python +to_dict() -> dict[str, Any] +``` + +Serialize the toolset to a dictionary. + +#### from_dict + +```python +from_dict(data: dict[str, Any]) -> DocumentStoreToolset +``` + +Deserialize the toolset from a dictionary. + +**Parameters:** + +- **data** (dict\[str, Any\]) – The dictionary produced by `to_dict`. + +**Returns:** + +- DocumentStoreToolset – The deserialized toolset. + +## haystack_integrations.agent_pack.deep_research.agent + +### create_deep_research_agent + +```python +create_deep_research_agent( + *, + scope_llm: ChatGenerator | None = None, + orchestrator_llm: ChatGenerator | None = None, + researcher_llm: ChatGenerator | None = None, + summarizer_llm: ChatGenerator | None = None, + writer_llm: ChatGenerator | None = None, + max_subtopics: int = 5, + max_concurrent_researchers: int = 5, + max_orchestrator_steps: int = 8, + max_researcher_steps: int = 20, + max_search_results: int = 10, + max_content_length: int = 50000 +) -> Agent +``` + +Create the deep research agent. + +**Parameters:** + +- **scope_llm** (ChatGenerator | None) – LLM that rewrites the user query into a focused research brief. + Defaults to `OpenAIResponsesChatGenerator("gpt-5.4")`. +- **orchestrator_llm** (ChatGenerator | None) – LLM that plans the investigation and delegates the sub-questions. + Defaults to `OpenAIResponsesChatGenerator("gpt-5.4")`. +- **researcher_llm** (ChatGenerator | None) – LLM that drives each sub-researcher's search/read/think loop. + Defaults to `OpenAIResponsesChatGenerator("gpt-5.4-mini")`. +- **summarizer_llm** (ChatGenerator | None) – LLM used inside the `read_url` tool to summarize a fetched page toward + the question. Defaults to `OpenAIResponsesChatGenerator("gpt-5.4-mini")`. +- **writer_llm** (ChatGenerator | None) – LLM that turns the brief plus collected notes into the final report. + Defaults to `OpenAIResponsesChatGenerator("gpt-5.4")`. +- **max_subtopics** (int) – Maximum number of sub-questions the orchestrator may delegate (breadth). +- **max_concurrent_researchers** (int) – Maximum number of sub-researchers that run at the same time. +- **max_orchestrator_steps** (int) – Maximum steps for the orchestrator's agent loop (reflect -> delegate rounds). +- **max_researcher_steps** (int) – Maximum steps for each sub-researcher's agent loop. +- **max_search_results** (int) – Number of results returned per `web_search` call. +- **max_content_length** (int) – Maximum raw page characters fed to the summarizer, before summarization. + +**Returns:** + +- Agent – The deep research `Agent`. Call it with the question as a user message, + `agent.run(messages=[ChatMessage.from_user(question)])`; it returns a dict whose main output is + `report` (the final markdown report, a `str`). The dict also carries the intermediate `brief` + (`str`) and `notes` (`list[str]`), plus the standard Agent outputs `messages`, `last_message`, + `step_count`, `token_usage` and `tool_call_counts`. diff --git a/docs-website/reference_versioned_docs/version-2.28/integrations-api/agent_pack.md b/docs-website/reference_versioned_docs/version-2.28/integrations-api/agent_pack.md new file mode 100644 index 0000000000..2921c4d640 --- /dev/null +++ b/docs-website/reference_versioned_docs/version-2.28/integrations-api/agent_pack.md @@ -0,0 +1,463 @@ +--- +title: "Agent Pack" +id: integrations-agent-pack +description: "Agent Pack integration for Haystack" +slug: "/integrations-agent-pack" +--- + + +## haystack_integrations.agent_pack.advanced_rag.agent + +### create_advanced_rag_agent + +```python +create_advanced_rag_agent( + *, + document_store: DocumentStore, + retriever: TextRetriever | Pipeline | None = None, + retrieval_pipeline_input_mapping: dict[str, list[str]] | None = None, + retrieval_pipeline_output_mapping: dict[str, str] | None = None, + llm: ChatGenerator | None = None, + backup_answer_llm: ChatGenerator | None = None, + system_prompt: str | None = None, + max_agent_steps: int = 20, + max_fetched_docs: int = 10, + extra_tools: ToolsType | None = None, + state_schema: dict[str, Any] | None = None, + hooks: dict[HookPoint, list[Hook]] | None = None, + raise_on_tool_invocation_failure: bool = False, + tool_concurrency_limit: int = 4 +) -> Agent +``` + +Create the advanced RAG agent. + +The agent answers questions from documents it retrieves out of the document store. Instead of guessing which +metadata fields exist, it can inspect the store (fields, values, ranges) and construct a Haystack filter to +narrow its retrieval when metadata helps — plain, unfiltered retrieval remains available when it doesn't. The +answer cites the retrieved documents. + +The required `retriever` becomes the `search_documents` tool; `document_store` additionally feeds the three +metadata inspection tools and must implement the metadata introspection methods (`get_metadata_fields_info`, +`get_metadata_field_unique_values`, `get_metadata_field_min_max`). + +**Parameters:** + +- **document_store** (DocumentStore) – The document store the metadata inspection tools and the `fetch_documents_by_filter` tool + run against. +- **retriever** (TextRetriever | Pipeline | None) – What retrieves for the `search_documents` tool (required). Either a standalone retriever + component following the `TextRetriever` protocol, i.e. its `run` method accepts `query` and `filters` + (e.g. `InMemoryBM25Retriever`, or an embedding retriever wrapped in `TextEmbeddingRetriever`), or a custom + retrieval `Pipeline` (e.g. embedder -> retriever, or hybrid retrieval) — a pipeline additionally requires + `retrieval_pipeline_input_mapping`. It should retrieve by relevance scoring (keyword or embedding-based) — + direct, unscored fetching is already covered by the built-in `fetch_documents_by_filter` tool. +- **retrieval_pipeline_input_mapping** (dict\[str, list\[str\]\] | None) – Required when `retriever` is a `Pipeline`: maps the tool inputs to + pipeline input sockets; must have exactly the keys "query" and "filters", + e.g. `{"query": ["embedder.text"], "filters": ["retriever.filters"]}`. +- **retrieval_pipeline_output_mapping** (dict\[str, str\] | None) – Optional when `retriever` is a `Pipeline`: maps pipeline output sockets + to tool outputs, e.g. `{"retriever.documents": "documents"}`. +- **llm** (ChatGenerator | None) – LLM that drives the agent loop. Defaults to `OpenAIResponsesChatGenerator("gpt-5.4")` with low + reasoning effort. +- **backup_answer_llm** (ChatGenerator | None) – LLM the built-in `BackupAnswerHook` uses to write a best-effort answer when the run + is cut off by `max_agent_steps`. Defaults to a separate `OpenAIResponsesChatGenerator("gpt-5.4")` with low + reasoning effort. +- **system_prompt** (str | None) – Overrides the pre-made system prompt. +- **max_agent_steps** (int) – Maximum steps for the agent loop. If the loop is cut off by this limit before writing an + answer, an `after_run` hook (`BackupAnswerHook`) makes one extra LLM call to produce a best-effort answer from + the evidence gathered so far, so `last_message` always carries a text answer. +- **max_fetched_docs** (int) – Maximum number of documents `fetch_documents_by_filter` shows per fetch. A filter fetch is + not bounded by a retriever's `top_k`, so this caps the tool result instead; the scored `search_documents` tool + is bounded by the `top_k` configured on your retrieval components. +- **extra_tools** (ToolsType | None) – Additional tools (or toolsets) for the agent, appended after the built-in document-store + toolset and the retrieval tool. +- **state_schema** (dict\[str, Any\] | None) – Additional entries merged into the agent's state schema. The built-in `documents` entry + (the accumulated retrieved documents) always takes precedence. +- **hooks** (dict\[HookPoint, list\[Hook\]\] | None) – Additional hooks per hook point, merged with the built-in hooks. For `after_run`, the built-in + backup-answer hook runs first, so custom hooks see the final answer. +- **raise_on_tool_invocation_failure** (bool) – If True, a failing tool call raises instead of being returned to the LLM + as an error message it can recover from (the default). +- **tool_concurrency_limit** (int) – Maximum number of tool calls executed in parallel within one agent step. + +**Returns:** + +- Agent – The advanced RAG `Agent`. Call it with the question as a user message, + `agent.run(messages=[ChatMessage.from_user(question)])`; the answer is in `last_message` (a `ChatMessage`) and + `documents` carries every document the agent retrieved during the run (deduplicated by id, in first-retrieved + order) — the answer cites them by the first 8 characters of their id, e.g. `[doc a1b2c3d4]`. The standard Agent + outputs `messages`, `step_count`, `token_usage` and `tool_call_counts` are also returned. + +## haystack_integrations.agent_pack.advanced_rag.hooks + +### BackupAnswerHook + +Produce a final answer when the agent run ends without one. Runs as an `after_run` hook. + +When the agent exhausts `max_agent_steps` mid-investigation, the run ends on a tool call or tool result instead of +an assistant text answer (and only `after_run` hooks run in this situation). This hook detects that case and makes +one LLM call over the conversation so far to produce a best-effort answer from the already-gathered evidence. + +#### __init__ + +```python +__init__(chat_generator: ChatGenerator) -> None +``` + +Create the hook. + +**Parameters:** + +- **chat_generator** (ChatGenerator) – LLM that writes the backup answer from the gathered evidence. + +#### warm_up + +```python +warm_up() -> None +``` + +Prepare the hook's generator for use; called from the Agent's `warm_up`. + +#### close + +```python +close() -> None +``` + +Release the hook's generator resources; called from the Agent's `close`. + +#### to_dict + +```python +to_dict() -> dict +``` + +Serialize the hook to a dictionary. + +**Returns:** + +- dict – Dictionary with serialized data. + +#### from_dict + +```python +from_dict(data: dict) -> BackupAnswerHook +``` + +Deserialize the hook from a dictionary. + +**Parameters:** + +- **data** (dict) – Dictionary to deserialize from. + +**Returns:** + +- BackupAnswerHook – Deserialized hook. + +#### run + +```python +run(state: State) -> None +``` + +Append a best-effort final answer when the run ended without one (e.g. step exhaustion). + +**Parameters:** + +- **state** (State) – The agent run's state. + +## haystack_integrations.agent_pack.advanced_rag.tools + +### ListMetadataFieldsTool + +Bases: Tool + +Tool that lists all metadata fields and their types from a document store. + +#### __init__ + +```python +__init__(document_store: DocumentStore) -> None +``` + +Create the tool. + +**Parameters:** + +- **document_store** (DocumentStore) – The document store to inspect. Must implement `get_metadata_fields_info`. + +**Raises:** + +- ValueError – If the store does not implement `get_metadata_fields_info`. + +#### to_dict + +```python +to_dict() -> dict[str, Any] +``` + +Serialize the tool to a dictionary. + +#### from_dict + +```python +from_dict(data: dict[str, Any]) -> ListMetadataFieldsTool +``` + +Deserialize the tool from a dictionary. + +**Parameters:** + +- **data** (dict\[str, Any\]) – The dictionary produced by `to_dict`. + +**Returns:** + +- ListMetadataFieldsTool – The deserialized tool. + +### GetMetadataFieldValuesTool + +Bases: Tool + +Tool that returns the distinct values of a metadata field from a document store. + +#### __init__ + +```python +__init__(document_store: DocumentStore) -> None +``` + +Create the tool. + +**Parameters:** + +- **document_store** (DocumentStore) – The document store to inspect. Must implement `get_metadata_field_unique_values`. + +**Raises:** + +- ValueError – If the store does not implement `get_metadata_field_unique_values`. + +#### to_dict + +```python +to_dict() -> dict[str, Any] +``` + +Serialize the tool to a dictionary. + +#### from_dict + +```python +from_dict(data: dict[str, Any]) -> GetMetadataFieldValuesTool +``` + +Deserialize the tool from a dictionary. + +**Parameters:** + +- **data** (dict\[str, Any\]) – The dictionary produced by `to_dict`. + +**Returns:** + +- GetMetadataFieldValuesTool – The deserialized tool. + +### GetMetadataFieldRangeTool + +Bases: Tool + +Tool that returns the minimum and maximum values of a metadata field from a document store. + +#### __init__ + +```python +__init__(document_store: DocumentStore) -> None +``` + +Create the tool. + +**Parameters:** + +- **document_store** (DocumentStore) – The document store to inspect. Must implement `get_metadata_field_min_max`. + +**Raises:** + +- ValueError – If the store does not implement `get_metadata_field_min_max`. + +#### to_dict + +```python +to_dict() -> dict[str, Any] +``` + +Serialize the tool to a dictionary. + +#### from_dict + +```python +from_dict(data: dict[str, Any]) -> GetMetadataFieldRangeTool +``` + +Deserialize the tool from a dictionary. + +**Parameters:** + +- **data** (dict\[str, Any\]) – The dictionary produced by `to_dict`. + +**Returns:** + +- GetMetadataFieldRangeTool – The deserialized tool. + +### FetchDocumentsByFilterTool + +Bases: Tool + +Tool that fetches documents directly from a document store by metadata filter. + +Unlike a scored retrieval tool, this fetches without any relevance ranking, so an agent can grab specific documents +(e.g. a known title or source file) without going through a relevance search. The fetched documents are put into +reading order first: grouped by their parent file (`file_name`/`file_path`/`source_id`) and sorted by their +position within it (`split_id`/`split_idx_start`/`page_number`), using whichever of those metadata fields the +documents carry. Match sets larger than `max_docs` are paged: each call returns one page plus the total match +count, and the tool's `offset` input continues where the previous page ended. + +#### __init__ + +```python +__init__( + document_store: DocumentStore, + max_docs: int = 10, + max_fetch_factor: int = 10, +) -> None +``` + +Create the tool. + +**Parameters:** + +- **document_store** (DocumentStore) – The document store to fetch documents from. +- **max_docs** (int) – Ceiling on the number of documents shown to the agent per fetch. Unlike scored retrieval, a + filter fetch is not bounded by a retriever's `top_k`, so this caps the tool result instead. The LLM can + request fewer via the tool's optional `max_docs` input, but never more. +- **max_fetch_factor** (int) – How many times the `max_docs` ceiling a filter may match before the fetch is + refused outright (when the store supports `count_documents_by_filter`) — the refusal is surfaced to the + LLM as an error it can recover from by narrowing the filter. + +#### to_dict + +```python +to_dict() -> dict[str, Any] +``` + +Serialize the tool to a dictionary. + +#### from_dict + +```python +from_dict(data: dict[str, Any]) -> FetchDocumentsByFilterTool +``` + +Deserialize the tool from a dictionary. + +**Parameters:** + +- **data** (dict\[str, Any\]) – The dictionary produced by `to_dict`. + +**Returns:** + +- FetchDocumentsByFilterTool – The deserialized tool. + +### DocumentStoreToolset + +Bases: Toolset + +All document-store-backed tools as one unit. + +Bundles the three metadata inspection tools (`ListMetadataFieldsTool`, `GetMetadataFieldValuesTool`, +`GetMetadataFieldRangeTool`) and the direct `FetchDocumentsByFilterTool`, so they can be handed to an `Agent` +(or combined with a retrieval tool) as a single object. + +#### __init__ + +```python +__init__(document_store: DocumentStore, max_fetched_docs: int = 10) -> None +``` + +Create the toolset. + +**Parameters:** + +- **document_store** (DocumentStore) – The document store all tools run against. Must implement the metadata introspection + methods (`get_metadata_fields_info`, `get_metadata_field_unique_values`, `get_metadata_field_min_max`). +- **max_fetched_docs** (int) – Maximum number of documents `fetch_documents_by_filter` shows per fetch (see + `FetchDocumentsByFilterTool.max_docs`). + +#### to_dict + +```python +to_dict() -> dict[str, Any] +``` + +Serialize the toolset to a dictionary. + +#### from_dict + +```python +from_dict(data: dict[str, Any]) -> DocumentStoreToolset +``` + +Deserialize the toolset from a dictionary. + +**Parameters:** + +- **data** (dict\[str, Any\]) – The dictionary produced by `to_dict`. + +**Returns:** + +- DocumentStoreToolset – The deserialized toolset. + +## haystack_integrations.agent_pack.deep_research.agent + +### create_deep_research_agent + +```python +create_deep_research_agent( + *, + scope_llm: ChatGenerator | None = None, + orchestrator_llm: ChatGenerator | None = None, + researcher_llm: ChatGenerator | None = None, + summarizer_llm: ChatGenerator | None = None, + writer_llm: ChatGenerator | None = None, + max_subtopics: int = 5, + max_concurrent_researchers: int = 5, + max_orchestrator_steps: int = 8, + max_researcher_steps: int = 20, + max_search_results: int = 10, + max_content_length: int = 50000 +) -> Agent +``` + +Create the deep research agent. + +**Parameters:** + +- **scope_llm** (ChatGenerator | None) – LLM that rewrites the user query into a focused research brief. + Defaults to `OpenAIResponsesChatGenerator("gpt-5.4")`. +- **orchestrator_llm** (ChatGenerator | None) – LLM that plans the investigation and delegates the sub-questions. + Defaults to `OpenAIResponsesChatGenerator("gpt-5.4")`. +- **researcher_llm** (ChatGenerator | None) – LLM that drives each sub-researcher's search/read/think loop. + Defaults to `OpenAIResponsesChatGenerator("gpt-5.4-mini")`. +- **summarizer_llm** (ChatGenerator | None) – LLM used inside the `read_url` tool to summarize a fetched page toward + the question. Defaults to `OpenAIResponsesChatGenerator("gpt-5.4-mini")`. +- **writer_llm** (ChatGenerator | None) – LLM that turns the brief plus collected notes into the final report. + Defaults to `OpenAIResponsesChatGenerator("gpt-5.4")`. +- **max_subtopics** (int) – Maximum number of sub-questions the orchestrator may delegate (breadth). +- **max_concurrent_researchers** (int) – Maximum number of sub-researchers that run at the same time. +- **max_orchestrator_steps** (int) – Maximum steps for the orchestrator's agent loop (reflect -> delegate rounds). +- **max_researcher_steps** (int) – Maximum steps for each sub-researcher's agent loop. +- **max_search_results** (int) – Number of results returned per `web_search` call. +- **max_content_length** (int) – Maximum raw page characters fed to the summarizer, before summarization. + +**Returns:** + +- Agent – The deep research `Agent`. Call it with the question as a user message, + `agent.run(messages=[ChatMessage.from_user(question)])`; it returns a dict whose main output is + `report` (the final markdown report, a `str`). The dict also carries the intermediate `brief` + (`str`) and `notes` (`list[str]`), plus the standard Agent outputs `messages`, `last_message`, + `step_count`, `token_usage` and `tool_call_counts`. diff --git a/docs-website/reference_versioned_docs/version-2.29/integrations-api/agent_pack.md b/docs-website/reference_versioned_docs/version-2.29/integrations-api/agent_pack.md new file mode 100644 index 0000000000..2921c4d640 --- /dev/null +++ b/docs-website/reference_versioned_docs/version-2.29/integrations-api/agent_pack.md @@ -0,0 +1,463 @@ +--- +title: "Agent Pack" +id: integrations-agent-pack +description: "Agent Pack integration for Haystack" +slug: "/integrations-agent-pack" +--- + + +## haystack_integrations.agent_pack.advanced_rag.agent + +### create_advanced_rag_agent + +```python +create_advanced_rag_agent( + *, + document_store: DocumentStore, + retriever: TextRetriever | Pipeline | None = None, + retrieval_pipeline_input_mapping: dict[str, list[str]] | None = None, + retrieval_pipeline_output_mapping: dict[str, str] | None = None, + llm: ChatGenerator | None = None, + backup_answer_llm: ChatGenerator | None = None, + system_prompt: str | None = None, + max_agent_steps: int = 20, + max_fetched_docs: int = 10, + extra_tools: ToolsType | None = None, + state_schema: dict[str, Any] | None = None, + hooks: dict[HookPoint, list[Hook]] | None = None, + raise_on_tool_invocation_failure: bool = False, + tool_concurrency_limit: int = 4 +) -> Agent +``` + +Create the advanced RAG agent. + +The agent answers questions from documents it retrieves out of the document store. Instead of guessing which +metadata fields exist, it can inspect the store (fields, values, ranges) and construct a Haystack filter to +narrow its retrieval when metadata helps — plain, unfiltered retrieval remains available when it doesn't. The +answer cites the retrieved documents. + +The required `retriever` becomes the `search_documents` tool; `document_store` additionally feeds the three +metadata inspection tools and must implement the metadata introspection methods (`get_metadata_fields_info`, +`get_metadata_field_unique_values`, `get_metadata_field_min_max`). + +**Parameters:** + +- **document_store** (DocumentStore) – The document store the metadata inspection tools and the `fetch_documents_by_filter` tool + run against. +- **retriever** (TextRetriever | Pipeline | None) – What retrieves for the `search_documents` tool (required). Either a standalone retriever + component following the `TextRetriever` protocol, i.e. its `run` method accepts `query` and `filters` + (e.g. `InMemoryBM25Retriever`, or an embedding retriever wrapped in `TextEmbeddingRetriever`), or a custom + retrieval `Pipeline` (e.g. embedder -> retriever, or hybrid retrieval) — a pipeline additionally requires + `retrieval_pipeline_input_mapping`. It should retrieve by relevance scoring (keyword or embedding-based) — + direct, unscored fetching is already covered by the built-in `fetch_documents_by_filter` tool. +- **retrieval_pipeline_input_mapping** (dict\[str, list\[str\]\] | None) – Required when `retriever` is a `Pipeline`: maps the tool inputs to + pipeline input sockets; must have exactly the keys "query" and "filters", + e.g. `{"query": ["embedder.text"], "filters": ["retriever.filters"]}`. +- **retrieval_pipeline_output_mapping** (dict\[str, str\] | None) – Optional when `retriever` is a `Pipeline`: maps pipeline output sockets + to tool outputs, e.g. `{"retriever.documents": "documents"}`. +- **llm** (ChatGenerator | None) – LLM that drives the agent loop. Defaults to `OpenAIResponsesChatGenerator("gpt-5.4")` with low + reasoning effort. +- **backup_answer_llm** (ChatGenerator | None) – LLM the built-in `BackupAnswerHook` uses to write a best-effort answer when the run + is cut off by `max_agent_steps`. Defaults to a separate `OpenAIResponsesChatGenerator("gpt-5.4")` with low + reasoning effort. +- **system_prompt** (str | None) – Overrides the pre-made system prompt. +- **max_agent_steps** (int) – Maximum steps for the agent loop. If the loop is cut off by this limit before writing an + answer, an `after_run` hook (`BackupAnswerHook`) makes one extra LLM call to produce a best-effort answer from + the evidence gathered so far, so `last_message` always carries a text answer. +- **max_fetched_docs** (int) – Maximum number of documents `fetch_documents_by_filter` shows per fetch. A filter fetch is + not bounded by a retriever's `top_k`, so this caps the tool result instead; the scored `search_documents` tool + is bounded by the `top_k` configured on your retrieval components. +- **extra_tools** (ToolsType | None) – Additional tools (or toolsets) for the agent, appended after the built-in document-store + toolset and the retrieval tool. +- **state_schema** (dict\[str, Any\] | None) – Additional entries merged into the agent's state schema. The built-in `documents` entry + (the accumulated retrieved documents) always takes precedence. +- **hooks** (dict\[HookPoint, list\[Hook\]\] | None) – Additional hooks per hook point, merged with the built-in hooks. For `after_run`, the built-in + backup-answer hook runs first, so custom hooks see the final answer. +- **raise_on_tool_invocation_failure** (bool) – If True, a failing tool call raises instead of being returned to the LLM + as an error message it can recover from (the default). +- **tool_concurrency_limit** (int) – Maximum number of tool calls executed in parallel within one agent step. + +**Returns:** + +- Agent – The advanced RAG `Agent`. Call it with the question as a user message, + `agent.run(messages=[ChatMessage.from_user(question)])`; the answer is in `last_message` (a `ChatMessage`) and + `documents` carries every document the agent retrieved during the run (deduplicated by id, in first-retrieved + order) — the answer cites them by the first 8 characters of their id, e.g. `[doc a1b2c3d4]`. The standard Agent + outputs `messages`, `step_count`, `token_usage` and `tool_call_counts` are also returned. + +## haystack_integrations.agent_pack.advanced_rag.hooks + +### BackupAnswerHook + +Produce a final answer when the agent run ends without one. Runs as an `after_run` hook. + +When the agent exhausts `max_agent_steps` mid-investigation, the run ends on a tool call or tool result instead of +an assistant text answer (and only `after_run` hooks run in this situation). This hook detects that case and makes +one LLM call over the conversation so far to produce a best-effort answer from the already-gathered evidence. + +#### __init__ + +```python +__init__(chat_generator: ChatGenerator) -> None +``` + +Create the hook. + +**Parameters:** + +- **chat_generator** (ChatGenerator) – LLM that writes the backup answer from the gathered evidence. + +#### warm_up + +```python +warm_up() -> None +``` + +Prepare the hook's generator for use; called from the Agent's `warm_up`. + +#### close + +```python +close() -> None +``` + +Release the hook's generator resources; called from the Agent's `close`. + +#### to_dict + +```python +to_dict() -> dict +``` + +Serialize the hook to a dictionary. + +**Returns:** + +- dict – Dictionary with serialized data. + +#### from_dict + +```python +from_dict(data: dict) -> BackupAnswerHook +``` + +Deserialize the hook from a dictionary. + +**Parameters:** + +- **data** (dict) – Dictionary to deserialize from. + +**Returns:** + +- BackupAnswerHook – Deserialized hook. + +#### run + +```python +run(state: State) -> None +``` + +Append a best-effort final answer when the run ended without one (e.g. step exhaustion). + +**Parameters:** + +- **state** (State) – The agent run's state. + +## haystack_integrations.agent_pack.advanced_rag.tools + +### ListMetadataFieldsTool + +Bases: Tool + +Tool that lists all metadata fields and their types from a document store. + +#### __init__ + +```python +__init__(document_store: DocumentStore) -> None +``` + +Create the tool. + +**Parameters:** + +- **document_store** (DocumentStore) – The document store to inspect. Must implement `get_metadata_fields_info`. + +**Raises:** + +- ValueError – If the store does not implement `get_metadata_fields_info`. + +#### to_dict + +```python +to_dict() -> dict[str, Any] +``` + +Serialize the tool to a dictionary. + +#### from_dict + +```python +from_dict(data: dict[str, Any]) -> ListMetadataFieldsTool +``` + +Deserialize the tool from a dictionary. + +**Parameters:** + +- **data** (dict\[str, Any\]) – The dictionary produced by `to_dict`. + +**Returns:** + +- ListMetadataFieldsTool – The deserialized tool. + +### GetMetadataFieldValuesTool + +Bases: Tool + +Tool that returns the distinct values of a metadata field from a document store. + +#### __init__ + +```python +__init__(document_store: DocumentStore) -> None +``` + +Create the tool. + +**Parameters:** + +- **document_store** (DocumentStore) – The document store to inspect. Must implement `get_metadata_field_unique_values`. + +**Raises:** + +- ValueError – If the store does not implement `get_metadata_field_unique_values`. + +#### to_dict + +```python +to_dict() -> dict[str, Any] +``` + +Serialize the tool to a dictionary. + +#### from_dict + +```python +from_dict(data: dict[str, Any]) -> GetMetadataFieldValuesTool +``` + +Deserialize the tool from a dictionary. + +**Parameters:** + +- **data** (dict\[str, Any\]) – The dictionary produced by `to_dict`. + +**Returns:** + +- GetMetadataFieldValuesTool – The deserialized tool. + +### GetMetadataFieldRangeTool + +Bases: Tool + +Tool that returns the minimum and maximum values of a metadata field from a document store. + +#### __init__ + +```python +__init__(document_store: DocumentStore) -> None +``` + +Create the tool. + +**Parameters:** + +- **document_store** (DocumentStore) – The document store to inspect. Must implement `get_metadata_field_min_max`. + +**Raises:** + +- ValueError – If the store does not implement `get_metadata_field_min_max`. + +#### to_dict + +```python +to_dict() -> dict[str, Any] +``` + +Serialize the tool to a dictionary. + +#### from_dict + +```python +from_dict(data: dict[str, Any]) -> GetMetadataFieldRangeTool +``` + +Deserialize the tool from a dictionary. + +**Parameters:** + +- **data** (dict\[str, Any\]) – The dictionary produced by `to_dict`. + +**Returns:** + +- GetMetadataFieldRangeTool – The deserialized tool. + +### FetchDocumentsByFilterTool + +Bases: Tool + +Tool that fetches documents directly from a document store by metadata filter. + +Unlike a scored retrieval tool, this fetches without any relevance ranking, so an agent can grab specific documents +(e.g. a known title or source file) without going through a relevance search. The fetched documents are put into +reading order first: grouped by their parent file (`file_name`/`file_path`/`source_id`) and sorted by their +position within it (`split_id`/`split_idx_start`/`page_number`), using whichever of those metadata fields the +documents carry. Match sets larger than `max_docs` are paged: each call returns one page plus the total match +count, and the tool's `offset` input continues where the previous page ended. + +#### __init__ + +```python +__init__( + document_store: DocumentStore, + max_docs: int = 10, + max_fetch_factor: int = 10, +) -> None +``` + +Create the tool. + +**Parameters:** + +- **document_store** (DocumentStore) – The document store to fetch documents from. +- **max_docs** (int) – Ceiling on the number of documents shown to the agent per fetch. Unlike scored retrieval, a + filter fetch is not bounded by a retriever's `top_k`, so this caps the tool result instead. The LLM can + request fewer via the tool's optional `max_docs` input, but never more. +- **max_fetch_factor** (int) – How many times the `max_docs` ceiling a filter may match before the fetch is + refused outright (when the store supports `count_documents_by_filter`) — the refusal is surfaced to the + LLM as an error it can recover from by narrowing the filter. + +#### to_dict + +```python +to_dict() -> dict[str, Any] +``` + +Serialize the tool to a dictionary. + +#### from_dict + +```python +from_dict(data: dict[str, Any]) -> FetchDocumentsByFilterTool +``` + +Deserialize the tool from a dictionary. + +**Parameters:** + +- **data** (dict\[str, Any\]) – The dictionary produced by `to_dict`. + +**Returns:** + +- FetchDocumentsByFilterTool – The deserialized tool. + +### DocumentStoreToolset + +Bases: Toolset + +All document-store-backed tools as one unit. + +Bundles the three metadata inspection tools (`ListMetadataFieldsTool`, `GetMetadataFieldValuesTool`, +`GetMetadataFieldRangeTool`) and the direct `FetchDocumentsByFilterTool`, so they can be handed to an `Agent` +(or combined with a retrieval tool) as a single object. + +#### __init__ + +```python +__init__(document_store: DocumentStore, max_fetched_docs: int = 10) -> None +``` + +Create the toolset. + +**Parameters:** + +- **document_store** (DocumentStore) – The document store all tools run against. Must implement the metadata introspection + methods (`get_metadata_fields_info`, `get_metadata_field_unique_values`, `get_metadata_field_min_max`). +- **max_fetched_docs** (int) – Maximum number of documents `fetch_documents_by_filter` shows per fetch (see + `FetchDocumentsByFilterTool.max_docs`). + +#### to_dict + +```python +to_dict() -> dict[str, Any] +``` + +Serialize the toolset to a dictionary. + +#### from_dict + +```python +from_dict(data: dict[str, Any]) -> DocumentStoreToolset +``` + +Deserialize the toolset from a dictionary. + +**Parameters:** + +- **data** (dict\[str, Any\]) – The dictionary produced by `to_dict`. + +**Returns:** + +- DocumentStoreToolset – The deserialized toolset. + +## haystack_integrations.agent_pack.deep_research.agent + +### create_deep_research_agent + +```python +create_deep_research_agent( + *, + scope_llm: ChatGenerator | None = None, + orchestrator_llm: ChatGenerator | None = None, + researcher_llm: ChatGenerator | None = None, + summarizer_llm: ChatGenerator | None = None, + writer_llm: ChatGenerator | None = None, + max_subtopics: int = 5, + max_concurrent_researchers: int = 5, + max_orchestrator_steps: int = 8, + max_researcher_steps: int = 20, + max_search_results: int = 10, + max_content_length: int = 50000 +) -> Agent +``` + +Create the deep research agent. + +**Parameters:** + +- **scope_llm** (ChatGenerator | None) – LLM that rewrites the user query into a focused research brief. + Defaults to `OpenAIResponsesChatGenerator("gpt-5.4")`. +- **orchestrator_llm** (ChatGenerator | None) – LLM that plans the investigation and delegates the sub-questions. + Defaults to `OpenAIResponsesChatGenerator("gpt-5.4")`. +- **researcher_llm** (ChatGenerator | None) – LLM that drives each sub-researcher's search/read/think loop. + Defaults to `OpenAIResponsesChatGenerator("gpt-5.4-mini")`. +- **summarizer_llm** (ChatGenerator | None) – LLM used inside the `read_url` tool to summarize a fetched page toward + the question. Defaults to `OpenAIResponsesChatGenerator("gpt-5.4-mini")`. +- **writer_llm** (ChatGenerator | None) – LLM that turns the brief plus collected notes into the final report. + Defaults to `OpenAIResponsesChatGenerator("gpt-5.4")`. +- **max_subtopics** (int) – Maximum number of sub-questions the orchestrator may delegate (breadth). +- **max_concurrent_researchers** (int) – Maximum number of sub-researchers that run at the same time. +- **max_orchestrator_steps** (int) – Maximum steps for the orchestrator's agent loop (reflect -> delegate rounds). +- **max_researcher_steps** (int) – Maximum steps for each sub-researcher's agent loop. +- **max_search_results** (int) – Number of results returned per `web_search` call. +- **max_content_length** (int) – Maximum raw page characters fed to the summarizer, before summarization. + +**Returns:** + +- Agent – The deep research `Agent`. Call it with the question as a user message, + `agent.run(messages=[ChatMessage.from_user(question)])`; it returns a dict whose main output is + `report` (the final markdown report, a `str`). The dict also carries the intermediate `brief` + (`str`) and `notes` (`list[str]`), plus the standard Agent outputs `messages`, `last_message`, + `step_count`, `token_usage` and `tool_call_counts`. diff --git a/docs-website/reference_versioned_docs/version-2.30/integrations-api/agent_pack.md b/docs-website/reference_versioned_docs/version-2.30/integrations-api/agent_pack.md new file mode 100644 index 0000000000..2921c4d640 --- /dev/null +++ b/docs-website/reference_versioned_docs/version-2.30/integrations-api/agent_pack.md @@ -0,0 +1,463 @@ +--- +title: "Agent Pack" +id: integrations-agent-pack +description: "Agent Pack integration for Haystack" +slug: "/integrations-agent-pack" +--- + + +## haystack_integrations.agent_pack.advanced_rag.agent + +### create_advanced_rag_agent + +```python +create_advanced_rag_agent( + *, + document_store: DocumentStore, + retriever: TextRetriever | Pipeline | None = None, + retrieval_pipeline_input_mapping: dict[str, list[str]] | None = None, + retrieval_pipeline_output_mapping: dict[str, str] | None = None, + llm: ChatGenerator | None = None, + backup_answer_llm: ChatGenerator | None = None, + system_prompt: str | None = None, + max_agent_steps: int = 20, + max_fetched_docs: int = 10, + extra_tools: ToolsType | None = None, + state_schema: dict[str, Any] | None = None, + hooks: dict[HookPoint, list[Hook]] | None = None, + raise_on_tool_invocation_failure: bool = False, + tool_concurrency_limit: int = 4 +) -> Agent +``` + +Create the advanced RAG agent. + +The agent answers questions from documents it retrieves out of the document store. Instead of guessing which +metadata fields exist, it can inspect the store (fields, values, ranges) and construct a Haystack filter to +narrow its retrieval when metadata helps — plain, unfiltered retrieval remains available when it doesn't. The +answer cites the retrieved documents. + +The required `retriever` becomes the `search_documents` tool; `document_store` additionally feeds the three +metadata inspection tools and must implement the metadata introspection methods (`get_metadata_fields_info`, +`get_metadata_field_unique_values`, `get_metadata_field_min_max`). + +**Parameters:** + +- **document_store** (DocumentStore) – The document store the metadata inspection tools and the `fetch_documents_by_filter` tool + run against. +- **retriever** (TextRetriever | Pipeline | None) – What retrieves for the `search_documents` tool (required). Either a standalone retriever + component following the `TextRetriever` protocol, i.e. its `run` method accepts `query` and `filters` + (e.g. `InMemoryBM25Retriever`, or an embedding retriever wrapped in `TextEmbeddingRetriever`), or a custom + retrieval `Pipeline` (e.g. embedder -> retriever, or hybrid retrieval) — a pipeline additionally requires + `retrieval_pipeline_input_mapping`. It should retrieve by relevance scoring (keyword or embedding-based) — + direct, unscored fetching is already covered by the built-in `fetch_documents_by_filter` tool. +- **retrieval_pipeline_input_mapping** (dict\[str, list\[str\]\] | None) – Required when `retriever` is a `Pipeline`: maps the tool inputs to + pipeline input sockets; must have exactly the keys "query" and "filters", + e.g. `{"query": ["embedder.text"], "filters": ["retriever.filters"]}`. +- **retrieval_pipeline_output_mapping** (dict\[str, str\] | None) – Optional when `retriever` is a `Pipeline`: maps pipeline output sockets + to tool outputs, e.g. `{"retriever.documents": "documents"}`. +- **llm** (ChatGenerator | None) – LLM that drives the agent loop. Defaults to `OpenAIResponsesChatGenerator("gpt-5.4")` with low + reasoning effort. +- **backup_answer_llm** (ChatGenerator | None) – LLM the built-in `BackupAnswerHook` uses to write a best-effort answer when the run + is cut off by `max_agent_steps`. Defaults to a separate `OpenAIResponsesChatGenerator("gpt-5.4")` with low + reasoning effort. +- **system_prompt** (str | None) – Overrides the pre-made system prompt. +- **max_agent_steps** (int) – Maximum steps for the agent loop. If the loop is cut off by this limit before writing an + answer, an `after_run` hook (`BackupAnswerHook`) makes one extra LLM call to produce a best-effort answer from + the evidence gathered so far, so `last_message` always carries a text answer. +- **max_fetched_docs** (int) – Maximum number of documents `fetch_documents_by_filter` shows per fetch. A filter fetch is + not bounded by a retriever's `top_k`, so this caps the tool result instead; the scored `search_documents` tool + is bounded by the `top_k` configured on your retrieval components. +- **extra_tools** (ToolsType | None) – Additional tools (or toolsets) for the agent, appended after the built-in document-store + toolset and the retrieval tool. +- **state_schema** (dict\[str, Any\] | None) – Additional entries merged into the agent's state schema. The built-in `documents` entry + (the accumulated retrieved documents) always takes precedence. +- **hooks** (dict\[HookPoint, list\[Hook\]\] | None) – Additional hooks per hook point, merged with the built-in hooks. For `after_run`, the built-in + backup-answer hook runs first, so custom hooks see the final answer. +- **raise_on_tool_invocation_failure** (bool) – If True, a failing tool call raises instead of being returned to the LLM + as an error message it can recover from (the default). +- **tool_concurrency_limit** (int) – Maximum number of tool calls executed in parallel within one agent step. + +**Returns:** + +- Agent – The advanced RAG `Agent`. Call it with the question as a user message, + `agent.run(messages=[ChatMessage.from_user(question)])`; the answer is in `last_message` (a `ChatMessage`) and + `documents` carries every document the agent retrieved during the run (deduplicated by id, in first-retrieved + order) — the answer cites them by the first 8 characters of their id, e.g. `[doc a1b2c3d4]`. The standard Agent + outputs `messages`, `step_count`, `token_usage` and `tool_call_counts` are also returned. + +## haystack_integrations.agent_pack.advanced_rag.hooks + +### BackupAnswerHook + +Produce a final answer when the agent run ends without one. Runs as an `after_run` hook. + +When the agent exhausts `max_agent_steps` mid-investigation, the run ends on a tool call or tool result instead of +an assistant text answer (and only `after_run` hooks run in this situation). This hook detects that case and makes +one LLM call over the conversation so far to produce a best-effort answer from the already-gathered evidence. + +#### __init__ + +```python +__init__(chat_generator: ChatGenerator) -> None +``` + +Create the hook. + +**Parameters:** + +- **chat_generator** (ChatGenerator) – LLM that writes the backup answer from the gathered evidence. + +#### warm_up + +```python +warm_up() -> None +``` + +Prepare the hook's generator for use; called from the Agent's `warm_up`. + +#### close + +```python +close() -> None +``` + +Release the hook's generator resources; called from the Agent's `close`. + +#### to_dict + +```python +to_dict() -> dict +``` + +Serialize the hook to a dictionary. + +**Returns:** + +- dict – Dictionary with serialized data. + +#### from_dict + +```python +from_dict(data: dict) -> BackupAnswerHook +``` + +Deserialize the hook from a dictionary. + +**Parameters:** + +- **data** (dict) – Dictionary to deserialize from. + +**Returns:** + +- BackupAnswerHook – Deserialized hook. + +#### run + +```python +run(state: State) -> None +``` + +Append a best-effort final answer when the run ended without one (e.g. step exhaustion). + +**Parameters:** + +- **state** (State) – The agent run's state. + +## haystack_integrations.agent_pack.advanced_rag.tools + +### ListMetadataFieldsTool + +Bases: Tool + +Tool that lists all metadata fields and their types from a document store. + +#### __init__ + +```python +__init__(document_store: DocumentStore) -> None +``` + +Create the tool. + +**Parameters:** + +- **document_store** (DocumentStore) – The document store to inspect. Must implement `get_metadata_fields_info`. + +**Raises:** + +- ValueError – If the store does not implement `get_metadata_fields_info`. + +#### to_dict + +```python +to_dict() -> dict[str, Any] +``` + +Serialize the tool to a dictionary. + +#### from_dict + +```python +from_dict(data: dict[str, Any]) -> ListMetadataFieldsTool +``` + +Deserialize the tool from a dictionary. + +**Parameters:** + +- **data** (dict\[str, Any\]) – The dictionary produced by `to_dict`. + +**Returns:** + +- ListMetadataFieldsTool – The deserialized tool. + +### GetMetadataFieldValuesTool + +Bases: Tool + +Tool that returns the distinct values of a metadata field from a document store. + +#### __init__ + +```python +__init__(document_store: DocumentStore) -> None +``` + +Create the tool. + +**Parameters:** + +- **document_store** (DocumentStore) – The document store to inspect. Must implement `get_metadata_field_unique_values`. + +**Raises:** + +- ValueError – If the store does not implement `get_metadata_field_unique_values`. + +#### to_dict + +```python +to_dict() -> dict[str, Any] +``` + +Serialize the tool to a dictionary. + +#### from_dict + +```python +from_dict(data: dict[str, Any]) -> GetMetadataFieldValuesTool +``` + +Deserialize the tool from a dictionary. + +**Parameters:** + +- **data** (dict\[str, Any\]) – The dictionary produced by `to_dict`. + +**Returns:** + +- GetMetadataFieldValuesTool – The deserialized tool. + +### GetMetadataFieldRangeTool + +Bases: Tool + +Tool that returns the minimum and maximum values of a metadata field from a document store. + +#### __init__ + +```python +__init__(document_store: DocumentStore) -> None +``` + +Create the tool. + +**Parameters:** + +- **document_store** (DocumentStore) – The document store to inspect. Must implement `get_metadata_field_min_max`. + +**Raises:** + +- ValueError – If the store does not implement `get_metadata_field_min_max`. + +#### to_dict + +```python +to_dict() -> dict[str, Any] +``` + +Serialize the tool to a dictionary. + +#### from_dict + +```python +from_dict(data: dict[str, Any]) -> GetMetadataFieldRangeTool +``` + +Deserialize the tool from a dictionary. + +**Parameters:** + +- **data** (dict\[str, Any\]) – The dictionary produced by `to_dict`. + +**Returns:** + +- GetMetadataFieldRangeTool – The deserialized tool. + +### FetchDocumentsByFilterTool + +Bases: Tool + +Tool that fetches documents directly from a document store by metadata filter. + +Unlike a scored retrieval tool, this fetches without any relevance ranking, so an agent can grab specific documents +(e.g. a known title or source file) without going through a relevance search. The fetched documents are put into +reading order first: grouped by their parent file (`file_name`/`file_path`/`source_id`) and sorted by their +position within it (`split_id`/`split_idx_start`/`page_number`), using whichever of those metadata fields the +documents carry. Match sets larger than `max_docs` are paged: each call returns one page plus the total match +count, and the tool's `offset` input continues where the previous page ended. + +#### __init__ + +```python +__init__( + document_store: DocumentStore, + max_docs: int = 10, + max_fetch_factor: int = 10, +) -> None +``` + +Create the tool. + +**Parameters:** + +- **document_store** (DocumentStore) – The document store to fetch documents from. +- **max_docs** (int) – Ceiling on the number of documents shown to the agent per fetch. Unlike scored retrieval, a + filter fetch is not bounded by a retriever's `top_k`, so this caps the tool result instead. The LLM can + request fewer via the tool's optional `max_docs` input, but never more. +- **max_fetch_factor** (int) – How many times the `max_docs` ceiling a filter may match before the fetch is + refused outright (when the store supports `count_documents_by_filter`) — the refusal is surfaced to the + LLM as an error it can recover from by narrowing the filter. + +#### to_dict + +```python +to_dict() -> dict[str, Any] +``` + +Serialize the tool to a dictionary. + +#### from_dict + +```python +from_dict(data: dict[str, Any]) -> FetchDocumentsByFilterTool +``` + +Deserialize the tool from a dictionary. + +**Parameters:** + +- **data** (dict\[str, Any\]) – The dictionary produced by `to_dict`. + +**Returns:** + +- FetchDocumentsByFilterTool – The deserialized tool. + +### DocumentStoreToolset + +Bases: Toolset + +All document-store-backed tools as one unit. + +Bundles the three metadata inspection tools (`ListMetadataFieldsTool`, `GetMetadataFieldValuesTool`, +`GetMetadataFieldRangeTool`) and the direct `FetchDocumentsByFilterTool`, so they can be handed to an `Agent` +(or combined with a retrieval tool) as a single object. + +#### __init__ + +```python +__init__(document_store: DocumentStore, max_fetched_docs: int = 10) -> None +``` + +Create the toolset. + +**Parameters:** + +- **document_store** (DocumentStore) – The document store all tools run against. Must implement the metadata introspection + methods (`get_metadata_fields_info`, `get_metadata_field_unique_values`, `get_metadata_field_min_max`). +- **max_fetched_docs** (int) – Maximum number of documents `fetch_documents_by_filter` shows per fetch (see + `FetchDocumentsByFilterTool.max_docs`). + +#### to_dict + +```python +to_dict() -> dict[str, Any] +``` + +Serialize the toolset to a dictionary. + +#### from_dict + +```python +from_dict(data: dict[str, Any]) -> DocumentStoreToolset +``` + +Deserialize the toolset from a dictionary. + +**Parameters:** + +- **data** (dict\[str, Any\]) – The dictionary produced by `to_dict`. + +**Returns:** + +- DocumentStoreToolset – The deserialized toolset. + +## haystack_integrations.agent_pack.deep_research.agent + +### create_deep_research_agent + +```python +create_deep_research_agent( + *, + scope_llm: ChatGenerator | None = None, + orchestrator_llm: ChatGenerator | None = None, + researcher_llm: ChatGenerator | None = None, + summarizer_llm: ChatGenerator | None = None, + writer_llm: ChatGenerator | None = None, + max_subtopics: int = 5, + max_concurrent_researchers: int = 5, + max_orchestrator_steps: int = 8, + max_researcher_steps: int = 20, + max_search_results: int = 10, + max_content_length: int = 50000 +) -> Agent +``` + +Create the deep research agent. + +**Parameters:** + +- **scope_llm** (ChatGenerator | None) – LLM that rewrites the user query into a focused research brief. + Defaults to `OpenAIResponsesChatGenerator("gpt-5.4")`. +- **orchestrator_llm** (ChatGenerator | None) – LLM that plans the investigation and delegates the sub-questions. + Defaults to `OpenAIResponsesChatGenerator("gpt-5.4")`. +- **researcher_llm** (ChatGenerator | None) – LLM that drives each sub-researcher's search/read/think loop. + Defaults to `OpenAIResponsesChatGenerator("gpt-5.4-mini")`. +- **summarizer_llm** (ChatGenerator | None) – LLM used inside the `read_url` tool to summarize a fetched page toward + the question. Defaults to `OpenAIResponsesChatGenerator("gpt-5.4-mini")`. +- **writer_llm** (ChatGenerator | None) – LLM that turns the brief plus collected notes into the final report. + Defaults to `OpenAIResponsesChatGenerator("gpt-5.4")`. +- **max_subtopics** (int) – Maximum number of sub-questions the orchestrator may delegate (breadth). +- **max_concurrent_researchers** (int) – Maximum number of sub-researchers that run at the same time. +- **max_orchestrator_steps** (int) – Maximum steps for the orchestrator's agent loop (reflect -> delegate rounds). +- **max_researcher_steps** (int) – Maximum steps for each sub-researcher's agent loop. +- **max_search_results** (int) – Number of results returned per `web_search` call. +- **max_content_length** (int) – Maximum raw page characters fed to the summarizer, before summarization. + +**Returns:** + +- Agent – The deep research `Agent`. Call it with the question as a user message, + `agent.run(messages=[ChatMessage.from_user(question)])`; it returns a dict whose main output is + `report` (the final markdown report, a `str`). The dict also carries the intermediate `brief` + (`str`) and `notes` (`list[str]`), plus the standard Agent outputs `messages`, `last_message`, + `step_count`, `token_usage` and `tool_call_counts`. diff --git a/docs-website/reference_versioned_docs/version-2.31/integrations-api/agent_pack.md b/docs-website/reference_versioned_docs/version-2.31/integrations-api/agent_pack.md new file mode 100644 index 0000000000..2921c4d640 --- /dev/null +++ b/docs-website/reference_versioned_docs/version-2.31/integrations-api/agent_pack.md @@ -0,0 +1,463 @@ +--- +title: "Agent Pack" +id: integrations-agent-pack +description: "Agent Pack integration for Haystack" +slug: "/integrations-agent-pack" +--- + + +## haystack_integrations.agent_pack.advanced_rag.agent + +### create_advanced_rag_agent + +```python +create_advanced_rag_agent( + *, + document_store: DocumentStore, + retriever: TextRetriever | Pipeline | None = None, + retrieval_pipeline_input_mapping: dict[str, list[str]] | None = None, + retrieval_pipeline_output_mapping: dict[str, str] | None = None, + llm: ChatGenerator | None = None, + backup_answer_llm: ChatGenerator | None = None, + system_prompt: str | None = None, + max_agent_steps: int = 20, + max_fetched_docs: int = 10, + extra_tools: ToolsType | None = None, + state_schema: dict[str, Any] | None = None, + hooks: dict[HookPoint, list[Hook]] | None = None, + raise_on_tool_invocation_failure: bool = False, + tool_concurrency_limit: int = 4 +) -> Agent +``` + +Create the advanced RAG agent. + +The agent answers questions from documents it retrieves out of the document store. Instead of guessing which +metadata fields exist, it can inspect the store (fields, values, ranges) and construct a Haystack filter to +narrow its retrieval when metadata helps — plain, unfiltered retrieval remains available when it doesn't. The +answer cites the retrieved documents. + +The required `retriever` becomes the `search_documents` tool; `document_store` additionally feeds the three +metadata inspection tools and must implement the metadata introspection methods (`get_metadata_fields_info`, +`get_metadata_field_unique_values`, `get_metadata_field_min_max`). + +**Parameters:** + +- **document_store** (DocumentStore) – The document store the metadata inspection tools and the `fetch_documents_by_filter` tool + run against. +- **retriever** (TextRetriever | Pipeline | None) – What retrieves for the `search_documents` tool (required). Either a standalone retriever + component following the `TextRetriever` protocol, i.e. its `run` method accepts `query` and `filters` + (e.g. `InMemoryBM25Retriever`, or an embedding retriever wrapped in `TextEmbeddingRetriever`), or a custom + retrieval `Pipeline` (e.g. embedder -> retriever, or hybrid retrieval) — a pipeline additionally requires + `retrieval_pipeline_input_mapping`. It should retrieve by relevance scoring (keyword or embedding-based) — + direct, unscored fetching is already covered by the built-in `fetch_documents_by_filter` tool. +- **retrieval_pipeline_input_mapping** (dict\[str, list\[str\]\] | None) – Required when `retriever` is a `Pipeline`: maps the tool inputs to + pipeline input sockets; must have exactly the keys "query" and "filters", + e.g. `{"query": ["embedder.text"], "filters": ["retriever.filters"]}`. +- **retrieval_pipeline_output_mapping** (dict\[str, str\] | None) – Optional when `retriever` is a `Pipeline`: maps pipeline output sockets + to tool outputs, e.g. `{"retriever.documents": "documents"}`. +- **llm** (ChatGenerator | None) – LLM that drives the agent loop. Defaults to `OpenAIResponsesChatGenerator("gpt-5.4")` with low + reasoning effort. +- **backup_answer_llm** (ChatGenerator | None) – LLM the built-in `BackupAnswerHook` uses to write a best-effort answer when the run + is cut off by `max_agent_steps`. Defaults to a separate `OpenAIResponsesChatGenerator("gpt-5.4")` with low + reasoning effort. +- **system_prompt** (str | None) – Overrides the pre-made system prompt. +- **max_agent_steps** (int) – Maximum steps for the agent loop. If the loop is cut off by this limit before writing an + answer, an `after_run` hook (`BackupAnswerHook`) makes one extra LLM call to produce a best-effort answer from + the evidence gathered so far, so `last_message` always carries a text answer. +- **max_fetched_docs** (int) – Maximum number of documents `fetch_documents_by_filter` shows per fetch. A filter fetch is + not bounded by a retriever's `top_k`, so this caps the tool result instead; the scored `search_documents` tool + is bounded by the `top_k` configured on your retrieval components. +- **extra_tools** (ToolsType | None) – Additional tools (or toolsets) for the agent, appended after the built-in document-store + toolset and the retrieval tool. +- **state_schema** (dict\[str, Any\] | None) – Additional entries merged into the agent's state schema. The built-in `documents` entry + (the accumulated retrieved documents) always takes precedence. +- **hooks** (dict\[HookPoint, list\[Hook\]\] | None) – Additional hooks per hook point, merged with the built-in hooks. For `after_run`, the built-in + backup-answer hook runs first, so custom hooks see the final answer. +- **raise_on_tool_invocation_failure** (bool) – If True, a failing tool call raises instead of being returned to the LLM + as an error message it can recover from (the default). +- **tool_concurrency_limit** (int) – Maximum number of tool calls executed in parallel within one agent step. + +**Returns:** + +- Agent – The advanced RAG `Agent`. Call it with the question as a user message, + `agent.run(messages=[ChatMessage.from_user(question)])`; the answer is in `last_message` (a `ChatMessage`) and + `documents` carries every document the agent retrieved during the run (deduplicated by id, in first-retrieved + order) — the answer cites them by the first 8 characters of their id, e.g. `[doc a1b2c3d4]`. The standard Agent + outputs `messages`, `step_count`, `token_usage` and `tool_call_counts` are also returned. + +## haystack_integrations.agent_pack.advanced_rag.hooks + +### BackupAnswerHook + +Produce a final answer when the agent run ends without one. Runs as an `after_run` hook. + +When the agent exhausts `max_agent_steps` mid-investigation, the run ends on a tool call or tool result instead of +an assistant text answer (and only `after_run` hooks run in this situation). This hook detects that case and makes +one LLM call over the conversation so far to produce a best-effort answer from the already-gathered evidence. + +#### __init__ + +```python +__init__(chat_generator: ChatGenerator) -> None +``` + +Create the hook. + +**Parameters:** + +- **chat_generator** (ChatGenerator) – LLM that writes the backup answer from the gathered evidence. + +#### warm_up + +```python +warm_up() -> None +``` + +Prepare the hook's generator for use; called from the Agent's `warm_up`. + +#### close + +```python +close() -> None +``` + +Release the hook's generator resources; called from the Agent's `close`. + +#### to_dict + +```python +to_dict() -> dict +``` + +Serialize the hook to a dictionary. + +**Returns:** + +- dict – Dictionary with serialized data. + +#### from_dict + +```python +from_dict(data: dict) -> BackupAnswerHook +``` + +Deserialize the hook from a dictionary. + +**Parameters:** + +- **data** (dict) – Dictionary to deserialize from. + +**Returns:** + +- BackupAnswerHook – Deserialized hook. + +#### run + +```python +run(state: State) -> None +``` + +Append a best-effort final answer when the run ended without one (e.g. step exhaustion). + +**Parameters:** + +- **state** (State) – The agent run's state. + +## haystack_integrations.agent_pack.advanced_rag.tools + +### ListMetadataFieldsTool + +Bases: Tool + +Tool that lists all metadata fields and their types from a document store. + +#### __init__ + +```python +__init__(document_store: DocumentStore) -> None +``` + +Create the tool. + +**Parameters:** + +- **document_store** (DocumentStore) – The document store to inspect. Must implement `get_metadata_fields_info`. + +**Raises:** + +- ValueError – If the store does not implement `get_metadata_fields_info`. + +#### to_dict + +```python +to_dict() -> dict[str, Any] +``` + +Serialize the tool to a dictionary. + +#### from_dict + +```python +from_dict(data: dict[str, Any]) -> ListMetadataFieldsTool +``` + +Deserialize the tool from a dictionary. + +**Parameters:** + +- **data** (dict\[str, Any\]) – The dictionary produced by `to_dict`. + +**Returns:** + +- ListMetadataFieldsTool – The deserialized tool. + +### GetMetadataFieldValuesTool + +Bases: Tool + +Tool that returns the distinct values of a metadata field from a document store. + +#### __init__ + +```python +__init__(document_store: DocumentStore) -> None +``` + +Create the tool. + +**Parameters:** + +- **document_store** (DocumentStore) – The document store to inspect. Must implement `get_metadata_field_unique_values`. + +**Raises:** + +- ValueError – If the store does not implement `get_metadata_field_unique_values`. + +#### to_dict + +```python +to_dict() -> dict[str, Any] +``` + +Serialize the tool to a dictionary. + +#### from_dict + +```python +from_dict(data: dict[str, Any]) -> GetMetadataFieldValuesTool +``` + +Deserialize the tool from a dictionary. + +**Parameters:** + +- **data** (dict\[str, Any\]) – The dictionary produced by `to_dict`. + +**Returns:** + +- GetMetadataFieldValuesTool – The deserialized tool. + +### GetMetadataFieldRangeTool + +Bases: Tool + +Tool that returns the minimum and maximum values of a metadata field from a document store. + +#### __init__ + +```python +__init__(document_store: DocumentStore) -> None +``` + +Create the tool. + +**Parameters:** + +- **document_store** (DocumentStore) – The document store to inspect. Must implement `get_metadata_field_min_max`. + +**Raises:** + +- ValueError – If the store does not implement `get_metadata_field_min_max`. + +#### to_dict + +```python +to_dict() -> dict[str, Any] +``` + +Serialize the tool to a dictionary. + +#### from_dict + +```python +from_dict(data: dict[str, Any]) -> GetMetadataFieldRangeTool +``` + +Deserialize the tool from a dictionary. + +**Parameters:** + +- **data** (dict\[str, Any\]) – The dictionary produced by `to_dict`. + +**Returns:** + +- GetMetadataFieldRangeTool – The deserialized tool. + +### FetchDocumentsByFilterTool + +Bases: Tool + +Tool that fetches documents directly from a document store by metadata filter. + +Unlike a scored retrieval tool, this fetches without any relevance ranking, so an agent can grab specific documents +(e.g. a known title or source file) without going through a relevance search. The fetched documents are put into +reading order first: grouped by their parent file (`file_name`/`file_path`/`source_id`) and sorted by their +position within it (`split_id`/`split_idx_start`/`page_number`), using whichever of those metadata fields the +documents carry. Match sets larger than `max_docs` are paged: each call returns one page plus the total match +count, and the tool's `offset` input continues where the previous page ended. + +#### __init__ + +```python +__init__( + document_store: DocumentStore, + max_docs: int = 10, + max_fetch_factor: int = 10, +) -> None +``` + +Create the tool. + +**Parameters:** + +- **document_store** (DocumentStore) – The document store to fetch documents from. +- **max_docs** (int) – Ceiling on the number of documents shown to the agent per fetch. Unlike scored retrieval, a + filter fetch is not bounded by a retriever's `top_k`, so this caps the tool result instead. The LLM can + request fewer via the tool's optional `max_docs` input, but never more. +- **max_fetch_factor** (int) – How many times the `max_docs` ceiling a filter may match before the fetch is + refused outright (when the store supports `count_documents_by_filter`) — the refusal is surfaced to the + LLM as an error it can recover from by narrowing the filter. + +#### to_dict + +```python +to_dict() -> dict[str, Any] +``` + +Serialize the tool to a dictionary. + +#### from_dict + +```python +from_dict(data: dict[str, Any]) -> FetchDocumentsByFilterTool +``` + +Deserialize the tool from a dictionary. + +**Parameters:** + +- **data** (dict\[str, Any\]) – The dictionary produced by `to_dict`. + +**Returns:** + +- FetchDocumentsByFilterTool – The deserialized tool. + +### DocumentStoreToolset + +Bases: Toolset + +All document-store-backed tools as one unit. + +Bundles the three metadata inspection tools (`ListMetadataFieldsTool`, `GetMetadataFieldValuesTool`, +`GetMetadataFieldRangeTool`) and the direct `FetchDocumentsByFilterTool`, so they can be handed to an `Agent` +(or combined with a retrieval tool) as a single object. + +#### __init__ + +```python +__init__(document_store: DocumentStore, max_fetched_docs: int = 10) -> None +``` + +Create the toolset. + +**Parameters:** + +- **document_store** (DocumentStore) – The document store all tools run against. Must implement the metadata introspection + methods (`get_metadata_fields_info`, `get_metadata_field_unique_values`, `get_metadata_field_min_max`). +- **max_fetched_docs** (int) – Maximum number of documents `fetch_documents_by_filter` shows per fetch (see + `FetchDocumentsByFilterTool.max_docs`). + +#### to_dict + +```python +to_dict() -> dict[str, Any] +``` + +Serialize the toolset to a dictionary. + +#### from_dict + +```python +from_dict(data: dict[str, Any]) -> DocumentStoreToolset +``` + +Deserialize the toolset from a dictionary. + +**Parameters:** + +- **data** (dict\[str, Any\]) – The dictionary produced by `to_dict`. + +**Returns:** + +- DocumentStoreToolset – The deserialized toolset. + +## haystack_integrations.agent_pack.deep_research.agent + +### create_deep_research_agent + +```python +create_deep_research_agent( + *, + scope_llm: ChatGenerator | None = None, + orchestrator_llm: ChatGenerator | None = None, + researcher_llm: ChatGenerator | None = None, + summarizer_llm: ChatGenerator | None = None, + writer_llm: ChatGenerator | None = None, + max_subtopics: int = 5, + max_concurrent_researchers: int = 5, + max_orchestrator_steps: int = 8, + max_researcher_steps: int = 20, + max_search_results: int = 10, + max_content_length: int = 50000 +) -> Agent +``` + +Create the deep research agent. + +**Parameters:** + +- **scope_llm** (ChatGenerator | None) – LLM that rewrites the user query into a focused research brief. + Defaults to `OpenAIResponsesChatGenerator("gpt-5.4")`. +- **orchestrator_llm** (ChatGenerator | None) – LLM that plans the investigation and delegates the sub-questions. + Defaults to `OpenAIResponsesChatGenerator("gpt-5.4")`. +- **researcher_llm** (ChatGenerator | None) – LLM that drives each sub-researcher's search/read/think loop. + Defaults to `OpenAIResponsesChatGenerator("gpt-5.4-mini")`. +- **summarizer_llm** (ChatGenerator | None) – LLM used inside the `read_url` tool to summarize a fetched page toward + the question. Defaults to `OpenAIResponsesChatGenerator("gpt-5.4-mini")`. +- **writer_llm** (ChatGenerator | None) – LLM that turns the brief plus collected notes into the final report. + Defaults to `OpenAIResponsesChatGenerator("gpt-5.4")`. +- **max_subtopics** (int) – Maximum number of sub-questions the orchestrator may delegate (breadth). +- **max_concurrent_researchers** (int) – Maximum number of sub-researchers that run at the same time. +- **max_orchestrator_steps** (int) – Maximum steps for the orchestrator's agent loop (reflect -> delegate rounds). +- **max_researcher_steps** (int) – Maximum steps for each sub-researcher's agent loop. +- **max_search_results** (int) – Number of results returned per `web_search` call. +- **max_content_length** (int) – Maximum raw page characters fed to the summarizer, before summarization. + +**Returns:** + +- Agent – The deep research `Agent`. Call it with the question as a user message, + `agent.run(messages=[ChatMessage.from_user(question)])`; it returns a dict whose main output is + `report` (the final markdown report, a `str`). The dict also carries the intermediate `brief` + (`str`) and `notes` (`list[str]`), plus the standard Agent outputs `messages`, `last_message`, + `step_count`, `token_usage` and `tool_call_counts`. diff --git a/docs-website/reference_versioned_docs/version-3.0/integrations-api/agent_pack.md b/docs-website/reference_versioned_docs/version-3.0/integrations-api/agent_pack.md new file mode 100644 index 0000000000..2921c4d640 --- /dev/null +++ b/docs-website/reference_versioned_docs/version-3.0/integrations-api/agent_pack.md @@ -0,0 +1,463 @@ +--- +title: "Agent Pack" +id: integrations-agent-pack +description: "Agent Pack integration for Haystack" +slug: "/integrations-agent-pack" +--- + + +## haystack_integrations.agent_pack.advanced_rag.agent + +### create_advanced_rag_agent + +```python +create_advanced_rag_agent( + *, + document_store: DocumentStore, + retriever: TextRetriever | Pipeline | None = None, + retrieval_pipeline_input_mapping: dict[str, list[str]] | None = None, + retrieval_pipeline_output_mapping: dict[str, str] | None = None, + llm: ChatGenerator | None = None, + backup_answer_llm: ChatGenerator | None = None, + system_prompt: str | None = None, + max_agent_steps: int = 20, + max_fetched_docs: int = 10, + extra_tools: ToolsType | None = None, + state_schema: dict[str, Any] | None = None, + hooks: dict[HookPoint, list[Hook]] | None = None, + raise_on_tool_invocation_failure: bool = False, + tool_concurrency_limit: int = 4 +) -> Agent +``` + +Create the advanced RAG agent. + +The agent answers questions from documents it retrieves out of the document store. Instead of guessing which +metadata fields exist, it can inspect the store (fields, values, ranges) and construct a Haystack filter to +narrow its retrieval when metadata helps — plain, unfiltered retrieval remains available when it doesn't. The +answer cites the retrieved documents. + +The required `retriever` becomes the `search_documents` tool; `document_store` additionally feeds the three +metadata inspection tools and must implement the metadata introspection methods (`get_metadata_fields_info`, +`get_metadata_field_unique_values`, `get_metadata_field_min_max`). + +**Parameters:** + +- **document_store** (DocumentStore) – The document store the metadata inspection tools and the `fetch_documents_by_filter` tool + run against. +- **retriever** (TextRetriever | Pipeline | None) – What retrieves for the `search_documents` tool (required). Either a standalone retriever + component following the `TextRetriever` protocol, i.e. its `run` method accepts `query` and `filters` + (e.g. `InMemoryBM25Retriever`, or an embedding retriever wrapped in `TextEmbeddingRetriever`), or a custom + retrieval `Pipeline` (e.g. embedder -> retriever, or hybrid retrieval) — a pipeline additionally requires + `retrieval_pipeline_input_mapping`. It should retrieve by relevance scoring (keyword or embedding-based) — + direct, unscored fetching is already covered by the built-in `fetch_documents_by_filter` tool. +- **retrieval_pipeline_input_mapping** (dict\[str, list\[str\]\] | None) – Required when `retriever` is a `Pipeline`: maps the tool inputs to + pipeline input sockets; must have exactly the keys "query" and "filters", + e.g. `{"query": ["embedder.text"], "filters": ["retriever.filters"]}`. +- **retrieval_pipeline_output_mapping** (dict\[str, str\] | None) – Optional when `retriever` is a `Pipeline`: maps pipeline output sockets + to tool outputs, e.g. `{"retriever.documents": "documents"}`. +- **llm** (ChatGenerator | None) – LLM that drives the agent loop. Defaults to `OpenAIResponsesChatGenerator("gpt-5.4")` with low + reasoning effort. +- **backup_answer_llm** (ChatGenerator | None) – LLM the built-in `BackupAnswerHook` uses to write a best-effort answer when the run + is cut off by `max_agent_steps`. Defaults to a separate `OpenAIResponsesChatGenerator("gpt-5.4")` with low + reasoning effort. +- **system_prompt** (str | None) – Overrides the pre-made system prompt. +- **max_agent_steps** (int) – Maximum steps for the agent loop. If the loop is cut off by this limit before writing an + answer, an `after_run` hook (`BackupAnswerHook`) makes one extra LLM call to produce a best-effort answer from + the evidence gathered so far, so `last_message` always carries a text answer. +- **max_fetched_docs** (int) – Maximum number of documents `fetch_documents_by_filter` shows per fetch. A filter fetch is + not bounded by a retriever's `top_k`, so this caps the tool result instead; the scored `search_documents` tool + is bounded by the `top_k` configured on your retrieval components. +- **extra_tools** (ToolsType | None) – Additional tools (or toolsets) for the agent, appended after the built-in document-store + toolset and the retrieval tool. +- **state_schema** (dict\[str, Any\] | None) – Additional entries merged into the agent's state schema. The built-in `documents` entry + (the accumulated retrieved documents) always takes precedence. +- **hooks** (dict\[HookPoint, list\[Hook\]\] | None) – Additional hooks per hook point, merged with the built-in hooks. For `after_run`, the built-in + backup-answer hook runs first, so custom hooks see the final answer. +- **raise_on_tool_invocation_failure** (bool) – If True, a failing tool call raises instead of being returned to the LLM + as an error message it can recover from (the default). +- **tool_concurrency_limit** (int) – Maximum number of tool calls executed in parallel within one agent step. + +**Returns:** + +- Agent – The advanced RAG `Agent`. Call it with the question as a user message, + `agent.run(messages=[ChatMessage.from_user(question)])`; the answer is in `last_message` (a `ChatMessage`) and + `documents` carries every document the agent retrieved during the run (deduplicated by id, in first-retrieved + order) — the answer cites them by the first 8 characters of their id, e.g. `[doc a1b2c3d4]`. The standard Agent + outputs `messages`, `step_count`, `token_usage` and `tool_call_counts` are also returned. + +## haystack_integrations.agent_pack.advanced_rag.hooks + +### BackupAnswerHook + +Produce a final answer when the agent run ends without one. Runs as an `after_run` hook. + +When the agent exhausts `max_agent_steps` mid-investigation, the run ends on a tool call or tool result instead of +an assistant text answer (and only `after_run` hooks run in this situation). This hook detects that case and makes +one LLM call over the conversation so far to produce a best-effort answer from the already-gathered evidence. + +#### __init__ + +```python +__init__(chat_generator: ChatGenerator) -> None +``` + +Create the hook. + +**Parameters:** + +- **chat_generator** (ChatGenerator) – LLM that writes the backup answer from the gathered evidence. + +#### warm_up + +```python +warm_up() -> None +``` + +Prepare the hook's generator for use; called from the Agent's `warm_up`. + +#### close + +```python +close() -> None +``` + +Release the hook's generator resources; called from the Agent's `close`. + +#### to_dict + +```python +to_dict() -> dict +``` + +Serialize the hook to a dictionary. + +**Returns:** + +- dict – Dictionary with serialized data. + +#### from_dict + +```python +from_dict(data: dict) -> BackupAnswerHook +``` + +Deserialize the hook from a dictionary. + +**Parameters:** + +- **data** (dict) – Dictionary to deserialize from. + +**Returns:** + +- BackupAnswerHook – Deserialized hook. + +#### run + +```python +run(state: State) -> None +``` + +Append a best-effort final answer when the run ended without one (e.g. step exhaustion). + +**Parameters:** + +- **state** (State) – The agent run's state. + +## haystack_integrations.agent_pack.advanced_rag.tools + +### ListMetadataFieldsTool + +Bases: Tool + +Tool that lists all metadata fields and their types from a document store. + +#### __init__ + +```python +__init__(document_store: DocumentStore) -> None +``` + +Create the tool. + +**Parameters:** + +- **document_store** (DocumentStore) – The document store to inspect. Must implement `get_metadata_fields_info`. + +**Raises:** + +- ValueError – If the store does not implement `get_metadata_fields_info`. + +#### to_dict + +```python +to_dict() -> dict[str, Any] +``` + +Serialize the tool to a dictionary. + +#### from_dict + +```python +from_dict(data: dict[str, Any]) -> ListMetadataFieldsTool +``` + +Deserialize the tool from a dictionary. + +**Parameters:** + +- **data** (dict\[str, Any\]) – The dictionary produced by `to_dict`. + +**Returns:** + +- ListMetadataFieldsTool – The deserialized tool. + +### GetMetadataFieldValuesTool + +Bases: Tool + +Tool that returns the distinct values of a metadata field from a document store. + +#### __init__ + +```python +__init__(document_store: DocumentStore) -> None +``` + +Create the tool. + +**Parameters:** + +- **document_store** (DocumentStore) – The document store to inspect. Must implement `get_metadata_field_unique_values`. + +**Raises:** + +- ValueError – If the store does not implement `get_metadata_field_unique_values`. + +#### to_dict + +```python +to_dict() -> dict[str, Any] +``` + +Serialize the tool to a dictionary. + +#### from_dict + +```python +from_dict(data: dict[str, Any]) -> GetMetadataFieldValuesTool +``` + +Deserialize the tool from a dictionary. + +**Parameters:** + +- **data** (dict\[str, Any\]) – The dictionary produced by `to_dict`. + +**Returns:** + +- GetMetadataFieldValuesTool – The deserialized tool. + +### GetMetadataFieldRangeTool + +Bases: Tool + +Tool that returns the minimum and maximum values of a metadata field from a document store. + +#### __init__ + +```python +__init__(document_store: DocumentStore) -> None +``` + +Create the tool. + +**Parameters:** + +- **document_store** (DocumentStore) – The document store to inspect. Must implement `get_metadata_field_min_max`. + +**Raises:** + +- ValueError – If the store does not implement `get_metadata_field_min_max`. + +#### to_dict + +```python +to_dict() -> dict[str, Any] +``` + +Serialize the tool to a dictionary. + +#### from_dict + +```python +from_dict(data: dict[str, Any]) -> GetMetadataFieldRangeTool +``` + +Deserialize the tool from a dictionary. + +**Parameters:** + +- **data** (dict\[str, Any\]) – The dictionary produced by `to_dict`. + +**Returns:** + +- GetMetadataFieldRangeTool – The deserialized tool. + +### FetchDocumentsByFilterTool + +Bases: Tool + +Tool that fetches documents directly from a document store by metadata filter. + +Unlike a scored retrieval tool, this fetches without any relevance ranking, so an agent can grab specific documents +(e.g. a known title or source file) without going through a relevance search. The fetched documents are put into +reading order first: grouped by their parent file (`file_name`/`file_path`/`source_id`) and sorted by their +position within it (`split_id`/`split_idx_start`/`page_number`), using whichever of those metadata fields the +documents carry. Match sets larger than `max_docs` are paged: each call returns one page plus the total match +count, and the tool's `offset` input continues where the previous page ended. + +#### __init__ + +```python +__init__( + document_store: DocumentStore, + max_docs: int = 10, + max_fetch_factor: int = 10, +) -> None +``` + +Create the tool. + +**Parameters:** + +- **document_store** (DocumentStore) – The document store to fetch documents from. +- **max_docs** (int) – Ceiling on the number of documents shown to the agent per fetch. Unlike scored retrieval, a + filter fetch is not bounded by a retriever's `top_k`, so this caps the tool result instead. The LLM can + request fewer via the tool's optional `max_docs` input, but never more. +- **max_fetch_factor** (int) – How many times the `max_docs` ceiling a filter may match before the fetch is + refused outright (when the store supports `count_documents_by_filter`) — the refusal is surfaced to the + LLM as an error it can recover from by narrowing the filter. + +#### to_dict + +```python +to_dict() -> dict[str, Any] +``` + +Serialize the tool to a dictionary. + +#### from_dict + +```python +from_dict(data: dict[str, Any]) -> FetchDocumentsByFilterTool +``` + +Deserialize the tool from a dictionary. + +**Parameters:** + +- **data** (dict\[str, Any\]) – The dictionary produced by `to_dict`. + +**Returns:** + +- FetchDocumentsByFilterTool – The deserialized tool. + +### DocumentStoreToolset + +Bases: Toolset + +All document-store-backed tools as one unit. + +Bundles the three metadata inspection tools (`ListMetadataFieldsTool`, `GetMetadataFieldValuesTool`, +`GetMetadataFieldRangeTool`) and the direct `FetchDocumentsByFilterTool`, so they can be handed to an `Agent` +(or combined with a retrieval tool) as a single object. + +#### __init__ + +```python +__init__(document_store: DocumentStore, max_fetched_docs: int = 10) -> None +``` + +Create the toolset. + +**Parameters:** + +- **document_store** (DocumentStore) – The document store all tools run against. Must implement the metadata introspection + methods (`get_metadata_fields_info`, `get_metadata_field_unique_values`, `get_metadata_field_min_max`). +- **max_fetched_docs** (int) – Maximum number of documents `fetch_documents_by_filter` shows per fetch (see + `FetchDocumentsByFilterTool.max_docs`). + +#### to_dict + +```python +to_dict() -> dict[str, Any] +``` + +Serialize the toolset to a dictionary. + +#### from_dict + +```python +from_dict(data: dict[str, Any]) -> DocumentStoreToolset +``` + +Deserialize the toolset from a dictionary. + +**Parameters:** + +- **data** (dict\[str, Any\]) – The dictionary produced by `to_dict`. + +**Returns:** + +- DocumentStoreToolset – The deserialized toolset. + +## haystack_integrations.agent_pack.deep_research.agent + +### create_deep_research_agent + +```python +create_deep_research_agent( + *, + scope_llm: ChatGenerator | None = None, + orchestrator_llm: ChatGenerator | None = None, + researcher_llm: ChatGenerator | None = None, + summarizer_llm: ChatGenerator | None = None, + writer_llm: ChatGenerator | None = None, + max_subtopics: int = 5, + max_concurrent_researchers: int = 5, + max_orchestrator_steps: int = 8, + max_researcher_steps: int = 20, + max_search_results: int = 10, + max_content_length: int = 50000 +) -> Agent +``` + +Create the deep research agent. + +**Parameters:** + +- **scope_llm** (ChatGenerator | None) – LLM that rewrites the user query into a focused research brief. + Defaults to `OpenAIResponsesChatGenerator("gpt-5.4")`. +- **orchestrator_llm** (ChatGenerator | None) – LLM that plans the investigation and delegates the sub-questions. + Defaults to `OpenAIResponsesChatGenerator("gpt-5.4")`. +- **researcher_llm** (ChatGenerator | None) – LLM that drives each sub-researcher's search/read/think loop. + Defaults to `OpenAIResponsesChatGenerator("gpt-5.4-mini")`. +- **summarizer_llm** (ChatGenerator | None) – LLM used inside the `read_url` tool to summarize a fetched page toward + the question. Defaults to `OpenAIResponsesChatGenerator("gpt-5.4-mini")`. +- **writer_llm** (ChatGenerator | None) – LLM that turns the brief plus collected notes into the final report. + Defaults to `OpenAIResponsesChatGenerator("gpt-5.4")`. +- **max_subtopics** (int) – Maximum number of sub-questions the orchestrator may delegate (breadth). +- **max_concurrent_researchers** (int) – Maximum number of sub-researchers that run at the same time. +- **max_orchestrator_steps** (int) – Maximum steps for the orchestrator's agent loop (reflect -> delegate rounds). +- **max_researcher_steps** (int) – Maximum steps for each sub-researcher's agent loop. +- **max_search_results** (int) – Number of results returned per `web_search` call. +- **max_content_length** (int) – Maximum raw page characters fed to the summarizer, before summarization. + +**Returns:** + +- Agent – The deep research `Agent`. Call it with the question as a user message, + `agent.run(messages=[ChatMessage.from_user(question)])`; it returns a dict whose main output is + `report` (the final markdown report, a `str`). The dict also carries the intermediate `brief` + (`str`) and `notes` (`list[str]`), plus the standard Agent outputs `messages`, `last_message`, + `step_count`, `token_usage` and `tool_call_counts`.