471 lines (470 with data), 59.8 kB
{
"cells": [
{
"cell_type": "markdown",
"id": "a3e3ebc4-57af-4fe4-bdd3-36aff67bf276",
"metadata": {
"id": "a3e3ebc4-57af-4fe4-bdd3-36aff67bf276"
},
"source": [
"## Agent Supervisor\n",
"\n",
"The [previous example](multi-agent-collaboration.ipynb) routed messages automatically based on the output of the initial researcher agent.\n",
"\n",
"We can also choose to use an LLM to orchestrate the different agents.\n",
"\n",
"Below, we will create an agent group, with an agent supervisor to help delegate tasks.\n",
"\n",
"\n",
"\n",
"To simplify the code in each agent node, we will use the AgentExecutor class from LangChain. This and other \"advanced agent\" notebooks are designed to show how you can implement certain design patterns in LangGraph. If the pattern suits your needs, we recommend combining it with some of the other fundamental patterns described elsewhere in the docs for best performance.\n",
"\n",
"Before we build, let's configure our environment:"
]
},
{
"cell_type": "code",
"execution_count": 1,
"id": "0d30b6f7-3bec-4d9f-af50-43dfdc81ae6c",
"metadata": {
"id": "0d30b6f7-3bec-4d9f-af50-43dfdc81ae6c"
},
"outputs": [],
"source": [
"%%capture --no-stderr\n",
"%pip install -U langchain langchain_openai langchain_experimental langsmith pandas langgraph"
]
},
{
"cell_type": "code",
"execution_count": 2,
"id": "30c2f3de-c730-4aec-85a6-af2c2f058803",
"metadata": {
"id": "30c2f3de-c730-4aec-85a6-af2c2f058803"
},
"outputs": [],
"source": [
"import getpass\n",
"import os\n",
"\n",
"os.environ['OPENAI_API_KEY'] = ''\n",
"os.environ['TAVILY_API_KEY'] = ''\n",
"\n",
"# Optional, add tracing in LangSmith\n",
"os.environ[\"LANGCHAIN_TRACING_V2\"] = \"true\"\n",
"os.environ['LANGCHAIN_ENDPOINT'] = 'https://api.smith.langchain.com'\n",
"os.environ[\"LANGCHAIN_PROJECT\"] = \"Agent Supervisor\"\n",
"os.environ['LANGCHAIN_API_KEY'] = ''"
]
},
{
"cell_type": "markdown",
"id": "1ac25624-4d83-45a4-b9ef-a10589aacfb7",
"metadata": {
"id": "1ac25624-4d83-45a4-b9ef-a10589aacfb7"
},
"source": [
"## Create tools\n",
"\n",
"For this example, you will make an agent to do web research with a search engine, and one agent to create plots. Define the tools they'll use below:"
]
},
{
"cell_type": "code",
"execution_count": 3,
"id": "f04c6778-403b-4b49-9b93-678e910d5cec",
"metadata": {
"id": "f04c6778-403b-4b49-9b93-678e910d5cec"
},
"outputs": [],
"source": [
"from typing import Annotated, List, Tuple, Union\n",
"\n",
"from langchain_community.tools.tavily_search import TavilySearchResults\n",
"from langchain_core.tools import tool\n",
"from langchain_experimental.tools import PythonREPLTool\n",
"\n",
"tavily_tool = TavilySearchResults(max_results=5)\n",
"\n",
"# This executes code locally, which can be unsafe\n",
"python_repl_tool = PythonREPLTool()"
]
},
{
"cell_type": "markdown",
"id": "d58d1e85-22d4-4c22-9062-72a346a0d709",
"metadata": {
"id": "d58d1e85-22d4-4c22-9062-72a346a0d709"
},
"source": [
"## Helper Utilities\n",
"\n",
"Define a helper function below, which make it easier to add new agent worker nodes."
]
},
{
"cell_type": "code",
"execution_count": 4,
"id": "c4823dd9-26bd-4e1a-8117-b97b2860211a",
"metadata": {
"id": "c4823dd9-26bd-4e1a-8117-b97b2860211a"
},
"outputs": [],
"source": [
"from langchain.agents import AgentExecutor, create_openai_tools_agent\n",
"from langchain_core.messages import BaseMessage, HumanMessage\n",
"from langchain_openai import ChatOpenAI\n",
"\n",
"\n",
"def create_agent(llm: ChatOpenAI, tools: list, system_prompt: str):\n",
" # Each worker node will be given a name and some tools.\n",
" prompt = ChatPromptTemplate.from_messages(\n",
" [\n",
" (\n",
" \"system\",\n",
" system_prompt,\n",
" ),\n",
" MessagesPlaceholder(variable_name=\"messages\"),\n",
" MessagesPlaceholder(variable_name=\"agent_scratchpad\"),\n",
" ]\n",
" )\n",
" agent = create_openai_tools_agent(llm, tools, prompt)\n",
" executor = AgentExecutor(agent=agent, tools=tools)\n",
" return executor"
]
},
{
"cell_type": "markdown",
"id": "b7c302b0-cd57-4913-986f-5dc7d6d77386",
"metadata": {
"id": "b7c302b0-cd57-4913-986f-5dc7d6d77386"
},
"source": [
"We can also define a function that we will use to be the nodes in the graph - it takes care of converting the agent response to a human message. This is important because that is how we will add it the global state of the graph"
]
},
{
"cell_type": "code",
"execution_count": 5,
"id": "80862241-a1a7-4726-bce5-f867b233832e",
"metadata": {
"id": "80862241-a1a7-4726-bce5-f867b233832e"
},
"outputs": [],
"source": [
"def agent_node(state, agent, name):\n",
" result = agent.invoke(state)\n",
" return {\"messages\": [HumanMessage(content=result[\"output\"], name=name)]}"
]
},
{
"cell_type": "markdown",
"id": "d32962d2-5487-496d-aefc-2a3b0d194985",
"metadata": {
"id": "d32962d2-5487-496d-aefc-2a3b0d194985"
},
"source": [
"### Create Agent Supervisor\n",
"\n",
"It will use function calling to choose the next worker node OR finish processing."
]
},
{
"cell_type": "code",
"execution_count": 6,
"id": "311f0a58-b425-4496-adac-dc4cd8ffb912",
"metadata": {
"id": "311f0a58-b425-4496-adac-dc4cd8ffb912"
},
"outputs": [],
"source": [
"from langchain_core.prompts import ChatPromptTemplate, MessagesPlaceholder\n",
"from langchain_core.output_parsers.openai_functions import JsonOutputFunctionsParser\n",
"\n",
"members = [\"Researcher\", \"Coder\"]\n",
"system_prompt = (\n",
" \"You are a supervisor tasked with managing a conversation between the\"\n",
" \" following workers: {members}. Given the following user request,\"\n",
" \" respond with the worker to act next. Each worker will perform a\"\n",
" \" task and respond with their results and status. When finished,\"\n",
" \" respond with FINISH.\"\n",
")\n",
"# Our team supervisor is an LLM node. It just picks the next agent to process\n",
"# and decides when the work is completed\n",
"options = [\"FINISH\"] + members\n",
"# Using openai function calling can make output parsing easier for us\n",
"function_def = {\n",
" \"name\": \"route\",\n",
" \"description\": \"Select the next role.\",\n",
" \"parameters\": {\n",
" \"title\": \"routeSchema\",\n",
" \"type\": \"object\",\n",
" \"properties\": {\n",
" \"next\": {\n",
" \"title\": \"Next\",\n",
" \"anyOf\": [\n",
" {\"enum\": options},\n",
" ],\n",
" }\n",
" },\n",
" \"required\": [\"next\"],\n",
" },\n",
"}\n",
"prompt = ChatPromptTemplate.from_messages(\n",
" [\n",
" (\"system\", system_prompt),\n",
" MessagesPlaceholder(variable_name=\"messages\"),\n",
" (\n",
" \"system\",\n",
" \"Given the conversation above, who should act next?\"\n",
" \" Or should we FINISH? Select one of: {options}\",\n",
" ),\n",
" ]\n",
").partial(options=str(options), members=\", \".join(members))\n",
"\n",
"llm = ChatOpenAI(model=\"gpt-3.5-turbo-0125\")\n",
"\n",
"supervisor_chain = (\n",
" prompt\n",
" | llm.bind_functions(functions=[function_def], function_call=\"route\")\n",
" | JsonOutputFunctionsParser()\n",
")"
]
},
{
"cell_type": "markdown",
"id": "a07d507f-34d1-4f1b-8dde-5e58d17b2166",
"metadata": {
"id": "a07d507f-34d1-4f1b-8dde-5e58d17b2166"
},
"source": [
"## Construct Graph\n",
"\n",
"We're ready to start building the graph. Below, define the state and worker nodes using the function we just defined."
]
},
{
"cell_type": "code",
"execution_count": 7,
"id": "6a430af7-8fce-4e66-ba9e-d940c1bc48e8",
"metadata": {
"id": "6a430af7-8fce-4e66-ba9e-d940c1bc48e8"
},
"outputs": [],
"source": [
"import operator\n",
"from typing import Annotated, Any, Dict, List, Optional, Sequence, TypedDict\n",
"import functools\n",
"\n",
"from langchain_core.prompts import ChatPromptTemplate, MessagesPlaceholder\n",
"from langgraph.graph import StateGraph, END\n",
"\n",
"\n",
"# The agent state is the input to each node in the graph\n",
"class AgentState(TypedDict):\n",
" # The annotation tells the graph that new messages will always\n",
" # be added to the current states\n",
" messages: Annotated[Sequence[BaseMessage], operator.add]\n",
" # The 'next' field indicates where to route to next\n",
" next: str\n",
"\n",
"\n",
"research_agent = create_agent(llm, [tavily_tool], \"You are a web researcher.\")\n",
"research_node = functools.partial(agent_node, agent=research_agent, name=\"Researcher\")\n",
"\n",
"# NOTE: THIS PERFORMS ARBITRARY CODE EXECUTION. PROCEED WITH CAUTION\n",
"code_agent = create_agent(\n",
" llm,\n",
" [python_repl_tool],\n",
" \"You may generate safe python code to analyze data and generate charts using matplotlib.\",\n",
")\n",
"code_node = functools.partial(agent_node, agent=code_agent, name=\"Coder\")\n",
"\n",
"workflow = StateGraph(AgentState)\n",
"workflow.add_node(\"Researcher\", research_node)\n",
"workflow.add_node(\"Coder\", code_node)\n",
"workflow.add_node(\"supervisor\", supervisor_chain)"
]
},
{
"cell_type": "markdown",
"id": "2c1593d5-39f7-4819-96d2-4ad7d7991d72",
"metadata": {
"id": "2c1593d5-39f7-4819-96d2-4ad7d7991d72"
},
"source": [
"Now connect all the edges in the graph."
]
},
{
"cell_type": "code",
"execution_count": 8,
"id": "14778e86-077b-4e6a-893c-400e59b0cdbf",
"metadata": {
"id": "14778e86-077b-4e6a-893c-400e59b0cdbf"
},
"outputs": [],
"source": [
"for member in members:\n",
" # We want our workers to ALWAYS \"report back\" to the supervisor when done\n",
" workflow.add_edge(member, \"supervisor\")\n",
"# The supervisor populates the \"next\" field in the graph state\n",
"# which routes to a node or finishes\n",
"conditional_map = {k: k for k in members}\n",
"conditional_map[\"FINISH\"] = END\n",
"workflow.add_conditional_edges(\"supervisor\", lambda x: x[\"next\"], conditional_map)\n",
"# Finally, add entrypoint\n",
"workflow.set_entry_point(\"supervisor\")\n",
"\n",
"graph = workflow.compile()"
]
},
{
"cell_type": "markdown",
"id": "d36496de-7121-4c49-8cb6-58c943c66628",
"metadata": {
"id": "d36496de-7121-4c49-8cb6-58c943c66628"
},
"source": [
"## Invoke the team\n",
"\n",
"With the graph created, we can now invoke it and see how it performs!"
]
},
{
"cell_type": "code",
"execution_count": 11,
"id": "56ba78e9-d9c1-457c-a073-d606d5d3e013",
"metadata": {
"colab": {
"base_uri": "https://localhost:8080/",
"height": 0
},
"id": "56ba78e9-d9c1-457c-a073-d606d5d3e013",
"outputId": "f2203a57-937c-45cc-f3f8-04f17193ddf0"
},
"outputs": [
{
"output_type": "stream",
"name": "stdout",
"text": [
"{'supervisor': {'next': 'Coder'}}\n",
"----\n",
"{'Coder': {'messages': [HumanMessage(content='Code drug discovery generative AI for cancer researchers', name='Coder')]}}\n",
"----\n",
"{'supervisor': {'next': 'Researcher'}}\n",
"----\n",
"{'Researcher': {'messages': [HumanMessage(content='I found some resources related to drug discovery generative AI for cancer researchers:\\n\\n1. [AI transforming drug discovery and assisting scientists](https://www.nature.com/articles/d43747-023-00029-9.pdf): Researchers at the University of Oxford have used generative AI to assist in drug discovery.\\n\\n2. [New AI tool for generating drug candidates for cancer](https://www.sciencedaily.com/releases/2024/05/240506131601.htm): Scientists at UC San Diego have developed a new AI tool to generate new drug candidates for cancer.\\n\\n3. [Hypothesis-driven AI in cancer research](https://cancerblog.mayoclinic.org/2024/04/30/mayo-researchers-invented-a-new-class-of-ai-to-improve-cancer-research-and-treatments/): Mayo Clinic researchers have invented a new class of AI for improving cancer research and treatments.\\n\\nYou can explore these resources for more detailed information on how AI is being used in drug discovery for cancer research.', name='Researcher')]}}\n",
"----\n",
"{'supervisor': {'next': 'FINISH'}}\n",
"----\n"
]
}
],
"source": [
"for s in graph.stream(\n",
" {\n",
" \"messages\": [\n",
" HumanMessage(content=\"Code drug discovery generative ai cancer researchers and print it to the terminal\")\n",
" ]\n",
" }\n",
"):\n",
" if \"__end__\" not in s:\n",
" print(s)\n",
" print(\"----\")"
]
},
{
"cell_type": "code",
"execution_count": 14,
"id": "45a92dfd-0e11-47f5-aad4-b68d24990e34",
"metadata": {
"colab": {
"base_uri": "https://localhost:8080/",
"height": 768
},
"id": "45a92dfd-0e11-47f5-aad4-b68d24990e34",
"outputId": "922dbd47-2924-4719-dcae-4ca2ad1e27ba"
},
"outputs": [
{
"output_type": "stream",
"name": "stdout",
"text": [
"{'supervisor': {'next': 'Researcher'}}\n",
"----\n",
"{'Researcher': {'messages': [HumanMessage(content='The article at the link https://www.sciencedirect.com/science/article/pii/S135964462400117X discusses the transformation of the drug discovery process through the integration of artificial intelligence (AI). It highlights the role of AI in providing actionable insights from vast amounts of data and mentions the use of deep-learning models, particularly generative adversarial networks (GANs) and Autoencoders, to accelerate de novo drug design.\\n\\nThe article emphasizes the rapid progress in both artificial intelligence and computational power, noting the introduction of machine learning-based decision-making models and the subsequent incorporation of deep learning techniques as alternatives to virtual screening campaigns conducted in recent decades. It suggests that the data-enriched field of drug discovery favors machine learning and deep learning methods due to their effectiveness.\\n\\nThe integration of AI in drug discovery is seen as a significant advancement, but the article also points out the hurdles that need to be addressed. It mentions the importance of improving data quality and interpretability to enhance the efficiency and reliability of AI-driven drug development processes.\\n\\nOverall, the article highlights the potential of artificial intelligence in revolutionizing the drug discovery landscape and underscores the need for continuous improvements to leverage the full benefits of AI technologies in pharmaceutical research.', name='Researcher')]}}\n",
"----\n",
"{'supervisor': {'next': 'Coder'}}\n",
"----\n"
]
},
{
"output_type": "display_data",
"data": {
"text/plain": [
"<Figure size 1000x600 with 1 Axes>"
],
"image/png": "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+6ic5fr0008rOjpaAQEBatWqlTZs2JDnNSaZmZkaOnSoSpcurRIlSqhbt25u3z95mTFjhqpXr65WrVqpTZs2mjFjRr6fmx/53X+2bNlS3377rXbs2GGtq9P3SZmZmRo1apSuuuoq+fr6KiYmRo8++qgyMzNdXi+/+6ezfV5d7p83sAeOBOGyd+jQIXXo0EF9+vTRLbfcosjISEmnPhwDAwM1dOhQBQYG6ocfftBTTz2ltLQ0jRs3zmUeKSkpat++vbp3765evXrps88+0/Dhw5WQkKAOHTpIkqZMmaIhQ4bopptu0oMPPqjjx4/rzz//1K+//qqbb75Z99xzj8qWLasXXnhBQ4YM0TXXXGPlsmjRInXo0EEVK1bU008/rWPHjum1115TkyZN9Mcff+T68tyzZ09VqlRJL7zwgowxVnzLli3Wa91yyy16+eWX1blzZ7311lt6/PHHdf/990uSxowZo169ermcTrBw4UJt27ZNt99+u6KiorR+/Xq9/fbbWr9+vVasWCGHw6Hu3btr06ZN+uijjzRhwgTrl/DSpUu7Xfb79+9X48aNdfToUQ0ZMkTh4eF6//33deONN+qzzz5Tt27dXMa/+OKL8vLy0rBhw5SamqqxY8eqX79++vXXX8+6jtevX69mzZopODhYjz76qIoXL67JkyerZcuWWrp0qRo2bKju3bsrNDRUDz/8sHWqWGBg4FnnezaNGjVSfHy8Fi5cmGva/fffr9KlS+upp57SkSNHCjzvAQMG6JNPPtGtt96qa6+9VkuXLtUNN9xw3rme7mx558jKylK7du2UmZmpBx54QFFRUfrf//6nb775RocPH1ZISIgkafTo0Xr66afVuHFjPfPMM/Lx8dGvv/6qH374QW3btpV06ovM6NGj1aZNG913331KTEzUpEmTtHLlSi1fvlzFixdX79699cYbb+jbb79Vz549rTyOHj2qr7/+WgMGDJC3t7ekU6fB9u/fX+3atdNLL72ko0ePatKkSWratKlWr17tsq2cPHlS7dq1U9OmTfXyyy8rICBAjRo10jPPPKNZs2a5nBKZlZWlzz77TD169Divow9bt26VJIWHh1sxd/ueY8eOqWXLltqyZYsGDx6sChUq6NNPP9WAAQN0+PBhPfjgg9bzBw4cqGnTpqlDhw668847dfLkSf34449asWKFdS3b888/ryef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3f7BvzN/nSxfvrycTqe2b9+uSpUqWfHCumtRQfJOSEhQQkKCnnjiCf38889q0qSJ3nrrLT333HOKj4+X0+nUhg0bdPXVV7t9/unv7dNPZ8rKytL27dvVpk0bl/G9evXSq6++qrS0NM2aNUtxcXHWKTLSvxfcR0RE5HpuQd12223q0qWLVq5cqRkzZqhOnTqqUaPGBc0zP8qXL68///xTTqfTpUE7c5uIj4/X/PnzlZycnOfRoPj4eBljVKFCBesX+7M52/qUTt0qvXXr1mrdurVeeeUVvfDCCxo5cqQWL1581uVdVH8XqSDbds6v+IcPH3a5Bb677Us6tT2dfoTi0KFDhX4EYMaMGapZs6bbUxonT56smTNnFvoPZOeS17qKj4/X2rVr1bp167Ouz8LYP13OnzewF06HwxUp5xeg03/xycrK0ptvvnne8zz91p7SqVN+qlevLmOMTpw4kefzypQpo6uvvlrvv/++y5fkv/76SwsWLFDHjh3PO6f8crc8JLn9y+I5DVl+/oJ3x44d9dtvv+mXX36xYkeOHNHbb7+tuLi4s55KlV/e3t5q27atvvzyS5fb4O7fv18zZ85U06ZNz3rE43zs2LFDAwYMkI+Pj3UL13OJj49Xamqq/vzzTyu2d+9eff755y7j2rVrJ0m53ouvvfbaBWad/7zT0tJ08uRJl1hCQoK8vLys2+V27dpVXl5eeuaZZ3L9cpvzPmrTpo18fHz03//+1+W99e677yo1NTXXHaV69+6tzMxMvf/++5o3b5569erlMr1du3YKDg7WCy+84HabKshtizt06KBSpUrppZde0tKlSwt0FOhCdOzYUfv27XO5s9jJkyf12muvKTAw0LomqUePHjLGuP2SnLMsu3fvLm9vb40ePTrXtmuMsfZJ+VmfycnJuV4np7k98xbJZypRokS+9gcFVZBtO6dBXrZsmTUu59bdp2vdurWKFSumSZMmucRff/31Qs19165dWrZsmXr16qWbbrop17/bb79dW7Zsueh3IitRooTb08169eql//3vf5oyZUquaceOHbNOyS6M/dPl/HkDe+FIEK5IjRs3VsmSJdW/f38NGTJEDodD06dPv6DD4G3btlVUVJSaNGmiyMhIbdy4Ua+//rpuuOGGc/518HHjxqlDhw5q1KiRBg4caN0iOyQk5IL+Lkx+BQcHq3nz5ho7dqxOnDihsmXLasGCBW6PjOVc9zBy5Ej16dNHxYsXV+fOnd0erXrsscf00UcfqUOHDhoyZIjCwsL0/vvva/v27Zo9e3ah/bXv5557zvobJ/fff7+KFSumyZMnKzMz0+3fcyqIP/74Qx9++KGcTqcOHz6slStXWhetT58+XbVq1crXfPr06aPhw4erW7duGjJkiHVr58qVK7tcCFyvXj316NFDEydO1KFDh6xb0OZcP5DfX0YvJO8ffvhBgwcPVs+ePVW5cmWdPHlS06dPl7e3t3r06CHp1DUAI0eO1LPPPqtmzZqpe/fu8vX11cqVKxUdHa0xY8aodOnSGjFihEaPHq327dvrxhtvVGJiot58801dc801uRqPunXrWvPNzMx0ORVOOvU+nTRpkm699VbVrVtXffr0UenSpbVz5059++23atKkSb6/zBYvXlx9+vTR66+/Lm9vb5cbFRSlu+++W5MnT9aAAQO0atUqxcXF6bPPPtPy5cs1ceJEa1/RqlUr3Xrrrfrvf/+rzZs3W6cJ/fjjj2rVqpUGDx6s+Ph4PffccxoxYoSSkpLUtWtXBQUFafv27fr888919913a9iwYflan88884yWLVumG264QeXLl9eBAwf05ptvqly5ci4XmrtTr149LVq0SK+88oqio6NVoUKF87p1tTv53bbbtm2r2NhYDRw4UI888oi8vb313nvvWe+PHJGRkXrwwQc1fvx43XjjjWrfvr3Wrl2ruXPnqlSpUoV2VGvmzJkyxujGG290O71jx44qVqyYZsyYUWjLKj/q1aunWbNmaejQobrmmmsUGBiozp0769Zbb9Unn3yie++9V4sXL1aTJk2UnZ2tv//+W5988onmz5+v+vXrF8r+6XL/vIGNXNR70QEXIK9bZOd12+rly5eba6+91vj7+5vo6Gjz6KOPWreUPv02uXnN48xbHk+ePNk0b97chIeHG19fXxMfH28eeeQR6zbExuR9i2xjjFm0aJFp0qSJ8ff3N8HBwaZz585mw4YNLmNybjnq7ja25cuXNzfccEOuuM64naox7m/Hunv3btOtWzcTGhpqQkJCTM+ePc2ePXvc3pb52WefNWXLljVeXl4uty8985alxhizdetWc9NNN5nQ0FDj5+dnGjRoYL755huXMXktl5w8p06dmquuM/3xxx+mXbt2JjAw0AQEBJhWrVq5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Jn311Vdq2bKlDh06dF7zy87OvmgfAN7e3oqKilKxYh6/Sz2uYDExMfr444917NgxK3b8+HHNnDlTsbGxFz2fsLAwBQUFXfTXLWr53R/6+/srIiKiiLMBzq19+/bau3evkpKSNHfuXLVq1UoPPvigOnXqpJMnT3o6PY84ceJEvsaVLl1aAQEBRZwNLgaaIJvp1KmTSpcurWnTprnEMzIy9Omnn2rgwIGScp/akvOrzPPPP6/o6GhVqVJFLVu21I4dO/Twww9bvyq5e64kTZw4UXFxcdbjlStX6vrrr1epUqUUEhKiFi1a6I8//sh3HYcPH9aPP/6ol156Sa1atVL58uXVoEEDjRgxQjfeeKPLuHvuuUeRkZHy8/NTzZo19c0330j699SUr776StWrV5evr6927typzMxMDRs2TGXLllWJEiXUsGFDLVmyxOX1f/rpJzVr1kz+/v6KiYnRkCFDdOTIEWt6XFycXnjhBd1xxx0KCgpSbGys3n77bWv6mb9WL1myRA6HQ99//73q16+vgIAANW7cWImJiS6v+9xzzykiIkJBQUG688479dhjj3n8tEVcuurWrauYmBjNmTPHis2ZM0exsbGqU6eOy9h58+apadOmCg0NVXh4uDp16qStW7e6jNm9e7f69u2rsLAwlShRQvXr19evv/7qMmb69OmKi4tTSEiI+vTpo/T0dGvamafDnWs7kaRdu3apV69eCg0NVVhYmLp06aKkpKTzXiZOp1NjxoxRhQoV5O/vr9q1a+uzzz6zpmdnZ2vgwIHW9CpVqujVV191mYe7/WHONj1nzhy1atVKAQEBql27tn755RfreWeeDpezrzzbMktPT1e/fv1UokQJlSlTRhMmTLD9aYW4cDlnT5QtW1Z169bV448/ri+//FJz5851+X5w+PBh3XnnnSpdurSCg4N13XXXae3atS7z+vLLL1W3bl35+fmpYsWKGj16tEsj5XA4NGnSJHXo0EH+/v6qWLGiyzZ3Pv766y916NBBgYGBioyM1K233qqDBw9a08+1P8vZXmfNmqUWLVrIz89PM2bMsLbtl19+WWXKlFF4eLgGDRrk0iCdeQaMw+HQO++8o27duikgIECVKlXSV1995ZLvV199pUqVKsnPz0+tWrXS+++/L4fDocOHD1/QcsCFoQmymWLFium2227TtGnTdPqfiPr000+VnZ2tvn375vnc77//XomJiVq4cKG++eYbzZkzR+XKldMzzzyjvXv3au/evfnOIz09Xf3799dPP/2kFStWqFKlSurYsaPLh//ZBAYGKjAwUF988YUyMzPdjnE6nerQoYOWL1+uDz/8UBs2bNCLL74ob29va8zRo0f10ksv6Z133tH69esVERGhwYMH65dfftHHH3+sP//8Uz179lT79u21efNmSdLWrVvVvn179ejRQ3/++admzZqln376SYMHD3Z5/fHjx6t+/fpavXq17r//ft133325mpozjRw5UuPHj9fvv/+uYsWK6Y477rCmzZgxQ88//7xeeuklrVq1SrGxsZo0aVK+lhfs64477tDUqVOtx++9955uv/32XOOOHDmioUOH6vfff9f3338vLy8vdevWzTo6mpGRoRYtWuh///ufvvrqK61du1aPPvqoy9HTrVu36osvvtA333yjb775RkuXLtWLL7541vzOtp2cOHFC7dq1U1BQkH788UctX75cgYGBat++/XkfjR4zZow++OADvfXWW1q/fr0efvhh3XLLLVq6dKmkU/uNcuXK6dNPP9WGDRv01FNP6fHHH9cnn3ziMp8z94c5Ro4cqWHDhmnNmjWqXLmy+vbte9Zf1s+1zIYOHarly5frq6++0sKFC/Xjjz8W6AcjIL+uu+461a5d2+VHk549e+rAgQOaO3euVq1apbp166p169ZKTk6WdOo0+ttuu00PPvigNmzYoMmTJ2vatGl6/vnnXeb95JNPqkePHlq7dq369eunPn36aOPGjeeV5+HDh3XdddepTp06+v333zVv3jzt379fvXr1ssaca3+W47HHHtODDz6ojRs3ql27dpKkxYsXa+vWrVq8eLHef/99TZs2LdcPx2caPXq0evXqpT///FMdO3ZUv379rGW0fft23XTTTeratavWrl2re+65RyNHjjyv2lHIDGxn48aNRpJZvHixFWvWrJm55ZZbrMejRo0ytWvXth7379/fREZGmszMTJd5lS9f3kyYMMElduZzjTFmwoQJpnz58nnmlJ2dbYKCgszXX39txSSZzz//PM/nfPbZZ6ZkyZLGz8/PNG7c2IwYMcKsXbvWmj5//nzj5eVlEhMT3T5/6tSpRpJZs2aNFduxY4fx9vY2//vf/1zGtm7d2owYMcIYY8zAgQPN3Xff7TL9xx9/NF5e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ph0Oh7777js1b95ct99+uypXrqw+ffpox44dioyMlCS1a9dO33zzjRYsWKBrrrlG1157rSZMmKDy5cu7vN7o0aP18ccfq1atWvrggw/00UcfqXr16mfNccmSJbm24dGjRys6OlrLly9Xdna22rZtq4SEBD300EMKDQ2Vl5dXvvZnF1OFChX02Wefac6cOapVq5YmTZpk3R0u5zRceIbDnHnxBoDLxvXXX6+oqChNnz7d06kAuAiOHDmismXLavz48ee8mQ1wKXA4HPr888/VtWtXT6dyyXj++ef11ltvadeuXZ5OxdY4HQ64TBw9elRvvfWW2rVrJ29vb3300UdatGiRFi5c6OnUABSR1atX6++//1aDBg2UmpqqZ555RpKs034BXPrefPNNXXPNNQoPD9fy5cs1bty4XH9bEBcfTRBwmcg5NeH555/X8ePHVaVKFc2ePVtt2rTxdGoAitDLL7+sxMRE+fj4qF69evrxxx/d3uYcwKVp8+bNeu6555ScnKzY2Fj95z//0YgRIzydlu1xOhwAAAAAW+HGCAAAAABshSYIAAAAgK3QBAEAAACwFZogAAAAALZCEwQAAADAVmiCAOAyN23aNIWGhhb568TFxWnixIlF/jqXugEDBvCHHwHgMkcTBOCy8Msvv8jb21s33HBDrmlJSUlyOBxas2ZNns9v2bKlHnrooXy/Xn7m6QnuGpHevXtr06ZNRf7aK1eu1N13331B82jZsqUcDoccDod8fX1VtmxZde7cWXPmzCmkLM/PkiVLrLy8vLwUEhKiOnXq6NFHH9XevXtdxr766quaNm2aZxL1oNOXkcPhUGRkpHr06KFt27Z5OjUAKDCaIACXhXfffVcPPPCAli1bpj179ng6nUJljNHJkyfP+/n+/v6KiIgoxIzcK126tAICAi54PnfddZf27t2rrVu3avbs2apevbr69OlzzgbrxIkTF/za55KYmKg9e/Zo5cqVGj58uBYtWqSaNWtq3bp11piQkJCLcuStqGRlZV3Q83OW0aeffqr169erc+fOys7OzjXuQt/XAFCUaIIAXPIyMjI0a9Ys3XfffbrhhhsK5Vf4uLg4vfDCC7rjjjsUFBSk2NhYvf3229b0ChUqSJLq1Kkjh8Ohli1bWtPeeecdVatWTX5+fqpatarefPNNl3n//PPPuvrqq+Xn56f69evriy++cDmqlPOL+ty5c1WvXj35+vrqp59+0tatW9WlSxdFRkYqMDBQ11xzjRYtWmTNt2XLltqxY4cefvhh69d4yf3pcJMmTVJ8fLx8fHxUpUoVTZ8+3WW6w+HQO++8o27duikgIECVKlXSV199dc5ldvpRqPOZhyQFBAQoKipK5cqV07XXXquXXnpJkydP1pQpU6x6c47EzZo1Sy1atJCfn59mzJihp59+WldffbXL/CZOnKi4uDjr8cmTJzVkyBCFhoYqPDxcw4cPV//+/fN1CltERISioqJUuXJl9enTR8uXL1fp0qV13333WWPOPB3us88+U0JCgvz9/RUeHq42bdroyJEj1vT33ntPNWrUkK+vr8qUKaPBgwdb03bu3KkuXbooMDBQwcHB6tWrl/bv3y9J2rRpkxwOh/7++2+XHCdMmKD4+Hjr8V9//aUOHTooMDBQkZGRuvXWW3Xw4EFresuWLTV48GA99NBDKlWqlNq1a6c77rhDnTp1cpnviRMnFBERoXffffecy6hMmTJq3ry5nnrqKW3YsEFbtmzJ832dmZmpIUOGKCIiQn5+fmratKlWrlzpMs/169erU6dOCg4OVlBQkJo1a6atW7da08+2zWVlZWnw4MEqU6aM/Pz8VL58eY0ZM0bSqUbs6aefVmxsrHx9fRUdHa0hQ4actT4ANmEA4BL37rvvmvr16xtjjPn6669NfHy8cTqd1vTt27cbSWb16tV5zqNFixbmwQcftB6XL1/ehIWFmTfeeMNs3rzZjBkzxnh5eZm///7bGGPMb7/9ZiSZRYsWmb1795pDhw4ZY4z58MMPTZkyZczs2bPNtm3bzOzZs01YWJiZNm2aMcaY1NRUExYWZm655Razfv16891335nKlSu75Ld48WIjydSqVcssWLDAbNmyxRw6dMisWbPGvPXWW2bdunVm06ZN5oknnjB+fn5mx44dxhhjDh06ZMqVK2eeeeYZs3fvXrN3715jjDFTp041ISEhVm1z5swxxYsXN2+88YZJTEw048ePN97e3uaHH36wxkgy5cqVMzNnzjSbN282Q4YMMYGBgVad7pQvX95MmDDhguZx5nrIkZ2dbUqWLGnuu+8+Y8y/6zQuLs5a1nv27DGjRo0ytWvXdnnuhAkTTPny5a3Hzz33nAkLCzNz5swxGzduNPfee68JDg42Xbp0yTOvnHWSkpKSa9qECROMJLN//35jjDH9+/e35rVnzx5TrFgx88orr5jt27ebP//807zxxhsmPT3dGGPMm2++afz8/MzEiRNNYmKi+e2336xlmJ2dba6++mrTtGlT8/vvv5sVK1aYevXqmRYtWlivXb9+ffPEE0+45FOvXj0rlpKSYkqXLm1GjBhhNm7caP744w9z/fXXm1atWrks88DAQPPII4+Yv//+2/z9999m+fLlxtvb2+zZs8caN2fOHFOiRAkr9/wsozlz5hhJ5s8//8zzfT1kyBATHR1tvvvuO7N+/XrTv39/U7JkSet9snv3bhMWFma6d+9uVq5caRITE817771nbYvn2ubGjRtnYmJizLJly0xSUpL58ccfzcyZM40xxnz66acmODjYfPfdd2bHjh3m119/NW+//Xae7wMA9kETBOCS17hxYzNx4kRjjDEnTpwwpUqVMosXL7amn28TdMstt1iPnU6niYiIMJMmTTrrPOPj460vWDmeffZZ06hRI2OMMZMmTTLh4eHm2LFj1vQpU6a4bYK++OKLc9Zeo0YN89prr7nkfXojYkzuJqhx48bmrrvuchnTs2dP07FjR+uxJJcv1xkZGUaSmTt3bp65uGuCCjqPvJogY4xp2LCh6dChgzHm3+Wfs95z5KcJioyMNOPGjbMenzx50sTGxp53EzR37lwjyfz666/GGNcmaNWqVUaSSUpKcjvf6OhoM3LkSLfTFixYYLy9vc3OnTut2Pr1640k89tvv1m1xcfHW9MTExONJLNx40ZjzKn3Xtu2bV3mu2vXLiPJJCYmGmNOLfM6derkev3q1aubl156yXrcuXNnM2DAALe5GpN7Ge3Zs8c0btzYlC1b1mRmZrp9X2dkZJjixYubGTNmWLGsrCwTHR1txo4da4wxZsSIEaZChQomKyvL7euea5t74IEHzHXXXefyw0iO8ePHm8qVK+c5bwD2xelwAC5piYmJ+u2339S3b19JUrFixdS7d+9znrKTH7Vq1bL+73A4FBUVpQMHDuQ5/siRI9q6dasGDhyowMBA699zzz1nnbqTmJioWrVqyc/Pz3pegwYN3M6vfv36Lo8zMjI0bNgwVatWTaGhoQoMDNTGjRu1c+fOAtW1ceNGNWnSxCXWpEkTbdy40SV2ev0lSpRQcHDwWet3pzDmkcMYY53il+PMZXQuqamp2r9/v8sy9/b2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\n"
},
"metadata": {}
},
{
"output_type": "stream",
"name": "stdout",
"text": [
"{'Coder': {'messages': [HumanMessage(content='Here is a bar chart representing the transformation of the drug discovery process through the integration of artificial intelligence. The chart illustrates the progress levels in different stages of AI integration, including Virtual Screening, Machine Learning, and Deep Learning. The chart shows how deep learning has made significant advancements in accelerating the drug discovery process compared to traditional methods like virtual screening.', name='Coder')]}}\n",
"----\n",
"{'supervisor': {'next': 'FINISH'}}\n",
"----\n"
]
}
],
"source": [
"for s in graph.stream(\n",
" {\"messages\": [HumanMessage(content=\"Write a research report on the article https://www.sciencedirect.com/science/article/pii/S135964462400117X.\")]},\n",
" {\"recursion_limit\": 100},\n",
"):\n",
" if \"__end__\" not in s:\n",
" print(s)\n",
" print(\"----\")"
]
},
{
"cell_type": "code",
"execution_count": 14,
"id": "1d363d2c-e0da-4cce-ba47-ad2aa9df0fef",
"metadata": {
"id": "1d363d2c-e0da-4cce-ba47-ad2aa9df0fef"
},
"outputs": [],
"source": []
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.11.1"
},
"colab": {
"provenance": [],
"machine_shape": "hm",
"gpuType": "L4"
},
"accelerator": "GPU"
},
"nbformat": 4,
"nbformat_minor": 5
}