Skip to content
Merged
Show file tree
Hide file tree
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
78 changes: 4 additions & 74 deletions tutorials/43_Building_a_Tool_Calling_Agent.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,7 @@
"metadata": {
"id": "2OvkPji9O-qX"
},
"source": [
"# Tutorial: Building a Tool-Calling Agent\n",
"\n",
"- **Level**: Beginner\n",
"- **Time to complete**: 15 minutes\n",
"- **Components Used**: [`Agent`](https://docs.haystack.deepset.ai/docs/agent), [`OpenAIChatGenerator`](https://docs.haystack.deepset.ai/docs/openaichatgenerator), [`SerperDevWebSearch`](https://docs.haystack.deepset.ai/docs/serperdevwebsearch), [`ComponentTool`](https://docs.haystack.deepset.ai/docs/componenttool), [`SuperComponent`](https://docs.haystack.deepset.ai/docs/supercomponents)\n",
"- **Prerequisites**: You must have an [OpenAI API Key](https://platform.openai.com/api-keys) and a [SerperDev API Key](https://serper.dev/api-key)\n",
"- **Goal**: After completing this tutorial, you'll have learned how to create an Agent that can use tools both components and pipelines to answer questions and perform tasks."
]
"source": "# Tutorial: Building a Tool-Calling Agent\n\n- **Level**: Beginner\n- **Time to complete**: 15 minutes\n- **Components Used**: [`Agent`](https://docs.haystack.deepset.ai/docs/agent), [`OpenAIChatGenerator`](https://docs.haystack.deepset.ai/docs/openaichatgenerator), [`SerperDevWebSearch`](https://docs.haystack.deepset.ai/docs/serperdevwebsearch), [`ComponentTool`](https://docs.haystack.deepset.ai/docs/componenttool), [`PipelineTool`](https://docs.haystack.deepset.ai/docs/pipelinetool)\n- **Prerequisites**: You must have an [OpenAI API Key](https://platform.openai.com/api-keys) and a [SerperDev API Key](https://serper.dev/api-key)\n- **Goal**: After completing this tutorial, you'll have learned how to create an Agent that can use both components and pipelines as tools to answer questions and perform tasks."
},
{
"cell_type": "markdown",
Expand Down Expand Up @@ -203,7 +195,6 @@
},
"outputs": [],
"source": [
"from haystack.components.builders.answer_builder import AnswerBuilder\n",
"from haystack.components.converters.html import HTMLToDocument\n",
"from haystack.components.converters.output_adapter import OutputAdapter\n",
"from haystack.components.fetchers.link_content import LinkContentFetcher\n",
Expand Down Expand Up @@ -242,17 +233,7 @@
"metadata": {
"id": "wLIcnWl-66QA"
},
"source": [
"### Creating a Tool from a Pipeline\n",
"\n",
"Next, wrap the `search_pipeline` inside a [`SuperComponent`](https://docs.haystack.deepset.ai/docs/supercomponents) and turn it into a tool using `ComponentTool`. The `ComponentTool` automatically creates LLM-compatible tool schemas based on the component’s input sockets. \n",
"\n",
"To control what data the `ComponentTool` should receive and returns, you can optionally define `input_mapping` and `output_mapping`. For example, this lets you ensure that only the `\"query\"` input of the `search_pipeline` is mentioned in LLM-compatible tool schema, and only `\"search_result\"` is returned from the `SuperComponent`.\n",
"\n",
"Finally, you can initialize the Agent with the resulting `search_tool`.\n",
"\n",
"> 💡 Learn alternative ways of creating tools in [`Tool`](https://docs.haystack.deepset.ai/docs/tool) and [`MCPTool`](https://docs.haystack.deepset.ai/docs/mcptool) documentation pages."
]
"source": "### Creating a Tool from a Pipeline\n\nNext, wrap the `search_pipeline` in a [`PipelineTool`](https://docs.haystack.deepset.ai/docs/pipelinetool). `PipelineTool` directly exposes a pipeline as an LLM-callable tool, replacing the older pattern of wrapping a pipeline in a `SuperComponent` and then passing it to `ComponentTool`.\n\nUse `input_mapping` and `output_mapping` to control which pipeline inputs and outputs are exposed. Here, `input_mapping` ensures only `\"query\"` is surfaced in the tool schema, and `output_mapping` extracts the formatted string produced by `output_adapter`.\n\nFinally, you can initialize the Agent with the resulting `search_tool`.\n\n> 💡 Learn alternative ways of creating tools in [`Tool`](https://docs.haystack.deepset.ai/docs/tool) and [`MCPTool`](https://docs.haystack.deepset.ai/docs/mcptool) documentation pages."
},
{
"cell_type": "code",
Expand All @@ -261,42 +242,7 @@
"id": "yxaN3KBo65pv"
},
"outputs": [],
"source": [
"from haystack.core.super_component import SuperComponent\n",
"from haystack.tools import ComponentTool\n",
"from haystack.components.agents import Agent\n",
"from haystack.components.generators.chat import OpenAIChatGenerator\n",
"\n",
"search_component = SuperComponent(\n",
" pipeline=search_pipeline,\n",
" input_mapping={\"query\": [\"search.query\"]},\n",
" output_mapping={\"output_adapter.output\": \"search_result\"},\n",
")\n",
"\n",
"search_tool = ComponentTool(\n",
" name=\"search\",\n",
" description=\"Use this tool to search for information on the internet.\",\n",
" component=search_component,\n",
" outputs_to_string={\"source\": \"search_result\"},\n",
")\n",
"\n",
"agent = Agent(\n",
" chat_generator=OpenAIChatGenerator(model=\"gpt-4o-mini\"),\n",
" tools=[search_tool],\n",
" system_prompt=\"\"\"\n",
" You are a deep research assistant.\n",
" You create comprehensive research reports to answer the user's questions.\n",
" You use the 'search'-tool to answer any questions.\n",
" You perform multiple searches until you have the information you need to answer the question.\n",
" Make sure you research different aspects of the question.\n",
" Use markdown to format your response.\n",
" When you use information from the websearch results, cite your sources using markdown links.\n",
" It is important that you cite accurately.\n",
" \"\"\",\n",
" exit_conditions=[\"text\"],\n",
" max_agent_steps=20,\n",
")"
]
"source": "from haystack.tools import PipelineTool\nfrom haystack.components.agents import Agent\nfrom haystack.components.generators.chat import OpenAIChatGenerator\n\nsearch_tool = PipelineTool(\n name=\"search\",\n description=\"Use this tool to search for information on the internet.\",\n pipeline=search_pipeline,\n input_mapping={\"query\": [\"search.query\"]},\n output_mapping={\"output_adapter.output\": \"search_result\"},\n outputs_to_string={\"source\": \"search_result\"},\n)\n\nagent = Agent(\n chat_generator=OpenAIChatGenerator(model=\"gpt-4o-mini\"),\n tools=[search_tool],\n system_prompt=\"\"\"\n You are a deep research assistant.\n You create comprehensive research reports to answer the user's questions.\n You use the 'search'-tool to answer any questions.\n You perform multiple searches until you have the information you need to answer the question.\n Make sure you research different aspects of the question.\n Use markdown to format your response.\n When you use information from the websearch results, cite your sources using markdown links.\n It is important that you cite accurately.\n \"\"\",\n exit_conditions=[\"text\"],\n max_agent_steps=20,\n)"
},
{
"cell_type": "markdown",
Expand All @@ -320,7 +266,6 @@
"query = \"What are the latest updates on the Artemis moon mission?\"\n",
"messages = [ChatMessage.from_user(query)]\n",
"\n",
"agent.warm_up()\n",
"agent_output = agent.run(messages=messages)\n",
"\n",
"print(agent_output[\"messages\"][-1].text)"
Expand Down Expand Up @@ -353,22 +298,7 @@
"metadata": {
"id": "czMjWwnxPA-3"
},
"source": [
"Let's break down this last example in the tutorial.\n",
"The **Agent** is the main component that orchestrates the interaction between the LLM and tools.\n",
"We use **ComponentTool** as a wrapper that allows Haystack components to be used as tools by the agent.\n",
"The **SuperComponent** wraps entire pipelines so that they can be used as components and thus also as tools.\n",
"\n",
"We created a sophisticated search pipeline that:\n",
"1. Searches the web using SerperDevWebSearch\n",
"2. Fetches content from the found links\n",
"3. Converts HTML content to Documents\n",
"4. Formats the results for the Agent\n",
"\n",
"The Agent then uses this pipeline as a tool to gather information and generate comprehensive answers.\n",
"\n",
"By the way, did you know that the Agent is a Haystack component itself? That means you can use and combine an Agent in your pipelines just like any other component!"
]
"source": "Let's break down this last example in the tutorial.\nThe **Agent** is the main component that orchestrates the interaction between the LLM and tools.\nWe use **ComponentTool** as a wrapper that allows individual Haystack components to be used as tools by the agent.\nThe **PipelineTool** wraps entire pipelines so that they can be used as tools directly, without needing an intermediate `SuperComponent`.\n\nWe created a sophisticated search pipeline that:\n1. Searches the web using SerperDevWebSearch\n2. Fetches content from the found links\n3. Converts HTML content to Documents\n4. Formats the results for the Agent\n\nThe Agent then uses this pipeline as a tool to gather information and generate comprehensive answers.\n\nBy the way, did you know that the Agent is a Haystack component itself? That means you can use and combine an Agent in your pipelines just like any other component!"
},
{
"cell_type": "markdown",
Expand Down
Loading