Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
42 changes: 31 additions & 11 deletions tutorials/50_Using_Pre_Built_Agents_from_Agent_Pack.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@
"There are three ways to use an agent from the pack:\n",
"\n",
"- **Run it as is.** Call the `create_*` function, pass a question, and get an answer. The defaults are chosen to work out of the box.\n",
"- **Customize it.** Each entry point exposes keyword arguments for swapping models, adding tools, and tuning behavior.\n",
"- **Customize it.** Each entry point exposes keyword arguments for the choices specific to that agent, such as which models to use. For everything else, such as adding tools or hooks, use [`clone()`](https://docs.haystack.deepset.ai/docs/agent#cloning-and-modifying-an-agent) on the returned agent.\n",
"- **Copy it.** Read the implementation and adapt it as a blueprint for your own architecture.\n",
"\n",
"### Why these two agents?\n",
Expand Down Expand Up @@ -242,12 +242,11 @@
"source": [
"### Customizing the agent\n",
"\n",
"Everything is configured through keyword arguments. Only `document_store` and `retriever` are required. A few useful ones:\n",
"Everything is configured through keyword arguments. Only `document_store` and `retriever` are required. The other keyword arguments cover the choices specific to this agent: models, the prompt, and limits. A few useful ones:\n",
"\n",
"- `llm`: the chat generator that drives the agent loop. Defaults to `OpenAIResponsesChatGenerator(\"gpt-5.4\")` with low reasoning effort. Swap in any tool-calling generator, from OpenAI or another provider.\n",
"- `max_agent_steps`: caps the loop (default `20`). If the loop is cut off before an answer is written, a built-in `BackupAnswerHook` makes one extra call to produce a best-effort answer, so `last_message` always carries text.\n",
"- `max_fetched_docs`: how many documents `fetch_documents_by_filter` shows per call (default `10`).\n",
"- `extra_tools`, `state_schema`, `hooks`: extend the agent with your own tools, state, and hooks.\n",
"\n",
"Here we swap the LLM for a smaller, widely available model and tighten the step budget:"
]
Expand Down Expand Up @@ -277,6 +276,15 @@
"id": "41b3360b",
"metadata": {},
"source": [
"**Extending the agent.** To change anything else, such as adding tools, [hooks](https://docs.haystack.deepset.ai/docs/hooks), or [`State`](https://docs.haystack.deepset.ai/docs/state) entries, use [`clone()`](https://docs.haystack.deepset.ai/docs/agent#cloning-and-modifying-an-agent) on the returned agent. Unpack the existing values so you keep the built-in tools and the `BackupAnswerHook`:\n",
"\n",
"```python\n",
"customized = rag_agent.clone(\n",
" tools=[*rag_agent.tools, my_tool],\n",
" hooks={**rag_agent.hooks, \"before_llm\": [my_hook]},\n",
")\n",
"```\n",
"\n",
"**Using a retrieval pipeline.** To use a multi-component retrieval flow (for example hybrid retrieval), pass a `Pipeline` as `retriever` and supply `retrieval_pipeline_input_mapping` (mapping the tool's `query` and `filters` to your pipeline's input sockets) and, optionally, `retrieval_pipeline_output_mapping`. See the [Advanced RAG Agent docs](https://docs.haystack.deepset.ai/docs/advanced-rag-agent) for a full hybrid-retrieval example.\n",
"\n",
"**Using the tools on their own.** The four document-store-backed tools are exported individually and bundled as `DocumentStoreToolset`, so you can drop them into your own `Agent` with your own prompt, treating the pack as a toolbox rather than a finished agent:\n",
Expand Down Expand Up @@ -320,12 +328,13 @@
"outputs": [],
"source": [
"from haystack_integrations.agent_pack import create_deep_research_agent\n",
"from haystack_integrations.tools.tavily import TavilyWebSearchTool\n",
"\n",
"research_agent = create_deep_research_agent(\n",
" max_subtopics=2, # delegate at most 2 sub-questions (breadth)\n",
" max_concurrent_researchers=2, # run at most 2 sub-researchers at once\n",
" max_researcher_steps=6, # cap each sub-researcher's search/read/think loop\n",
" max_search_results=5, # results per web_search call\n",
" search_tool=TavilyWebSearchTool(top_k=5), # results per web_search call (default: top_k=10)\n",
")"
]
},
Expand Down Expand Up @@ -392,10 +401,12 @@
"\n",
"Each phase takes its own `ChatGenerator`, so you can mix models by cost and capability, or swap in a different provider entirely:\n",
"\n",
"- `scope_llm`, `orchestrator_llm`, `writer_llm`: default to `OpenAIResponsesChatGenerator(\"gpt-5.4\")` (the heavier reasoning steps).\n",
"- `researcher_llm`, `summarizer_llm`: default to `OpenAIResponsesChatGenerator(\"gpt-5.4-mini\")` (run many times, so a cheaper model keeps cost down).\n",
"- `llm`, `brief_llm`, `report_llm`: default to `OpenAIResponsesChatGenerator(\"gpt-5.4\")` (the heavier reasoning steps).\n",
"- `researcher_llm`, `page_summary_llm`: default to `OpenAIResponsesChatGenerator(\"gpt-5.4-mini\")` (run many times, so a cheaper model keeps cost down).\n",
"\n",
"The breadth/depth of the investigation is fully tunable: `max_subtopics`, `max_concurrent_researchers`, `max_agent_steps`, `max_researcher_steps`, and `max_page_chars`. The orchestrator's `system_prompt` can also be overridden (the `{{ max_subtopics }}` placeholder is substituted).\n",
"\n",
"And the breadth/depth of the investigation is fully tunable: `max_subtopics`, `max_concurrent_researchers`, `max_orchestrator_steps`, `max_researcher_steps`, `max_search_results`, and `max_content_length`.\n",
"The sub-researchers' web search is a `search_tool` you can replace, as we did above to limit results. It defaults to `TavilyWebSearchTool(top_k=10)`, and the researcher prompt refers to it as `web_search`, so a custom tool should keep that name.\n",
"\n",
"For example, to make the whole run cheaper you might point every phase at a smaller model:\n",
"\n",
Expand All @@ -404,13 +415,22 @@
"from haystack_integrations.agent_pack import create_deep_research_agent\n",
"\n",
"cheap_agent = create_deep_research_agent(\n",
" scope_llm=OpenAIChatGenerator(model=\"gpt-4o-mini\"),\n",
" orchestrator_llm=OpenAIChatGenerator(model=\"gpt-4o-mini\"),\n",
" llm=OpenAIChatGenerator(model=\"gpt-4o-mini\"),\n",
" brief_llm=OpenAIChatGenerator(model=\"gpt-4o-mini\"),\n",
" researcher_llm=OpenAIChatGenerator(model=\"gpt-4o-mini\"),\n",
" summarizer_llm=OpenAIChatGenerator(model=\"gpt-4o-mini\"),\n",
" writer_llm=OpenAIChatGenerator(model=\"gpt-4o-mini\"),\n",
" page_summary_llm=OpenAIChatGenerator(model=\"gpt-4o-mini\"),\n",
" report_llm=OpenAIChatGenerator(model=\"gpt-4o-mini\"),\n",
" max_subtopics=3,\n",
")\n",
"```\n",
"\n",
"As with the Advanced RAG Agent, to change anything else, such as adding tools or hooks to the orchestrator, use [`clone()`](https://docs.haystack.deepset.ai/docs/agent#cloning-and-modifying-an-agent) on the returned agent, unpacking the existing values to keep the built-in tools and the Scope and Write hooks:\n",
"\n",
"```python\n",
"customized = research_agent.clone(\n",
" tools=[*research_agent.tools, my_tool],\n",
" hooks={**research_agent.hooks, \"before_llm\": [my_hook]},\n",
")\n",
"```"
]
},
Expand Down