{ "cells": [ { "cell_type": "code", "execution_count": 1, "metadata": {}, "outputs": [], "source": [ "%%capture --no-stderr\n", "%pip install -U tavily-python langchain_community" ] }, { "cell_type": "code", "execution_count": 2, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "True" ] }, "execution_count": 2, "metadata": {}, "output_type": "execute_result" } ], "source": [ "from typing import Annotated\n", "\n", "from langchain_openai import ChatOpenAI as Chat\n", "from langchain_community.tools.tavily_search import TavilySearchResults\n", "from langchain_core.messages import BaseMessage\n", "# NOTE: you must use langchain-core >= 0.3 with Pydantic v2\n", "from pydantic import BaseModel\n", "from typing_extensions import TypedDict\n", "\n", "from langgraph.checkpoint.memory import MemorySaver\n", "from langgraph.graph import StateGraph\n", "from langgraph.graph.message import add_messages\n", "from langgraph.prebuilt import ToolNode, tools_condition\n", "\n", "import os\n", "from dotenv import load_dotenv\n", "\n", "load_dotenv()" ] }, { "cell_type": "code", "execution_count": 3, "metadata": {}, "outputs": [], "source": [ "openai_api_key = os.getenv(\"OPENAI_API_KEY\")\n", "model = os.getenv(\"OPENAI_MODEL\", \"gpt-4o\")\n", "temperature = float(os.getenv(\"OPENAI_TEMPERATURE\", 0))" ] }, { "cell_type": "code", "execution_count": 4, "metadata": {}, "outputs": [], "source": [ "class State(TypedDict):\n", " messages: Annotated[list, add_messages]\n", " # This flag is new\n", " ask_human: bool" ] }, { "cell_type": "code", "execution_count": 5, "metadata": {}, "outputs": [], "source": [ "class RequestAssistance(BaseModel):\n", " \"\"\"Escalate the conversation to an expert. Use this if you are unable to assist directly or if the user requires support beyond your permissions.\n", "\n", " To use this function, relay the user's 'request' so the expert can provide the right guidance.\n", " \"\"\"\n", "\n", " request: str\n", "\n", "\n", "tool = TavilySearchResults(max_results=2)\n", "tools = [tool]\n", "llm = Chat(\n", " openai_api_key=openai_api_key,\n", " model=model,\n", " temperature=temperature\n", ")\n", "# We can bind the llm to a tool definition, a pydantic model, or a json schema\n", "llm_with_tools = llm.bind_tools(tools + [RequestAssistance])\n", "\n", "\n", "def chatbot(state: State):\n", " response = llm_with_tools.invoke(state[\"messages\"])\n", " ask_human = False\n", " if (\n", " response.tool_calls\n", " and response.tool_calls[0][\"name\"] == RequestAssistance.__name__\n", " ):\n", " ask_human = True\n", " return {\"messages\": [response], \"ask_human\": ask_human}" ] }, { "cell_type": "code", "execution_count": 6, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "" ] }, "execution_count": 6, "metadata": {}, "output_type": "execute_result" } ], "source": [ "graph_builder = StateGraph(State)\n", "\n", "graph_builder.add_node(\"chatbot\", chatbot)\n", "graph_builder.add_node(\"tools\", ToolNode(tools=[tool]))" ] }, { "cell_type": "code", "execution_count": 8, "metadata": {}, "outputs": [], "source": [ "from langchain_core.messages import AIMessage, ToolMessage\n", "\n", "def create_response(response: str, ai_message: AIMessage):\n", " return ToolMessage(\n", " content=response,\n", " tool_call_id=ai_message.tool_calls[0][\"id\"],\n", " )\n", "\n", "\n", "def human_node(state: State):\n", " new_messages = []\n", " if not isinstance(state[\"messages\"][-1], ToolMessage):\n", " # Typically, the user will have updated the state during the interrupt.\n", " # If they choose not to, we will include a placeholder ToolMessage to\n", " # let the LLM continue.\n", " new_messages.append(\n", " create_response(\"No response from human.\", state[\"messages\"][-1])\n", " )\n", " return {\n", " # Append the new messages\n", " \"messages\": new_messages,\n", " # Unset the flag\n", " \"ask_human\": False,\n", " }" ] }, { "cell_type": "code", "execution_count": 9, "metadata": {}, "outputs": [], "source": [ "graph_builder.add_node(\"human\", human_node)\n", "\n", "\n", "def select_next_node(state: State):\n", " if state[\"ask_human\"]:\n", " return \"human\"\n", " # Otherwise, we can route as before\n", " return tools_condition(state)\n", "\n", "\n", "graph_builder.add_conditional_edges(\n", " \"chatbot\",\n", " select_next_node,\n", " {\"human\": \"human\", \"tools\": \"tools\", \"__end__\": \"__end__\"},\n", ")\n", "graph_builder.add_edge(\"tools\", \"chatbot\")\n", "graph_builder.add_edge(\"human\", \"chatbot\")\n", "graph_builder.set_entry_point(\"chatbot\")\n", "memory = MemorySaver()\n", "graph = graph_builder.compile(\n", " checkpointer=memory,\n", " interrupt_before=[\"human\"],\n", ")" ] }, { "cell_type": "code", "execution_count": 10, "metadata": {}, "outputs": [ { "data": { "image/jpeg": "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fp6km0/mspg8vpeLCsuYii+22vZZdfIRMGAmNpZKDzu83zT16INwREQFV8ftiNeZGizZtfJVW5BjB6JmOEcx/sIdB0HpDj3lWhVgjx3iUxzNy3HYlzJDt03sTNLRv69qxJHo3HrC6ML+6J0W/wDOdlhZ0RFzoIiICIiAiIgIiICIiAiIgIiICIiAiIgIiICIiAiIgIiICIiAiIgIiICIiAiIgIiICIiCv5mhYx2VbncfD4xL2QguVWnzp4WkuaWejtGFztgehDnDpuCPDJ4jS/FPT3iuToY/UmIdIHOrXYGzRtkb6HMePNe3fqCAQe8BWNQmV0bistdN18MlXIEAG7SmfXmcB3BzmEF4HqduOp6LfFVNcRFerX1XTpVNvg3cKWBwbw40u0PGzgMTB1G4Ox831gf4Lv0/wM4d6TzFbLYXQ+n8Tk6xJhuU8bFFLGSC08rmtBG4JH9hKkDoiYABmp88xo9HbxO/5mMlPImx7VZ766H+Er+Hh7/KS0bVoRVfyJse1We+uh/hKp8VcfldG6ByuYx2qcwblYRmMTywlnnSsadx2Y9Dj6U/Dw9/lJaNrVF+EBwII3B7wqx5E2ParPfXQ/wk8ibHtVnvrof4Sfh4e/yktG1Xv/Vr4T/9W2lf+EQfur9Pg2cJ3Ek8N9LEnvJxMBJ/8KsHkTY9qs99dD/CX6NDueOWfUWdsM67t8bEW4P542tP+BTIw9/lJaNrvy2eq4PsKMDG2MjK3arjoSA9wHTcj+jGPS89B/aQD5adwz8TWnksvZNkbkvjFuZgPK6QgDZu/Xla1rWj8zRv1JXswunMbp6OVmPqMrmUh0su5dJKR0Be9xLnnb0uJKkljVVTEZNGj9zyERFpQREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQFnvH8gcIs/uSBtB3f9vH+cLQlnvH/f8EWf2232g+Ntt/p4/Wg0JERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQFnnhAjfhDqDqG9IOpHT/TxrQ1nnhA7fgh1Bv0G0Ho3/18aDQ0REBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEUPqHUIworwwwG5kLTi2vWDuUO225nOdseVjQRudj3gAEkAwJzuryemPwgHqNyY7f39l1XRRgV1xlRa3GbLZdkVI+HdYfMMH73N/DT4d1h8wwfvc38NbO617Y9YLLuvk3w7PCTt8F8RU07No6TK4vUFcOiy7b4ibHNHKHPiMZiduQ0MO+4+P3eb13v4d1h8wwfvc38NZn4QnCPLeERw+fpfM1sPS5bEdqtehsSukgkaepAMY3BaXNI/Pv6E7rXtj1gsufg5cZbnHvhnX1jZ0zJpeC3YkjqVpLYsmaFmw7Xm5GbAv527bf0N9+vTUFmumINQ6P05jMHisTgq2Nx1aOrXiFubzY2NDR/q+p2HU+kqT+HdYfMMH73N/DTute2PWCy7oqR8O6w+YYP3ub+Gnw7rD5hg/e5v4ad1r2x6wWXdFS2ai1XDu+bE4qxG3qYq92Rsjht/R5o+Xf1AkD1kK0YjK183jobtVznQyg7c7S1zSCQ5rgeoIIIIPcQVqxMGvDi86OE3LOxERaEEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERBStRn/wB4uEHqxV4j838tVUkozUf84+E/RN3/ADqqk16v5eH5e8sp1CIofKauxOG1BhcJct9jlMyZhQg7N7u2MTOeTzgC1uzevnEb+jcrBimERcOazmP05jZchlbsGPoxFofYsyBjGlzg1oJPpLnNAHpJA9Ko7kUPb1diaOqcdpye3yZnIVprdat2bz2kURYJHcwHKNjIzoSCd+m+xUwoCLhzOcx+nqPjmUuwY+r2jIu2sSBjed7gxjdz6XOc1oHpJAXcqC5eGR30/cHoGWyGwH0uVdS5eGX4gu/pbIftUqmJ4NXnHuy1LaiIvNYiIiAiIgIiICIiAiIgIiICIiAiIgIiICIiAiIgIiICIiAiIgIiICIiAiIgIiICIiAiIgpOo/5x8J+ibv8AnVVJqM1H/OPhP0Td/wA6qpNer+Xh+XvLKdTHeNuUyeS1/wAN9DVc1d07i9Rz3pL9/GS9jakbWhbIyvHL3xl5cSS3Z20ZAI3Kp/EbhoyrxM4N6bj1PqV0ElrMvOQlybpL7WeKAmNthwLw3ptvvzbE7OHetv11w807xKxEeM1JjI8lUimbYi3e+OSGVvc+ORhD2OG585pB6lRuA4M6P0xYw1jHYl8VjETWLFOaS5PK9kk7BHM9znvJkLmgDd/Ntt02WqabsWEwasyMejs1omzl9U5zLQ65sadwj6OW8UvWYmV2WQ2xcILgxjHv5njd5DG7bqp6okzue8G3iVhNVZHIvs6Y1hTpwP8AhiSxK2F01Jwjkshsbpw3xh5Dnt33DD3sBX09luCOis5RyNS5hi+O/lTnJnx2545ReLGxmeORrw+J3I0N8wtG2/Tqd/DHcCtCYnA5/C1dOwMxOea0ZOo6WR8dktbyh7g5x2eRsS8bOcQCSSAVjkyMu1zw1q3OOPDTTTM7qOpVh0/mXeOwZifx947aqdnWXOMpG7v63c0DuGyqmD1hqvPZLCcNrmrMoMYNa5XAy6mgnEWQt1KlQWIoTO0DaRz3GN0jdnHsjsdyVttzwceH+Qo4yrZw9qZuNZNHTmdlrnbwtlLTIGzdt2nncjR8bu3HcSDKWeCmiLWh6ekHaerx6fpyietVhe+J0MoJIlZK1wkbJu5x5w7mPMdz1KuTI+Z+KcFuzpviBoq9qDNZbE6X1Zp00L9jIy+MsZakgMkEszXB0nZl5c0vJc0uYd92tI+v8BhYtO4erjYLFy1FXbytmyFqS1O7qTu+WQlzj17ySqxU4KaJo6GyOj4sBAdPZF7pbtaWSSR9mQkEySSucZHP3a0h5dzDlbsRsFYdLaWx2jMFWw+JjmioV+bs2WLMth45nFx3klc57urj3kqxFpEsuXhl+ILv6WyH7VKupR3Cy7Xs4fKwRWIpZq+XvtmjY8F0ZNmRwDgO4kEHr6CFlieDV5x7so0SuiIi81iIiICIiAiIgIiICIiAiIgIiICIiAiIgIiICIiAiIgIiICIiAiIgIiICIiAiIgIiICIq4NYszDCzTkTM06WrPNXvNk2x5kY4sEb52h2xLwQeRry0NcSO4EIzUf84+E/RN3/ADqqk1GZTSmalyNTPtyIt5SCs2u/GebHTLSAZuzPLzhznBpBe5w2ja3ZvM5y9DspnmnbyOybj6Sy1T2/5zg/8l6tExiYdMRMZotnmI1ztZaU0ihPhbPexmV96pfx0+Fs97GZX3ql/HWWR+qPujqWTaLNbHHPHVuJVXQD8TddrCzXdZZi47FV72xtbzEvc2YtYeXzgHEEjYgHcKx5fVmWweOmvW9G5kV4tuYxSVZXdSANmsmLj1I7gmR+qPujqWWdFCfC2e9jMr71S/jp8LZ72MyvvVL+OmR+qPujqWTaKE+Fs97GZX3ql/HT4Wz3sZlfeqX8dMj9UfdHUsm18yas8Kvg7wst5rTOsqd+fMxZexbkbTx5LnOFmR8TxLu3ct32B36dR619BMvais7si0parSno1925XbEPzuMcj3bf2NJWXeEZ4G+F47cOa9DxmKnrTHdrPSzroyBJJI90kkUoG57Fz3HYecY+hbv5wdqxpinCmm8XmY0TE6L7DRC7cI9YQcZtDQ6z0nkc/h8VlMk6zCM0yKbtY43GOVjGF7zHE5zXgDma4Fu7QGkc12NrU1F57Sjj8oyXJiNprTOrugou/wBY4P5g+Rh72gtDh1Gx8007T/Be9w209jcZoTVuRoV8fWjrR0M//wBJ05QxrWgkEtkiJDe6GRkYLj/JnoB3nibldLBzda6YtYuFp2+F8Lz5KgR/WdyME0XrJfEGN3+OdiV5rFYoda1e3jgu0sji5pr8mPgbaquLZntG4eHs5mhjh1a5xG/d0PRSuJzOPz1JtzGXq2RqOcWtsVJmyxkg7EBzSRuCCCvXgtQYvU+NjyGHyNTK0JPiWqU7Zo3evZzSQvTa0ph7tylblx1c2qU7rNeZrOV8cjhs5wI2+MO/1+ndBLIq9Q0taxEmKjpZ7ImhUfM6etdeLTrTX7lrXSyAyDkPxSHd3Q79NvDHXNUU2YuDJ0KORkkbP49dxsphZEW9YuSGTcnnHQ+f5p9YO4CyIq7R11jbHwdHcZaw1y9BJYjqZKAxPY2P/SBzurAQOu3N1HUbjqp2rbgvVorFaaOxXlaHxyxODmPae4gjoQg9qIiAiIgIiICIiAiIgIiICIiAiIgIiICIiAiIgIiICIiAiIgIiiMvqOLH2jj60L7+YfVltQUowRzhg6B0m3LHzOIaC4jck7b8p2CXUBPqsWLUtXD1JMxZrXYqlzkcIoqocOZ73PdsHlje9jOZ27mghu5I9NjS0up61qHUrorePuQQNkwkXnVo3tIfJvJytfMHO2HnBrS1oBZ1dvZUEBBpqe7NVs5u869ZqW5LNZlTtK0DAdxG18Yee1LGnveSC7dwa0hobORRMgiZFExscbGhrWMGwaB3AD0BeaICIiAo7UVG7lNP5OnjcicRkbFWWGtkBEJTVlcwhkvISA7lcQ7lJ2O2ykVUOKWet4bSzquKlbHn8xM3FYsknpYlB/lNh1IiYJJiP6sTkHw/4MfgqcRNF+Eph+I0+Tg1dpmTIZevYzzrBZYlDRNALEsUh5j2r9y3kdJ3bk8pDj9369m8W0jkpjPkqwjY15lxEfPaaA4H+Tbsdz6D07iV36cwFLSmn8ZhcbF2GPx1aOpXj335Y2NDWjf09AF6tW0ZMnpXM04bV2jNPTmiZaxpAtQuLCA+Lfp2gJ3bv03A3QSyLiwuTjzWHo5CKOaKK3BHYbHYjMcjQ5ocA5p6tcN+oPcV2oCIiAiIgIiIKZnuEmnszkpsrVisaez0pDn5jBTGpZkI7u15fNnA3PmzNe38y4HT8Q9HueZIKev8Y3q3xUMx+UaN+4te7xeZ3f15oB3DY960JEFQ05xV05qTJtxItyYrPFvN8C5eJ1S4QO8tjk2MjR/Xj5m/nVvUXqLTGI1bjnUM1jKuVpuO/Y24myNB225huOhG/QjqFUmaH1Jo0sdpHPOv49rt3YPUs0lhnL082G3500R/7Ttm+gNb3gNAc0OaWuAII2IPpUC/Q2GbLHNVqnGTxVJKUMmPkdX7KJ53Ia1pDdwTzAkHY9QuTSvEGpqG6/FXadnAaiiYZJMRkQ1srmAgOkhc0lk0YLm+fGSBzAO5XHlVqQVxuJ1Bi2NFLMR5OGDGmCOvlYQJZ7Y+JNJPHsGtI6OAiPoI22IP4/VN7FxvdmMDbgjgxzbtm3jP/boBL3SQRNYBYlc3vBEI5h3Dm80WREEbjdR4vL2X1qd+vPbjhjsSVQ8CaOOQbsc+M+c0OHdzAdxUko3N6bxeo6dmrkqMNuGxF2Moe3q5m/NtzDqNiARsehAPeo69pvJwMyUuEz0tO5YjgZBHkovHKlYxkAkR8zHnnb0d/KD1jY7khY0VevZ/LYd+TmuYJ9rHwywtqPxU3jFiaN2we+SFzWcnI7vDHSbt2I67tEhjtQ43LWbtapdinsUp/FrMIds+KTl5uVwPUbtII9Y6jogkUREBERAREQEREBERAREQEREBERAREQEREBEVc1U+PI3sXp+STGvr5ITm7RvBzn2qjI9pGxtBAPnyQh3Nu3lc4EHmGwe/xu/m7QbRe7HUqtuMyWZImyC/F2fMRCebzW8zmNL3Ak8sgDRu2QduEwlLTmMix+Og8XqxFzgzmLiXOcXPc5ziS5znOc4uJJJJJJJXbHGyGNscbWsY0BrWtGwAHcAF5ICIiAiIgIiIPwnYLP8AR5PEDUw1s882EghfV083fzZon8plvd+x7Xla2I+iNpcDtO4Lyy8r+J+UsYOlMW6VpTOgzNuMuBuytPnUonDvYD0meDsNjCN3dr2V9jjbExrGNDGNADWtGwA9QQeSIiCv6SD6AyOIk+Fp/ELLuS9lSH+Msl/lR2cg+MxnOYhzbOHZdd9w91gUFqHGyx2IM1j6RvZemx0LIDbdA2aF72GRp72ucA3mZzD4w25mB7nKVoZCrlakdqlZhuVZBuyevIHscN9ujh0PUFB0IiICIiAiIgIiICIiCG1RpPHaupQwX4j2teVtipbiIbPUmbvyyxP/AKLhuR6iC5rgWuIMZofUd63aymn82WnO4d0YknbH2bL0D27xWmN68ocRIxzd+j4pAPN5SbYs+yrDBx90y+FjgbWmsoLLx8Utis0OyB6d4M0u3XuL+h9AaCiIgIiICj8zp7GahZWZk8fWvtq2I7dfxiIPMMzDuyRhPxXN3Ozh16n1qQRBARYLJ4ycOx+YfNBNkH27MOUYbBELx50MDg5pjAds5vNzgec3YAt5PChq4sNCtnKMuEydx07Y4XEzwu7IcxInaOQAs89ofyuIDvN8121iXhLEyeN8cjGyRvBa5jhuHA94IQeaKry4O3pOlz6ahE1KnSbXracDmQV/NfuDE/l3Y7kLmBpPJ0jHmAEmdx+Wp5R1plWwyaSpMa9iNp86GQNDuR472nlcxw372ua4bhwJDrREQEREBERAREQERQuY1tp7T9oVsnnMdj7JHN2Nm0xj9vXyk77LOmiqubUxeVtdNIqt+FLR3tTiPfY/tT8KWjvanEe+x/atvd8bcn0lcmdi0oqt+FLR3tTiPfY/tT8KWjvanEe+x/and8bcn0kyZ2LSiq34UtHe1OI99j+1PwpaO9qcR77H9qd3xtyfSTJnYtKpmvtT4zRWU05l81msHgcUbE1Oa1mZGwucXwue1kUrtg0kw7kEgENPpAXV+FLR3tTiPfY/tXwX/wCkD4H4XiDqWhxA0Plsdksvdkho5ijWtsfI/YBkVkDfua0NY71ANPocU7vjbk+kmTOx/Q3A6gxeqcTXymFyVPL4ywCYbtCdk8MoBLTyvaSDsQR0PeCpBZpw5z+g+HWgtP6YpaowwrYmjFTaW3IxzljQC7v73Hc/3qxfhS0d7U4j32P7U7vjbk+kmTOxaUVW/Clo72pxHvsf2p+FLR3tTiPfY/tTu+NuT6SZM7FpRVb8KWjvanEe+x/an4UtHe1OI99j+1O7425PpJkzsWlUjOZW7rLLWNOYKeSpSgPZ5fMwuLXQ7jrWruH+uIPnPH+jB/rkbQOp+LeGzeTGn8RqehjIHMD7+c8ajb2EZ7o6/N0fM7Y+d1bGOp3dytM/htc6A09i6+Ox2oMLUpQN5Y4o7sew67kkl25JJJJO5JJJJJTu+NuT6SZM7FrxOJp4HGVcdjq0dOjVjbFDXhbysjYBsAAutVb8KWjvanEe+x/avZDxM0jYkDI9TYh7jsABdj9J2Hp9ZA/vTu+NuT6Slp2LKiIudBQFuKXTdyS9Wjmnxk2zZsdSqMc6OV0hLrIIIcd+c842eTytLQCHc8+iAirToY9DxukrxQ19NxtLn1ataWSWGVz+r2hhcOz87q0MAb1dvtvtZGua9oc0hzSNwQdwQg/UREBERAREQEREBZ3pHbU/FbVuoWgup4uGHTtR5O4dIwma09v5ueSGI/7Vd3qU3xG1XPpTThfjomWs9flFDE1JN+We28HkDtuvI0NdI8juZG8+hd+jNMRaM0vjsNFYluGtHtLbn/0lmZxLpZn/AO097nPP53FBNIiICIiAiIgIiICgtTGbFxtzVZuRtGk1zpsbj2sebbCADux3VzmgczeUhx5eXrvsZ1eEsbZonxvHMx4LXD1goPNFAaBifX0VhK76VzHmvVjgFbITdtYYGDkHaP8A6btmgl3p33U+gIiICIiAiIg4s1cdj8PetMAL4IJJWg+trSR/5Ko6SqR1sBSkA5p7MTJ55ndXzSOaC57iepJJ/u7u4Kz6q+TGY+hzfqFV7TXycxX0SL9QL0MDNhT5rqSSIizQREQEREBERAREQEREBERAREQF+PY2Rha9oc0jYtcNwV+og5OHbxBDnMZGSKmMyJrVo9ukUboIZgxv+y0ykAdwAAAAACtyp3D78Z6z/TDP2GoriubtPiz9OcQs6RERcqCrll/kc6e26T/oAmWzcmtWZZH1HEg7sBDv5Lq4kczWxgbgcu/LY0QeMcjJo2yRuD2OAc1zTuCD3EFeSp+rNUUeFWLv5/NXjBpeMyWb969b38Q325QxpaXPa524DQ4uDnMaxpB2bXPB28IPB+Efou5qLCVLOPjq35qUlW4WmVoad43nlJA543McR6HFzd3cvMQ1NERAREQF4ve2Npc4hrWjcknYALyWfarkPEXPz6MquJwtQtOpJmjdsjHs5mY8H0Oka5j5O/aEgbAzNc0P3RQdr3UDtbTgOxDI3V9ORlvfXcAZLnUb7zEAM9UTGkbdq8LQF4sY2NjWtaGtaNg0DYALyQEREBERAREQEREBERBW+HVZlPReMhjpX8exrHbVsm/msM893xz6T6f7CFZFXeHsLq+jsbG+peoua129fJzdrYZ57vjv9J9P9hCsSAiIgIiICIiCL1V8mMx9Dm/UKr2mvk5ivokX6gVh1V8mMx9Dm/UKr2mvk5ivokX6gXo4Pgz5+y6kkiIskEREBZV4UubyGm+AmrMlirlqhkK8ULorFGV0UzSbEYPK4EEEgkd471qqonHPQeQ4m8Ks9pnFzVoL99kTYpLjnNiHLMx55i1rj3NPcD12WM6JFQu+EFltODWFbU2inYXL4XTdjVFOozKMsMvVoQQ9jpGs/kpA7kaRs8Dn3Bd6bNlOLvwbl9AUfgntPKupatdp4zt4r2NUT8u3J5++/Lv5u3f17lFcRODVzX2u8rkH3K9bD5HRWQ0vIQXGwyWzLG4SBu3KWhrXf0gd9unpFdxvCniNk9UcPb2oZ9Mw0dKUblJzMbNYfLadLU7BsvnxtDeoBLOu3U8zugGOcc2G8JvVGboaFuxcNmtra1j2xJOej5hMIjK4TDsvMj5WyOD2lziGjdgJ5VZqnHPKZDQOczMOlq0GbwWXkw+Ux1/NxVqtaRga50ptvZsY+WSMg8m/n7cvQqO0twPzuD09wQoT28c+bQ7nHIujkkLZd6UsH8juwc3nSNPncvQH09FEZ3wfNS2Z8rfrS4PITHXUmq62KyckvidqF1OOu2OciMlsjXNMjSGvALW9+/SfzDtxvhUwZbhz5R09Oi/kYtSQaZnxtDKQzxusSvjDHw2QOSVhEsZBPKOpB22V64ecTMhqnVGpNMZ7AM09n8IytYfDXvC5BPBOH9nIyTkYd943tc0tGxA6ndZnT8H/AFk+DKNvW9PiS/rbF6sIpGaOONkJh7eANLDuQIAGO388kkiPuWoYTQl/G8ZtVaulmrOxuVxVCjBExzjM18D7Dnlw5dg0iZu2xJ6HcDpvYytYvaIi2AiIgIiIOHh9+M9Z/phn7DUVxVO4ffjPWf6YZ+w1FcVzdq8T6R+0LIiIuVBERBjnhNcHdK8bNJ47A6lZlZ5hZMuPgxd0wHteQgyPad4y1rd93vaS0EhvnP5XZZ4L3g46s8GG/qMY7JYzOYjMNid4lasSRPhkZzbO52xEO6OI+KN+h6bbL6B1M4/hE0+3oR8F5B3UentaY/8A2VJL0qKKKaKZmm98+e+2Y1TGxloRnlHq/wDIuE/4rN92Tyj1f+RcJ/xWb7spNFn8vcjn1L8EZ5R6v/IuE/4rN92Tyj1f+RcJ/wAVm+7KTRPl7kc+pfghMjntczY+1HRxmAq3XxObBPNkJpWRyEHlc5ggbzAHYlvMN9ttx3qO0jBqTRuCgxlTD4mflLpZ7VjLSumtTPJdJNIRWAL3uJcdgB12AAAAtiJ8vcjn1L8H7gdUzXrxx2TpNx2RLDLEIpjNDMwEAljy1p3G43aWg9RtuNyLEqHePLrXSe3eZrDSfzeLvO3+IH+Cvi5O0UU0TTNMWvF+cx7JIiIuVBERARFG6g1Fj9L4517J2RWrgho6FznuPc1rRuXOOx6AE9CsqaZrmKaYvMiSRY5k+OmQmlcMVg4ooP6MuRnIe7/7bAdv95R5406q3O1LD7f/AEy/vL2KfhHa6ovkxH1hW5rL/CO4w5HgRwwt6yoaYOq46U8bbdQXfFTFC7cGXm7N++zuQbbdzid+nWufhp1V8zw/+7L+8o7UXErOarwGRwuUxeFs47IV5KtiFzZdnxvaWuHxvUe9ZfwbteyPWD6oHwKvCZtceqeTxlPQ0+nsBgYWt+E7OaN58sz3lwi2MEe/m87i7fps0bden1EvkngTDc8H7QEOldP1MbNXbPJZmtWWyGWeR5+M7YgdGhrRt6GhaH+GnVXzPD/7sv7yfwbteyPWD6tzRYZ+GnVXzPD/AO7L+8uirxxz0DwbWGx9uP0ivYfE7+7ma4H+w7f2qT8H7XEf0x6wNrRVvR+v8VrRkjabpILkQ5paVlvJKwev0hzf9ppI9G+/RWReRiYdeFVNFcWmEERFrEXqr5MZj6HN+oVXtNfJzFfRIv1ArDqr5MZj6HN+oVXtNfJzFfRIv1AvRwfBnz9l1JJF6L1U3aNiuJpK5mjdGJoXcr2bjbmafQR3gqO8mIPnmS9+l/eVmZRMIofyYg+eZL36X95PJiD55kvfpf3lLzsEwih/JiD55kvfpf3k8mIPnmS9+l/eS87BMIofyYg+eZL36X95PJiD55kvfpf3kvOwTCKH8mIPnmS9+l/eTyYg+eZL36X95LzsEwih/JiD55kvfpf3k8mIPnmS9+l/eS87BMIofyYg+eZL36X95PJiD55kvfpf3kvOwTCKH8mIPnmS9+l/eTyYg+eZL36X95LzsEwi56NFmPhMTJJpQTzc08rpHf4uJK6FRw8PvxnrP9MM/YaiuKp3D78Z6z/TDP2GoriuftXifSP2hZERFyoIiIKTqb+cfT/6JyH+dSUmozU384+n/wBE5D/OpKTXq/lYfl/lKzqcOUzmPwhpjIXYKZuWG1KwnkDTNM4EtjZv8ZxDXHYddgT6F3LCPCn0zW1Fb4TssXMjUa7WNasXY+/NVIEkE+7gY3N2eCwBr/jN5nAEcx35psHe4gcXdV6Stau1Hp/CaRw2Nbj2YzKyQT2HzMlL7U8u/PMW9k1uzyWkhxcCStV89kfQCh8lq7E4jUeGwVu32WVzDZ3Ua/Zvd2wha10vnAFrdg5p84jffpuvmXhhq/UnH3IaEwuf1HlsRSOkH5qxNgrTqE2Tsi46qJHSR7ODAyNsnK0gEzDfoAE4caoyepeJPCVmWyEmYmxWT1Zh4crNtz3oa/JHHK4jYOcWtAJHeWk+tTK2D6yRfPXCSTNaN4sTYLXuU1HY1Plhfnx1mTJGfC5Ou2UPBhg/+HlijcxpZsBsXHd242+hVlE3ELkPlrpL6RY/Z5FfVQsh8tdJfSLH7PIr6tfav7PL3lZ1CIi4kEREHjJI2GN0j3BjGguc5x2AA7yvmvUWp59bZl+WnLhX85tGAnpFBv5p29DngBzj39w32aFt3FGaSvw31PJES14xs/nD+iOzIJ/uG5WANaGNDWgBoGwA9C+t+B4NMxXjTp0R7k5ofqIi+rYCLLON2dzcF/SGn8M90Bzl2WKeVl00nObHC54ibOGPMZcR3hu55dgRvuqjmqGutLaebVyWYs4+rc1Fiq9F9fLPu24I5Jgydjp3xMLmndpAcHd5B3Gy46+0xRVVTFMzbpdX0Co6TUWPh1DBgn2NsrPWfcjr8jvOiY5rXO5tuUbF7RsTv17lh2rNUZnhm7iHjMbmLs8Feri5qdnKWHWn0XWZ3QSv55CSWgAPAJIBHqU5gdIt0jx7w8Lcxlsx2um7bnSZa46y4OFivuWk/F39Q6dOgCx7zMzFMRri/rMe0jZkRF3I8oZ7FK3BcpzOrXa7ueGZh6tPqPrae4g9CF9E6M1KzV2mqOUawRSTNLZogd+zlaS2Ru/p2cCN/SNivnRatwCle7CagiJ3iiypDPzb14HEf4kn+9fPfGsGmvAjF10zylnGeGoIiL4gReqvkxmPoc36hVe018nMV9Ei/UCsOqvkxmPoc36hVe018nMV9Ei/UC9HB8GfP2XUkkRFkgiqfFfWr+HHDbUmp46r7kmLoyWWxRta4kgdCWuewOA7yA4EgEN3cQDUs74QVLR3wjXy2BzVyfB16cmbuY2tF4rTM7AQ7z5g4gE9WtDngddiOqxmYgayizClxisHiHrnF5DCT4/Sul4InWc/JJB2UcnYGxKZP5bn5eydCW8sZPV3Ny9N4+fwm8BRx2Uu38DqHHRU8T8NwMs1oRLeqmRsbXRMEpc1znPYAyURuO/d0OzKga+izzK8Y2Ye7gsfPpHUTsvm32RRxsbKpmeyBjHukce35I2kPaBzuaQTs4NJC/ZeNuGgwOXyslDJNjxuch08+ARxmWa3JJBEBHtJs5ofYDSSR1Y/YHYbrwNCRZhB4QGImy8FZ+CzsGNmzkunWZqSCHxM3WTPh5Okpk5XSMLQ/k5dyASDuB18IeJeV4kt1BZuabtYfHVMpZp0LcskDmWY4ZTC/wCJM93OJI5dzyhu3Lyl3UpeBoiKrz8UtF1dQDBTavwMWcMzawxkmThbZMriA2Psi7m5iSAG7bncKv8AG/XGV0VjtKtwsdmfIZXUNOj4vTijkmnhHNNPGwSbNBdFDI3mJby82/M3bcW8DSEWXw+EJgrdGkKmJzVvP2rtnHt03HBEL7Jq+xnD+aQRNawOYS8ychD2bOPMFW9S8a8jrP8AB7Q0XVzFJmqp7Uk+QgipOs1K9bmbMGNnkMfOJezBds9vIXFvOS0KZUDdEWbYrjnhcjmcVSix+Xdi8nekxdDUckMQo3LUbZC5jCH9p17KQB5jDHFvmuO435Mb4RGEyOkYNTfAedrYe7KytjJJoITJk53yOjZFXibKXlzi0kFwa3l87m2BIZUDVEVW0BxAq8QKmVkhx17E2sXedjrtLIdkZYZmxxyEbxSSMcOWVh3a495B2IIVpVHDw+/Ges/0wz9hqK4qncPvxnrP9MM/YaiuK5+1eJ9I/aFkREXKgiIgpOpv5x9P/onIf51JSajNTfzj6f8A0TkP86kpNer+Vh+X+UrOpAa20JguI2Cdh9RY9uRoGVk7Wdo+N8cjDux7HsLXMcD3OaQVWc/4PmgdUV8dDk8JJY8QqeIwzDIWY5nV99zDJK2QPlZuSeWQuHU+srRUWFolFJ1TwW0XrHH4ilksHG2DDxmHHmjPLTfVjLQ0xxvhcxzWENaC0HY7DcdF5v4OaMdjNM49uArQVNNWGWsQyu58JpyNO+7XMIJ3PxgSQ/c8wO6uaJaBRtKcEdFaJ1JLn8PhfF8s9sjRPLamnEQkdzSCJsj3NiDiNzyBu6vKIlrCFyHy10l9Isfs8ivqoWQ+WukvpFj9nkV9WrtX9nl7ys6hERcSCIiDmyePhy+Nt0bDS6vaifBI0elrgQf+RXzHLj7WGtWMZeBF2k8wyE/09viyD8zxs4f2+sFfUqqWuuHlPWkTJmyCjloW8kN1rObze/ke3cc7NzvtuCDvsRud/b+Gdujslc04n9NXL/tZpzPmbUFXVU91jsHk8PSqdmA6PIY6WxIX7nchzJ4wBty9NvQevXYRvwfxC2/H2md/X8CWPva03J6A1Xh5XMlwkl+Md1jHSskY7/uuLXj/AA/vUecDnwdvJvL+6n7V9jGJgYn80Ykfd/tMmVGn0VPq7DT43XHwVnIDKyWAUaktQxObv5wcZnuDh6HNLSOvrXspcLtM0MTFjYcc7xSK/FkwJLMz3mzGWlkjnueXOILG9HEjoARsrr8A572by/up+1PgHPezeX91P2rK/Z9MzTM+cGTKsXdEYPJXMtat46OzNlarKV3tXOc2aFnNysLSeUbc7uoAPXv6BQOM4Q4TSEjshpSpFjs4ysakFu/LZuRxxOe1zmFjpgS3zBsA4bejpuDovwDnvZvL+6n7U+Ac97N5f3U/akz2eZvM0384MmVCGP4henO6ZP8A+FsD/wDrXuoUdcsuwOu5rT01QPBmjgxE8cjmb9Q1xtOAO3cSD/YVd/gHPezeX91P2roq6P1RfeGV9N3gT/TsmOFjfzkudv8A4An8yxmrApzziR93+zJlFSythjL3b7D0DqSfQB6ye7Zb5wv01LpfR9WC0zs79lzrdlhO5ZI878n/AHW8rf8AuqD0JwlGFtRZPOSw3shGeaCvC0mCs7+sCer3j0OIbt6Bv1WkL5b4r8Qo7REYOFnpjPM7V0CIi+cEXqr5MZj6HN+oVXtNfJzFfRIv1ArDqr5MZj6HN+oVXtNfJzFfRIv1AvRwfBnz9l1Ou9YkqUrE8VaW7LFG57K0BYJJSBuGNL3NaCe4czgNz1IHVVHy/wA7/wBWuqPecV99V1RVGa6rx+S4waZv6Xu6ezOkatkwSS3sh4lPHIyOxE98IbBae7eRjXN3I2AJPUgNPoz3BH4fx2tKs2a5XaozlPKWJfFdzHXriq3xUDn6hzaxHP6O1J5Tt11FFLbRlNrgdNkqvEvE3s+2fTutXTTSV2UuS3UmkgihLhP2ha9rWxN5WmMbekkBcWM8HuOpouTAST6fpGfKUL1qfT+nGY1tqKtYjm7KRjZXbueYyC/fYBx2Z6FsaJkwKxZ0T43xLx+rZLnMKOJsYyCkYvimaaKSSXn5u8iBjduX19fQs+/ANk616uZdVsl07U1TNqz4OjxJNmeR0sk4hfN2x5g2R7S0tjB2YAQehG0IloGBcHOEWocjo7RFvV+VEdKpP5RM063GGtPFfmfJPtaldI4vMck7zyhkfnAc2/KtG4R6AyPDPS5wNvNw5unBNK+nI2ia8rGPkfIRKe0eJH8zzu8Bm/8AVV3RIiIFXn4c4qxqAZl9vPC2Jmz9nHqHIMrczSCB4uJxFy9OrOTlPXcHcqL4j8PMvq/P6WzOHz9bC3NPyWJ4WW8cbkUkssXYhzmiWM+bG+YAA97wd9mkOviK2gYJlvBQoXXYq8Mjjsrm4JLs2Qs6nwkeTr35bT43yyGDnjEbmmJgYWu81o5SHAlW3GaRvScbKuT+DhS09p3TrsTSkDGRxyzzyxSSmGNp81jGQRN32A3cQN9itORTJgYzprwfb2ExeBxNnVYuYjTEc/k/XZjuyfXlfFJFHNYf2p7d8bJXhvKIwS4kgnYjr1R4PdDUPCrRejW2qh8lTUfUlyOObcqzuhgdAe2rucA9rmSP3HOCCQQ7cLW0TJgQeidLw6N0xRxMMGOgEDTzNxNBtKtzEkkshaXBg6925PrJU4iKjh4ffjPWf6YZ+w1FcVTuH34z1n+mGfsNRXFc/avE+kftCyIiLlQREQVzVWFt27VDKY4Mlu0hJGa0jyxs8MnLztDvQ8FjHNJGx5S07c3M2Fdmsyw7eRuacdhuWy0tv2hX1F1UdomimKZpibbb+0wt1A+HMz7GZv62l95T4czPsZm/raX3lX9Fs71G5HPqX4KB8OZn2Mzf1tL7ynw5mfYzN/W0vvKv6J3qNyOfUvwUD4czPsZm/raX3lPhzM+xmb+tpfeVf0TvUbkc+pfgqGExGQymbrZXJU3YuKm17a1SSRr5XPeNi95Y4tADdwACT5xJI7lb0Rc2JiTiTeSZuIiLUgiIgIiICIiAiIgIiICIiAiIgIiII7UcL7GnspFG0ukfVla1o9JLCAq1pd7ZNNYlzTu11SEg+scgV2VTtcPm9vI/GZvJYOF7i81aYgfCHHqS1ssT+Xc9dmkDck7dV24OJTFM0VTbWuqzpRcHkBkPbPN/UUvu6eQGQ9s839RS+7rffD3459C3F3ouDyAyHtnm/qKX3dPIDIe2eb+opfd0vh78c+hbi70XB5AZD2zzf1FL7unkBkPbPN/UUvu6Xw9+OfQtxd6Lg8gMh7Z5v6il93TyAyHtnm/qKX3dL4e/HPoW4u9FweQGQ9s839RS+7p5AZD2zzf1FL7ul8Pfjn0LcXei4PIDIe2eb+opfd08gMh7Z5v6il93S+Hvxz6FuLvRcHkBkPbPN/UUvu6eQGQ9s839RS+7pfD3459C3F3ouDyAyHtnm/qKX3dPIDIe2eb+opfd0vh78c+hbi70XB5AZD2zzf1FL7uvJmgbm5Eurs1Mw97ezqM36+tsAI/uPpUvh78c+hbi/eH7CL2rZQd2S5cFp2PoqVmH/wATXD+5W9cmKxVXCY+GlShEFaIENbuXEkkkuJO5c4kklxJJJJJJJXWuLGrjErmqNHTMTnERFpQREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERB//9k=", "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "from IPython.display import Image, display\n", "\n", "try:\n", " display(Image(graph.get_graph().draw_mermaid_png()))\n", "except Exception:\n", " # This requires some extra dependencies and is optional\n", " pass" ] }, { "cell_type": "code", "execution_count": 11, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "================================\u001b[1m Human Message \u001b[0m=================================\n", "\n", "I'm learning LangGraph. Could you do some research on it for me?\n", "==================================\u001b[1m Ai Message \u001b[0m==================================\n", "Tool Calls:\n", " tavily_search_results_json (call_VKkBzQsN4sGkuRDrg0qhqJLi)\n", " Call ID: call_VKkBzQsN4sGkuRDrg0qhqJLi\n", " Args:\n", " query: LangGraph programming language\n", "=================================\u001b[1m Tool Message \u001b[0m=================================\n", "Name: tavily_search_results_json\n", "\n", "[{\"url\": \"https://www.gettingstarted.ai/langgraph-tutorial-with-example/\", \"content\": \"LangGraph is a library built by the LangChain team that aims to help developers create graph-based single or multi-agent AI applications. As a low-level framework, LangGraph lets you control how agents interact with each other, which tools to use, and how information flows within the application. LangGraph uses this graph concept to organize AI agents and their interactions. We can then build our Graph by passing our State to the StateGraph class so that all graph nodes communicate by reading and writing to the shared state. A LangGraph node takes the state of the graph as a parameter and returns an updated state after it is executed. Great, now we'll wrap these mock methods and expose them as tools which will become part of the Tools node within our LangGraph graph.\"}, {\"url\": \"https://www.datacamp.com/tutorial/langgraph-tutorial\", \"content\": \"LangGraph can be used to build a wide range of applications. Chatbots. LangGraph is ideal for developing sophisticated chatbots that can handle a wide array of user requests. By leveraging multiple LLM agents, these chatbots can process natural language queries, provide accurate responses, and seamlessly switch between different conversation\"}]\n", "==================================\u001b[1m Ai Message \u001b[0m==================================\n", "\n", "LangGraph is a library developed by the LangChain team, designed to assist developers in creating graph-based single or multi-agent AI applications. It serves as a low-level framework that allows you to control how agents interact with each other, which tools to use, and how information flows within the application. The concept of a graph is used to organize AI agents and their interactions.\n", "\n", "Key features of LangGraph include:\n", "\n", "1. **Graph-Based Structure**: LangGraph uses a graph concept to manage AI agents and their interactions. You can build a graph by passing your state to the `StateGraph` class, allowing all graph nodes to communicate by reading and writing to a shared state.\n", "\n", "2. **Node Functionality**: A LangGraph node takes the state of the graph as a parameter and returns an updated state after execution. This allows for dynamic and flexible interactions within the graph.\n", "\n", "3. **Tool Integration**: You can wrap methods and expose them as tools, which become part of the Tools node within your LangGraph graph.\n", "\n", "4. **Application Versatility**: LangGraph is suitable for building a wide range of applications, such as sophisticated chatbots that can handle various user requests. By leveraging multiple LLM (Large Language Model) agents, these chatbots can process natural language queries, provide accurate responses, and switch seamlessly between different conversation topics.\n", "\n", "For more detailed tutorials and examples, you can visit resources like [Getting Started with LangGraph](https://www.gettingstarted.ai/langgraph-tutorial-with-example/) and [DataCamp's LangGraph Tutorial](https://www.datacamp.com/tutorial/langgraph-tutorial).\n" ] } ], "source": [ "config = {\"configurable\": {\"thread_id\": \"1\"}}\n", "events = graph.stream(\n", " {\n", " \"messages\": [\n", " (\"user\", \"I'm learning LangGraph. Could you do some research on it for me?\")\n", " ]\n", " },\n", " config,\n", " stream_mode=\"values\",\n", ")\n", "for event in events:\n", " if \"messages\" in event:\n", " event[\"messages\"][-1].pretty_print()" ] }, { "cell_type": "code", "execution_count": 15, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "================================\u001b[1m Human Message \u001b[0m=================================\n", "\n", "Ya that's helpful. Maybe I'll build an autonomous agent with it!\n", "==================================\u001b[1m Ai Message \u001b[0m==================================\n", "\n", "That sounds like an exciting project! Building an autonomous agent with LangGraph can be a great way to explore the capabilities of graph-based AI applications. If you have any questions or need further assistance as you work on your project, feel free to ask. Good luck with your development!\n" ] } ], "source": [ "events = graph.stream(\n", " {\n", " \"messages\": [\n", " (\"user\", \"Ya that's helpful. Maybe I'll build an autonomous agent with it!\")\n", " ]\n", " },\n", " config,\n", " stream_mode=\"values\",\n", ")\n", "for event in events:\n", " if \"messages\" in event:\n", " event[\"messages\"][-1].pretty_print()" ] }, { "cell_type": "code", "execution_count": 16, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Num Messages: 8 Next: ()\n", "--------------------------------------------------------------------------------\n", "Num Messages: 7 Next: ('chatbot',)\n", "--------------------------------------------------------------------------------\n", "Num Messages: 6 Next: ('__start__',)\n", "--------------------------------------------------------------------------------\n", "Num Messages: 6 Next: ()\n", "--------------------------------------------------------------------------------\n", "Num Messages: 5 Next: ('chatbot',)\n", "--------------------------------------------------------------------------------\n", "Num Messages: 4 Next: ('__start__',)\n", "--------------------------------------------------------------------------------\n", "Num Messages: 4 Next: ()\n", "--------------------------------------------------------------------------------\n", "Num Messages: 3 Next: ('chatbot',)\n", "--------------------------------------------------------------------------------\n", "Num Messages: 2 Next: ('tools',)\n", "--------------------------------------------------------------------------------\n", "Num Messages: 1 Next: ('chatbot',)\n", "--------------------------------------------------------------------------------\n", "Num Messages: 0 Next: ('__start__',)\n", "--------------------------------------------------------------------------------\n" ] } ], "source": [ "to_replay = None\n", "for state in graph.get_state_history(config):\n", " print(\"Num Messages: \", len(\n", " state.values[\"messages\"]), \"Next: \", state.next)\n", " print(\"-\" * 80)\n", " if len(state.values[\"messages\"]) == 6:\n", " # We are somewhat arbitrarily selecting a specific state based on the number of chat messages in the state.\n", " to_replay = state" ] }, { "cell_type": "code", "execution_count": 17, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "()\n", "{'configurable': {'thread_id': '1', 'checkpoint_ns': '', 'checkpoint_id': '1ef9777b-23cb-64a2-8006-ecf6bb76b8ce'}}\n" ] } ], "source": [ "print(to_replay.next)\n", "print(to_replay.config)" ] }, { "cell_type": "code", "execution_count": 18, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "==================================\u001b[1m Ai Message \u001b[0m==================================\n", "\n", "That sounds like an exciting project! Building an autonomous agent with LangGraph can be a great way to explore the capabilities of graph-based AI applications. If you have any questions or need further assistance as you work on your project, feel free to ask. Good luck with your development!\n" ] } ], "source": [ "# The `checkpoint_id` in the `to_replay.config` corresponds to a state we've persisted to our checkpointer.\n", "for event in graph.stream(None, to_replay.config, stream_mode=\"values\"):\n", " if \"messages\" in event:\n", " event[\"messages\"][-1].pretty_print()" ] } ], "metadata": { "kernelspec": { "display_name": ".venv", "language": "python", "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.12.7" } }, "nbformat": 4, "nbformat_minor": 2 }