mirror of
https://github.com/langchain-ai/langgraph.git
synced 2026-08-17 21:25:46 +02:00
docs: update cassettes & notebook runner processing (#4667)
This commit is contained in:
@@ -5,6 +5,7 @@ import os
|
||||
import json
|
||||
import click
|
||||
import nbformat
|
||||
import re
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
NOTEBOOK_DIRS = ("docs/how-tos","docs/tutorials")
|
||||
@@ -88,12 +89,10 @@ def has_blocklisted_command(code: str, metadata: dict) -> bool:
|
||||
return True
|
||||
return False
|
||||
|
||||
MERMAID_PATTERN = re.compile(r'display\(Image\((\w+)\.get_graph\(\)\.draw_mermaid_png\(\)\)\)')
|
||||
|
||||
def remove_mermaid(code: str) -> str:
|
||||
return code.replace(
|
||||
"display(Image(graph.get_graph().draw_mermaid_png()))",
|
||||
# replace with a dummy statement
|
||||
"print()"
|
||||
)
|
||||
return MERMAID_PATTERN.sub('print()', code)
|
||||
|
||||
|
||||
def add_vcr_to_notebook(
|
||||
@@ -108,6 +107,8 @@ def add_vcr_to_notebook(
|
||||
continue
|
||||
|
||||
lines = cell.source.splitlines()
|
||||
# remove the special tag for hidden cells
|
||||
lines = [line for line in lines if not line.strip().startswith("# hide-cell")]
|
||||
# skip if empty cell
|
||||
if not lines:
|
||||
continue
|
||||
@@ -195,6 +196,11 @@ def remove_mermaid_from_notebook(notebook: nbformat.NotebookNode) -> nbformat.No
|
||||
continue
|
||||
|
||||
cell.source = remove_mermaid(cell.source)
|
||||
|
||||
# skip the cell entirely if it contains PYPPETEER
|
||||
if "PYPPETEER" in cell.source:
|
||||
cell.source = ""
|
||||
|
||||
return notebook
|
||||
|
||||
|
||||
|
||||
+1
File diff suppressed because one or more lines are too long
+1
File diff suppressed because one or more lines are too long
+1
File diff suppressed because one or more lines are too long
@@ -0,0 +1 @@
|
||||
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
|
||||
@@ -0,0 +1 @@
|
||||
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
|
||||
+1
File diff suppressed because one or more lines are too long
+1
File diff suppressed because one or more lines are too long
+1
-1
@@ -1 +1 @@
|
||||
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
|
||||
+1
-1
@@ -1 +1 @@
|
||||
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
|
||||
+1
-1
@@ -1 +1 @@
|
||||
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
|
||||
@@ -0,0 +1 @@
|
||||
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
|
||||
@@ -0,0 +1 @@
|
||||
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
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -0,0 +1 @@
|
||||
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
|
||||
@@ -1 +0,0 @@
|
||||
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
|
||||
@@ -1 +0,0 @@
|
||||
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
|
||||
@@ -1 +0,0 @@
|
||||
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
|
||||
@@ -0,0 +1 @@
|
||||
eNqNVX1sE2UYLxkYQlyiEf5QEzgbBon0be96t3YdYFy2AYPsg7WCfDnf3r1tj13vPe59b6GDiU6UEIx6MQrGj8DWtVgX2AIJjA9jIhBiQCVgTBNi0BiNGogxkohR53tduw+3AfdXe+/z+z2/3/M873Pd2Q5kEhXrM/pVnSITypT9IXZ31kTbLETo7kwS0QRW0i3N4UivZar5igSlBqn2+aCheqFOEyY2VNkr46SvQ/AlESEwjkg6ipVU/q0d7iTc3kZxO9KJu1rg/ZLHXQpxV2/a4TaxhtzVbosg0+1xy5iJ0Cl7sd5UKeIgRxLYpNxWRsDBKLYoJydUucDWtYVRYQVpLFrWoKUgIIIgIFjXEQUapEw9o6QoaTBf1DJZHt7Ld2UTCCrM9Leuh9MJTKg9OMnIUSjLyKAA6TJWVD1uH4t3qoaHU1DM4fVwnYQqOdnJVKiXnWtHyABQUzvQse2AUKjqGnMJqJpETLT9UVNzpG1lw7r6pswItT0ADUNTZejAfVuZ6P6id0BTBpp8nHMqBFjZdGqfqCmJ9bWkWHN0jvdKIS8/MD61BpnujFE4Pz3+wIByO+MBxcbbmRHwkfExmNh9jVBuDk+ghKacsPugmQxIE1yalu4YtbO1LZPTFQ/H0oleQfCGBicQk5Qu230xqBE0ONqJUUjOz/tFwAcAL5yYQI2omQIyZhnsQ/yRUgE1pMdpwu4VpOBhExGDzTN6OcNg1CLdadZRdOlitjiEPc1rxubh0XQd6659thHrHk7wc40wxbHUlZwgVYtSNV/FrWyM9NcW00Sm7NNgxIQ6ibFe1ZeGJysnLL0dKbnaKQcmv2jMMZtTpKlJlQJVNyw2C4WLAwqv7Iyfd578k/eMN1GS1cjJXcIsug8MQdQ+7vgFfCUQ/JGS6435xVOh2VxPkthXVci25N7xYxKLmMX3g5leonsqeHGHldSlpWlLMRo5pisthkKhe/BOqyi4Mc9NhfxfQ0esL7xL5PhWjkRzd42etkK5omigKvYZ9ruNF4TaFhGHhTXtJCAlOyuDIX8y1h4eItRUZUbpDLLBti8gSGaLn6bsvIdtc2cJLReFSjHA1CzlVF3W2O4NW9E67EglSznDRBqGytCYUGzGoa52Fq6JIyC/UAwFxEpFjAIUjSlAClUFQSjkF0DU769SpCohKCmB3g4V2jnBK3BxjOMaOirHgAzlBAIjl9nO1m1oqmlsqO1/FrTiKGYNiUDWOB3rKBNGJtsfdk7WsKWwtW2iTO0K0FqzwT4eEhGE/pAUUIJRKcr2Sv361oHStR69tmln5xc+Yy9lnJLo8fMz5i3YN9tVeMqUN2rWnOPn7h5evfOnuaeesS/X/3ajYdbaudv6zv2QvxBrO5XyfWX9vGv/ls0ty8ovBUV+6ez5D/YPtf96/vLVz06eOT184PrNgYZv/F3L37k1S7rYca5rzrvJPQefyJ4MesjzgwsPwg+WreBv9ID5H1/9pef7ut2tlRZ5LrivImHsndnw6Zlbr/d2X/3khYfKvvxn3Z0bb/9xePOC6y+mnwpz6OvTFbuGeuZtOXTslbWz1p69PWfxHsG99/eh/g3dj/8588dguUfVxI1NMx94c+eSikf+dl1orDFnv7r6tcc+/+69fM3BwVVL1Kej/D6x/ItT8zftv7J61bV/y6+t/PDKX8OeeXduSreX7SpzuYaHy1zvH15VZs1wuf4DgoVD8g==
|
||||
@@ -3219,13 +3219,7 @@
|
||||
"from IPython.display import Image, display\n",
|
||||
"from langchain_core.runnables.graph import CurveStyle, MermaidDrawMethod, NodeStyles\n",
|
||||
"\n",
|
||||
"display(\n",
|
||||
" Image(\n",
|
||||
" app.get_graph().draw_mermaid_png(\n",
|
||||
" draw_method=MermaidDrawMethod.API,\n",
|
||||
" )\n",
|
||||
" )\n",
|
||||
")"
|
||||
"display(Image(app.get_graph().draw_mermaid_png()))"
|
||||
]
|
||||
},
|
||||
{
|
||||
|
||||
@@ -23,38 +23,6 @@
|
||||
"This allows the agent to keep track of the conversation without exceeding the LLM's context window."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "af4ce0ba-7596-4e5f-8bf8-0b0bd6e62833",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"# hide-cell\n",
|
||||
"%%capture --no-stderr\n",
|
||||
"%pip install --quiet -U langgraph \"langchain[anthropic]\""
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "c903a1cf-2977-4e2d-ad7d-8b3946821d89",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"# hide-cell\n",
|
||||
"import getpass\n",
|
||||
"import os\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"def _set_env(var: str):\n",
|
||||
" if not os.environ.get(var):\n",
|
||||
" os.environ[var] = getpass.getpass(f\"{var}: \")\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"_set_env(\"ANTHROPIC_API_KEY\")"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "db38b03c-5609-49e3-9b93-bad0aab47ffb",
|
||||
@@ -425,9 +393,9 @@
|
||||
],
|
||||
"metadata": {
|
||||
"kernelspec": {
|
||||
"display_name": "langgraph",
|
||||
"display_name": "Python 3 (ipykernel)",
|
||||
"language": "python",
|
||||
"name": "langgraph"
|
||||
"name": "python3"
|
||||
},
|
||||
"language_info": {
|
||||
"codemirror_mode": {
|
||||
@@ -439,7 +407,7 @@
|
||||
"name": "python",
|
||||
"nbconvert_exporter": "python",
|
||||
"pygments_lexer": "ipython3",
|
||||
"version": "3.11.9"
|
||||
"version": "3.12.3"
|
||||
}
|
||||
},
|
||||
"nbformat": 4,
|
||||
|
||||
@@ -635,9 +635,9 @@
|
||||
],
|
||||
"metadata": {
|
||||
"kernelspec": {
|
||||
"display_name": "langgraph",
|
||||
"display_name": "Python 3 (ipykernel)",
|
||||
"language": "python",
|
||||
"name": "langgraph"
|
||||
"name": "python3"
|
||||
},
|
||||
"language_info": {
|
||||
"codemirror_mode": {
|
||||
@@ -649,7 +649,7 @@
|
||||
"name": "python",
|
||||
"nbconvert_exporter": "python",
|
||||
"pygments_lexer": "ipython3",
|
||||
"version": "3.11.9"
|
||||
"version": "3.12.3"
|
||||
}
|
||||
},
|
||||
"nbformat": 4,
|
||||
|
||||
@@ -31,7 +31,6 @@
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"# hide-cell\n",
|
||||
"%%capture --no-stderr\n",
|
||||
"%pip install --quiet -U langgraph \"langchain[anthropic]\""
|
||||
]
|
||||
},
|
||||
@@ -1604,9 +1603,9 @@
|
||||
],
|
||||
"metadata": {
|
||||
"kernelspec": {
|
||||
"display_name": "langgraph",
|
||||
"display_name": "Python 3 (ipykernel)",
|
||||
"language": "python",
|
||||
"name": "langgraph"
|
||||
"name": "python3"
|
||||
},
|
||||
"language_info": {
|
||||
"codemirror_mode": {
|
||||
@@ -1618,7 +1617,7 @@
|
||||
"name": "python",
|
||||
"nbconvert_exporter": "python",
|
||||
"pygments_lexer": "ipython3",
|
||||
"version": "3.11.9"
|
||||
"version": "3.12.3"
|
||||
}
|
||||
},
|
||||
"nbformat": 4,
|
||||
|
||||
@@ -1,604 +0,0 @@
|
||||
{
|
||||
"cells": [
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "51466c8d-8ce4-4b3d-be4e-18fdbeda5f53",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"# How to use Postgres checkpointer for persistence\n",
|
||||
"\n",
|
||||
"<div class=\"admonition tip\">\n",
|
||||
" <p class=\"admonition-title\">Prerequisites</p>\n",
|
||||
" <p>\n",
|
||||
" This guide assumes familiarity with the following:\n",
|
||||
" <ul>\n",
|
||||
" <li>\n",
|
||||
" <a href=\"https://langchain-ai.github.io/langgraph/concepts/persistence/\">\n",
|
||||
" Persistence\n",
|
||||
" </a>\n",
|
||||
" </li> \n",
|
||||
" <li>\n",
|
||||
" <a href=\"https://www.postgresql.org/about/\">\n",
|
||||
" Postgresql\n",
|
||||
" </a>\n",
|
||||
" </li> \n",
|
||||
" </ul>\n",
|
||||
" </p>\n",
|
||||
"</div> \n",
|
||||
"\n",
|
||||
"!!! info \"Not needed for LangGraph API users\"\n",
|
||||
"\n",
|
||||
" If you're using the LangGraph API, you needn't manually implement a checkpointer. The API automatically handles checkpointing for you. This guide is relevant when implementing LangGraph in your own custom server.\n",
|
||||
"\n",
|
||||
"When creating LangGraph agents, you can also set them up so that they persist their state. This allows you to do things like interact with an agent multiple times and have it remember previous interactions.\n",
|
||||
"\n",
|
||||
"This how-to guide shows how to use `Postgres` as the backend for persisting checkpoint state using the [`langgraph-checkpoint-postgres`](https://github.com/langchain-ai/langgraph/tree/main/libs/checkpoint-postgres) library.\n",
|
||||
"\n",
|
||||
"For demonstration purposes we add persistence to the [pre-built create react agent](https://langchain-ai.github.io/langgraph/reference/prebuilt/#langgraph.prebuilt.chat_agent_executor.create_react_agent). \n",
|
||||
"\n",
|
||||
"In general, you can add a checkpointer to any custom graph that you build like this:\n",
|
||||
"\n",
|
||||
"```python\n",
|
||||
"from langgraph.graph import StateGraph\n",
|
||||
"\n",
|
||||
"builder = StateGraph(....)\n",
|
||||
"# ... define the graph\n",
|
||||
"checkpointer = # postgres checkpointer (see examples below)\n",
|
||||
"graph = builder.compile(checkpointer=checkpointer)\n",
|
||||
"...\n",
|
||||
"```\n",
|
||||
"\n",
|
||||
"!!! info \"Setup\"\n",
|
||||
"\n",
|
||||
" You need to run `.setup()` once on your checkpointer to initialize the database before you can use it."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "456fa19c-93a5-4750-a410-f2d810b964ad",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## Setup\n",
|
||||
"\n",
|
||||
"You will need access to a postgres instance. There are many resources online that can help\n",
|
||||
"you set up a postgres instance.\n",
|
||||
"\n",
|
||||
"Next, let's install the required packages and set our API keys"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 1,
|
||||
"id": "faadfb1b-cebe-4dcf-82fd-34044c380bc4",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"%%capture --no-stderr\n",
|
||||
"%pip install -U psycopg psycopg-pool langgraph langgraph-checkpoint-postgres"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 1,
|
||||
"id": "eca9aafb-a155-407a-8036-682a2f1297d7",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"import getpass\n",
|
||||
"import os\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"def _set_env(var: str):\n",
|
||||
" if not os.environ.get(var):\n",
|
||||
" os.environ[var] = getpass.getpass(f\"{var}: \")\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"_set_env(\"OPENAI_API_KEY\")"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "b394e26c",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"<div class=\"admonition tip\">\n",
|
||||
" <p class=\"admonition-title\">Set up <a href=\"https://smith.langchain.com\">LangSmith</a> for LangGraph development</p>\n",
|
||||
" <p style=\"padding-top: 5px;\">\n",
|
||||
" Sign up for LangSmith to quickly spot issues and improve the performance of your LangGraph projects. LangSmith lets you use trace data to debug, test, and monitor your LLM apps built with LangGraph — read more about how to get started <a href=\"https://docs.smith.langchain.com\">here</a>. \n",
|
||||
" </p>\n",
|
||||
"</div>"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "e26b3204-cca2-414c-800e-7e09032445ae",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## Define model and tools for the graph"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 1,
|
||||
"id": "e5213193-5a7d-43e7-aeba-fe732bb1cd7a",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"from typing import Literal\n",
|
||||
"\n",
|
||||
"from langchain_core.tools import tool\n",
|
||||
"from langchain_openai import ChatOpenAI\n",
|
||||
"from langgraph.prebuilt import create_react_agent\n",
|
||||
"from langgraph.checkpoint.postgres import PostgresSaver\n",
|
||||
"from langgraph.checkpoint.postgres.aio import AsyncPostgresSaver\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"@tool\n",
|
||||
"def get_weather(city: Literal[\"nyc\", \"sf\"]):\n",
|
||||
" \"\"\"Use this to get weather information.\"\"\"\n",
|
||||
" if city == \"nyc\":\n",
|
||||
" return \"It might be cloudy in nyc\"\n",
|
||||
" elif city == \"sf\":\n",
|
||||
" return \"It's always sunny in sf\"\n",
|
||||
" else:\n",
|
||||
" raise AssertionError(\"Unknown city\")\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"tools = [get_weather]\n",
|
||||
"model = ChatOpenAI(model_name=\"gpt-4o-mini\", temperature=0)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "e9342c62-dbb4-40f6-9271-7393f1ca48c4",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## Use sync connection\n",
|
||||
"\n",
|
||||
"This sets up a synchronous connection to the database. \n",
|
||||
"\n",
|
||||
"Synchronous connections execute operations in a blocking manner, meaning each operation waits for completion before moving to the next one. The `DB_URI` is the database connection URI, with the protocol used for connecting to a PostgreSQL database, authentication, and host where database is running. The connection_kwargs dictionary defines additional parameters for the database connection."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 2,
|
||||
"id": "2b9d13b1-9d72-48a0-b63a-adc062c06c29",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"DB_URI = \"postgresql://postgres:postgres@localhost:5442/postgres?sslmode=disable\""
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 3,
|
||||
"id": "3fe36f67-073a-4fd7-a8f8-da196dd46a0d",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"connection_kwargs = {\n",
|
||||
" \"autocommit\": True,\n",
|
||||
" \"prepare_threshold\": 0,\n",
|
||||
"}"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "e39fc712-9e1c-4831-9077-dd07b0c13594",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"### With a connection pool\n",
|
||||
"\n",
|
||||
"This manages a pool of reusable database connections: \n",
|
||||
"- Advantages: Efficient resource utilization, improved performance for frequent connections\n",
|
||||
"- Best for: Applications with many short-lived database operations\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 4,
|
||||
"id": "bd235fc7-1e5c-4db6-a90b-ea75462ccf7d",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"from psycopg_pool import ConnectionPool\n",
|
||||
"\n",
|
||||
"with ConnectionPool(\n",
|
||||
" # Example configuration\n",
|
||||
" conninfo=DB_URI,\n",
|
||||
" max_size=20,\n",
|
||||
" kwargs=connection_kwargs,\n",
|
||||
") as pool:\n",
|
||||
" checkpointer = PostgresSaver(pool)\n",
|
||||
"\n",
|
||||
" # NOTE: you need to call .setup() the first time you're using your checkpointer\n",
|
||||
" checkpointer.setup()\n",
|
||||
"\n",
|
||||
" graph = create_react_agent(model, tools=tools, checkpointer=checkpointer)\n",
|
||||
" config = {\"configurable\": {\"thread_id\": \"1\"}}\n",
|
||||
" res = graph.invoke({\"messages\": [(\"human\", \"what's the weather in sf\")]}, config)\n",
|
||||
" checkpoint = checkpointer.get(config)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 7,
|
||||
"id": "a7e0e7ec-a675-470b-9270-e4bdc59d4a4d",
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
"text/plain": [
|
||||
"{'messages': [HumanMessage(content=\"what's the weather in sf\", id='735b7deb-b0fe-4ad5-8920-2a3c69bbe9f7'),\n",
|
||||
" AIMessage(content='', additional_kwargs={'tool_calls': [{'id': 'call_lJHMDYgfgRdiEAGfFsEhqqKV', 'function': {'arguments': '{\"city\":\"sf\"}', 'name': 'get_weather'}, 'type': 'function'}]}, response_metadata={'token_usage': {'completion_tokens': 14, 'prompt_tokens': 57, 'total_tokens': 71}, 'model_name': 'gpt-4o-mini-2024-07-18', 'system_fingerprint': 'fp_48196bc67a', 'finish_reason': 'tool_calls', 'logprobs': None}, id='run-c56b3e04-08a9-4a59-b3f5-ee52d0ef0656-0', tool_calls=[{'name': 'get_weather', 'args': {'city': 'sf'}, 'id': 'call_lJHMDYgfgRdiEAGfFsEhqqKV', 'type': 'tool_call'}], usage_metadata={'input_tokens': 57, 'output_tokens': 14, 'total_tokens': 71}),\n",
|
||||
" ToolMessage(content=\"It's always sunny in sf\", name='get_weather', id='0644bf7b-4d1b-4ebe-afa1-d2169ccce582', tool_call_id='call_lJHMDYgfgRdiEAGfFsEhqqKV'),\n",
|
||||
" AIMessage(content='The weather in San Francisco is always sunny!', response_metadata={'token_usage': {'completion_tokens': 10, 'prompt_tokens': 84, 'total_tokens': 94}, 'model_name': 'gpt-4o-mini-2024-07-18', 'system_fingerprint': 'fp_48196bc67a', 'finish_reason': 'stop', 'logprobs': None}, id='run-1ed9b8d0-9b50-4b87-b3a2-9860f51e9fd1-0', usage_metadata={'input_tokens': 84, 'output_tokens': 10, 'total_tokens': 94})]}"
|
||||
]
|
||||
},
|
||||
"execution_count": 7,
|
||||
"metadata": {},
|
||||
"output_type": "execute_result"
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"res"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 8,
|
||||
"id": "96efd8b2-97c9-4207-83b2-00131723a75a",
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
"text/plain": [
|
||||
"{'v': 1,\n",
|
||||
" 'id': '1ef559b7-3b19-6ce8-8003-18d0f60634be',\n",
|
||||
" 'ts': '2024-08-08T15:32:42.108605+00:00',\n",
|
||||
" 'current_tasks': {},\n",
|
||||
" 'pending_sends': [],\n",
|
||||
" 'versions_seen': {'agent': {'tools': '00000000000000000000000000000004.022986cd20ae85c77ea298a383f69ba8',\n",
|
||||
" 'start:agent': '00000000000000000000000000000002.d6f25946c3108fc12f27abbcf9b4cedc'},\n",
|
||||
" 'tools': {'branch:agent:should_continue:tools': '00000000000000000000000000000003.065d90dd7f7cd091f0233855210bb2af'},\n",
|
||||
" '__input__': {},\n",
|
||||
" '__start__': {'__start__': '00000000000000000000000000000001.ab89befb52cc0e91e106ef7f500ea033'}},\n",
|
||||
" 'channel_versions': {'agent': '00000000000000000000000000000005.065d90dd7f7cd091f0233855210bb2af',\n",
|
||||
" 'tools': '00000000000000000000000000000005.',\n",
|
||||
" 'messages': '00000000000000000000000000000005.b9adc75836c78af94af1d6811340dd13',\n",
|
||||
" '__start__': '00000000000000000000000000000002.',\n",
|
||||
" 'start:agent': '00000000000000000000000000000003.',\n",
|
||||
" 'branch:agent:should_continue:tools': '00000000000000000000000000000004.'},\n",
|
||||
" 'channel_values': {'agent': 'agent',\n",
|
||||
" 'messages': [HumanMessage(content=\"what's the weather in sf\", id='735b7deb-b0fe-4ad5-8920-2a3c69bbe9f7'),\n",
|
||||
" AIMessage(content='', additional_kwargs={'tool_calls': [{'id': 'call_lJHMDYgfgRdiEAGfFsEhqqKV', 'function': {'arguments': '{\"city\":\"sf\"}', 'name': 'get_weather'}, 'type': 'function'}]}, response_metadata={'token_usage': {'completion_tokens': 14, 'prompt_tokens': 57, 'total_tokens': 71}, 'model_name': 'gpt-4o-mini-2024-07-18', 'system_fingerprint': 'fp_48196bc67a', 'finish_reason': 'tool_calls', 'logprobs': None}, id='run-c56b3e04-08a9-4a59-b3f5-ee52d0ef0656-0', tool_calls=[{'name': 'get_weather', 'args': {'city': 'sf'}, 'id': 'call_lJHMDYgfgRdiEAGfFsEhqqKV', 'type': 'tool_call'}], usage_metadata={'input_tokens': 57, 'output_tokens': 14, 'total_tokens': 71}),\n",
|
||||
" ToolMessage(content=\"It's always sunny in sf\", name='get_weather', id='0644bf7b-4d1b-4ebe-afa1-d2169ccce582', tool_call_id='call_lJHMDYgfgRdiEAGfFsEhqqKV'),\n",
|
||||
" AIMessage(content='The weather in San Francisco is always sunny!', response_metadata={'token_usage': {'completion_tokens': 10, 'prompt_tokens': 84, 'total_tokens': 94}, 'model_name': 'gpt-4o-mini-2024-07-18', 'system_fingerprint': 'fp_48196bc67a', 'finish_reason': 'stop', 'logprobs': None}, id='run-1ed9b8d0-9b50-4b87-b3a2-9860f51e9fd1-0', usage_metadata={'input_tokens': 84, 'output_tokens': 10, 'total_tokens': 94})]}}"
|
||||
]
|
||||
},
|
||||
"execution_count": 8,
|
||||
"metadata": {},
|
||||
"output_type": "execute_result"
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"checkpoint"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "967c95c7-e392-4819-bd71-f29e91c68df3",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"### With a connection\n",
|
||||
"\n",
|
||||
"This creates a single, dedicated connection to the database:\n",
|
||||
"- Advantages: Simple to use, suitable for longer transactions\n",
|
||||
"- Best for: Applications with fewer, longer-lived database operations"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 9,
|
||||
"id": "180d6daf-8fa7-4608-bd2e-bfbf44ed5836",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"from psycopg import Connection\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"with Connection.connect(DB_URI, **connection_kwargs) as conn:\n",
|
||||
" checkpointer = PostgresSaver(conn)\n",
|
||||
" # NOTE: you need to call .setup() the first time you're using your checkpointer\n",
|
||||
" # checkpointer.setup()\n",
|
||||
" graph = create_react_agent(model, tools=tools, checkpointer=checkpointer)\n",
|
||||
" config = {\"configurable\": {\"thread_id\": \"2\"}}\n",
|
||||
" res = graph.invoke({\"messages\": [(\"human\", \"what's the weather in sf\")]}, config)\n",
|
||||
"\n",
|
||||
" checkpoint_tuple = checkpointer.get_tuple(config)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 10,
|
||||
"id": "613d0bbc-0e38-45c4-aace-1f6f7ae27c7b",
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
"text/plain": [
|
||||
"CheckpointTuple(config={'configurable': {'thread_id': '2', 'checkpoint_ns': '', 'checkpoint_id': '1ef559b7-4650-6bfc-8003-1c5488f19318'}}, checkpoint={'v': 1, 'id': '1ef559b7-4650-6bfc-8003-1c5488f19318', 'ts': '2024-08-08T15:32:43.284551+00:00', 'current_tasks': {}, 'pending_sends': [], 'versions_seen': {'agent': {'tools': '00000000000000000000000000000004.022986cd20ae85c77ea298a383f69ba8', 'start:agent': '00000000000000000000000000000002.d6f25946c3108fc12f27abbcf9b4cedc'}, 'tools': {'branch:agent:should_continue:tools': '00000000000000000000000000000003.065d90dd7f7cd091f0233855210bb2af'}, '__input__': {}, '__start__': {'__start__': '00000000000000000000000000000001.ab89befb52cc0e91e106ef7f500ea033'}}, 'channel_versions': {'agent': '00000000000000000000000000000005.065d90dd7f7cd091f0233855210bb2af', 'tools': '00000000000000000000000000000005.', 'messages': '00000000000000000000000000000005.af9f229d2c4e14f4866eb37f72ec39f6', '__start__': '00000000000000000000000000000002.', 'start:agent': '00000000000000000000000000000003.', 'branch:agent:should_continue:tools': '00000000000000000000000000000004.'}, 'channel_values': {'agent': 'agent', 'messages': [HumanMessage(content=\"what's the weather in sf\", id='7a14f96c-2d88-454f-9520-0e0287a4abbb'), AIMessage(content='', additional_kwargs={'tool_calls': [{'id': 'call_NcL4dBTYu4kSPGMKdxztdpjN', 'function': {'arguments': '{\"city\":\"sf\"}', 'name': 'get_weather'}, 'type': 'function'}]}, response_metadata={'token_usage': {'completion_tokens': 14, 'prompt_tokens': 57, 'total_tokens': 71}, 'model_name': 'gpt-4o-mini-2024-07-18', 'system_fingerprint': 'fp_48196bc67a', 'finish_reason': 'tool_calls', 'logprobs': None}, id='run-39adbf2c-36ef-40f6-9cad-8e1f8167fc19-0', tool_calls=[{'name': 'get_weather', 'args': {'city': 'sf'}, 'id': 'call_NcL4dBTYu4kSPGMKdxztdpjN', 'type': 'tool_call'}], usage_metadata={'input_tokens': 57, 'output_tokens': 14, 'total_tokens': 71}), ToolMessage(content=\"It's always sunny in sf\", name='get_weather', id='c9f82354-3225-40a8-bf54-81f3e199043b', tool_call_id='call_NcL4dBTYu4kSPGMKdxztdpjN'), AIMessage(content='The weather in San Francisco is always sunny!', response_metadata={'token_usage': {'completion_tokens': 10, 'prompt_tokens': 84, 'total_tokens': 94}, 'model_name': 'gpt-4o-mini-2024-07-18', 'system_fingerprint': 'fp_48196bc67a', 'finish_reason': 'stop', 'logprobs': None}, id='run-83888be3-d681-42ca-ad67-e2f5ee8550de-0', usage_metadata={'input_tokens': 84, 'output_tokens': 10, 'total_tokens': 94})]}}, metadata={'step': 3, 'source': 'loop', 'writes': {'agent': {'messages': [AIMessage(content='The weather in San Francisco is always sunny!', response_metadata={'logprobs': None, 'model_name': 'gpt-4o-mini-2024-07-18', 'token_usage': {'total_tokens': 94, 'prompt_tokens': 84, 'completion_tokens': 10}, 'finish_reason': 'stop', 'system_fingerprint': 'fp_48196bc67a'}, id='run-83888be3-d681-42ca-ad67-e2f5ee8550de-0', usage_metadata={'input_tokens': 84, 'output_tokens': 10, 'total_tokens': 94})]}}}, parent_config={'configurable': {'thread_id': '2', 'checkpoint_ns': '', 'checkpoint_id': '1ef559b7-4087-681a-8002-88a5738f76f1'}}, pending_writes=[])"
|
||||
]
|
||||
},
|
||||
"execution_count": 10,
|
||||
"metadata": {},
|
||||
"output_type": "execute_result"
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"checkpoint_tuple"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "49fb52fd-af31-4603-889d-66d783244bce",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"### With a connection string\n",
|
||||
"\n",
|
||||
"This creates a connection based on a connection string:\n",
|
||||
"- Advantages: Simplicity, encapsulates connection details\n",
|
||||
"- Best for: Quick setup or when connection details are provided as a string"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 11,
|
||||
"id": "5fe54e79-9eaf-44e2-b2d9-1e0284b984d0",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"with PostgresSaver.from_conn_string(DB_URI) as checkpointer:\n",
|
||||
" graph = create_react_agent(model, tools=tools, checkpointer=checkpointer)\n",
|
||||
" config = {\"configurable\": {\"thread_id\": \"3\"}}\n",
|
||||
" res = graph.invoke({\"messages\": [(\"human\", \"what's the weather in sf\")]}, config)\n",
|
||||
"\n",
|
||||
" checkpoint_tuples = list(checkpointer.list(config))"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 12,
|
||||
"id": "b2ce743b-5896-443b-9ec0-a655b065895c",
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
"text/plain": [
|
||||
"[CheckpointTuple(config={'configurable': {'thread_id': '3', 'checkpoint_ns': '', 'checkpoint_id': '1ef559b7-5024-6476-8003-cf0a750e6b37'}}, checkpoint={'v': 1, 'id': '1ef559b7-5024-6476-8003-cf0a750e6b37', 'ts': '2024-08-08T15:32:44.314900+00:00', 'current_tasks': {}, 'pending_sends': [], 'versions_seen': {'agent': {'tools': '00000000000000000000000000000004.022986cd20ae85c77ea298a383f69ba8', 'start:agent': '00000000000000000000000000000002.d6f25946c3108fc12f27abbcf9b4cedc'}, 'tools': {'branch:agent:should_continue:tools': '00000000000000000000000000000003.065d90dd7f7cd091f0233855210bb2af'}, '__input__': {}, '__start__': {'__start__': '00000000000000000000000000000001.ab89befb52cc0e91e106ef7f500ea033'}}, 'channel_versions': {'agent': '00000000000000000000000000000005.065d90dd7f7cd091f0233855210bb2af', 'tools': '00000000000000000000000000000005.', 'messages': '00000000000000000000000000000005.3f8b8d9923575b911e17157008ab75ac', '__start__': '00000000000000000000000000000002.', 'start:agent': '00000000000000000000000000000003.', 'branch:agent:should_continue:tools': '00000000000000000000000000000004.'}, 'channel_values': {'agent': 'agent', 'messages': [HumanMessage(content=\"what's the weather in sf\", id='5bf79d15-6332-4bf5-89bd-ee192b31ed84'), AIMessage(content='', additional_kwargs={'tool_calls': [{'id': 'call_9y3q1BiwW7zGh2gk2faInTRk', 'function': {'arguments': '{\"city\":\"sf\"}', 'name': 'get_weather'}, 'type': 'function'}]}, response_metadata={'token_usage': {'completion_tokens': 14, 'prompt_tokens': 57, 'total_tokens': 71}, 'model_name': 'gpt-4o-mini-2024-07-18', 'system_fingerprint': 'fp_507c9469a1', 'finish_reason': 'tool_calls', 'logprobs': None}, id='run-2958adc7-f6a4-415d-ade1-5ee77e0b9276-0', tool_calls=[{'name': 'get_weather', 'args': {'city': 'sf'}, 'id': 'call_9y3q1BiwW7zGh2gk2faInTRk', 'type': 'tool_call'}], usage_metadata={'input_tokens': 57, 'output_tokens': 14, 'total_tokens': 71}), ToolMessage(content=\"It's always sunny in sf\", name='get_weather', id='cac4f90a-dc3e-4bfa-940f-1c630289a583', tool_call_id='call_9y3q1BiwW7zGh2gk2faInTRk'), AIMessage(content='The weather in San Francisco is always sunny!', response_metadata={'token_usage': {'completion_tokens': 10, 'prompt_tokens': 84, 'total_tokens': 94}, 'model_name': 'gpt-4o-mini-2024-07-18', 'system_fingerprint': 'fp_48196bc67a', 'finish_reason': 'stop', 'logprobs': None}, id='run-97d3fb7a-3d2e-4090-84f4-dafdfe44553f-0', usage_metadata={'input_tokens': 84, 'output_tokens': 10, 'total_tokens': 94})]}}, metadata={'step': 3, 'source': 'loop', 'writes': {'agent': {'messages': [AIMessage(content='The weather in San Francisco is always sunny!', response_metadata={'logprobs': None, 'model_name': 'gpt-4o-mini-2024-07-18', 'token_usage': {'total_tokens': 94, 'prompt_tokens': 84, 'completion_tokens': 10}, 'finish_reason': 'stop', 'system_fingerprint': 'fp_48196bc67a'}, id='run-97d3fb7a-3d2e-4090-84f4-dafdfe44553f-0', usage_metadata={'input_tokens': 84, 'output_tokens': 10, 'total_tokens': 94})]}}}, parent_config={'configurable': {'thread_id': '3', 'checkpoint_ns': '', 'checkpoint_id': '1ef559b7-4b3d-6430-8002-b5c99d2eb4db'}}, pending_writes=None),\n",
|
||||
" CheckpointTuple(config={'configurable': {'thread_id': '3', 'checkpoint_ns': '', 'checkpoint_id': '1ef559b7-4b3d-6430-8002-b5c99d2eb4db'}}, checkpoint={'v': 1, 'id': '1ef559b7-4b3d-6430-8002-b5c99d2eb4db', 'ts': '2024-08-08T15:32:43.800857+00:00', 'current_tasks': {}, 'pending_sends': [], 'versions_seen': {'agent': {'start:agent': '00000000000000000000000000000002.d6f25946c3108fc12f27abbcf9b4cedc'}, 'tools': {'branch:agent:should_continue:tools': '00000000000000000000000000000003.065d90dd7f7cd091f0233855210bb2af'}, '__input__': {}, '__start__': {'__start__': '00000000000000000000000000000001.ab89befb52cc0e91e106ef7f500ea033'}}, 'channel_versions': {'agent': '00000000000000000000000000000004.', 'tools': '00000000000000000000000000000004.022986cd20ae85c77ea298a383f69ba8', 'messages': '00000000000000000000000000000004.1195f50946feaedb0bae1fdbfadc806b', '__start__': '00000000000000000000000000000002.', 'start:agent': '00000000000000000000000000000003.', 'branch:agent:should_continue:tools': '00000000000000000000000000000004.'}, 'channel_values': {'tools': 'tools', 'messages': [HumanMessage(content=\"what's the weather in sf\", id='5bf79d15-6332-4bf5-89bd-ee192b31ed84'), AIMessage(content='', additional_kwargs={'tool_calls': [{'id': 'call_9y3q1BiwW7zGh2gk2faInTRk', 'function': {'arguments': '{\"city\":\"sf\"}', 'name': 'get_weather'}, 'type': 'function'}]}, response_metadata={'token_usage': {'completion_tokens': 14, 'prompt_tokens': 57, 'total_tokens': 71}, 'model_name': 'gpt-4o-mini-2024-07-18', 'system_fingerprint': 'fp_507c9469a1', 'finish_reason': 'tool_calls', 'logprobs': None}, id='run-2958adc7-f6a4-415d-ade1-5ee77e0b9276-0', tool_calls=[{'name': 'get_weather', 'args': {'city': 'sf'}, 'id': 'call_9y3q1BiwW7zGh2gk2faInTRk', 'type': 'tool_call'}], usage_metadata={'input_tokens': 57, 'output_tokens': 14, 'total_tokens': 71}), ToolMessage(content=\"It's always sunny in sf\", name='get_weather', id='cac4f90a-dc3e-4bfa-940f-1c630289a583', tool_call_id='call_9y3q1BiwW7zGh2gk2faInTRk')]}}, metadata={'step': 2, 'source': 'loop', 'writes': {'tools': {'messages': [ToolMessage(content=\"It's always sunny in sf\", name='get_weather', id='cac4f90a-dc3e-4bfa-940f-1c630289a583', tool_call_id='call_9y3q1BiwW7zGh2gk2faInTRk')]}}}, parent_config={'configurable': {'thread_id': '3', 'checkpoint_ns': '', 'checkpoint_id': '1ef559b7-4b30-6078-8001-eaf8c9bd8844'}}, pending_writes=None),\n",
|
||||
" CheckpointTuple(config={'configurable': {'thread_id': '3', 'checkpoint_ns': '', 'checkpoint_id': '1ef559b7-4b30-6078-8001-eaf8c9bd8844'}}, checkpoint={'v': 1, 'id': '1ef559b7-4b30-6078-8001-eaf8c9bd8844', 'ts': '2024-08-08T15:32:43.795440+00:00', 'current_tasks': {}, 'pending_sends': [], 'versions_seen': {'agent': {'start:agent': '00000000000000000000000000000002.d6f25946c3108fc12f27abbcf9b4cedc'}, '__input__': {}, '__start__': {'__start__': '00000000000000000000000000000001.ab89befb52cc0e91e106ef7f500ea033'}}, 'channel_versions': {'agent': '00000000000000000000000000000003.065d90dd7f7cd091f0233855210bb2af', 'messages': '00000000000000000000000000000003.bab5fb3a70876f600f5f2fd46945ce5f', '__start__': '00000000000000000000000000000002.', 'start:agent': '00000000000000000000000000000003.', 'branch:agent:should_continue:tools': '00000000000000000000000000000003.065d90dd7f7cd091f0233855210bb2af'}, 'channel_values': {'agent': 'agent', 'messages': [HumanMessage(content=\"what's the weather in sf\", id='5bf79d15-6332-4bf5-89bd-ee192b31ed84'), AIMessage(content='', additional_kwargs={'tool_calls': [{'id': 'call_9y3q1BiwW7zGh2gk2faInTRk', 'function': {'arguments': '{\"city\":\"sf\"}', 'name': 'get_weather'}, 'type': 'function'}]}, response_metadata={'token_usage': {'completion_tokens': 14, 'prompt_tokens': 57, 'total_tokens': 71}, 'model_name': 'gpt-4o-mini-2024-07-18', 'system_fingerprint': 'fp_507c9469a1', 'finish_reason': 'tool_calls', 'logprobs': None}, id='run-2958adc7-f6a4-415d-ade1-5ee77e0b9276-0', tool_calls=[{'name': 'get_weather', 'args': {'city': 'sf'}, 'id': 'call_9y3q1BiwW7zGh2gk2faInTRk', 'type': 'tool_call'}], usage_metadata={'input_tokens': 57, 'output_tokens': 14, 'total_tokens': 71})], 'branch:agent:should_continue:tools': 'agent'}}, metadata={'step': 1, 'source': 'loop', 'writes': {'agent': {'messages': [AIMessage(content='', additional_kwargs={'tool_calls': [{'id': 'call_9y3q1BiwW7zGh2gk2faInTRk', 'type': 'function', 'function': {'name': 'get_weather', 'arguments': '{\"city\":\"sf\"}'}}]}, response_metadata={'logprobs': None, 'model_name': 'gpt-4o-mini-2024-07-18', 'token_usage': {'total_tokens': 71, 'prompt_tokens': 57, 'completion_tokens': 14}, 'finish_reason': 'tool_calls', 'system_fingerprint': 'fp_507c9469a1'}, id='run-2958adc7-f6a4-415d-ade1-5ee77e0b9276-0', tool_calls=[{'name': 'get_weather', 'args': {'city': 'sf'}, 'id': 'call_9y3q1BiwW7zGh2gk2faInTRk', 'type': 'tool_call'}], usage_metadata={'input_tokens': 57, 'output_tokens': 14, 'total_tokens': 71})]}}}, parent_config={'configurable': {'thread_id': '3', 'checkpoint_ns': '', 'checkpoint_id': '1ef559b7-46d7-6116-8000-8976b7c89a2f'}}, pending_writes=None),\n",
|
||||
" CheckpointTuple(config={'configurable': {'thread_id': '3', 'checkpoint_ns': '', 'checkpoint_id': '1ef559b7-46d7-6116-8000-8976b7c89a2f'}}, checkpoint={'v': 1, 'id': '1ef559b7-46d7-6116-8000-8976b7c89a2f', 'ts': '2024-08-08T15:32:43.339573+00:00', 'current_tasks': {}, 'pending_sends': [], 'versions_seen': {'__input__': {}, '__start__': {'__start__': '00000000000000000000000000000001.ab89befb52cc0e91e106ef7f500ea033'}}, 'channel_versions': {'messages': '00000000000000000000000000000002.ba0c90d32863686481f7fe5eab9ecdf0', '__start__': '00000000000000000000000000000002.', 'start:agent': '00000000000000000000000000000002.d6f25946c3108fc12f27abbcf9b4cedc'}, 'channel_values': {'messages': [HumanMessage(content=\"what's the weather in sf\", id='5bf79d15-6332-4bf5-89bd-ee192b31ed84')], 'start:agent': '__start__'}}, metadata={'step': 0, 'source': 'loop', 'writes': None}, parent_config={'configurable': {'thread_id': '3', 'checkpoint_ns': '', 'checkpoint_id': '1ef559b7-46ce-6c64-bfff-ef7fe2663573'}}, pending_writes=None),\n",
|
||||
" CheckpointTuple(config={'configurable': {'thread_id': '3', 'checkpoint_ns': '', 'checkpoint_id': '1ef559b7-46ce-6c64-bfff-ef7fe2663573'}}, checkpoint={'v': 1, 'id': '1ef559b7-46ce-6c64-bfff-ef7fe2663573', 'ts': '2024-08-08T15:32:43.336188+00:00', 'current_tasks': {}, 'pending_sends': [], 'versions_seen': {'__input__': {}}, 'channel_versions': {'__start__': '00000000000000000000000000000001.ab89befb52cc0e91e106ef7f500ea033'}, 'channel_values': {'__start__': {'messages': [['human', \"what's the weather in sf\"]]}}}, metadata={'step': -1, 'source': 'input', 'writes': {'messages': [['human', \"what's the weather in sf\"]]}}, parent_config=None, pending_writes=None)]"
|
||||
]
|
||||
},
|
||||
"execution_count": 12,
|
||||
"metadata": {},
|
||||
"output_type": "execute_result"
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"checkpoint_tuples"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "c0a47d3e-e588-48fc-a5d4-2145dff17e77",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## Use async connection\n",
|
||||
"\n",
|
||||
"This sets up an asynchronous connection to the database. \n",
|
||||
"\n",
|
||||
"Async connections allow non-blocking database operations. This means other parts of your application can continue running while waiting for database operations to complete. It's particularly useful in high-concurrency scenarios or when dealing with I/O-bound operations."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "ee6b6cf7-d8f7-4777-a48d-93b5855fe681",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"### With a connection pool"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 5,
|
||||
"id": "4faf6087-73cc-4957-9a4f-f3509a32a740",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"from psycopg_pool import AsyncConnectionPool\n",
|
||||
"\n",
|
||||
"async with AsyncConnectionPool(\n",
|
||||
" # Example configuration\n",
|
||||
" conninfo=DB_URI,\n",
|
||||
" max_size=20,\n",
|
||||
" kwargs=connection_kwargs,\n",
|
||||
") as pool:\n",
|
||||
" checkpointer = AsyncPostgresSaver(pool)\n",
|
||||
"\n",
|
||||
" # NOTE: you need to call .setup() the first time you're using your checkpointer\n",
|
||||
" await checkpointer.setup()\n",
|
||||
"\n",
|
||||
" graph = create_react_agent(model, tools=tools, checkpointer=checkpointer)\n",
|
||||
" config = {\"configurable\": {\"thread_id\": \"4\"}}\n",
|
||||
" res = await graph.ainvoke(\n",
|
||||
" {\"messages\": [(\"human\", \"what's the weather in nyc\")]}, config\n",
|
||||
" )\n",
|
||||
"\n",
|
||||
" checkpoint = await checkpointer.aget(config)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 14,
|
||||
"id": "e0c42044-4de6-4742-8e00-fe295d50c95a",
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
"text/plain": [
|
||||
"{'v': 1,\n",
|
||||
" 'id': '1ef559b7-5cc9-6460-8003-8655824c0944',\n",
|
||||
" 'ts': '2024-08-08T15:32:45.640793+00:00',\n",
|
||||
" 'current_tasks': {},\n",
|
||||
" 'pending_sends': [],\n",
|
||||
" 'versions_seen': {'agent': {'tools': '00000000000000000000000000000004.022986cd20ae85c77ea298a383f69ba8',\n",
|
||||
" 'start:agent': '00000000000000000000000000000002.d6f25946c3108fc12f27abbcf9b4cedc'},\n",
|
||||
" 'tools': {'branch:agent:should_continue:tools': '00000000000000000000000000000003.065d90dd7f7cd091f0233855210bb2af'},\n",
|
||||
" '__input__': {},\n",
|
||||
" '__start__': {'__start__': '00000000000000000000000000000001.0e148ae3debe753278387e84f786e863'}},\n",
|
||||
" 'channel_versions': {'agent': '00000000000000000000000000000005.065d90dd7f7cd091f0233855210bb2af',\n",
|
||||
" 'tools': '00000000000000000000000000000005.',\n",
|
||||
" 'messages': '00000000000000000000000000000005.d869fc7231619df0db74feed624efe41',\n",
|
||||
" '__start__': '00000000000000000000000000000002.',\n",
|
||||
" 'start:agent': '00000000000000000000000000000003.',\n",
|
||||
" 'branch:agent:should_continue:tools': '00000000000000000000000000000004.'},\n",
|
||||
" 'channel_values': {'agent': 'agent',\n",
|
||||
" 'messages': [HumanMessage(content=\"what's the weather in nyc\", id='d883b8a0-99de-486d-91a2-bcfa7f25dc05'),\n",
|
||||
" AIMessage(content='', additional_kwargs={'tool_calls': [{'id': 'call_H6TAYfyd6AnaCrkQGs6Q2fVp', 'function': {'arguments': '{\"city\":\"nyc\"}', 'name': 'get_weather'}, 'type': 'function'}]}, response_metadata={'token_usage': {'completion_tokens': 15, 'prompt_tokens': 58, 'total_tokens': 73}, 'model_name': 'gpt-4o-mini-2024-07-18', 'system_fingerprint': 'fp_48196bc67a', 'finish_reason': 'tool_calls', 'logprobs': None}, id='run-6f542f84-ad73-444c-8ef7-b5ea75a2e09b-0', tool_calls=[{'name': 'get_weather', 'args': {'city': 'nyc'}, 'id': 'call_H6TAYfyd6AnaCrkQGs6Q2fVp', 'type': 'tool_call'}], usage_metadata={'input_tokens': 58, 'output_tokens': 15, 'total_tokens': 73}),\n",
|
||||
" ToolMessage(content='It might be cloudy in nyc', name='get_weather', id='c0e52254-77a4-4ea9-a2b7-61dd2d65ec68', tool_call_id='call_H6TAYfyd6AnaCrkQGs6Q2fVp'),\n",
|
||||
" AIMessage(content='The weather in NYC might be cloudy.', response_metadata={'token_usage': {'completion_tokens': 9, 'prompt_tokens': 88, 'total_tokens': 97}, 'model_name': 'gpt-4o-mini-2024-07-18', 'system_fingerprint': 'fp_48196bc67a', 'finish_reason': 'stop', 'logprobs': None}, id='run-977140d4-7582-40c3-b2b6-31b542c430a3-0', usage_metadata={'input_tokens': 88, 'output_tokens': 9, 'total_tokens': 97})]}}"
|
||||
]
|
||||
},
|
||||
"execution_count": 14,
|
||||
"metadata": {},
|
||||
"output_type": "execute_result"
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"checkpoint"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "56552584-9eb8-40df-a6a0-44151018b509",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"### With a connection"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 15,
|
||||
"id": "386b78bc-2f73-49ba-a2a4-47bce6fc49b7",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"from psycopg import AsyncConnection\n",
|
||||
"\n",
|
||||
"async with await AsyncConnection.connect(DB_URI, **connection_kwargs) as conn:\n",
|
||||
" checkpointer = AsyncPostgresSaver(conn)\n",
|
||||
" graph = create_react_agent(model, tools=tools, checkpointer=checkpointer)\n",
|
||||
" config = {\"configurable\": {\"thread_id\": \"5\"}}\n",
|
||||
" res = await graph.ainvoke(\n",
|
||||
" {\"messages\": [(\"human\", \"what's the weather in nyc\")]}, config\n",
|
||||
" )\n",
|
||||
" checkpoint_tuple = await checkpointer.aget_tuple(config)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 16,
|
||||
"id": "d1ed1344-c923-4a46-b04e-cc3646737d48",
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
"text/plain": [
|
||||
"CheckpointTuple(config={'configurable': {'thread_id': '5', 'checkpoint_ns': '', 'checkpoint_id': '1ef559b7-65b4-60ca-8003-1ef4b620559a'}}, checkpoint={'v': 1, 'id': '1ef559b7-65b4-60ca-8003-1ef4b620559a', 'ts': '2024-08-08T15:32:46.575814+00:00', 'current_tasks': {}, 'pending_sends': [], 'versions_seen': {'agent': {'tools': '00000000000000000000000000000004.022986cd20ae85c77ea298a383f69ba8', 'start:agent': '00000000000000000000000000000002.d6f25946c3108fc12f27abbcf9b4cedc'}, 'tools': {'branch:agent:should_continue:tools': '00000000000000000000000000000003.065d90dd7f7cd091f0233855210bb2af'}, '__input__': {}, '__start__': {'__start__': '00000000000000000000000000000001.0e148ae3debe753278387e84f786e863'}}, 'channel_versions': {'agent': '00000000000000000000000000000005.065d90dd7f7cd091f0233855210bb2af', 'tools': '00000000000000000000000000000005.', 'messages': '00000000000000000000000000000005.1557a6006d58f736d5cb2dd5c5f10111', '__start__': '00000000000000000000000000000002.', 'start:agent': '00000000000000000000000000000003.', 'branch:agent:should_continue:tools': '00000000000000000000000000000004.'}, 'channel_values': {'agent': 'agent', 'messages': [HumanMessage(content=\"what's the weather in nyc\", id='935e7732-b288-49bd-9ec2-1f7610cc38cb'), AIMessage(content='', additional_kwargs={'tool_calls': [{'id': 'call_94KtjtPmsiaj7T8yXvL7Ef31', 'function': {'arguments': '{\"city\":\"nyc\"}', 'name': 'get_weather'}, 'type': 'function'}]}, response_metadata={'token_usage': {'completion_tokens': 15, 'prompt_tokens': 58, 'total_tokens': 73}, 'model_name': 'gpt-4o-mini-2024-07-18', 'system_fingerprint': 'fp_48196bc67a', 'finish_reason': 'tool_calls', 'logprobs': None}, id='run-790c929a-7982-49e7-af67-2cbe4a86373b-0', tool_calls=[{'name': 'get_weather', 'args': {'city': 'nyc'}, 'id': 'call_94KtjtPmsiaj7T8yXvL7Ef31', 'type': 'tool_call'}], usage_metadata={'input_tokens': 58, 'output_tokens': 15, 'total_tokens': 73}), ToolMessage(content='It might be cloudy in nyc', name='get_weather', id='b2dc1073-abc4-4492-8982-434a7e32e445', tool_call_id='call_94KtjtPmsiaj7T8yXvL7Ef31'), AIMessage(content='The weather in NYC might be cloudy.', response_metadata={'token_usage': {'completion_tokens': 9, 'prompt_tokens': 88, 'total_tokens': 97}, 'model_name': 'gpt-4o-mini-2024-07-18', 'system_fingerprint': 'fp_48196bc67a', 'finish_reason': 'stop', 'logprobs': None}, id='run-7e8a7f16-d8e1-457a-89f3-192102396449-0', usage_metadata={'input_tokens': 88, 'output_tokens': 9, 'total_tokens': 97})]}}, metadata={'step': 3, 'source': 'loop', 'writes': {'agent': {'messages': [AIMessage(content='The weather in NYC might be cloudy.', response_metadata={'logprobs': None, 'model_name': 'gpt-4o-mini-2024-07-18', 'token_usage': {'total_tokens': 97, 'prompt_tokens': 88, 'completion_tokens': 9}, 'finish_reason': 'stop', 'system_fingerprint': 'fp_48196bc67a'}, id='run-7e8a7f16-d8e1-457a-89f3-192102396449-0', usage_metadata={'input_tokens': 88, 'output_tokens': 9, 'total_tokens': 97})]}}}, parent_config={'configurable': {'thread_id': '5', 'checkpoint_ns': '', 'checkpoint_id': '1ef559b7-62ae-6128-8002-c04af82bcd41'}}, pending_writes=[])"
|
||||
]
|
||||
},
|
||||
"execution_count": 16,
|
||||
"metadata": {},
|
||||
"output_type": "execute_result"
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"checkpoint_tuple"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "2f7e486a-3e63-41d7-b84b-6743f0a5764c",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"### With a connection string"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 17,
|
||||
"id": "6a39d1ff-ca37-4457-8b52-07d33b59c36e",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"async with AsyncPostgresSaver.from_conn_string(DB_URI) as checkpointer:\n",
|
||||
" graph = create_react_agent(model, tools=tools, checkpointer=checkpointer)\n",
|
||||
" config = {\"configurable\": {\"thread_id\": \"6\"}}\n",
|
||||
" res = await graph.ainvoke(\n",
|
||||
" {\"messages\": [(\"human\", \"what's the weather in nyc\")]}, config\n",
|
||||
" )\n",
|
||||
" checkpoint_tuples = [c async for c in checkpointer.alist(config)]"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 18,
|
||||
"id": "2b6d73ca-519e-45f7-90c2-1b8596624505",
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
"text/plain": [
|
||||
"[CheckpointTuple(config={'configurable': {'thread_id': '6', 'checkpoint_ns': '', 'checkpoint_id': '1ef559b7-723c-67de-8003-63bd4eab35af'}}, checkpoint={'v': 1, 'id': '1ef559b7-723c-67de-8003-63bd4eab35af', 'ts': '2024-08-08T15:32:47.890003+00:00', 'current_tasks': {}, 'pending_sends': [], 'versions_seen': {'agent': {'tools': '00000000000000000000000000000004.022986cd20ae85c77ea298a383f69ba8', 'start:agent': '00000000000000000000000000000002.d6f25946c3108fc12f27abbcf9b4cedc'}, 'tools': {'branch:agent:should_continue:tools': '00000000000000000000000000000003.065d90dd7f7cd091f0233855210bb2af'}, '__input__': {}, '__start__': {'__start__': '00000000000000000000000000000001.0e148ae3debe753278387e84f786e863'}}, 'channel_versions': {'agent': '00000000000000000000000000000005.065d90dd7f7cd091f0233855210bb2af', 'tools': '00000000000000000000000000000005.', 'messages': '00000000000000000000000000000005.b6fe2a26011590cfe8fd6a39151a9e92', '__start__': '00000000000000000000000000000002.', 'start:agent': '00000000000000000000000000000003.', 'branch:agent:should_continue:tools': '00000000000000000000000000000004.'}, 'channel_values': {'agent': 'agent', 'messages': [HumanMessage(content=\"what's the weather in nyc\", id='977ddb90-9991-44cb-9f73-361c6dd21396'), AIMessage(content='', additional_kwargs={'tool_calls': [{'id': 'call_QIFCuh4zfP9owpjToycJiZf7', 'function': {'arguments': '{\"city\":\"nyc\"}', 'name': 'get_weather'}, 'type': 'function'}]}, response_metadata={'token_usage': {'completion_tokens': 15, 'prompt_tokens': 58, 'total_tokens': 73}, 'model_name': 'gpt-4o-mini-2024-07-18', 'system_fingerprint': 'fp_48196bc67a', 'finish_reason': 'tool_calls', 'logprobs': None}, id='run-47b10c48-4db3-46d8-b4fa-e021818e01c5-0', tool_calls=[{'name': 'get_weather', 'args': {'city': 'nyc'}, 'id': 'call_QIFCuh4zfP9owpjToycJiZf7', 'type': 'tool_call'}], usage_metadata={'input_tokens': 58, 'output_tokens': 15, 'total_tokens': 73}), ToolMessage(content='It might be cloudy in nyc', name='get_weather', id='798c520f-4f9a-4f6d-a389-da721eb4d4ce', tool_call_id='call_QIFCuh4zfP9owpjToycJiZf7'), AIMessage(content='The weather in NYC might be cloudy.', response_metadata={'token_usage': {'completion_tokens': 9, 'prompt_tokens': 88, 'total_tokens': 97}, 'model_name': 'gpt-4o-mini-2024-07-18', 'system_fingerprint': 'fp_48196bc67a', 'finish_reason': 'stop', 'logprobs': None}, id='run-4a34e05d-8bcf-41ad-adc3-715919fde64c-0', usage_metadata={'input_tokens': 88, 'output_tokens': 9, 'total_tokens': 97})]}}, metadata={'step': 3, 'source': 'loop', 'writes': {'agent': {'messages': [AIMessage(content='The weather in NYC might be cloudy.', response_metadata={'logprobs': None, 'model_name': 'gpt-4o-mini-2024-07-18', 'token_usage': {'total_tokens': 97, 'prompt_tokens': 88, 'completion_tokens': 9}, 'finish_reason': 'stop', 'system_fingerprint': 'fp_48196bc67a'}, id='run-4a34e05d-8bcf-41ad-adc3-715919fde64c-0', usage_metadata={'input_tokens': 88, 'output_tokens': 9, 'total_tokens': 97})]}}}, parent_config={'configurable': {'thread_id': '6', 'checkpoint_ns': '', 'checkpoint_id': '1ef559b7-6bf5-63c6-8002-ed990dbbc96e'}}, pending_writes=None),\n",
|
||||
" CheckpointTuple(config={'configurable': {'thread_id': '6', 'checkpoint_ns': '', 'checkpoint_id': '1ef559b7-6bf5-63c6-8002-ed990dbbc96e'}}, checkpoint={'v': 1, 'id': '1ef559b7-6bf5-63c6-8002-ed990dbbc96e', 'ts': '2024-08-08T15:32:47.231667+00:00', 'current_tasks': {}, 'pending_sends': [], 'versions_seen': {'agent': {'start:agent': '00000000000000000000000000000002.d6f25946c3108fc12f27abbcf9b4cedc'}, 'tools': {'branch:agent:should_continue:tools': '00000000000000000000000000000003.065d90dd7f7cd091f0233855210bb2af'}, '__input__': {}, '__start__': {'__start__': '00000000000000000000000000000001.0e148ae3debe753278387e84f786e863'}}, 'channel_versions': {'agent': '00000000000000000000000000000004.', 'tools': '00000000000000000000000000000004.022986cd20ae85c77ea298a383f69ba8', 'messages': '00000000000000000000000000000004.c9074f2a41f05486b5efb86353dc75c0', '__start__': '00000000000000000000000000000002.', 'start:agent': '00000000000000000000000000000003.', 'branch:agent:should_continue:tools': '00000000000000000000000000000004.'}, 'channel_values': {'tools': 'tools', 'messages': [HumanMessage(content=\"what's the weather in nyc\", id='977ddb90-9991-44cb-9f73-361c6dd21396'), AIMessage(content='', additional_kwargs={'tool_calls': [{'id': 'call_QIFCuh4zfP9owpjToycJiZf7', 'function': {'arguments': '{\"city\":\"nyc\"}', 'name': 'get_weather'}, 'type': 'function'}]}, response_metadata={'token_usage': {'completion_tokens': 15, 'prompt_tokens': 58, 'total_tokens': 73}, 'model_name': 'gpt-4o-mini-2024-07-18', 'system_fingerprint': 'fp_48196bc67a', 'finish_reason': 'tool_calls', 'logprobs': None}, id='run-47b10c48-4db3-46d8-b4fa-e021818e01c5-0', tool_calls=[{'name': 'get_weather', 'args': {'city': 'nyc'}, 'id': 'call_QIFCuh4zfP9owpjToycJiZf7', 'type': 'tool_call'}], usage_metadata={'input_tokens': 58, 'output_tokens': 15, 'total_tokens': 73}), ToolMessage(content='It might be cloudy in nyc', name='get_weather', id='798c520f-4f9a-4f6d-a389-da721eb4d4ce', tool_call_id='call_QIFCuh4zfP9owpjToycJiZf7')]}}, metadata={'step': 2, 'source': 'loop', 'writes': {'tools': {'messages': [ToolMessage(content='It might be cloudy in nyc', name='get_weather', id='798c520f-4f9a-4f6d-a389-da721eb4d4ce', tool_call_id='call_QIFCuh4zfP9owpjToycJiZf7')]}}}, parent_config={'configurable': {'thread_id': '6', 'checkpoint_ns': '', 'checkpoint_id': '1ef559b7-6be0-6926-8001-1a8ce73baf9e'}}, pending_writes=None),\n",
|
||||
" CheckpointTuple(config={'configurable': {'thread_id': '6', 'checkpoint_ns': '', 'checkpoint_id': '1ef559b7-6be0-6926-8001-1a8ce73baf9e'}}, checkpoint={'v': 1, 'id': '1ef559b7-6be0-6926-8001-1a8ce73baf9e', 'ts': '2024-08-08T15:32:47.223198+00:00', 'current_tasks': {}, 'pending_sends': [], 'versions_seen': {'agent': {'start:agent': '00000000000000000000000000000002.d6f25946c3108fc12f27abbcf9b4cedc'}, '__input__': {}, '__start__': {'__start__': '00000000000000000000000000000001.0e148ae3debe753278387e84f786e863'}}, 'channel_versions': {'agent': '00000000000000000000000000000003.065d90dd7f7cd091f0233855210bb2af', 'messages': '00000000000000000000000000000003.097b5407d709b297591f1ef5d50c8368', '__start__': '00000000000000000000000000000002.', 'start:agent': '00000000000000000000000000000003.', 'branch:agent:should_continue:tools': '00000000000000000000000000000003.065d90dd7f7cd091f0233855210bb2af'}, 'channel_values': {'agent': 'agent', 'messages': [HumanMessage(content=\"what's the weather in nyc\", id='977ddb90-9991-44cb-9f73-361c6dd21396'), AIMessage(content='', additional_kwargs={'tool_calls': [{'id': 'call_QIFCuh4zfP9owpjToycJiZf7', 'function': {'arguments': '{\"city\":\"nyc\"}', 'name': 'get_weather'}, 'type': 'function'}]}, response_metadata={'token_usage': {'completion_tokens': 15, 'prompt_tokens': 58, 'total_tokens': 73}, 'model_name': 'gpt-4o-mini-2024-07-18', 'system_fingerprint': 'fp_48196bc67a', 'finish_reason': 'tool_calls', 'logprobs': None}, id='run-47b10c48-4db3-46d8-b4fa-e021818e01c5-0', tool_calls=[{'name': 'get_weather', 'args': {'city': 'nyc'}, 'id': 'call_QIFCuh4zfP9owpjToycJiZf7', 'type': 'tool_call'}], usage_metadata={'input_tokens': 58, 'output_tokens': 15, 'total_tokens': 73})], 'branch:agent:should_continue:tools': 'agent'}}, metadata={'step': 1, 'source': 'loop', 'writes': {'agent': {'messages': [AIMessage(content='', additional_kwargs={'tool_calls': [{'id': 'call_QIFCuh4zfP9owpjToycJiZf7', 'type': 'function', 'function': {'name': 'get_weather', 'arguments': '{\"city\":\"nyc\"}'}}]}, response_metadata={'logprobs': None, 'model_name': 'gpt-4o-mini-2024-07-18', 'token_usage': {'total_tokens': 73, 'prompt_tokens': 58, 'completion_tokens': 15}, 'finish_reason': 'tool_calls', 'system_fingerprint': 'fp_48196bc67a'}, id='run-47b10c48-4db3-46d8-b4fa-e021818e01c5-0', tool_calls=[{'name': 'get_weather', 'args': {'city': 'nyc'}, 'id': 'call_QIFCuh4zfP9owpjToycJiZf7', 'type': 'tool_call'}], usage_metadata={'input_tokens': 58, 'output_tokens': 15, 'total_tokens': 73})]}}}, parent_config={'configurable': {'thread_id': '6', 'checkpoint_ns': '', 'checkpoint_id': '1ef559b7-663d-60b4-8000-10a8922bffbf'}}, pending_writes=None),\n",
|
||||
" CheckpointTuple(config={'configurable': {'thread_id': '6', 'checkpoint_ns': '', 'checkpoint_id': '1ef559b7-663d-60b4-8000-10a8922bffbf'}}, checkpoint={'v': 1, 'id': '1ef559b7-663d-60b4-8000-10a8922bffbf', 'ts': '2024-08-08T15:32:46.631935+00:00', 'current_tasks': {}, 'pending_sends': [], 'versions_seen': {'__input__': {}, '__start__': {'__start__': '00000000000000000000000000000001.0e148ae3debe753278387e84f786e863'}}, 'channel_versions': {'messages': '00000000000000000000000000000002.2a79db8da664e437bdb25ea804457ca7', '__start__': '00000000000000000000000000000002.', 'start:agent': '00000000000000000000000000000002.d6f25946c3108fc12f27abbcf9b4cedc'}, 'channel_values': {'messages': [HumanMessage(content=\"what's the weather in nyc\", id='977ddb90-9991-44cb-9f73-361c6dd21396')], 'start:agent': '__start__'}}, metadata={'step': 0, 'source': 'loop', 'writes': None}, parent_config={'configurable': {'thread_id': '6', 'checkpoint_ns': '', 'checkpoint_id': '1ef559b7-6637-6d4e-bfff-6cecf690c3cb'}}, pending_writes=None),\n",
|
||||
" CheckpointTuple(config={'configurable': {'thread_id': '6', 'checkpoint_ns': '', 'checkpoint_id': '1ef559b7-6637-6d4e-bfff-6cecf690c3cb'}}, checkpoint={'v': 1, 'id': '1ef559b7-6637-6d4e-bfff-6cecf690c3cb', 'ts': '2024-08-08T15:32:46.629806+00:00', 'current_tasks': {}, 'pending_sends': [], 'versions_seen': {'__input__': {}}, 'channel_versions': {'__start__': '00000000000000000000000000000001.0e148ae3debe753278387e84f786e863'}, 'channel_values': {'__start__': {'messages': [['human', \"what's the weather in nyc\"]]}}}, metadata={'step': -1, 'source': 'input', 'writes': {'messages': [['human', \"what's the weather in nyc\"]]}}, parent_config=None, pending_writes=None)]"
|
||||
]
|
||||
},
|
||||
"execution_count": 18,
|
||||
"metadata": {},
|
||||
"output_type": "execute_result"
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"checkpoint_tuples"
|
||||
]
|
||||
}
|
||||
],
|
||||
"metadata": {
|
||||
"kernelspec": {
|
||||
"display_name": "Python 3 (ipykernel)",
|
||||
"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.11.4"
|
||||
}
|
||||
},
|
||||
"nbformat": 4,
|
||||
"nbformat_minor": 5
|
||||
}
|
||||
Reference in New Issue
Block a user