From 083a14c2c5bc90d597dd162219d1006a723abdf0 Mon Sep 17 00:00:00 2001 From: Vadym Barda Date: Thu, 12 Dec 2024 08:15:17 -0500 Subject: [PATCH] docs: update how-to to remove agent wrapper (#2721) --- ...f-ff99-40f0-92a8-0b3f2c591040.msgpack.zlib | 2 +- ...4-0a15-43bd-aeed-c9ba1dfe388f.msgpack.zlib | 2 +- .../multi-agent-multi-turn-convo.ipynb | 128 +++++++++++------ docs/docs/how-tos/multi-agent-network.ipynb | 130 +++++++++++------- poetry.lock | 18 +-- 5 files changed, 181 insertions(+), 99 deletions(-) diff --git a/docs/cassettes/multi-agent-network_26a0d4df-ff99-40f0-92a8-0b3f2c591040.msgpack.zlib b/docs/cassettes/multi-agent-network_26a0d4df-ff99-40f0-92a8-0b3f2c591040.msgpack.zlib index 8c7f584d7..eb0081989 100644 --- a/docs/cassettes/multi-agent-network_26a0d4df-ff99-40f0-92a8-0b3f2c591040.msgpack.zlib +++ b/docs/cassettes/multi-agent-network_26a0d4df-ff99-40f0-92a8-0b3f2c591040.msgpack.zlib @@ -1 +1 @@ -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+iT51iVvbT37TUVc1lBXfqLkXU6fOH+85oXOU4P2OQt2bXk67vO4F4Wib14avyNUP3T+ke8P3v7P1qmz1xo23Bc1d9b2G+6Zkvduk/mHB2tCFaEX/3R+84YHYpWG+tqyl95eN7BqdmHhmdOt3Ldnv5669tzmEx3s+dumDfYvxyjv8co1ZateHfj0x88a34luu/OJL8p+sFR//UXjkn1PDb7l+vt7B7fTRPzKpB+ToqMaP/+5stPxzYzj5IYlz1esvMM74fzpaVF3fMCuenmyP++zte2PPcOuex0f609yjc8+4rr3nXbKd8n25dOH0zqoP5469d0LJ757+KmHF9UMlk8aPFxYvnrg1tmb9zfa/nG8oaX3+Bs1oW+/ejr008zJj/g86WemrFxf01V+IOo6++kqOf78bwuX3XRocG7fLRcX233NGeumdcTcFd0xdx15H9GRaCn9/dnopctufOX9oij15txXks/1Jn0fN2Xl8q+mVF/31oGkyXOK84botrvoN4mKmpRfxQ1suvP6twueLHtn74xFxXuetVutezJXVX18MPrI2aWf3Hgi63j8K/uNMXvH7Uh67jbLsjn+1eN2r64qSLdRzx/lyi/8ZeKy9KN9qYcU/m3nF+1bN6+cOy52N9XxRI69/b0FJ9tbb78u9qEjpe0J888UPXNk9+v8Xyfnln7o+GlF26k9ju/zc9IOzPTIf+YPbst871yVq3vqB3U909L23HOmbd6bKRPGT0ztWp99bvHN4ZefcRR3XlDuf2PRS7snTji0um3fhntbjq15+VhRimXOmvU77k5dsaB5f5un6ctThw5MubC5n3ksOwO9cXytwz5r54726thWebV1zqHWvKdaOsa1nd35yfILN0OxD7YOlJdxPYxjhfvix/UPFH6Udml/itrcm9wZ212/bfaF1075voxZd/HYrl9fTG4mA457nc4zh4/W772pM7Q99tHxfGgo7uc842/uTpxk2zB50okVdxNlMU9aO2KbXz25LfTgBHHitPdP/+2DLbOemNr6u5rDzy/b8u6+G/O+fffnsqPVH4Y+Hzp2afmScV1xG7KFh9DGT998/LC3+Wvnpa3eAVNDS9aHr2UGHFy546uMhoGFpUscW44WbLr/ubZZVHD9j7doVRIT5f/Xvhb2hqiofwOhx+ms \ No newline at end of file +eNqdVg1wFOUZDhKYULRR2sIwlPJ5lkZqdnN3e0kuiQeGuwAH+SGXSAgBz73d7+422dtv2d275JIeyt/IqIMcWNtRamtIchIjIUDFgqgU8KeIHQXUMAWrQsGCgFqQWsb03b07uAxMO+3O3O3u973/z/O+365IRLCiCkQa0SdIGlZYToMXNb4ioeClYaxqq3pCWAsSvmt+TV39prAiDP48qGmyWlpQwMoCTWQssQLNkVBBxFLABVmtAJ5lERtmunyEjx7L3txhCmFVZQNYNZWipg4TR8CXpMGLqZGEEatgxKIAlsC/iDSFjWAR4TYZKxrSwCTiWAkpGAyHsMSnBXiITpBYwxG6G9MBGnEkLGmKgNV8xAmacccaN41Gbj+KgiMJYx6pMuYEv8AhVQgENRVjQQpct560l49YtQXlZUh4WT4iqETJQ36ioCAW5eFWg0SDmG5uxtj7DwaCkA/CEgkHgkiQYDtkqCONgEFVJnrOBCqBUVjFSj4samFFQnl+QRLUYB6NqjGgiMCvoUZAUkFQbUlTkS+KJDaEaVM+MilExHrN1aiq4ZAplo+GQSGgVlaSAAiCVBLCrWAFw5ISgqAM7xyrCD4fZqVMY3pIptgSWAkRHov6UkDWKBvRhSR4tcBdZgFZEYqgESJ6OXjWmeBnRRXDrqopmA1lLEB0AD4LWeouzHSxvmZoBonA6WsdJi0qG/79YcngrO7u2rMuoKetC3iMEqrYFIulzKRY+L9bSGUCHQFNMywK4mvGnGYIKEQnroCTAkpaN1MaEgZK6dJAYk4R5JRLUzkKhkMG2Vme9YkYpdXTBCCKEADSi8hoTtCikYtgFUlES/IQ5Hx6N/kNqbQ6jRoEUdR3krUGQR/LtWTSitb5YAoQjRihYimsI9JkukkP6IEP47S+4PUC7b1ek86E/5pnPTiVcJuWZKkehs6JfEgPpewgwX8ttDxVT1eJQqMAoTHW66MSMYJ5GlWFVU3Pi0jwS6qkGhxyjLAilIlOIq8PNEHBvJGVkgGpkfOSWCy2JJYIQuEB2ye6gkTV4luGj7h+luMwcBtLHOEhsfiLgXZBzodJ5BdZDfdCL0nYoE+8twVjmWJFIYJ7klrxrawsiwJntHZBs0qkvlTvUXq5btzu1VOnjALFd9RAEOXugvlRmMUSstCFxbR1axulaqwgiTBbKZGFeHpkY3935oYMOIMRKjXn4z1J5S2ZMkSNd1exXE3dMJOswgXj3dD/RbbtmesKDFkhhOMJ5/wb3aU2r7tjaIuFLhkYZliNSly82+j2ncOUsaZEKWOKx58zb0nXR8RSQAvGuyyWEub5NHIre0BPC6srugAM/M5bidQR01kzL43iiawJXS4AJr6nAfP5yGJBLswhq9lqg7/SQmupxYxmV9X3OVN+6m+Kw0C9wkqqH7CoSOOe4IJhqQXzvc6bIr5HRxzS0eOHMUnBUUZUTKWiivctpDzJw5Vyu7Yn6UURJcBKQrvhNr5ZRxMOU0HakdqGqaKbBOdUSIVKWC3MltRWutK9kJiZspgps2VXGwXTE4tCSIDqGf+p4xyAtpjhevlGCY20YDj5n2fMyevVTBEFhyAa3f01Q10lcL1yc6G0LasuY7ebdw0XU3FGQJuKQurLN+6nTHSa1b62tDAl8PHBn8KLl7PbrPaiEsz4OF8RZv08z9nNXLEVFu0lZhv+gz56OLCiYycTRaNUzMHXixaND+aH2Da9rxyMpZApgkzL4IDjxDCP68I+F9FzUMuQrGCRsHy/cxblZLkgpuoMusUTrsbq8iq3s7cOgnQS0iLg9cdGjPR6Ob/XF3LcHy30Y7o4upC45xPR7Y8yfMjaUOj08PWN3ipW4ISZsuYtItKcCspSzDAlhWaGAdhoM22hLZTXU9/SRker5gTaIpEo42FxhJltxQGzfwHd4poznzS2+pVFvrZWWVjqdVr85c3VDXNbl9Y4q3xig1jR7olwxd55rMW1aE5rmMzy+6JewVUO2bBa0FFQpn9VwQxUHamGoKAhKL0dLKXWdDuUId6ogYMePv3K0Bz48KuRxGgZqtOLieEOR0mdoGFHNczfwSehBuGIwDui9c7KULPPrTJuz8JKvrJi5oJ5tda57vm2WrNYos1uVapqZtYV2r3l5owiMDbgbqoORWab3WDh9dD/z6heWkhl9jdVIye/cBMSUSXB7++pwwq0ULyXE0mYh0Gu4B7A3FPeGN9h95vthb5CG8OXlNiY4iKqosGzNW3t2jTo0k+BBCsCxyJcfHuQcZhKbTbGVIZCrMNeZDObje/g5T3J4/DALfumPJaTZVwjH6+vIpOKb99ztqEy+sDEbfzsl6Twp86m13M+/fH7C/b6ntp4vHtfwbp9d/d+MvSA3PDBn9aO1XLH+k6808Hsmzj93axVC3wjZ15+6/3RzND9x7+YIh09frQZn4r1zCD9i9t2Xj19+eAjX0+q/WXOx/euO3n6eebzkHn/sd13PBVft3nrs/0NL5w9eKA56sj64B7r1L6x97528etTvqjFu/jQhAvfX77nw/XrP3r9Yybr4Tc/8Xq0R5etuS2/N/BY95Nb7xooKR2x5kzVQE6lO2/Wm51P3/f55A33NO4W3xnz+olnFnVaNly84nh2Y2L6c5ZLkwtbp/TPGDp1ZMqh9p1vXfjysz1HZkTy2u+6NP3WMb8ffJt7qPriptjXc2+9z77DeS5v7t7drn7fiOw36CZl8Vfjn2i6I/fZpoHBR//s2Nvx+C4hZ/KZ7Byq9I39i/74UTAYWzV51tiymeen3VI66jbWf9xfV70toY3+5sS47Cnb9uY8Oq7lkalfZB9zb/jR3gvB2nl9D3esyD3RnJhaesV1Z/Gsg+8tW+lYVHkUqSsHyk8dnviXznN7dx6Yekf2yvXjrrzU/Wu0NFK9+3zJr7736tmfdXLrBuW1tvWjnGu/WZ099eyFpwunPph78idXv7t1WQt7gbGbRk1bd+TFp253t7e8vdk5rXuiu9WR19l55q7f5dPf/bV2+Z2j51089M/jBU21oYrTg7nHt7QovVt2fup+5eXuxGDT6f68wxM2HxpziM3PvZz4bOOkj1efeeYfzWLFC7+pjk0ec9g83TSQuyny3sQfupYNmEwuMvLDc6/F71l18IBy8geHR9ec+fZq1raALa/27P2XRntfXFObW6Ytbmo8X1n13OFvfQuO/TZr+4beh979G3V+QPli15BzxgiP50FPeE3Xjl80fnly/OZ75aFTkXNfrds651/7+bMLdq/1rWlv41yT/h6Jhd2HcMfA+O2JwdeArUNDI7NQ2+oT4qisrH8DKyiG7A== \ No newline at end of file diff --git a/docs/cassettes/multi-agent-network_68a547d4-0a15-43bd-aeed-c9ba1dfe388f.msgpack.zlib b/docs/cassettes/multi-agent-network_68a547d4-0a15-43bd-aeed-c9ba1dfe388f.msgpack.zlib index 798718a46..02061cf68 100644 --- a/docs/cassettes/multi-agent-network_68a547d4-0a15-43bd-aeed-c9ba1dfe388f.msgpack.zlib +++ b/docs/cassettes/multi-agent-network_68a547d4-0a15-43bd-aeed-c9ba1dfe388f.msgpack.zlib @@ -1 +1 @@ -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 \ No newline at end of file +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 \ No newline at end of file diff --git a/docs/docs/how-tos/multi-agent-multi-turn-convo.ipynb b/docs/docs/how-tos/multi-agent-multi-turn-convo.ipynb index 411eb4216..1ff3714c4 100644 --- a/docs/docs/how-tos/multi-agent-multi-turn-convo.ipynb +++ b/docs/docs/how-tos/multi-agent-multi-turn-convo.ipynb @@ -139,71 +139,117 @@ "from typing_extensions import TypedDict, Literal\n", "\n", "from langchain_openai import ChatOpenAI\n", - "from langchain_core.messages import HumanMessage\n", + "from langchain_core.messages import AnyMessage\n", + "from langchain_openai import ChatOpenAI\n", "from langgraph.graph import MessagesState, StateGraph, START, END\n", "from langgraph.types import Command, interrupt\n", "from langgraph.checkpoint.memory import MemorySaver\n", - "from langgraph.prebuilt import create_react_agent\n", "\n", "model = ChatOpenAI(model=\"gpt-4o\")\n", "\n", "\n", - "def make_agent_node(*, name: str, destinations: list[str], system_prompt: str):\n", - " def agent_node(state: MessagesState) -> Command[Literal[*destinations, \"human\"]]:\n", - " # define schema for the structured output:\n", - " # - model's text response (`response`)\n", - " # - name of the node to go to next (or 'finish')\n", - " class Response(TypedDict):\n", - " response: str\n", - " goto: Literal[*destinations, \"finish\"]\n", + "# Define a helper for each of the agent nodes to call\n", + "def call_llm(messages: list[AnyMessage], target_agent_nodes: list[str]):\n", + " \"\"\"Call LLM with structured output to get a natural language response as well as a target agent (node) to go to next.\n", "\n", - " messages = [{\"role\": \"system\", \"content\": system_prompt}] + state[\"messages\"]\n", - " response = model.with_structured_output(Response).invoke(messages)\n", - " goto = response[\"goto\"]\n", - " if goto == \"finish\":\n", - " # When the agent is done, we should go to the\n", - " goto = \"human\"\n", - "\n", - " # Handoff to another agent or halt\n", - " ai_msg = {\"role\": \"ai\", \"content\": response[\"response\"], \"name\": name}\n", - " return Command(goto=goto, update={\"messages\": [ai_msg]})\n", - "\n", - " return agent_node\n", + " Args:\n", + " messages: list of messages to pass to the LLM\n", + " target_agents: list of the node names of the target agents to navigate to\n", + " \"\"\"\n", + " # define JSON schema for the structured output:\n", + " # - model's text response (`response`)\n", + " # - name of the node to go to next (or 'finish')\n", + " # see more on structured output here https://python.langchain.com/docs/concepts/structured_outputs\n", + " json_schema = {\n", + " \"name\": \"Response\",\n", + " \"parameters\": {\n", + " \"type\": \"object\",\n", + " \"properties\": {\n", + " \"response\": {\n", + " \"type\": \"string\",\n", + " \"description\": \"A human readable response to the original question. Does not need to be a final response. Will be streamed back to the user.\",\n", + " },\n", + " \"goto\": {\n", + " \"enum\": [*target_agent_nodes, \"finish\"],\n", + " \"type\": \"string\",\n", + " \"description\": \"The next agent to call, or 'finish' if the user's query has been resolved. Must be one of the specified values.\",\n", + " },\n", + " },\n", + " \"required\": [\"response\", \"goto\"],\n", + " },\n", + " }\n", + " response = model.with_structured_output(json_schema).invoke(messages)\n", + " return response\n", "\n", "\n", - "travel_advisor = make_agent_node(\n", - " name=\"travel_advisor\",\n", - " destinations=[\"sightseeing_advisor\", \"hotel_advisor\", \"human\"],\n", - " system_prompt=(\n", + "def travel_advisor(\n", + " state: MessagesState,\n", + ") -> Command[Literal[\"sightseeing_advisor\", \"hotel_advisor\", \"__end__\"]]:\n", + " system_prompt = (\n", " \"You are a general travel expert that can recommend travel destinations (e.g. countries, cities, etc). \"\n", " \"If you need specific sightseeing recommendations, ask 'sightseeing_advisor' for help. \"\n", " \"If you need hotel recommendations, ask 'hotel_advisor' for help. \"\n", " \"If you have enough information to respond to the user, return 'finish'. \"\n", " \"Never mention other agents by name.\"\n", - " ),\n", - ")\n", - "sightseeing_advisor = make_agent_node(\n", - " name=\"sightseeing_advisor\",\n", - " destinations=[\"travel_advisor\", \"hotel_advisor\", \"human\"],\n", - " system_prompt=(\n", + " )\n", + " messages = [{\"role\": \"system\", \"content\": system_prompt}] + state[\"messages\"]\n", + " target_agent_nodes = [\"sightseeing_advisor\", \"hotel_advisor\"]\n", + " response = call_llm(messages, target_agent_nodes)\n", + " ai_msg = {\"role\": \"ai\", \"content\": response[\"response\"], \"name\": \"travel_advisor\"}\n", + " # handoff to another agent or go to the human when agent is done\n", + " goto = response[\"goto\"]\n", + " if goto == \"finish\":\n", + " goto = \"human\"\n", + "\n", + " return Command(goto=goto, update={\"messages\": [ai_msg]})\n", + "\n", + "\n", + "def sightseeing_advisor(\n", + " state: MessagesState,\n", + ") -> Command[Literal[\"travel_advisor\", \"hotel_advisor\", \"__end__\"]]:\n", + " system_prompt = (\n", " \"You are a travel expert that can provide specific sightseeing recommendations for a given destination. \"\n", " \"If you need general travel help, go to 'travel_advisor' for help. \"\n", " \"If you need hotel recommendations, go to 'hotel_advisor' for help. \"\n", " \"If you have enough information to respond to the user, return 'finish'. \"\n", " \"Never mention other agents by name.\"\n", - " ),\n", - ")\n", - "hotel_advisor = make_agent_node(\n", - " name=\"hotel_advisor\",\n", - " destinations=[\"travel_advisor\", \"sightseeing_advisor\", \"human\"],\n", - " system_prompt=(\n", + " )\n", + " messages = [{\"role\": \"system\", \"content\": system_prompt}] + state[\"messages\"]\n", + " target_agent_nodes = [\"travel_advisor\", \"hotel_advisor\"]\n", + " response = call_llm(messages, target_agent_nodes)\n", + " ai_msg = {\n", + " \"role\": \"ai\",\n", + " \"content\": response[\"response\"],\n", + " \"name\": \"sightseeing_advisor\",\n", + " }\n", + " # handoff to another agent or go to the human when agent is done\n", + " goto = response[\"goto\"]\n", + " if goto == \"finish\":\n", + " goto = \"human\"\n", + "\n", + " return Command(goto=goto, update={\"messages\": [ai_msg]})\n", + "\n", + "\n", + "def hotel_advisor(\n", + " state: MessagesState,\n", + ") -> Command[Literal[\"travel_advisor\", \"sightseeing_advisor\", \"__end__\"]]:\n", + " system_prompt = (\n", " \"You are a travel expert that can provide hotel recommendations for a given destination. \"\n", " \"If you need general travel help, ask 'travel_advisor' for help. \"\n", " \"If you need specific sightseeing recommendations, ask 'sightseeing_advisor' for help. \"\n", " \"If you have enough information to respond to the user, return 'finish'. \"\n", " \"Never mention other agents by name.\"\n", - " ),\n", - ")\n", + " )\n", + " messages = [{\"role\": \"system\", \"content\": system_prompt}] + state[\"messages\"]\n", + " target_agent_nodes = [\"travel_advisor\", \"sightseeing_advisor\"]\n", + " response = call_llm(messages, target_agent_nodes)\n", + " ai_msg = {\"role\": \"ai\", \"content\": response[\"response\"], \"name\": \"hotel_advisor\"}\n", + " # handoff to another agent or go to the human when agent is done\n", + " goto = response[\"goto\"]\n", + " if goto == \"finish\":\n", + " goto = \"human\"\n", + "\n", + " return Command(goto=goto, update={\"messages\": [ai_msg]})\n", "\n", "\n", "def human_node(\n", @@ -376,7 +422,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.11.4" + "version": "3.12.3" } }, "nbformat": 4, diff --git a/docs/docs/how-tos/multi-agent-network.ipynb b/docs/docs/how-tos/multi-agent-network.ipynb index 3c8461438..e1c48b98f 100644 --- a/docs/docs/how-tos/multi-agent-network.ipynb +++ b/docs/docs/how-tos/multi-agent-network.ipynb @@ -133,74 +133,110 @@ { "cell_type": "code", "execution_count": 3, - "id": "aa4bdbff-9461-46cc-aee9-8a22d3c3d9ec", + "id": "29e2a824-dbeb-4944-9df2-63fdbd883252", "metadata": {}, "outputs": [], "source": [ "from typing_extensions import TypedDict, Literal\n", "\n", "from langchain_openai import ChatOpenAI\n", + "from langchain_core.messages import AnyMessage\n", "from langgraph.graph import MessagesState, StateGraph, START, END\n", "from langgraph.types import Command\n", "\n", "model = ChatOpenAI(model=\"gpt-4o\")\n", "\n", "\n", - "def make_agent_node(*, name: str, destinations: list[str], system_prompt: str):\n", - " def agent_node(state: MessagesState) -> Command[Literal[*destinations, END]]:\n", - " # define schema for the structured output:\n", - " # - model's text response (`response`)\n", - " # - name of the node to go to next (or 'finish')\n", - " class Response(TypedDict):\n", - " response: str\n", - " goto: Literal[*destinations, \"finish\"]\n", + "# Define a helper for each of the agent nodes to call\n", + "def call_llm(messages: list[AnyMessage], target_agent_nodes: list[str]):\n", + " \"\"\"Call LLM with structured output to get a natural language response as well as a target agent (node) to go to next.\n", "\n", - " messages = [{\"role\": \"system\", \"content\": system_prompt}] + state[\"messages\"]\n", - " response = model.with_structured_output(Response).invoke(messages)\n", - " goto = response[\"goto\"]\n", - " if goto == \"finish\":\n", - " goto = END\n", - "\n", - " # handoff to another agent or halt\n", - " ai_msg = {\"role\": \"ai\", \"content\": response[\"response\"], \"name\": name}\n", - " return Command(goto=goto, update={\"messages\": ai_msg})\n", - "\n", - " return agent_node\n", + " Args:\n", + " messages: list of messages to pass to the LLM\n", + " target_agents: list of the node names of the target agents to navigate to\n", + " \"\"\"\n", + " # define JSON schema for the structured output:\n", + " # - model's text response (`response`)\n", + " # - name of the node to go to next (or 'finish')\n", + " # see more on structured output here https://python.langchain.com/docs/concepts/structured_outputs\n", + " json_schema = {\n", + " \"name\": \"Response\",\n", + " \"parameters\": {\n", + " \"type\": \"object\",\n", + " \"properties\": {\n", + " \"response\": {\n", + " \"type\": \"string\",\n", + " \"description\": \"A human readable response to the original question. Does not need to be a final response. Will be streamed back to the user.\",\n", + " },\n", + " \"goto\": {\n", + " \"enum\": [*target_agent_nodes, \"__end__\"],\n", + " \"type\": \"string\",\n", + " \"description\": \"The next agent to call, or __end__ if the user's query has been resolved. Must be one of the specified values.\",\n", + " },\n", + " },\n", + " \"required\": [\"response\", \"goto\"],\n", + " },\n", + " }\n", + " response = model.with_structured_output(json_schema).invoke(messages)\n", + " return response\n", "\n", "\n", - "travel_advisor = make_agent_node(\n", - " name=\"travel_advisor\",\n", - " destinations=[\"sightseeing_advisor\", \"hotel_advisor\"],\n", - " system_prompt=(\n", + "def travel_advisor(\n", + " state: MessagesState,\n", + ") -> Command[Literal[\"sightseeing_advisor\", \"hotel_advisor\", \"__end__\"]]:\n", + " system_prompt = (\n", " \"You are a general travel expert that can recommend travel destinations (e.g. countries, cities, etc). \"\n", " \"If you need specific sightseeing recommendations, ask 'sightseeing_advisor' for help. \"\n", " \"If you need hotel recommendations, ask 'hotel_advisor' for help. \"\n", " \"If you have enough information to respond to the user, return 'finish'. \"\n", " \"Never mention other agents by name.\"\n", - " ),\n", - ")\n", - "sightseeing_advisor = make_agent_node(\n", - " name=\"sightseeing_advisor\",\n", - " destinations=[\"travel_advisor\", \"hotel_advisor\"],\n", - " system_prompt=(\n", + " )\n", + " messages = [{\"role\": \"system\", \"content\": system_prompt}] + state[\"messages\"]\n", + " target_agent_nodes = [\"sightseeing_advisor\", \"hotel_advisor\"]\n", + " response = call_llm(messages, target_agent_nodes)\n", + " ai_msg = {\"role\": \"ai\", \"content\": response[\"response\"], \"name\": \"travel_advisor\"}\n", + " # handoff to another agent or halt\n", + " return Command(goto=response[\"goto\"], update={\"messages\": ai_msg})\n", + "\n", + "\n", + "def sightseeing_advisor(\n", + " state: MessagesState,\n", + ") -> Command[Literal[\"travel_advisor\", \"hotel_advisor\", \"__end__\"]]:\n", + " system_prompt = (\n", " \"You are a travel expert that can provide specific sightseeing recommendations for a given destination. \"\n", " \"If you need general travel help, go to 'travel_advisor' for help. \"\n", " \"If you need hotel recommendations, go to 'hotel_advisor' for help. \"\n", " \"If you have enough information to respond to the user, return 'finish'. \"\n", " \"Never mention other agents by name.\"\n", - " ),\n", - ")\n", - "hotel_advisor = make_agent_node(\n", - " name=\"hotel_advisor\",\n", - " destinations=[\"travel_advisor\", \"sightseeing_advisor\"],\n", - " system_prompt=(\n", + " )\n", + " messages = [{\"role\": \"system\", \"content\": system_prompt}] + state[\"messages\"]\n", + " target_agent_nodes = [\"travel_advisor\", \"hotel_advisor\"]\n", + " response = call_llm(messages, target_agent_nodes)\n", + " ai_msg = {\n", + " \"role\": \"ai\",\n", + " \"content\": response[\"response\"],\n", + " \"name\": \"sightseeing_advisor\",\n", + " }\n", + " # handoff to another agent or halt\n", + " return Command(goto=response[\"goto\"], update={\"messages\": ai_msg})\n", + "\n", + "\n", + "def hotel_advisor(\n", + " state: MessagesState,\n", + ") -> Command[Literal[\"travel_advisor\", \"sightseeing_advisor\", \"__end__\"]]:\n", + " system_prompt = (\n", " \"You are a travel expert that can provide hotel recommendations for a given destination. \"\n", " \"If you need general travel help, ask 'travel_advisor' for help. \"\n", " \"If you need specific sightseeing recommendations, ask 'sightseeing_advisor' for help. \"\n", " \"If you have enough information to respond to the user, return 'finish'. \"\n", " \"Never mention other agents by name.\"\n", - " ),\n", - ")\n", + " )\n", + " messages = [{\"role\": \"system\", \"content\": system_prompt}] + state[\"messages\"]\n", + " target_agent_nodes = [\"travel_advisor\", \"sightseeing_advisor\"]\n", + " response = call_llm(messages, target_agent_nodes)\n", + " ai_msg = {\"role\": \"ai\", \"content\": response[\"response\"], \"name\": \"hotel_advisor\"}\n", + " # handoff to another agent or halt\n", + " return Command(goto=response[\"goto\"], update={\"messages\": ai_msg})\n", "\n", "\n", "builder = StateGraph(MessagesState)\n", @@ -254,7 +290,7 @@ "name": "stdout", "output_type": "stream", "text": [ - "{'travel_advisor': {'messages': {'role': 'ai', 'content': 'The Caribbean offers many warm destinations perfect for a relaxing getaway. Consider visiting Jamaica for its beautiful beaches and vibrant culture, the Bahamas for its stunning islands and clear waters, or the Dominican Republic for its all-inclusive resorts and rich history. Let me know if you need more information on sightseeing or hotel recommendations!', 'name': 'travel_advisor'}}}\n", + "{'travel_advisor': {'messages': {'role': 'ai', 'content': 'The Caribbean offers many warm and beautiful destinations. Some popular ones include:\\n\\n1. **Jamaica** - Known for its beautiful beaches, reggae music, and vibrant culture.\\n2. **Bahamas** - Offers stunning beaches and clear turquoise waters, perfect for relaxation and water activities.\\n3. **Barbados** - Known for its friendly locals, delicious cuisine, and beautiful beaches.\\n4. **Dominican Republic** - Offers a mix of beaches, mountains, and historical sites.\\n5. **Aruba** - Known for its dry climate, beautiful beaches, and outdoor activities.\\n\\nWould you like recommendations for sightseeing or hotels in any of these destinations?', 'name': 'travel_advisor'}}}\n", "\n", "\n" ] @@ -286,13 +322,13 @@ "name": "stdout", "output_type": "stream", "text": [ - "{'travel_advisor': {'messages': {'role': 'ai', 'content': 'I recommend visiting Jamaica, a beautiful Caribbean island known for its warm climate, stunning beaches, and vibrant culture.', 'name': 'travel_advisor'}}}\n", + "{'travel_advisor': {'messages': {'role': 'ai', 'content': 'I recommend visiting Jamaica, a vibrant and warm destination in the Caribbean known for its beautiful beaches, rich culture, and exciting activities.', 'name': 'travel_advisor'}}}\n", "\n", "\n", - "{'sightseeing_advisor': {'messages': {'role': 'ai', 'content': \"Jamaica is a fantastic choice for a warm Caribbean getaway. Here are some top things to do while you're there:\\n\\n1. **Dunn's River Falls**: Located near Ocho Rios, this is one of Jamaica's most famous waterfalls. You can climb the falls, swim in the refreshing pools, or simply enjoy the beautiful surroundings.\\n\\n2. **Seven Mile Beach**: Located in Negril, this is one of the most beautiful beaches in the Caribbean. It's perfect for sunbathing, swimming, and enjoying water sports.\\n\\n3. **Bob Marley Museum**: Situated in Kingston, this museum is dedicated to the life and legacy of the reggae legend Bob Marley and is a must-visit for music lovers.\\n\\n4. **Blue Mountains**: Go hiking or take a tour to explore the Blue Mountains, where you can enjoy breathtaking views and taste some of the world's best coffee.\\n\\n5. **Luminous Lagoon**: Experience the natural wonder of the Luminous Lagoon in Falmouth, where the water glows at night due to bioluminescent microorganisms.\\n\\nFor hotel recommendations, I suggest checking with a hotel advisor for the best options that suit your budget and preferences.\", 'name': 'sightseeing_advisor'}}}\n", + "{'sightseeing_advisor': {'messages': {'role': 'ai', 'content': \"For a warm and vibrant Caribbean destination, I recommend Jamaica. It's renowned for its stunning beaches, lively culture, and exciting activities.\\n\\n### Things to Do in Jamaica:\\n1. **Explore Dunn’s River Falls**: A famous waterfall near Ocho Rios where you can climb the terraced steps and enjoy the natural pools.\\n2. **Visit Bob Marley Museum**: Located in Kingston, this museum offers a deep dive into the life of the reggae legend.\\n3. **Relax at Seven Mile Beach**: Known for its beautiful white sand and clear blue waters, it’s perfect for sunbathing and swimming.\\n4. **Experience Negril Cliffs**: Enjoy breathtaking views and adventurous cliff diving.\\n5. **Discover Blue Hole**: A hidden gem near Ocho Rios, offering a refreshing swim in stunning turquoise waters.\\n\\nI will now find some hotel recommendations for you in Jamaica.\", 'name': 'sightseeing_advisor'}}}\n", "\n", "\n", - "{'hotel_advisor': {'messages': {'role': 'ai', 'content': 'For hotel recommendations in Jamaica, here are a few options across different areas: \\n\\n1. **Sandals Montego Bay** (Montego Bay): A luxurious all-inclusive resort ideal for couples, offering beautiful beachfront views and a variety of dining options.\\n\\n2. **Half Moon Resort** (Montego Bay): A family-friendly resort with a private beach, golf course, and various activities for all ages.\\n\\n3. **Jamaica Inn** (Ocho Rios): A charming boutique hotel known for its excellent service and tranquil atmosphere.\\n\\n4. **The Caves** (Negril): A unique and romantic cliff-side resort offering stunning ocean views and intimate dining experiences.\\n\\n5. **Trident Hotel** (Port Antonio): A luxurious and contemporary hotel offering privacy, elegance, and beautiful views of the Caribbean Sea.\\n\\nThese options cater to different tastes and budgets, ensuring a comfortable and enjoyable stay in Jamaica.', 'name': 'hotel_advisor'}}}\n", + "{'hotel_advisor': {'messages': {'role': 'ai', 'content': 'For your stay in Jamaica, here are some hotel recommendations:\\n\\n1. **Sandals Montego Bay**: An all-inclusive resort offering luxury accommodations, private beaches, and various dining options.\\n\\n2. **Jamaica Inn**: Located in Ocho Rios, this boutique hotel offers a more intimate experience with stunning beach views and personalized service.\\n\\n3. **Half Moon Resort**: Situated in Montego Bay, this resort features a private beach, golf course, and a world-class spa.\\n\\n4. **The Caves Hotel**: In Negril, offering unique cliffside cottages and a romantic atmosphere.\\n\\n5. **Round Hill Hotel and Villas**: A classic resort near Montego Bay with luxurious villas and an elegant ambiance.\\n\\nEnjoy your trip to Jamaica, where warm weather and vibrant culture await!', 'name': 'hotel_advisor'}}}\n", "\n", "\n" ] @@ -374,7 +410,7 @@ " guard_on_duty: bool\n", "\n", "\n", - "def villager(state: GameState) -> Command[Literal[\"villager\", END]]:\n", + "def villager(state: GameState) -> Command[Literal[\"villager\", \"__end__\"]]:\n", " \"\"\"Villager NPC that gathers wood and food.\"\"\"\n", " current_resources = state[\"wood\"] + state[\"food\"]\n", " if current_resources < 15: # Continue gathering until we have enough resources\n", @@ -387,7 +423,7 @@ " return Command(goto=END)\n", "\n", "\n", - "def guard(state: GameState) -> Command[Literal[\"guard\", END]]:\n", + "def guard(state: GameState) -> Command[Literal[\"guard\", \"__end__\"]]:\n", " \"\"\"Guard NPC that protects gold and consumes food.\"\"\"\n", " if not state[\"guard_on_duty\"]:\n", " return Command(goto=END)\n", @@ -404,7 +440,7 @@ " return Command(goto=END, update={\"guard_on_duty\": False}) # Leave to get food\n", "\n", "\n", - "def merchant(state: GameState) -> Command[Literal[\"merchant\", END]]:\n", + "def merchant(state: GameState) -> Command[Literal[\"merchant\", \"__end__\"]]:\n", " \"\"\"Merchant NPC that trades wood for gold.\"\"\"\n", " if state[\"wood\"] >= 5: # Trade wood for gold when available\n", " print(\"Merchant trading wood for gold.\")\n", @@ -413,7 +449,7 @@ " return Command(goto=END)\n", "\n", "\n", - "def thief(state: GameState) -> Command[Literal[\"thief\", END]]:\n", + "def thief(state: GameState) -> Command[Literal[\"thief\", \"__end__\"]]:\n", " \"\"\"Thief NPC that steals gold if the guard leaves to get food.\"\"\"\n", " if not state[\"guard_on_duty\"]:\n", " print(\"Thief stealing gold.\")\n", @@ -561,7 +597,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.11.9" + "version": "3.12.3" } }, "nbformat": 4, diff --git a/poetry.lock b/poetry.lock index e2317d365..f25351691 100644 --- a/poetry.lock +++ b/poetry.lock @@ -3005,18 +3005,18 @@ pillow = ">=10.3.0,<11.0.0" [[package]] name = "langchain-openai" -version = "0.2.1" +version = "0.2.12" description = "An integration package connecting OpenAI and LangChain" optional = false python-versions = "<4.0,>=3.9" files = [ - {file = "langchain_openai-0.2.1-py3-none-any.whl", hash = "sha256:215efa4526c88f8105f002b43b7cbf98cebd9baeb4f62c3b58faebdb578715bc"}, - {file = "langchain_openai-0.2.1.tar.gz", hash = "sha256:a131ea18736f1a8792925391b91a8c8bd834431ffc2055c92ba49f59c3dcaaf0"}, + {file = "langchain_openai-0.2.12-py3-none-any.whl", hash = "sha256:916965c45584d9ea565825ad3bb7629b1ff57f12f36d4b937e5b7d65903839d6"}, + {file = "langchain_openai-0.2.12.tar.gz", hash = "sha256:8b92096623065a2820e89aa5fb0a262fb109d56c346e3b09ba319af424c45cd1"}, ] [package.dependencies] -langchain-core = ">=0.3,<0.4" -openai = ">=1.40.0,<2.0.0" +langchain-core = ">=0.3.21,<0.4.0" +openai = ">=1.55.3,<2.0.0" tiktoken = ">=0.7,<1" [[package]] @@ -4339,13 +4339,13 @@ sympy = "*" [[package]] name = "openai" -version = "1.50.1" +version = "1.57.2" description = "The official Python library for the openai API" optional = false -python-versions = ">=3.7.1" +python-versions = ">=3.8" files = [ - {file = "openai-1.50.1-py3-none-any.whl", hash = "sha256:7967fc8372d5e005ad61514586fb286d593facafccedbee00416bc38ee07c2e6"}, - {file = "openai-1.50.1.tar.gz", hash = "sha256:80cbdf275488894c70bfbad711dbba6f31ea71d579b97e364bfd99cdf030158e"}, + {file = "openai-1.57.2-py3-none-any.whl", hash = "sha256:f7326283c156fdee875746e7e54d36959fb198eadc683952ee05e3302fbd638d"}, + {file = "openai-1.57.2.tar.gz", hash = "sha256:5f49fd0f38e9f2131cda7deb45dafdd1aee4f52a637e190ce0ecf40147ce8cee"}, ] [package.dependencies]