|
10 | 10 | "\n", |
11 | 11 | "- **Level**: Advanced\n", |
12 | 12 | "- **Time to complete**: 20 minutes\n", |
13 | | - "- **Components Used**: [`Agent`](https://docs.haystack.deepset.ai/docs/agent), [`SerperDevWebSearch`](https://docs.haystack.deepset.ai/docs/serperdevwebsearch), [`OpenAIChatGenerator`](https://docs.haystack.deepset.ai/docs/openaichatgenerator), [`DocumentWriter`](https://docs.haystack.deepset.ai/docs/documentwriter)\n", |
14 | | - "- **Prerequisites**: You need an [OpenAI API Key](https://platform.openai.com/api-keys), a [Serper API Key](https://serper.dev/api-key) and a [Notion Integration](https://developers.notion.com/docs/create-a-notion-integration#getting-started) set up beforehand\n", |
| 13 | + "- **Components Used**: [`Agent`](https://docs.haystack.deepset.ai/docs/agent), [`DuckduckgoApiWebSearch`](https://haystack.deepset.ai/integrations/duckduckgo-api-websearch), [`OpenAIChatGenerator`](https://docs.haystack.deepset.ai/docs/openaichatgenerator), [`DocumentWriter`](https://docs.haystack.deepset.ai/docs/documentwriter)\n", |
| 14 | + "- **Prerequisites**: You need an [OpenAI API Key](https://platform.openai.com/api-keys), and a [Notion Integration](https://developers.notion.com/docs/create-a-notion-integration#getting-started) set up beforehand\n", |
15 | 15 | "- **Goal**: After completing this tutorial, you'll have learned how to build a multi-agent system in Haystack where each agent is specialized for a specific task.\n", |
16 | 16 | "\n", |
17 | 17 | "## Overview\n", |
|
37 | 37 | "source": [ |
38 | 38 | "## Preparing the Environment\n", |
39 | 39 | "\n", |
40 | | - "First, let's install Haystack:" |
| 40 | + "First, let's install required packages:" |
41 | 41 | ] |
42 | 42 | }, |
43 | 43 | { |
44 | 44 | "cell_type": "code", |
45 | | - "execution_count": 2, |
| 45 | + "execution_count": null, |
46 | 46 | "metadata": { |
47 | 47 | "colab": { |
48 | 48 | "base_uri": "https://localhost:8080/" |
|
64 | 64 | } |
65 | 65 | ], |
66 | 66 | "source": [ |
67 | | - "!pip install -q haystack-ai" |
| 67 | + "!pip install -q haystack-ai duckduckgo-api-haystack" |
68 | 68 | ] |
69 | 69 | }, |
70 | 70 | { |
|
80 | 80 | }, |
81 | 81 | { |
82 | 82 | "cell_type": "code", |
83 | | - "execution_count": 1, |
| 83 | + "execution_count": null, |
84 | 84 | "metadata": { |
85 | 85 | "colab": { |
86 | 86 | "base_uri": "https://localhost:8080/" |
87 | 87 | }, |
88 | 88 | "id": "PU26Ayr8rI3t", |
89 | 89 | "outputId": "eea1c012-870f-4376-ac9c-879d4e4a14e2" |
90 | 90 | }, |
91 | | - "outputs": [ |
92 | | - { |
93 | | - "name": "stdout", |
94 | | - "output_type": "stream", |
95 | | - "text": [ |
96 | | - "Enter your OpenAI API key:··········\n", |
97 | | - "Enter your SERPER API key:··········\n", |
98 | | - "Enter your NOTION API key:··········\n" |
99 | | - ] |
100 | | - } |
101 | | - ], |
| 91 | + "outputs": [], |
102 | 92 | "source": [ |
103 | 93 | "from getpass import getpass\n", |
104 | 94 | "import os\n", |
105 | 95 | "\n", |
106 | 96 | "if not os.environ.get(\"OPENAI_API_KEY\"):\n", |
107 | 97 | " os.environ[\"OPENAI_API_KEY\"] = getpass(\"Enter your OpenAI API key:\")\n", |
108 | | - "if not os.environ.get(\"SERPERDEV_API_KEY\"): # skip this if you want to use DuckDuckGo instead\n", |
109 | | - " os.environ[\"SERPERDEV_API_KEY\"] = getpass(\"Enter your SERPER API key:\")\n", |
110 | 98 | "if not os.environ.get(\"NOTION_API_KEY\"):\n", |
111 | 99 | " os.environ[\"NOTION_API_KEY\"] = getpass(\"Enter your NOTION API key:\")" |
112 | 100 | ] |
|
121 | 109 | "\n", |
122 | 110 | "Let's set up the tools for your research agent. Its job is to gather information on a topic, and in this tutorial, it will use just two sources: the whole web and Wikipedia. In other scenarios, it could also connect to a retrieval or RAG pipeline linked to a document store.\n", |
123 | 111 | "\n", |
124 | | - "You'll create two [`ComponentTool`s](https://docs.haystack.deepset.ai/docs/componenttool) using the `SerperDevWebSearch` component: one for general web search, and one limited to Wikipedia by setting `allowed_domains`.\n", |
| 112 | + "You'll create two [`ComponentTool`s](https://docs.haystack.deepset.ai/docs/componenttool) using the [DuckduckgoApiWebSearch](https://haystack.deepset.ai/integrations/duckduckgo-api-websearch) component: one for general web search, and one limited to Wikipedia by setting `allowed_domain`.\n", |
125 | 113 | "\n", |
126 | | - "One more step before wrapping up: `SerperDevWebSearch` returns a list of documents, but the `Agent` works best when tools return a single string in this setting. To handle that, define a `doc_to_string` function that converts the Document list into a string. This function, used as the `outputs_to_string` handler, can also add custom elements like filenames or links before returning the output.\n", |
127 | | - "\n" |
| 114 | + "One more step before wrapping up: `DuckduckgoApiWebSearch` returns a list of documents, but the `Agent` works best when tools return a single string in this setting. To handle that, define a `doc_to_string` function that converts the Document list into a string. This function, used as the `outputs_to_string` handler, can also add custom elements like filenames or links before returning the output." |
128 | 115 | ] |
129 | 116 | }, |
130 | 117 | { |
131 | 118 | "cell_type": "code", |
132 | | - "execution_count": 58, |
| 119 | + "execution_count": null, |
133 | 120 | "metadata": { |
134 | 121 | "id": "YRREx0yzRaE2" |
135 | 122 | }, |
136 | 123 | "outputs": [], |
137 | 124 | "source": [ |
138 | 125 | "from haystack.tools import ComponentTool\n", |
139 | | - "from haystack.components.websearch import SerperDevWebSearch\n", |
| 126 | + "from haystack.components.websearch import DuckduckgoApiWebSearch\n", |
140 | 127 | "\n", |
141 | 128 | "\n", |
142 | 129 | "def doc_to_string(documents) -> str:\n", |
|
154 | 141 | "\n", |
155 | 142 | "\n", |
156 | 143 | "web_search = ComponentTool(\n", |
157 | | - " component=SerperDevWebSearch(top_k=5),\n", |
| 144 | + " component=DuckduckgoApiWebSearch(top_k=5, backend=\"lite\"),\n", |
158 | 145 | " name=\"web_search\",\n", |
159 | 146 | " description=\"Search the web\",\n", |
160 | 147 | " outputs_to_string={\"source\": \"documents\", \"handler\": doc_to_string},\n", |
161 | 148 | ")\n", |
162 | 149 | "\n", |
163 | 150 | "wiki_search = ComponentTool(\n", |
164 | | - " component=SerperDevWebSearch(top_k=5, allowed_domains=[\"https://www.wikipedia.org/\", \"https://en.wikipedia.org\"]),\n", |
| 151 | + " component=DuckduckgoApiWebSearch(top_k=5, backend=\"lite\", allowed_domain=\"https://en.wikipedia.org\"),\n", |
165 | 152 | " name=\"wiki_search\",\n", |
166 | 153 | " description=\"Search Wikipedia\",\n", |
167 | 154 | " outputs_to_string={\"source\": \"documents\", \"handler\": doc_to_string},\n", |
|
174 | 161 | "id": "C5qn6kyJ2hSX" |
175 | 162 | }, |
176 | 163 | "source": [ |
177 | | - "Alternatively, you can use [DuckDuckGo](https://haystack.deepset.ai/integrations/duckduckgo-api-websearch) as your websearch component for these tools. Just keep in mind that it's more prone to hitting rate limits as it's completely free." |
| 164 | + "If you're hitting rate limits with DuckDuckGo, you can use [`SerperDevWebSearch`](https://docs.haystack.deepset.ai/docs/serperdevwebsearch) as your websearch component for these tools. You need to enter the free [Serper API Key](https://serper.dev/api-key) to use `SerperDevWebSearch`. " |
178 | 165 | ] |
179 | 166 | }, |
180 | 167 | { |
|
185 | 172 | }, |
186 | 173 | "outputs": [], |
187 | 174 | "source": [ |
188 | | - "# !pip install duckduckgo-api-haystack\n", |
189 | | - "#\n", |
190 | | - "# from duckduckgo_api_haystack import DuckduckgoApiWebSearch\n", |
| 175 | + "# from getpass import getpass\n", |
| 176 | + "# import os\n", |
| 177 | + "\n", |
| 178 | + "# from haystack.components.websearch import SerperDevWebSearch\n", |
191 | 179 | "# from haystack.tools import ComponentTool\n", |
192 | | - "#\n", |
| 180 | + "\n", |
| 181 | + "# if not os.environ.get(\"SERPERDEV_API_KEY\"):\n", |
| 182 | + "# os.environ[\"SERPERDEV_API_KEY\"] = getpass(\"Enter your SERPER API key:\")\n", |
| 183 | + "\n", |
193 | 184 | "# web_search = ComponentTool(\n", |
194 | | - "# component=DuckduckgoApiWebSearch(top_k=5, backend=\"lite\"),\n", |
| 185 | + "# component=SerperDevWebSearch(top_k=5),\n", |
195 | 186 | "# name=\"web_search\",\n", |
196 | 187 | "# description=\"Search the web\",\n", |
197 | | - "# outputs_to_string={\"source\": \"documents\", \"handler\": doc_to_string}\n", |
| 188 | + "# outputs_to_string={\"source\": \"documents\", \"handler\": doc_to_string},\n", |
198 | 189 | "# )\n", |
199 | 190 | "\n", |
200 | 191 | "# wiki_search = ComponentTool(\n", |
201 | | - "# component=DuckduckgoApiWebSearch(top_k=5, backend=\"lite\", allowed_domain=\"https://www.wikipedia.org/\"),\n", |
| 192 | + "# component=SerperDevWebSearch(top_k=5, allowed_domains=[\"https://www.wikipedia.org/\", \"https://en.wikipedia.org\"]),\n", |
202 | 193 | "# name=\"wiki_search\",\n", |
203 | 194 | "# description=\"Search Wikipedia\",\n", |
204 | | - "# outputs_to_string={\"source\": \"documents\", \"handler\": doc_to_string}\n", |
| 195 | + "# outputs_to_string={\"source\": \"documents\", \"handler\": doc_to_string},\n", |
205 | 196 | "# )" |
206 | 197 | ] |
207 | 198 | }, |
|
655 | 646 | }, |
656 | 647 | { |
657 | 648 | "cell_type": "code", |
658 | | - "execution_count": 51, |
| 649 | + "execution_count": null, |
659 | 650 | "metadata": { |
660 | 651 | "colab": { |
661 | 652 | "base_uri": "https://localhost:8080/" |
|
687 | 678 | " messages=[\n", |
688 | 679 | " ChatMessage.from_user(\n", |
689 | 680 | " \"\"\"\n", |
690 | | - "Save the this text on Notion:\n", |
| 681 | + "Save this text on Notion:\n", |
691 | 682 | "\n", |
692 | 683 | "Florence Nightingale is widely recognized as the founder of modern nursing, and her contributions significantly transformed the field.\n", |
693 | 684 | "Florence Nightingale's legacy endures, as she set professional standards that have shaped nursing into a respected and essential component of the healthcare system. Her influence is still felt in nursing education and practice today.\n", |
|
0 commit comments