mirror of
https://github.com/langchain-ai/langgraph.git
synced 2026-08-17 21:25:46 +02:00
Add cleaned up csbot chatbot example (#971)
This commit is contained in:
@@ -2,10 +2,739 @@
|
||||
"cells": [
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "4c37bb65-6e2c-42e4-bfa7-9df10e2652a0",
|
||||
"id": "d9d1a28b-c2a1-4246-b1c2-c58d6938f798",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"This example has moved! Check out the [Customer Support Tutorial](../customer-support/customer-support.ipynb) for more information."
|
||||
"# Customer Support\n",
|
||||
"\n",
|
||||
"Here, we show an example of building a customer support chatbot.\n",
|
||||
"\n",
|
||||
"This customer support chatbot interacts with SQL database to answer questions.\n",
|
||||
"We will use a mock SQL database to get started: the [Chinook](https://www.sqlitetutorial.net/sqlite-sample-database/) database.\n",
|
||||
"This database is about sales from a music store: what songs and album exists, customer orders, things like that.\n",
|
||||
"\n",
|
||||
"This chatbot has two different states: \n",
|
||||
"1. Music: the user can inquire about different songs and albums present in the store\n",
|
||||
"2. Account: the user can ask questions about their account\n",
|
||||
"\n",
|
||||
"Under the hood, this is handled by two separate agents. \n",
|
||||
"Each has a specific prompt and tools related to their objective. \n",
|
||||
"There is also a generic agent who is responsible for routing between these two agents as needed.\n",
|
||||
"\n",
|
||||
"Note: This is a very simple example! For a more complete tutorial on building a customer support bot, check out the [Customer Support Tutorial](../customer-support/customer-support.ipynb) for more information."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "35abc013-2613-4a49-a806-939dcf13ccf3",
|
||||
"metadata": {
|
||||
"scrolled": true
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"%%capture --no-stderr\n",
|
||||
"%pip install -U langgraph langchain-community langchain-openai scikit-learn"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "9431e7f1-07fa-49d9-ac45-29613703dcc1",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## Load the data"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 1,
|
||||
"id": "3d1ef253-6b0c-4481-868c-e1fe84f2c8ff",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"import requests\n",
|
||||
"\n",
|
||||
"url = \"https://storage.googleapis.com/benchmarks-artifacts/chinook/Chinook.db\"\n",
|
||||
"response = requests.get(url)\n",
|
||||
"\n",
|
||||
"with open(\"Chinook.db\", \"wb\") as file:\n",
|
||||
" file.write(response.content)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 2,
|
||||
"id": "61f7ef9c",
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
"text/plain": [
|
||||
"['Album',\n",
|
||||
" 'Artist',\n",
|
||||
" 'Customer',\n",
|
||||
" 'Employee',\n",
|
||||
" 'Genre',\n",
|
||||
" 'Invoice',\n",
|
||||
" 'InvoiceLine',\n",
|
||||
" 'MediaType',\n",
|
||||
" 'Playlist',\n",
|
||||
" 'PlaylistTrack',\n",
|
||||
" 'Track']"
|
||||
]
|
||||
},
|
||||
"execution_count": 2,
|
||||
"metadata": {},
|
||||
"output_type": "execute_result"
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"from langchain_community.utilities import SQLDatabase\n",
|
||||
"\n",
|
||||
"db = SQLDatabase.from_uri(\"sqlite:///Chinook.db\")\n",
|
||||
"db.get_usable_table_names()"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "1cf668e4-8cb4-4de1-bc5e-c90284bf74bc",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## Load an LLM\n",
|
||||
"\n",
|
||||
"We will load a language model to use.\n",
|
||||
"For this demo we will use OpenAI."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 3,
|
||||
"id": "d9ea4e80-30e6-4d46-b480-35f0be2fb055",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"from langchain_openai import ChatOpenAI\n",
|
||||
"\n",
|
||||
"model = ChatOpenAI(temperature=0, streaming=True, model=\"gpt-4o\")"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "73907422-7e05-431e-b06d-256c9ec1f6f6",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## Load Other Modules\n",
|
||||
"\n",
|
||||
"Load other modules we will use.\n",
|
||||
"\n",
|
||||
"All of the tools our agents will use will be custom tools. As such, we will use the `@tool` decorator to create custom tools.\n",
|
||||
"\n",
|
||||
"We will pass in messages to the agent, so we load `HumanMessage` and `SystemMessage`"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 4,
|
||||
"id": "ea958e9f-ab1f-49b5-bd85-16332055297c",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"from langchain_core.messages import HumanMessage, SystemMessage"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "35271d4d-2a1c-41be-9359-a3a7c3fed3d9",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## Define the Customer Agent\n",
|
||||
"\n",
|
||||
"This agent is responsible for looking up customer information.\n",
|
||||
"It will have a specific prompt as well a specific tool to look up information about that customer (after asking for their user id)."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 5,
|
||||
"id": "975b039a",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"# This tool is given to the agent to look up information about a customer\n",
|
||||
"def get_customer_info(customer_id: int):\n",
|
||||
" \"\"\"Look up customer info given their ID. ALWAYS make sure you have the customer ID before invoking this.\"\"\"\n",
|
||||
" return db.run(f\"SELECT * FROM Customer WHERE CustomerID = {customer_id};\")"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 6,
|
||||
"id": "1d5fa446",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"customer_prompt = \"\"\"Your job is to help a user update their profile.\n",
|
||||
"\n",
|
||||
"You only have certain tools you can use. These tools require specific input. If you don't know the required input, then ask the user for it.\n",
|
||||
"\n",
|
||||
"If you are unable to help the user, you can \"\"\"\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"def get_customer_messages(messages):\n",
|
||||
" return [SystemMessage(content=customer_prompt)] + messages\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"customer_chain = get_customer_messages | model.bind_tools([get_customer_info])"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "904a9485-3857-458e-8b9d-33bc33842bc9",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## Define the Music Agent\n",
|
||||
"\n",
|
||||
"This agent is responsible for figuring out information about music. To do that, we will create a prompt and various tools for looking up information about music\n",
|
||||
"\n",
|
||||
"First, we will create indexes for looking up artists and track names.\n",
|
||||
"This will allow us to look up artists and tracks without having to spell their names exactly right."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 7,
|
||||
"id": "a8604a3b-b484-4b2b-a914-4236cb98c524",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"from langchain_community.vectorstores import SKLearnVectorStore\n",
|
||||
"from langchain_openai import OpenAIEmbeddings\n",
|
||||
"\n",
|
||||
"artists = db._execute(\"select * from Artist\")\n",
|
||||
"songs = db._execute(\"select * from Track\")\n",
|
||||
"artist_retriever = SKLearnVectorStore.from_texts(\n",
|
||||
" [a[\"Name\"] for a in artists], OpenAIEmbeddings(), metadatas=artists\n",
|
||||
").as_retriever()\n",
|
||||
"song_retriever = SKLearnVectorStore.from_texts(\n",
|
||||
" [a[\"Name\"] for a in songs], OpenAIEmbeddings(), metadatas=songs\n",
|
||||
").as_retriever()"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "ac7eb264-c572-4925-ad55-a1d52a18b1c0",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"First, let's create a tool for getting albums by artist."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 8,
|
||||
"id": "0a2a2b74",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"def get_albums_by_artist(artist):\n",
|
||||
" \"\"\"Get albums by an artist (or similar artists).\"\"\"\n",
|
||||
" docs = artist_retriever.get_relevant_documents(artist)\n",
|
||||
" artist_ids = \", \".join([str(d.metadata[\"ArtistId\"]) for d in docs])\n",
|
||||
" return db.run(\n",
|
||||
" f\"SELECT Title, Name FROM Album LEFT JOIN Artist ON Album.ArtistId = Artist.ArtistId WHERE Album.ArtistId in ({artist_ids});\",\n",
|
||||
" include_columns=True,\n",
|
||||
" )"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "45e85066-f2fc-490e-992d-cd66c9cd6486",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"Next, lets create a tool for getting tracks by an artist"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 9,
|
||||
"id": "da533f50",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"def get_tracks_by_artist(artist):\n",
|
||||
" \"\"\"Get songs by an artist (or similar artists).\"\"\"\n",
|
||||
" docs = artist_retriever.invoke(artist)\n",
|
||||
" artist_ids = \", \".join([str(d.metadata[\"ArtistId\"]) for d in docs])\n",
|
||||
" return db.run(\n",
|
||||
" f\"SELECT Track.Name as SongName, Artist.Name as ArtistName FROM Album LEFT JOIN Artist ON Album.ArtistId = Artist.ArtistId LEFT JOIN Track ON Track.AlbumId = Album.AlbumId WHERE Album.ArtistId in ({artist_ids});\",\n",
|
||||
" include_columns=True,\n",
|
||||
" )"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "bb0e50ab-b059-427c-924b-f8072d8db23c",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"Finally, let's create a tool for looking up songs by their name."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 10,
|
||||
"id": "b3c07010",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"def check_for_songs(song_title):\n",
|
||||
" \"\"\"Check if a song exists by its name.\"\"\"\n",
|
||||
" return song_retriever.invoke(song_title)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "88388ff8-38b5-4e4e-a24d-de8c3670bd2b",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"Create the chain to call the relevant tools"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 11,
|
||||
"id": "72a14d5c",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"song_system_message = \"\"\"Your job is to help a customer find any songs they are looking for. \n",
|
||||
"\n",
|
||||
"You only have certain tools you can use. If a customer asks you to look something up that you don't know how, politely tell them what you can help with.\n",
|
||||
"\n",
|
||||
"When looking up artists and songs, sometimes the artist/song will not be found. In that case, the tools will return information \\\n",
|
||||
"on similar songs and artists. This is intentional, it is not the tool messing up.\"\"\"\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"def get_song_messages(messages):\n",
|
||||
" return [SystemMessage(content=song_system_message)] + messages\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"song_recc_chain = get_song_messages | model.bind_tools(\n",
|
||||
" [get_albums_by_artist, get_tracks_by_artist, check_for_songs]\n",
|
||||
")"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 12,
|
||||
"id": "cff15eb0-62c7-451d-a5f9-4576b24c879e",
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
"text/plain": [
|
||||
"AIMessage(content='', additional_kwargs={'tool_calls': [{'index': 0, 'id': 'call_aXa9rSRXvTCJabrMY6AqkSV8', 'function': {'arguments': '{\"artist\":\"Amy Winehouse\"}', 'name': 'get_tracks_by_artist'}, 'type': 'function'}]}, response_metadata={'finish_reason': 'tool_calls', 'model_name': 'gpt-4o-2024-05-13', 'system_fingerprint': 'fp_ce0793330f'}, id='run-60633269-fd02-43e8-b434-28e3b8b69fb1-0', tool_calls=[{'name': 'get_tracks_by_artist', 'args': {'artist': 'Amy Winehouse'}, 'id': 'call_aXa9rSRXvTCJabrMY6AqkSV8'}])"
|
||||
]
|
||||
},
|
||||
"execution_count": 12,
|
||||
"metadata": {},
|
||||
"output_type": "execute_result"
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"msgs = [HumanMessage(content=\"hi! can you help me find songs by amy whinehouse?\")]\n",
|
||||
"song_recc_chain.invoke(msgs)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "0a42c293-0816-4f3c-b4a3-5b9f3a0665d1",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## Define the Generic Agent\n",
|
||||
"\n",
|
||||
"We now define a generic agent that is responsible for handling initial inquiries and routing to the right sub agent."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 13,
|
||||
"id": "73e74268",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"from langchain_core.messages import AIMessage, HumanMessage, SystemMessage\n",
|
||||
"from langchain_core.pydantic_v1 import BaseModel, Field\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"class Router(BaseModel):\n",
|
||||
" \"\"\"Call this if you are able to route the user to the appropriate representative.\"\"\"\n",
|
||||
"\n",
|
||||
" choice: str = Field(description=\"should be one of: music, customer\")\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"system_message = \"\"\"Your job is to help as a customer service representative for a music store.\n",
|
||||
"\n",
|
||||
"You should interact politely with customers to try to figure out how you can help. You can help in a few ways:\n",
|
||||
"\n",
|
||||
"- Updating user information: if a customer wants to update the information in the user database. Call the router with `customer`\n",
|
||||
"- Recommending music: if a customer wants to find some music or information about music. Call the router with `music`\n",
|
||||
"\n",
|
||||
"If the user is asking or wants to ask about updating or accessing their information, send them to that route.\n",
|
||||
"If the user is asking or wants to ask about music, send them to that route.\n",
|
||||
"Otherwise, respond.\"\"\"\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"def get_messages(messages):\n",
|
||||
" return [SystemMessage(content=system_message)] + messages"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 14,
|
||||
"id": "ddf27314",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"chain = get_messages | model.bind_tools([Router])"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 15,
|
||||
"id": "3c896f34",
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
"text/plain": [
|
||||
"AIMessage(content='', additional_kwargs={'tool_calls': [{'index': 0, 'id': 'call_0aaFPPCWDiAoPyXQX2PS8TcJ', 'function': {'arguments': '{\"choice\":\"music\"}', 'name': 'Router'}, 'type': 'function'}]}, response_metadata={'finish_reason': 'tool_calls', 'model_name': 'gpt-4o-2024-05-13', 'system_fingerprint': 'fp_ce0793330f'}, id='run-73d51d75-b7c5-49fe-b558-105ede7c75d1-0', tool_calls=[{'name': 'Router', 'args': {'choice': 'music'}, 'id': 'call_0aaFPPCWDiAoPyXQX2PS8TcJ'}])"
|
||||
]
|
||||
},
|
||||
"execution_count": 15,
|
||||
"metadata": {},
|
||||
"output_type": "execute_result"
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"msgs = [HumanMessage(content=\"hi! can you help me find a good song?\")]\n",
|
||||
"chain.invoke(msgs)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 16,
|
||||
"id": "40d86f59",
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
"text/plain": [
|
||||
"AIMessage(content='', additional_kwargs={'tool_calls': [{'index': 0, 'id': 'call_Okla9DfMHIPs5TslS6KPaoBA', 'function': {'arguments': '{\"choice\":\"customer\"}', 'name': 'Router'}, 'type': 'function'}]}, response_metadata={'finish_reason': 'tool_calls', 'model_name': 'gpt-4o-2024-05-13', 'system_fingerprint': 'fp_4008e3b719'}, id='run-0d82d4f8-f4eb-4b16-add8-3e7fdffd6332-0', tool_calls=[{'name': 'Router', 'args': {'choice': 'customer'}, 'id': 'call_Okla9DfMHIPs5TslS6KPaoBA'}])"
|
||||
]
|
||||
},
|
||||
"execution_count": 16,
|
||||
"metadata": {},
|
||||
"output_type": "execute_result"
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"msgs = [HumanMessage(content=\"hi! what's the email you have for me?\")]\n",
|
||||
"chain.invoke(msgs)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 17,
|
||||
"id": "bd6ddd8b-7500-46a7-811d-3bcb937bda51",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"from langchain_core.messages import AIMessage\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"def add_name(message, name):\n",
|
||||
" _dict = message.dict()\n",
|
||||
" _dict[\"name\"] = name\n",
|
||||
" return AIMessage(**_dict)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 18,
|
||||
"id": "27494de5-8345-4c23-bc0e-81e0dd5d47d8",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"import json\n",
|
||||
"\n",
|
||||
"from langgraph.graph import END\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"def _get_last_ai_message(messages):\n",
|
||||
" for m in messages[::-1]:\n",
|
||||
" if isinstance(m, AIMessage):\n",
|
||||
" return m\n",
|
||||
" return None\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"def _is_tool_call(msg):\n",
|
||||
" return hasattr(msg, \"additional_kwargs\") and \"tool_calls\" in msg.additional_kwargs\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"def _route(messages):\n",
|
||||
" last_message = messages[-1]\n",
|
||||
" if isinstance(last_message, AIMessage):\n",
|
||||
" if not last_message.tool_calls:\n",
|
||||
" return END\n",
|
||||
" else:\n",
|
||||
" if last_message.name == \"general\":\n",
|
||||
" if len(last_message.tool_calls) > 1:\n",
|
||||
" raise ValueError(\"Too many tools\")\n",
|
||||
" return last_message.tool_calls[0][\"args\"][\"choice\"]\n",
|
||||
" else:\n",
|
||||
" return \"tools\"\n",
|
||||
" last_m = _get_last_ai_message(messages)\n",
|
||||
" if last_m is None:\n",
|
||||
" return \"general\"\n",
|
||||
" if last_m.name == \"music\":\n",
|
||||
" return \"music\"\n",
|
||||
" elif last_m.name == \"customer\":\n",
|
||||
" return \"customer\"\n",
|
||||
" else:\n",
|
||||
" return \"general\""
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 19,
|
||||
"id": "8aec704a-46fe-4fb3-bdee-11c3bbffc370",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"from langgraph.prebuilt import ToolNode\n",
|
||||
"\n",
|
||||
"tools = [get_albums_by_artist, get_tracks_by_artist, check_for_songs, get_customer_info]\n",
|
||||
"tool_node = ToolNode(tools)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 20,
|
||||
"id": "4d5b75c6-73e0-4922-a765-a15be63f869e",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"def _filter_out_routes(messages):\n",
|
||||
" ms = []\n",
|
||||
" for m in messages:\n",
|
||||
" if _is_tool_call(m):\n",
|
||||
" if m.name == \"general\":\n",
|
||||
" continue\n",
|
||||
" ms.append(m)\n",
|
||||
" return ms"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 21,
|
||||
"id": "fd4dbf98-dbb3-411a-bad6-2bb334072aaf",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"from functools import partial\n",
|
||||
"\n",
|
||||
"general_node = _filter_out_routes | chain | partial(add_name, name=\"general\")\n",
|
||||
"music_node = _filter_out_routes | song_recc_chain | partial(add_name, name=\"music\")\n",
|
||||
"customer_node = _filter_out_routes | customer_chain | partial(add_name, name=\"customer\")"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 22,
|
||||
"id": "dcade924",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"from langgraph.checkpoint.sqlite import SqliteSaver\n",
|
||||
"\n",
|
||||
"from langgraph.graph import MessageGraph\n",
|
||||
"\n",
|
||||
"memory = SqliteSaver.from_conn_string(\":memory:\")\n",
|
||||
"graph = MessageGraph()\n",
|
||||
"nodes = {\n",
|
||||
" \"general\": \"general\",\n",
|
||||
" \"music\": \"music\",\n",
|
||||
" END: END,\n",
|
||||
" \"tools\": \"tools\",\n",
|
||||
" \"customer\": \"customer\",\n",
|
||||
"}\n",
|
||||
"# Define a new graph\n",
|
||||
"workflow = MessageGraph()\n",
|
||||
"workflow.add_node(\"general\", general_node)\n",
|
||||
"workflow.add_node(\"music\", music_node)\n",
|
||||
"workflow.add_node(\"customer\", customer_node)\n",
|
||||
"workflow.add_node(\"tools\", tool_node)\n",
|
||||
"workflow.add_conditional_edges(\"general\", _route, nodes)\n",
|
||||
"workflow.add_conditional_edges(\"tools\", _route, nodes)\n",
|
||||
"workflow.add_conditional_edges(\"music\", _route, nodes)\n",
|
||||
"workflow.add_conditional_edges(\"customer\", _route, nodes)\n",
|
||||
"workflow.set_conditional_entry_point(_route, nodes)\n",
|
||||
"graph = workflow.compile()"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 23,
|
||||
"id": "ac65d6d2",
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdin",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"User (q/Q to quit): what music do you have?\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"Output from node 'general':\n",
|
||||
"---\n",
|
||||
"content='' additional_kwargs={'tool_calls': [{'index': 0, 'id': 'call_iste6NuKvZou8O9QudOectOU', 'function': {'arguments': '{\"choice\":\"music\"}', 'name': 'Router'}, 'type': 'function'}]} response_metadata={'finish_reason': 'tool_calls', 'model_name': 'gpt-4o-2024-05-13', 'system_fingerprint': 'fp_4008e3b719'} name='general' id='run-9eb940ff-6592-43ae-aa34-22c3d630ac65-0' tool_calls=[{'name': 'Router', 'args': {'choice': 'music'}, 'id': 'call_iste6NuKvZou8O9QudOectOU'}]\n",
|
||||
"\n",
|
||||
"---\n",
|
||||
"\n",
|
||||
"Output from node 'music':\n",
|
||||
"---\n",
|
||||
"content=\"I can help you find songs and albums by specific artists, or check if a particular song exists. Just let me know the name of the artist or song you're interested in!\" response_metadata={'finish_reason': 'stop', 'model_name': 'gpt-4o-2024-05-13', 'system_fingerprint': 'fp_4008e3b719'} name='music' id='run-91f560e7-ffa5-437f-afda-27490cbd1efe-0'\n",
|
||||
"\n",
|
||||
"---\n",
|
||||
"\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "stdin",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"User (q/Q to quit): how about shakira?\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"Output from node 'general':\n",
|
||||
"---\n",
|
||||
"content='' additional_kwargs={'tool_calls': [{'index': 0, 'id': 'call_fH4oKyA3U9aQy3p31MYXv2VP', 'function': {'arguments': '{\"choice\":\"music\"}', 'name': 'Router'}, 'type': 'function'}]} response_metadata={'finish_reason': 'tool_calls', 'model_name': 'gpt-4o-2024-05-13', 'system_fingerprint': 'fp_d576307f90'} name='general' id='run-6f2eee09-9e3e-4011-a045-196cc5baa1ee-0' tool_calls=[{'name': 'Router', 'args': {'choice': 'music'}, 'id': 'call_fH4oKyA3U9aQy3p31MYXv2VP'}]\n",
|
||||
"\n",
|
||||
"---\n",
|
||||
"\n",
|
||||
"Output from node 'music':\n",
|
||||
"---\n",
|
||||
"content='' additional_kwargs={'tool_calls': [{'index': 0, 'id': 'call_qivZqsI8zQAqSDP2jsvHyR7T', 'function': {'arguments': '{\"artist\": \"Shakira\"}', 'name': 'get_albums_by_artist'}, 'type': 'function'}, {'index': 1, 'id': 'call_GER0B3vlAjxcvYOYq1NGlV4r', 'function': {'arguments': '{\"artist\": \"Shakira\"}', 'name': 'get_tracks_by_artist'}, 'type': 'function'}]} response_metadata={'finish_reason': 'tool_calls', 'model_name': 'gpt-4o-2024-05-13', 'system_fingerprint': 'fp_ce0793330f'} name='music' id='run-38e2eca8-771c-48a2-83be-023fd17fc6f6-0' tool_calls=[{'name': 'get_albums_by_artist', 'args': {'artist': 'Shakira'}, 'id': 'call_qivZqsI8zQAqSDP2jsvHyR7T'}, {'name': 'get_tracks_by_artist', 'args': {'artist': 'Shakira'}, 'id': 'call_GER0B3vlAjxcvYOYq1NGlV4r'}]\n",
|
||||
"\n",
|
||||
"---\n",
|
||||
"\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "stderr",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"/Users/wfh/code/lc/langchain/libs/core/langchain_core/_api/deprecation.py:139: LangChainDeprecationWarning: The method `BaseRetriever.get_relevant_documents` was deprecated in langchain-core 0.1.46 and will be removed in 0.3.0. Use invoke instead.\n",
|
||||
" warn_deprecated(\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"Output from node 'tools':\n",
|
||||
"---\n",
|
||||
"[ToolMessage(content=\"[{'Title': 'Supernatural', 'Name': 'Santana'}, {'Title': 'Santana - As Years Go By', 'Name': 'Santana'}, {'Title': 'Santana Live', 'Name': 'Santana'}, {'Title': 'Lulu Santos - RCA 100 Anos De Música - Álbum 01', 'Name': 'Lulu Santos'}, {'Title': 'Lulu Santos - RCA 100 Anos De Música - Álbum 02', 'Name': 'Lulu Santos'}]\", name='get_albums_by_artist', id='14ad12f3-afa1-4375-a89d-e878babf2d95', tool_call_id='call_qivZqsI8zQAqSDP2jsvHyR7T'), ToolMessage(content='[{\\'SongName\\': \\'(Da Le) Yaleo\\', \\'ArtistName\\': \\'Santana\\'}, {\\'SongName\\': \\'Love Of My Life\\', \\'ArtistName\\': \\'Santana\\'}, {\\'SongName\\': \\'Put Your Lights On\\', \\'ArtistName\\': \\'Santana\\'}, {\\'SongName\\': \\'Africa Bamba\\', \\'ArtistName\\': \\'Santana\\'}, {\\'SongName\\': \\'Smooth\\', \\'ArtistName\\': \\'Santana\\'}, {\\'SongName\\': \\'Do You Like The Way\\', \\'ArtistName\\': \\'Santana\\'}, {\\'SongName\\': \\'Maria Maria\\', \\'ArtistName\\': \\'Santana\\'}, {\\'SongName\\': \\'Migra\\', \\'ArtistName\\': \\'Santana\\'}, {\\'SongName\\': \\'Corazon Espinado\\', \\'ArtistName\\': \\'Santana\\'}, {\\'SongName\\': \\'Wishing It Was\\', \\'ArtistName\\': \\'Santana\\'}, {\\'SongName\\': \\'El Farol\\', \\'ArtistName\\': \\'Santana\\'}, {\\'SongName\\': \\'Primavera\\', \\'ArtistName\\': \\'Santana\\'}, {\\'SongName\\': \\'The Calling\\', \\'ArtistName\\': \\'Santana\\'}, {\\'SongName\\': \\'Jingo\\', \\'ArtistName\\': \\'Santana\\'}, {\\'SongName\\': \\'El Corazon Manda\\', \\'ArtistName\\': \\'Santana\\'}, {\\'SongName\\': \\'La Puesta Del Sol\\', \\'ArtistName\\': \\'Santana\\'}, {\\'SongName\\': \\'Persuasion\\', \\'ArtistName\\': \\'Santana\\'}, {\\'SongName\\': \\'As The Years Go by\\', \\'ArtistName\\': \\'Santana\\'}, {\\'SongName\\': \\'Soul Sacrifice\\', \\'ArtistName\\': \\'Santana\\'}, {\\'SongName\\': \\'Fried Neckbones And Home Fries\\', \\'ArtistName\\': \\'Santana\\'}, {\\'SongName\\': \\'Santana Jam\\', \\'ArtistName\\': \\'Santana\\'}, {\\'SongName\\': \\'Evil Ways\\', \\'ArtistName\\': \\'Santana\\'}, {\\'SongName\\': \"We\\'ve Got To Get Together/Jingo\", \\'ArtistName\\': \\'Santana\\'}, {\\'SongName\\': \\'Rock Me\\', \\'ArtistName\\': \\'Santana\\'}, {\\'SongName\\': \"Just Ain\\'t Good Enough\", \\'ArtistName\\': \\'Santana\\'}, {\\'SongName\\': \\'Funky Piano\\', \\'ArtistName\\': \\'Santana\\'}, {\\'SongName\\': \\'The Way You Do To Mer\\', \\'ArtistName\\': \\'Santana\\'}, {\\'SongName\\': \\'Assim Caminha A Humanidade\\', \\'ArtistName\\': \\'Lulu Santos\\'}, {\\'SongName\\': \\'Um Pro Outro\\', \\'ArtistName\\': \\'Lulu Santos\\'}, {\\'SongName\\': \\'Casa\\', \\'ArtistName\\': \\'Lulu Santos\\'}, {\\'SongName\\': \\'Condição\\', \\'ArtistName\\': \\'Lulu Santos\\'}, {\\'SongName\\': \\'Satisfação\\', \\'ArtistName\\': \\'Lulu Santos\\'}, {\\'SongName\\': \\'Brumário\\', \\'ArtistName\\': \\'Lulu Santos\\'}, {\\'SongName\\': \\'Sábado À Noite\\', \\'ArtistName\\': \\'Lulu Santos\\'}, {\\'SongName\\': \\'A Cura\\', \\'ArtistName\\': \\'Lulu Santos\\'}, {\\'SongName\\': \\'Atrás Do Trio Elétrico\\', \\'ArtistName\\': \\'Lulu Santos\\'}, {\\'SongName\\': \\'Tudo Bem\\', \\'ArtistName\\': \\'Lulu Santos\\'}, {\\'SongName\\': \\'Toda Forma De Amor\\', \\'ArtistName\\': \\'Lulu Santos\\'}, {\\'SongName\\': \\'Sereia\\', \\'ArtistName\\': \\'Lulu Santos\\'}, {\\'SongName\\': \\'Se Você Pensa\\', \\'ArtistName\\': \\'Lulu Santos\\'}, {\\'SongName\\': \\'Lá Vem O Sol (Here Comes The Sun)\\', \\'ArtistName\\': \\'Lulu Santos\\'}, {\\'SongName\\': \\'Honolulu\\', \\'ArtistName\\': \\'Lulu Santos\\'}, {\\'SongName\\': \\'Dancin´Days\\', \\'ArtistName\\': \\'Lulu Santos\\'}, {\\'SongName\\': \\'Aviso Aos Navegantes\\', \\'ArtistName\\': \\'Lulu Santos\\'}, {\\'SongName\\': \\'Hyperconectividade\\', \\'ArtistName\\': \\'Lulu Santos\\'}, {\\'SongName\\': \\'O Descobridor Dos Sete Mares\\', \\'ArtistName\\': \\'Lulu Santos\\'}, {\\'SongName\\': \\'Um Certo Alguém\\', \\'ArtistName\\': \\'Lulu Santos\\'}, {\\'SongName\\': \\'Fullgás\\', \\'ArtistName\\': \\'Lulu Santos\\'}, {\\'SongName\\': \\'Aquilo\\', \\'ArtistName\\': \\'Lulu Santos\\'}, {\\'SongName\\': \\'Senta A Pua\\', \\'ArtistName\\': \\'Lulu Santos\\'}, {\\'SongName\\': \\'Ro-Que-Se-Da-Ne\\', \\'ArtistName\\': \\'Lulu Santos\\'}, {\\'SongName\\': \\'Tudo Igual\\', \\'ArtistName\\': \\'Lulu Santos\\'}, {\\'SongName\\': \\'Fogo De Palha\\', \\'ArtistName\\': \\'Lulu Santos\\'}, {\\'SongName\\': \\'Assaltaram A Gramática\\', \\'ArtistName\\': \\'Lulu Santos\\'}, {\\'SongName\\': \\'O Último Romântico (Ao Vivo)\\', \\'ArtistName\\': \\'Lulu Santos\\'}]', name='get_tracks_by_artist', id='4ddcebc3-8e4e-42d4-8ae4-3ce3a62b548c', tool_call_id='call_GER0B3vlAjxcvYOYq1NGlV4r')]\n",
|
||||
"\n",
|
||||
"---\n",
|
||||
"\n",
|
||||
"Output from node 'music':\n",
|
||||
"---\n",
|
||||
"content=\"It seems I couldn't find specific albums or songs by Shakira, but I did find some related artists and their works. Here are some albums and songs by Santana and Lulu Santos:\\n\\n### Albums:\\n- **Santana:**\\n - Supernatural\\n - Santana - As Years Go By\\n - Santana Live\\n\\n- **Lulu Santos:**\\n - Lulu Santos - RCA 100 Anos De Música - Álbum 01\\n - Lulu Santos - RCA 100 Anos De Música - Álbum 02\\n\\n### Songs:\\n- **Santana:**\\n - (Da Le) Yaleo\\n - Love Of My Life\\n - Put Your Lights On\\n - Africa Bamba\\n - Smooth\\n - Maria Maria\\n - Corazon Espinado\\n - Jingo\\n - Evil Ways\\n\\n- **Lulu Santos:**\\n - Assim Caminha A Humanidade\\n - Um Pro Outro\\n - Casa\\n - Condição\\n - Satisfação\\n - A Cura\\n - Atrás Do Trio Elétrico\\n - Toda Forma De Amor\\n - Sereia\\n - Se Você Pensa\\n\\nIf you have any other specific artists or songs in mind, feel free to let me know!\" response_metadata={'finish_reason': 'stop', 'model_name': 'gpt-4o-2024-05-13', 'system_fingerprint': 'fp_d576307f90'} name='music' id='run-3d90d7cc-e7f7-48dc-bffd-00765c3f5d13-0'\n",
|
||||
"\n",
|
||||
"---\n",
|
||||
"\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "stdin",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"User (q/Q to quit): hm cool\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"Output from node 'general':\n",
|
||||
"---\n",
|
||||
"content='' additional_kwargs={'tool_calls': [{'index': 0, 'id': 'call_Nc5d0TWNbpnVJFeYJdQFuFGd', 'function': {'arguments': '{\"choice\":\"music\"}', 'name': 'Router'}, 'type': 'function'}]} response_metadata={'finish_reason': 'tool_calls', 'model_name': 'gpt-4o-2024-05-13', 'system_fingerprint': 'fp_4008e3b719'} name='general' id='run-19a3588e-f04c-48db-a54f-95d6b930ee3e-0' tool_calls=[{'name': 'Router', 'args': {'choice': 'music'}, 'id': 'call_Nc5d0TWNbpnVJFeYJdQFuFGd'}]\n",
|
||||
"\n",
|
||||
"---\n",
|
||||
"\n",
|
||||
"Output from node 'music':\n",
|
||||
"---\n",
|
||||
"content='' additional_kwargs={'tool_calls': [{'index': 0, 'id': 'call_weMHkgu3GYaMwXZM6hnCZd0z', 'function': {'arguments': '{\"artist\": \"Shakira\"}', 'name': 'get_albums_by_artist'}, 'type': 'function'}, {'index': 1, 'id': 'call_rXlVbPiEHbt10CNDUJ5GA2ZQ', 'function': {'arguments': '{\"artist\": \"Shakira\"}', 'name': 'get_tracks_by_artist'}, 'type': 'function'}]} response_metadata={'finish_reason': 'tool_calls', 'model_name': 'gpt-4o-2024-05-13', 'system_fingerprint': 'fp_ce0793330f'} name='music' id='run-71bf8550-b5a8-423f-b463-83d9ff51391b-0' tool_calls=[{'name': 'get_albums_by_artist', 'args': {'artist': 'Shakira'}, 'id': 'call_weMHkgu3GYaMwXZM6hnCZd0z'}, {'name': 'get_tracks_by_artist', 'args': {'artist': 'Shakira'}, 'id': 'call_rXlVbPiEHbt10CNDUJ5GA2ZQ'}]\n",
|
||||
"\n",
|
||||
"---\n",
|
||||
"\n",
|
||||
"Output from node 'tools':\n",
|
||||
"---\n",
|
||||
"[ToolMessage(content=\"[{'Title': 'Supernatural', 'Name': 'Santana'}, {'Title': 'Santana - As Years Go By', 'Name': 'Santana'}, {'Title': 'Santana Live', 'Name': 'Santana'}, {'Title': 'Lulu Santos - RCA 100 Anos De Música - Álbum 01', 'Name': 'Lulu Santos'}, {'Title': 'Lulu Santos - RCA 100 Anos De Música - Álbum 02', 'Name': 'Lulu Santos'}]\", name='get_albums_by_artist', id='52ada997-83f6-4500-b0a7-1104d4d38eb9', tool_call_id='call_weMHkgu3GYaMwXZM6hnCZd0z'), ToolMessage(content='[{\\'SongName\\': \\'(Da Le) Yaleo\\', \\'ArtistName\\': \\'Santana\\'}, {\\'SongName\\': \\'Love Of My Life\\', \\'ArtistName\\': \\'Santana\\'}, {\\'SongName\\': \\'Put Your Lights On\\', \\'ArtistName\\': \\'Santana\\'}, {\\'SongName\\': \\'Africa Bamba\\', \\'ArtistName\\': \\'Santana\\'}, {\\'SongName\\': \\'Smooth\\', \\'ArtistName\\': \\'Santana\\'}, {\\'SongName\\': \\'Do You Like The Way\\', \\'ArtistName\\': \\'Santana\\'}, {\\'SongName\\': \\'Maria Maria\\', \\'ArtistName\\': \\'Santana\\'}, {\\'SongName\\': \\'Migra\\', \\'ArtistName\\': \\'Santana\\'}, {\\'SongName\\': \\'Corazon Espinado\\', \\'ArtistName\\': \\'Santana\\'}, {\\'SongName\\': \\'Wishing It Was\\', \\'ArtistName\\': \\'Santana\\'}, {\\'SongName\\': \\'El Farol\\', \\'ArtistName\\': \\'Santana\\'}, {\\'SongName\\': \\'Primavera\\', \\'ArtistName\\': \\'Santana\\'}, {\\'SongName\\': \\'The Calling\\', \\'ArtistName\\': \\'Santana\\'}, {\\'SongName\\': \\'Jingo\\', \\'ArtistName\\': \\'Santana\\'}, {\\'SongName\\': \\'El Corazon Manda\\', \\'ArtistName\\': \\'Santana\\'}, {\\'SongName\\': \\'La Puesta Del Sol\\', \\'ArtistName\\': \\'Santana\\'}, {\\'SongName\\': \\'Persuasion\\', \\'ArtistName\\': \\'Santana\\'}, {\\'SongName\\': \\'As The Years Go by\\', \\'ArtistName\\': \\'Santana\\'}, {\\'SongName\\': \\'Soul Sacrifice\\', \\'ArtistName\\': \\'Santana\\'}, {\\'SongName\\': \\'Fried Neckbones And Home Fries\\', \\'ArtistName\\': \\'Santana\\'}, {\\'SongName\\': \\'Santana Jam\\', \\'ArtistName\\': \\'Santana\\'}, {\\'SongName\\': \\'Evil Ways\\', \\'ArtistName\\': \\'Santana\\'}, {\\'SongName\\': \"We\\'ve Got To Get Together/Jingo\", \\'ArtistName\\': \\'Santana\\'}, {\\'SongName\\': \\'Rock Me\\', \\'ArtistName\\': \\'Santana\\'}, {\\'SongName\\': \"Just Ain\\'t Good Enough\", \\'ArtistName\\': \\'Santana\\'}, {\\'SongName\\': \\'Funky Piano\\', \\'ArtistName\\': \\'Santana\\'}, {\\'SongName\\': \\'The Way You Do To Mer\\', \\'ArtistName\\': \\'Santana\\'}, {\\'SongName\\': \\'Assim Caminha A Humanidade\\', \\'ArtistName\\': \\'Lulu Santos\\'}, {\\'SongName\\': \\'Um Pro Outro\\', \\'ArtistName\\': \\'Lulu Santos\\'}, {\\'SongName\\': \\'Casa\\', \\'ArtistName\\': \\'Lulu Santos\\'}, {\\'SongName\\': \\'Condição\\', \\'ArtistName\\': \\'Lulu Santos\\'}, {\\'SongName\\': \\'Satisfação\\', \\'ArtistName\\': \\'Lulu Santos\\'}, {\\'SongName\\': \\'Brumário\\', \\'ArtistName\\': \\'Lulu Santos\\'}, {\\'SongName\\': \\'Sábado À Noite\\', \\'ArtistName\\': \\'Lulu Santos\\'}, {\\'SongName\\': \\'A Cura\\', \\'ArtistName\\': \\'Lulu Santos\\'}, {\\'SongName\\': \\'Atrás Do Trio Elétrico\\', \\'ArtistName\\': \\'Lulu Santos\\'}, {\\'SongName\\': \\'Tudo Bem\\', \\'ArtistName\\': \\'Lulu Santos\\'}, {\\'SongName\\': \\'Toda Forma De Amor\\', \\'ArtistName\\': \\'Lulu Santos\\'}, {\\'SongName\\': \\'Sereia\\', \\'ArtistName\\': \\'Lulu Santos\\'}, {\\'SongName\\': \\'Se Você Pensa\\', \\'ArtistName\\': \\'Lulu Santos\\'}, {\\'SongName\\': \\'Lá Vem O Sol (Here Comes The Sun)\\', \\'ArtistName\\': \\'Lulu Santos\\'}, {\\'SongName\\': \\'Honolulu\\', \\'ArtistName\\': \\'Lulu Santos\\'}, {\\'SongName\\': \\'Dancin´Days\\', \\'ArtistName\\': \\'Lulu Santos\\'}, {\\'SongName\\': \\'Aviso Aos Navegantes\\', \\'ArtistName\\': \\'Lulu Santos\\'}, {\\'SongName\\': \\'Hyperconectividade\\', \\'ArtistName\\': \\'Lulu Santos\\'}, {\\'SongName\\': \\'O Descobridor Dos Sete Mares\\', \\'ArtistName\\': \\'Lulu Santos\\'}, {\\'SongName\\': \\'Um Certo Alguém\\', \\'ArtistName\\': \\'Lulu Santos\\'}, {\\'SongName\\': \\'Fullgás\\', \\'ArtistName\\': \\'Lulu Santos\\'}, {\\'SongName\\': \\'Aquilo\\', \\'ArtistName\\': \\'Lulu Santos\\'}, {\\'SongName\\': \\'Senta A Pua\\', \\'ArtistName\\': \\'Lulu Santos\\'}, {\\'SongName\\': \\'Ro-Que-Se-Da-Ne\\', \\'ArtistName\\': \\'Lulu Santos\\'}, {\\'SongName\\': \\'Tudo Igual\\', \\'ArtistName\\': \\'Lulu Santos\\'}, {\\'SongName\\': \\'Fogo De Palha\\', \\'ArtistName\\': \\'Lulu Santos\\'}, {\\'SongName\\': \\'Assaltaram A Gramática\\', \\'ArtistName\\': \\'Lulu Santos\\'}, {\\'SongName\\': \\'O Último Romântico (Ao Vivo)\\', \\'ArtistName\\': \\'Lulu Santos\\'}]', name='get_tracks_by_artist', id='7583e077-2fb4-44bf-bb00-b89d599ae84d', tool_call_id='call_rXlVbPiEHbt10CNDUJ5GA2ZQ')]\n",
|
||||
"\n",
|
||||
"---\n",
|
||||
"\n",
|
||||
"Output from node 'music':\n",
|
||||
"---\n",
|
||||
"content=\"It seems like I couldn't find specific albums or songs by Shakira. However, I did find some related artists and their works. Here are some albums and songs by Santana and Lulu Santos:\\n\\n### Albums:\\n1. **Santana**\\n - Supernatural\\n - Santana - As Years Go By\\n - Santana Live\\n\\n2. **Lulu Santos**\\n - RCA 100 Anos De Música - Álbum 01\\n - RCA 100 Anos De Música - Álbum 02\\n\\n### Songs:\\n1. **Santana**\\n - (Da Le) Yaleo\\n - Love Of My Life\\n - Put Your Lights On\\n - Africa Bamba\\n - Smooth\\n - Maria Maria\\n - Corazon Espinado\\n - Jingo\\n - Evil Ways\\n\\n2. **Lulu Santos**\\n - Assim Caminha A Humanidade\\n - Um Pro Outro\\n - Casa\\n - Condição\\n - Satisfação\\n - A Cura\\n - Atrás Do Trio Elétrico\\n - Toda Forma De Amor\\n - Sereia\\n\\nIf you have any other artists or songs in mind, feel free to let me know!\" response_metadata={'finish_reason': 'stop', 'model_name': 'gpt-4o-2024-05-13', 'system_fingerprint': 'fp_d576307f90'} name='music' id='run-2418b45b-2762-49ca-b166-a0fee309ed9e-0'\n",
|
||||
"\n",
|
||||
"---\n",
|
||||
"\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "stdin",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"User (q/Q to quit): q\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"AI: Byebye\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"import uuid\n",
|
||||
"\n",
|
||||
"from langchain_core.messages import HumanMessage\n",
|
||||
"\n",
|
||||
"from langgraph.graph.graph import START\n",
|
||||
"\n",
|
||||
"history = []\n",
|
||||
"while True:\n",
|
||||
" user = input(\"User (q/Q to quit): \")\n",
|
||||
" if user in {\"q\", \"Q\"}:\n",
|
||||
" print(\"AI: Byebye\")\n",
|
||||
" break\n",
|
||||
" history.append(HumanMessage(content=user))\n",
|
||||
" async for output in graph.astream(history):\n",
|
||||
" for key, value in output.items():\n",
|
||||
" print(f\"Output from node '{key}':\")\n",
|
||||
" print(\"---\")\n",
|
||||
" print(value)\n",
|
||||
" print(\"\\n---\\n\")"
|
||||
]
|
||||
}
|
||||
],
|
||||
|
||||
Reference in New Issue
Block a user