rename, update

This commit is contained in:
Lance Martin
2025-01-28 15:24:35 -08:00
parent 58e2824ea3
commit 2da005b4bd
@@ -28,7 +28,7 @@
},
{
"cell_type": "code",
"execution_count": 57,
"execution_count": 2,
"metadata": {},
"outputs": [],
"source": [
@@ -49,7 +49,7 @@
},
{
"cell_type": "code",
"execution_count": 90,
"execution_count": 26,
"metadata": {},
"outputs": [],
"source": [
@@ -96,7 +96,7 @@
},
{
"cell_type": "code",
"execution_count": 63,
"execution_count": 4,
"metadata": {},
"outputs": [
{
@@ -108,10 +108,10 @@
"Add 3 and 4.\n",
"==================================\u001b[1m Ai Message \u001b[0m==================================\n",
"\n",
"[{'text': \"I'll help you add those numbers using the `add` function.\", 'type': 'text'}, {'id': 'toolu_01Lr23DbYsJvGSuzwQdXqDvH', 'input': {'a': 3, 'b': 4}, 'name': 'add', 'type': 'tool_use'}]\n",
"[{'text': \"I'll help you add 3 and 4 using the `add` function.\", 'type': 'text'}, {'id': 'toolu_01Js4XXxB1oMDqZKz6VkxpnQ', 'input': {'a': 3, 'b': 4}, 'name': 'add', 'type': 'tool_use'}]\n",
"Tool Calls:\n",
" add (toolu_01Lr23DbYsJvGSuzwQdXqDvH)\n",
" Call ID: toolu_01Lr23DbYsJvGSuzwQdXqDvH\n",
" add (toolu_01Js4XXxB1oMDqZKz6VkxpnQ)\n",
" Call ID: toolu_01Js4XXxB1oMDqZKz6VkxpnQ\n",
" Args:\n",
" a: 3\n",
" b: 4\n",
@@ -181,7 +181,8 @@
"source": [
"### Agent with short-term memory (within a thread)\n",
"\n",
"* LangGraph persistence layer \n",
"* LangGraph persistence layer\n",
"* Allows you to resume any conversation with the agent\n",
"\n",
"`@entrypoint` \n",
"* Decorator indicates the start of a workflow / agent \n",
@@ -206,7 +207,7 @@
},
{
"cell_type": "code",
"execution_count": 65,
"execution_count": 5,
"metadata": {},
"outputs": [],
"source": [
@@ -233,9 +234,9 @@
" tool = tools_by_name[tool_call[\"name\"]]\n",
" return tool.invoke(tool_call)\n",
"\n",
"checkpointer = MemorySaver()\n",
"checkpointer = MemorySaver() # New\n",
"@entrypoint(checkpointer=checkpointer) # New \n",
"def agent(messages: list[BaseMessage], previous: list[BaseMessage]): # New \n",
"def agent(messages: list[BaseMessage], previous: list[BaseMessage]): # previous (state associated with the previous ckpt)\n",
" \"\"\" Tool calling agent \"\"\"\n",
"\n",
" # Add previous messages from short-term memory to the current messages\n",
@@ -264,7 +265,7 @@
},
{
"cell_type": "code",
"execution_count": 66,
"execution_count": 6,
"metadata": {},
"outputs": [
{
@@ -276,10 +277,10 @@
"Add 3 and 4.\n",
"==================================\u001b[1m Ai Message \u001b[0m==================================\n",
"\n",
"[{'text': \"I'll help you add 3 and 4 using the `add` function.\", 'type': 'text'}, {'id': 'toolu_013z1syyD8SvfDKdysUSwyeq', 'input': {'a': 3, 'b': 4}, 'name': 'add', 'type': 'tool_use'}]\n",
"[{'text': \"I'll help you add 3 and 4 using the `add` function.\", 'type': 'text'}, {'id': 'toolu_016nz34fiRCrz2pcipHGRbEc', 'input': {'a': 3, 'b': 4}, 'name': 'add', 'type': 'tool_use'}]\n",
"Tool Calls:\n",
" add (toolu_013z1syyD8SvfDKdysUSwyeq)\n",
" Call ID: toolu_013z1syyD8SvfDKdysUSwyeq\n",
" add (toolu_016nz34fiRCrz2pcipHGRbEc)\n",
" Call ID: toolu_016nz34fiRCrz2pcipHGRbEc\n",
" Args:\n",
" a: 3\n",
" b: 4\n",
@@ -308,7 +309,7 @@
},
{
"cell_type": "code",
"execution_count": 67,
"execution_count": 7,
"metadata": {},
"outputs": [
{
@@ -320,10 +321,10 @@
"Add 3 and 4.\n",
"==================================\u001b[1m Ai Message \u001b[0m==================================\n",
"\n",
"[{'text': \"I'll help you add 3 and 4 using the `add` function.\", 'type': 'text'}, {'id': 'toolu_013z1syyD8SvfDKdysUSwyeq', 'input': {'a': 3, 'b': 4}, 'name': 'add', 'type': 'tool_use'}]\n",
"[{'text': \"I'll help you add 3 and 4 using the `add` function.\", 'type': 'text'}, {'id': 'toolu_016nz34fiRCrz2pcipHGRbEc', 'input': {'a': 3, 'b': 4}, 'name': 'add', 'type': 'tool_use'}]\n",
"Tool Calls:\n",
" add (toolu_013z1syyD8SvfDKdysUSwyeq)\n",
" Call ID: toolu_013z1syyD8SvfDKdysUSwyeq\n",
" add (toolu_016nz34fiRCrz2pcipHGRbEc)\n",
" Call ID: toolu_016nz34fiRCrz2pcipHGRbEc\n",
" Args:\n",
" a: 3\n",
" b: 4\n",
@@ -346,7 +347,7 @@
},
{
"cell_type": "code",
"execution_count": 68,
"execution_count": 8,
"metadata": {},
"outputs": [
{
@@ -358,10 +359,10 @@
"Add 3 and 4.\n",
"==================================\u001b[1m Ai Message \u001b[0m==================================\n",
"\n",
"[{'text': \"I'll help you add 3 and 4 using the `add` function.\", 'type': 'text'}, {'id': 'toolu_013z1syyD8SvfDKdysUSwyeq', 'input': {'a': 3, 'b': 4}, 'name': 'add', 'type': 'tool_use'}]\n",
"[{'text': \"I'll help you add 3 and 4 using the `add` function.\", 'type': 'text'}, {'id': 'toolu_016nz34fiRCrz2pcipHGRbEc', 'input': {'a': 3, 'b': 4}, 'name': 'add', 'type': 'tool_use'}]\n",
"Tool Calls:\n",
" add (toolu_013z1syyD8SvfDKdysUSwyeq)\n",
" Call ID: toolu_013z1syyD8SvfDKdysUSwyeq\n",
" add (toolu_016nz34fiRCrz2pcipHGRbEc)\n",
" Call ID: toolu_016nz34fiRCrz2pcipHGRbEc\n",
" Args:\n",
" a: 3\n",
" b: 4\n",
@@ -377,10 +378,10 @@
"Take the result and multiply it by 2.\n",
"==================================\u001b[1m Ai Message \u001b[0m==================================\n",
"\n",
"[{'text': \"I'll multiply the previous result (7) by 2 using the `multiply` function.\", 'type': 'text'}, {'id': 'toolu_01RhScbTXybkGxYG6RA1tQpM', 'input': {'a': 7, 'b': 2}, 'name': 'multiply', 'type': 'tool_use'}]\n",
"[{'text': \"I'll take the previous result (7) and multiply it by 2 using the `multiply` function.\", 'type': 'text'}, {'id': 'toolu_01Mqx3AB6Xiiz3gZcQHrxnPB', 'input': {'a': 7, 'b': 2}, 'name': 'multiply', 'type': 'tool_use'}]\n",
"Tool Calls:\n",
" multiply (toolu_01RhScbTXybkGxYG6RA1tQpM)\n",
" Call ID: toolu_01RhScbTXybkGxYG6RA1tQpM\n",
" multiply (toolu_01Mqx3AB6Xiiz3gZcQHrxnPB)\n",
" Call ID: toolu_01Mqx3AB6Xiiz3gZcQHrxnPB\n",
" Args:\n",
" a: 7\n",
" b: 2\n",
@@ -390,7 +391,7 @@
"14\n",
"==================================\u001b[1m Ai Message \u001b[0m==================================\n",
"\n",
"The result of multiplying 7 by 2 is 14.\n"
"7 multiplied by 2 equals 14.\n"
]
}
],
@@ -407,6 +408,7 @@
"source": [
"### Agent with HITL\n",
"\n",
"* Very useful for [approval](https://www.anthropic.com/research/building-effective-agents) in agents.\n",
"* Add interrupt to the workflow to allow for HITL.\n",
"* Re-executes from the start of the entrypoint.\n",
"* Output of each `@task` is cached / saved as a checkpoint."
@@ -414,7 +416,7 @@
},
{
"cell_type": "code",
"execution_count": 72,
"execution_count": 37,
"metadata": {},
"outputs": [],
"source": [
@@ -423,7 +425,7 @@
"@task\n",
"def call_llm(messages: list[BaseMessage]):\n",
" \"\"\"LLM decides whether to call a tool or not\"\"\"\n",
" print(\"Calling LLM or using cached LLM output!\")\n",
" print(\"Calling LLM!\")\n",
" return llm_with_tools.invoke(\n",
" [\n",
" SystemMessage(\n",
@@ -436,7 +438,7 @@
"@task\n",
"def call_tool(tool_call: ToolCall):\n",
" \"\"\"Performs the tool call\"\"\"\n",
" print(\"Calling tool or using cached tool output!\")\n",
" print(\"Calling tool!\")\n",
" # Interrupt the workflow to get a review from a human.\n",
" is_approved = interrupt({ # New \n",
" # Any json-serializable payload provided to interrupt as argument.\n",
@@ -457,7 +459,8 @@
"@entrypoint(checkpointer=MemorySaver()) \n",
"def agent(messages: list[BaseMessage], previous: list[BaseMessage]): \n",
" \"\"\" Tool calling agent \"\"\"\n",
"\n",
" print(\"Executing agent!\")\n",
" \n",
" # Add previous messages from short-term memory to the current messages\n",
" if previous is not None:\n",
" messages = add_messages(previous, messages)\n",
@@ -482,16 +485,17 @@
},
{
"cell_type": "code",
"execution_count": 76,
"execution_count": 38,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Calling LLM or using cached LLM output!\n",
"Calling tool or using cached tool output!\n",
"{'tool_call': {'name': 'add', 'args': {'a': 3, 'b': 4}, 'id': 'toolu_017uJdvp4SfEyPLVWamxBjGT', 'type': 'tool_call'}, 'action': 'Please approve/reject the tool call'}\n"
"Executing agent!\n",
"Calling LLM!\n",
"Calling tool!\n",
"{'tool_call': {'name': 'add', 'args': {'a': 3, 'b': 4}, 'id': 'toolu_01GGBdQZJ11bZGyHuvRkuRrh', 'type': 'tool_call'}, 'action': 'Please approve/reject the tool call'}\n"
]
}
],
@@ -510,15 +514,16 @@
},
{
"cell_type": "code",
"execution_count": 77,
"execution_count": 39,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Calling tool or using cached tool output!\n",
"Calling LLM or using cached LLM output!\n",
"Executing agent!\n",
"Calling tool!\n",
"Calling LLM!\n",
"==================================\u001b[1m Ai Message \u001b[0m==================================\n",
"\n",
"The sum of 3 and 4 is 7.\n"
@@ -532,18 +537,35 @@
" item['agent'][-1].pretty_print()"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Initial Execution Flow:\n",
"* `call_llm` runs first and is cached\n",
"* `call_tool` starts but hits the interrupt\n",
"* Execution pauses waiting for human input\n",
"\n",
"After Resume:\n",
"* `call_tool` continues from where it left off (since it didn't complete)\n",
"* The tool executes if approved\n",
"* `call_llm` runs again with the tool results\n",
"* Final response is generated"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Time travel\n",
"\n",
"* It can be useful to add time travel to the workflow.\n"
"* It can be useful to add time travel to the workflow.\n",
"* This allows you to rewind to specific checkpoint, modify the workflow, and re-run it. \n"
]
},
{
"cell_type": "code",
"execution_count": 108,
"execution_count": 11,
"metadata": {},
"outputs": [],
"source": [
@@ -593,7 +615,7 @@
},
{
"cell_type": "code",
"execution_count": 109,
"execution_count": 12,
"metadata": {},
"outputs": [
{
@@ -605,10 +627,10 @@
"Add 3 and 4.\n",
"==================================\u001b[1m Ai Message \u001b[0m==================================\n",
"\n",
"[{'text': \"I'll help you add 3 and 4 using the `add` function.\", 'type': 'text'}, {'id': 'toolu_015EBCekAyhHGVExDSCbSppi', 'input': {'a': 3, 'b': 4}, 'name': 'add', 'type': 'tool_use'}]\n",
"[{'text': \"I'll help you add 3 and 4 using the `add` function.\", 'type': 'text'}, {'id': 'toolu_0144yacRC2U5UkwEfEzBdzm2', 'input': {'a': 3, 'b': 4}, 'name': 'add', 'type': 'tool_use'}]\n",
"Tool Calls:\n",
" add (toolu_015EBCekAyhHGVExDSCbSppi)\n",
" Call ID: toolu_015EBCekAyhHGVExDSCbSppi\n",
" add (toolu_0144yacRC2U5UkwEfEzBdzm2)\n",
" Call ID: toolu_0144yacRC2U5UkwEfEzBdzm2\n",
" Args:\n",
" a: 3\n",
" b: 4\n",
@@ -637,7 +659,7 @@
},
{
"cell_type": "code",
"execution_count": 110,
"execution_count": 13,
"metadata": {},
"outputs": [
{
@@ -646,7 +668,7 @@
"text": [
"==================================\u001b[1m Ai Message \u001b[0m==================================\n",
"\n",
"The result of multiplying 7 by 2 is 14.\n"
"7 multiplied by 2 equals 14.\n"
]
}
],
@@ -659,18 +681,18 @@
},
{
"cell_type": "code",
"execution_count": 111,
"execution_count": 14,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"{'configurable': {'thread_id': 'ac13180b-31f0-4ff5-8d71-0354addc0a59',\n",
"{'configurable': {'thread_id': 'c0336c2c-1a97-4b6d-826c-21c33eb47ccb',\n",
" 'checkpoint_ns': '',\n",
" 'checkpoint_id': '1efddb89-50bb-6c16-8001-4b2a0f971b4e'}}"
" 'checkpoint_id': '1efddbc1-103d-66d4-8001-48133c20ef14'}}"
]
},
"execution_count": 111,
"execution_count": 14,
"metadata": {},
"output_type": "execute_result"
}
@@ -683,7 +705,7 @@
},
{
"cell_type": "code",
"execution_count": 112,
"execution_count": 15,
"metadata": {},
"outputs": [
{
@@ -695,10 +717,10 @@
"Add 3 and 4.\n",
"==================================\u001b[1m Ai Message \u001b[0m==================================\n",
"\n",
"[{'text': \"I'll help you add 3 and 4 using the `add` function.\", 'type': 'text'}, {'id': 'toolu_015EBCekAyhHGVExDSCbSppi', 'input': {'a': 3, 'b': 4}, 'name': 'add', 'type': 'tool_use'}]\n",
"[{'text': \"I'll help you add 3 and 4 using the `add` function.\", 'type': 'text'}, {'id': 'toolu_0144yacRC2U5UkwEfEzBdzm2', 'input': {'a': 3, 'b': 4}, 'name': 'add', 'type': 'tool_use'}]\n",
"Tool Calls:\n",
" add (toolu_015EBCekAyhHGVExDSCbSppi)\n",
" Call ID: toolu_015EBCekAyhHGVExDSCbSppi\n",
" add (toolu_0144yacRC2U5UkwEfEzBdzm2)\n",
" Call ID: toolu_0144yacRC2U5UkwEfEzBdzm2\n",
" Args:\n",
" a: 3\n",
" b: 4\n",
@@ -721,7 +743,7 @@
},
{
"cell_type": "code",
"execution_count": 113,
"execution_count": 16,
"metadata": {},
"outputs": [
{
@@ -730,63 +752,17 @@
"text": [
"==================================\u001b[1m Ai Message \u001b[0m==================================\n",
"\n",
"The result of multiplying 7 by 2 is 14.\n",
"==================================\u001b[1m Ai Message \u001b[0m==================================\n",
"\n",
"The result of multiplying 7 by 2 is 14.\n",
"==================================\u001b[1m Ai Message \u001b[0m==================================\n",
"\n",
"The result of multiplying 7 by 2 is 14.\n",
"==================================\u001b[1m Ai Message \u001b[0m==================================\n",
"\n",
"The result of multiplying 7 by 2 is 14.\n"
"7 multiplied by 3 equals 21.\n"
]
}
],
"source": [
"# Re-run the workflow from the fork\n",
"for chunk in agent.stream([HumanMessage(content=\"Take the result and multiply it by 3.\")], to_fork_from, stream_mode=\"updates\"):\n",
"for item in agent.stream([HumanMessage(content=\"Take the result and multiply it by 3.\")], to_fork_from, stream_mode=\"updates\"):\n",
" if 'agent' in item:\n",
" item['agent'][-1].pretty_print()"
]
},
{
"cell_type": "code",
"execution_count": 114,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"================================\u001b[1m Human Message \u001b[0m=================================\n",
"\n",
"Add 3 and 4.\n",
"==================================\u001b[1m Ai Message \u001b[0m==================================\n",
"\n",
"[{'text': \"I'll help you add 3 and 4 using the `add` function.\", 'type': 'text'}, {'id': 'toolu_015EBCekAyhHGVExDSCbSppi', 'input': {'a': 3, 'b': 4}, 'name': 'add', 'type': 'tool_use'}]\n",
"Tool Calls:\n",
" add (toolu_015EBCekAyhHGVExDSCbSppi)\n",
" Call ID: toolu_015EBCekAyhHGVExDSCbSppi\n",
" Args:\n",
" a: 3\n",
" b: 4\n",
"=================================\u001b[1m Tool Message \u001b[0m=================================\n",
"Name: add\n",
"\n",
"7\n",
"==================================\u001b[1m Ai Message \u001b[0m==================================\n",
"\n",
"The sum of 3 and 4 is 7.\n"
]
}
],
"source": [
"agent_state = agent.get_state(to_fork_from)\n",
"for m in agent_state.values:\n",
" m.pretty_print()"
]
},
{
"cell_type": "markdown",
"metadata": {},
@@ -799,7 +775,7 @@
},
{
"cell_type": "code",
"execution_count": 78,
"execution_count": 48,
"metadata": {},
"outputs": [],
"source": [
@@ -833,7 +809,7 @@
"\n",
" # BaseStore is a LangGraph persistence layer\n",
" store.put(\n",
" (\"memories\"),\n",
" (\"memories\",\"lance\"),\n",
" key=str(mem_id),\n",
" value={\"content\": content},\n",
" )\n",
@@ -847,7 +823,7 @@
},
{
"cell_type": "code",
"execution_count": 83,
"execution_count": 50,
"metadata": {},
"outputs": [],
"source": [
@@ -905,7 +881,7 @@
" # New \n",
" # Retrieve the most recent memories for context\n",
" memories = store.search( \n",
" (\"memories\"),\n",
" (\"memories\",\"lance\"),\n",
" limit=10,\n",
" )\n",
"\n",
@@ -939,14 +915,14 @@
},
{
"cell_type": "code",
"execution_count": 84,
"execution_count": 51,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"{'tool_call': {'name': 'upsert_memory', 'args': {'content': \"User's name is Lance.\"}, 'id': 'toolu_01Ppw9sRsBnkpmfUPmeHZVyR', 'type': 'tool_call'}, 'action': 'Please approve/reject the tool call'}\n"
"{'tool_call': {'name': 'upsert_memory', 'args': {'content': \"User's name is Lance.\"}, 'id': 'toolu_01Y1J6BnLWejpoQfF72GWP9L', 'type': 'tool_call'}, 'action': 'Please approve/reject the tool call'}\n"
]
}
],
@@ -965,9 +941,20 @@
},
{
"cell_type": "code",
"execution_count": 86,
"execution_count": 52,
"metadata": {},
"outputs": [],
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Tool call approved, Memory Added!\n",
"==================================\u001b[1m Ai Message \u001b[0m==================================\n",
"\n",
"Nice to meet you Lance! Is there anything else you'd like me to help you with?\n"
]
}
],
"source": [
"for item in agent.stream(Command(resume=True), config, stream_mode=\"updates\"):\n",
" if 'agent' in item:\n",
@@ -976,10 +963,23 @@
},
{
"cell_type": "code",
"execution_count": 87,
"execution_count": 55,
"metadata": {},
"outputs": [],
"source": []
"outputs": [
{
"data": {
"text/plain": [
"[Item(namespace=['memories', 'lance'], key='20544090-a509-46ac-85f2-04b3f54db0d2', value={'content': \"User's name is Lance.\"}, created_at='2025-01-28T21:41:25.959474+00:00', updated_at='2025-01-28T21:41:25.959475+00:00', score=None)]"
]
},
"execution_count": 55,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"in_memory_store.search((\"memories\",\"lance\"))"
]
},
{
"cell_type": "code",
@@ -987,6 +987,24 @@
"metadata": {},
"outputs": [],
"source": []
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Overview\n",
"\n",
"- Vanilla agent\n",
"- Added short-term memory (w/ tracing)\n",
"- Added short-term memory + HITL (w/ tracing)\n",
"- Added short-term memory + HITL + time travel (w/ tracing)\n",
"- Added short-term memory + HITL + long-term memory (w/ tracing)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": []
}
],
"metadata": {