|
7 | 7 | "# Talk with your Database\n", |
8 | 8 | "\n", |
9 | 9 | "\n", |
10 | | - "Databases are an inavitable part of every company infrastructure. Chatbot capable of interacting with database can free up teams' time by handling novel user queries.\n", |
| 10 | + "Databases are an ineavitable part of every company's infrastructure. Chatbots capable of interacting with databases can free up teams' time by handling novel user queries.\n", |
11 | 11 | "\n", |
12 | 12 | "In this tutorial, we will build an agent with access to the database tool, being able to ground its answers with data stored there. Along the way we will create:\n", |
13 | 13 | "1. Custom LangChain tool.\n", |
14 | 14 | "2. Assistant agent with access to database tool.\n", |
15 | | - "3. Tool agent, specialized in executing calls returned by assistant.\n", |
| 15 | + "3. Tool agent, specialized in executing calls returned by an assistant.\n", |
16 | 16 | "4. Graph of connected agents.\n", |
17 | 17 | "5. Persistent storage component.\n", |
18 | 18 | "\n", |
|
47 | 47 | "import getpass\n", |
48 | 48 | "import os\n", |
49 | 49 | "\n", |
| 50 | + "\n", |
50 | 51 | "def _set_env(var: str):\n", |
51 | 52 | " if not os.environ.get(var):\n", |
52 | 53 | " os.environ[var] = getpass.getpass(f\"{var}: \")\n", |
53 | 54 | "\n", |
| 55 | + "\n", |
54 | 56 | "_set_env(\"OPENAI_API_KEY\")" |
55 | 57 | ] |
56 | 58 | }, |
|
60 | 62 | "source": [ |
61 | 63 | "### Populate the database\n", |
62 | 64 | "\n", |
63 | | - "Here, we just fill a dummy database containing some fixtional HR information." |
| 65 | + "Here, we just fill a dummy database containing some fictional HR information." |
64 | 66 | ] |
65 | 67 | }, |
66 | 68 | { |
|
73 | 75 | "from sqlalchemy import create_engine, text\n", |
74 | 76 | "\n", |
75 | 77 | "print(\"Downloading the HR database\")\n", |
76 | | - "request.urlretrieve('https://drive.google.com/uc?export=download&id=1zo3j8x7qH8opTKyQ9qFgRpS3yqU6uTRs', 'recruitment.db')\n", |
| 78 | + "request.urlretrieve(\n", |
| 79 | + " \"https://drive.google.com/uc?export=download&id=1zo3j8x7qH8opTKyQ9qFgRpS3yqU6uTRs\", \"recruitment.db\"\n", |
| 80 | + ")\n", |
77 | 81 | "print(\"Database downloaded\")\n", |
78 | 82 | "print(\"Creating the database\")\n", |
79 | 83 | "\n", |
|
93 | 97 | "source": [ |
94 | 98 | "## Database Tool\n", |
95 | 99 | "\n", |
96 | | - "Next, define our [assistant database tool](https://python.langchain.com/v0.1/docs/modules/tools/) to help it answer any questions concerning HR. Under the hood it uses [db-ally](https://db-ally.deepsense.ai/) database framework. " |
| 100 | + "Next, define our [assistant database tool](https://python.langchain.com/v0.1/docs/modules/tools/) to help it answer any questions concerning HR. Under the hood, it uses [db-ally](https://github.com/deepsense-ai/db-ally) database framework. " |
97 | 101 | ] |
98 | 102 | }, |
99 | 103 | { |
|
115 | 119 | "\n", |
116 | 120 | "nest_asyncio.apply()\n", |
117 | 121 | "\n", |
| 122 | + "\n", |
118 | 123 | "class DatabaseQuery(BaseModel):\n", |
119 | 124 | " query: str = Field(description=\"should be a query to the database in the natural language.\")\n", |
120 | 125 | "\n", |
|
125 | 130 | " collection: Collection\n", |
126 | 131 | " args_schema: Type[BaseModel] = DatabaseQuery\n", |
127 | 132 | "\n", |
128 | | - "\n", |
129 | | - " def _run(\n", |
130 | | - " self, query: str, run_manager: Optional[CallbackManagerForToolRun] = None\n", |
131 | | - " ) -> str:\n", |
| 133 | + " def _run(self, query: str, run_manager: Optional[CallbackManagerForToolRun] = None) -> str:\n", |
132 | 134 | " \"\"\"Use the tool synchronously.\"\"\"\n", |
133 | 135 | " try:\n", |
134 | 136 | " result = asyncio.run(self.collection.ask(query))\n", |
|
145 | 147 | "cell_type": "markdown", |
146 | 148 | "metadata": {}, |
147 | 149 | "source": [ |
148 | | - "Now, let's test our tool. If everything goes correctly you should see `[{'COUNT(*)': 10}]`. In case it doesn't first make sure that provided `OPENAI KEY` is correct. If it didn't help neither, [let the db-ally team now by creating an issue](https://github.com/deepsense-ai/db-ally/issues)." |
| 150 | + "Now, let's test our tool. If everything goes correctly, you should see `[{'COUNT(*)': 10}]`. In case it doesn't, first make sure that provided `OPENAI KEY` is correct." |
149 | 151 | ] |
150 | 152 | }, |
151 | 153 | { |
|
195 | 197 | "\n", |
196 | 198 | "from langgraph.graph.message import AnyMessage, add_messages\n", |
197 | 199 | "\n", |
| 200 | + "\n", |
198 | 201 | "class State(TypedDict):\n", |
199 | 202 | " messages: Annotated[list[AnyMessage], add_messages]" |
200 | 203 | ] |
|
205 | 208 | "source": [ |
206 | 209 | "### Assistant Agent\n", |
207 | 210 | "\n", |
208 | | - "Next, define the assistant agent. This simply takes the graph state, and then calls an LLM for it to predict the best response. The most important thing is that we give the access to use the database tool to our assistant." |
| 211 | + "Next, define the assistant agent. This simply takes the graph state and then calls an LLM for it to predict the best response. The most important thing is that we give access to the database tool to our assistant." |
209 | 212 | ] |
210 | 213 | }, |
211 | 214 | { |
|
233 | 236 | " (\n", |
234 | 237 | " \"system\",\n", |
235 | 238 | " \"You are a helpful talent aquisition assistant \"\n", |
236 | | - " \" Use the provided tools to search for candidates, job offers, and other information to assist the user's queries. \"\n", |
| 239 | + " \" Use the provided tools to search for candidates, job offers, and other information to assist the user's queries. \",\n", |
237 | 240 | " ),\n", |
238 | 241 | " (\"placeholder\", \"{messages}\"),\n", |
239 | 242 | " ]\n", |
|
259 | 262 | "outputs": [], |
260 | 263 | "source": [ |
261 | 264 | "response = assistant_agent({\"messages\": [\"Do we have any software engineers?\"]})\n", |
262 | | - "response['messages'].pretty_print()" |
| 265 | + "response[\"messages\"].pretty_print()" |
263 | 266 | ] |
264 | 267 | }, |
265 | 268 | { |
266 | 269 | "cell_type": "markdown", |
267 | 270 | "metadata": {}, |
268 | 271 | "source": [ |
269 | | - "But, assistant don't now how to execute the tools. This is why we need to finish our system by connecting all building blocks into the graph" |
| 272 | + "But, assistant doesn't know how to execute the tools. This is why we need to finish our system by connecting all building blocks to the graph" |
270 | 273 | ] |
271 | 274 | }, |
272 | 275 | { |
|
275 | 278 | "source": [ |
276 | 279 | "### Define Graph\n", |
277 | 280 | "\n", |
278 | | - "Here we connect our previously generated agent by using [StateGraph](https://langchain-ai.github.io/langgraph/reference/graphs/#langgraph.graph.StateGraph), [ToolNode](https://langchain-ai.github.io/langgraph/reference/prebuilt/#toolnode), [persistent memory](https://langchain-ai.github.io/langgraph/how-tos/persistence/) to build our final application" |
| 281 | + "Here we connect our previously generated agent by using [StateGraph](https://langchain-ai.github.io/langgraph/reference/graphs/#langgraph.graph.StateGraph), [ToolNode](https://langchain-ai.github.io/langgraph/reference/prebuilt/#toolnode), and [persistent memory](https://langchain-ai.github.io/langgraph/how-tos/persistence/) to build our final application" |
279 | 282 | ] |
280 | 283 | }, |
281 | 284 | { |
|
305 | 308 | ")\n", |
306 | 309 | "\n", |
307 | 310 | "memory = SqliteSaver.from_conn_string(\":memory:\")\n", |
308 | | - "graph = builder.compile(checkpointer=memory)\n" |
| 311 | + "graph = builder.compile(checkpointer=memory)" |
309 | 312 | ] |
310 | 313 | }, |
311 | 314 | { |
|
339 | 342 | "}\n", |
340 | 343 | "\n", |
341 | 344 | "for question in tutorial_questions:\n", |
342 | | - " events = graph.stream(\n", |
343 | | - " {\"messages\": (\"user\", question)}, graph_config, stream_mode=\"values\"\n", |
344 | | - " )\n", |
| 345 | + " events = graph.stream({\"messages\": (\"user\", question)}, graph_config, stream_mode=\"values\")\n", |
345 | 346 | " for event in events:\n", |
346 | 347 | " event[\"messages\"][-1].pretty_print()" |
347 | 348 | ] |
|
352 | 353 | "source": [ |
353 | 354 | "Congratulations! Together, we built an agentic system capable of querying the database. Good job!\n", |
354 | 355 | "\n", |
355 | | - "The full code that you can just copy and paste to use is available in langgraph_tut.py" |
| 356 | + "The full code that you can just copy and paste to use is available in langgraph_tools.py" |
356 | 357 | ] |
| 358 | + }, |
| 359 | + { |
| 360 | + "cell_type": "markdown", |
| 361 | + "metadata": {}, |
| 362 | + "source": [] |
357 | 363 | } |
358 | 364 | ], |
359 | 365 | "metadata": { |
|
0 commit comments