Files
langgraph/examples/configuration.ipynb
T

301 lines
8.8 KiB
Plaintext

{
"cells": [
{
"cell_type": "markdown",
"id": "6e6a0a39-9a4c-47ae-a238-1a3a847eea5b",
"metadata": {},
"source": [
"# Configuration\n",
"\n",
"Sometimes you want to be able to configure your agent when calling it. \n",
"Examples of this include configuring which LLM to use.\n",
"Below we walk through an example of doing so."
]
},
{
"cell_type": "markdown",
"id": "df1ff9cf-f8d2-4109-adf9-2adec83f5a95",
"metadata": {},
"source": [
"## Base\n",
"\n",
"First, let's create a very simple graph"
]
},
{
"cell_type": "code",
"execution_count": 7,
"id": "816523d0-0b59-47cf-9f4c-4838024efe22",
"metadata": {},
"outputs": [],
"source": [
"from langgraph.graph import StateGraph, END\n",
"from langchain_anthropic import ChatAnthropic\n",
"from typing import TypedDict, Annotated, Sequence\n",
"import operator\n",
"from langchain_core.messages import BaseMessage, HumanMessage\n",
"\n",
"\n",
"model = ChatAnthropic(model_name=\"claude-2.1\")\n",
"\n",
"\n",
"class AgentState(TypedDict):\n",
" messages: Annotated[Sequence[BaseMessage], operator.add]\n",
"\n",
"\n",
"def _call_model(state):\n",
" response = model.invoke(state[\"messages\"])\n",
" return {\"messages\": [response]}\n",
"\n",
"\n",
"# Define a new graph\n",
"workflow = StateGraph(AgentState)\n",
"workflow.add_node(\"model\", _call_model)\n",
"workflow.set_entry_point(\"model\")\n",
"workflow.add_edge(\"model\", END)\n",
"\n",
"app = workflow.compile()"
]
},
{
"cell_type": "code",
"execution_count": 8,
"id": "070f11a6-2441-4db5-9df6-e318f110e281",
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"{'messages': [HumanMessage(content='hi'),\n",
" AIMessage(content='Hello!', response_metadata={'id': 'msg_01YZj7CVCUSc76faX4VM9i5d', 'model': 'claude-2.1', 'stop_reason': 'end_turn', 'stop_sequence': None, 'usage': {'input_tokens': 10, 'output_tokens': 6}}, id='run-d343db34-598c-46a2-93d6-ffa886d9b264-0')]}"
]
},
"execution_count": 8,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"app.invoke({\"messages\": [HumanMessage(content=\"hi\")]})"
]
},
{
"cell_type": "markdown",
"id": "69a1dd47-c5b3-4e04-af56-45682f74d61f",
"metadata": {},
"source": [
"## Configure the graph\n",
"\n",
"Great! Now let's suppose that we want to extend this example so the user is able to choose from multiple llms.\n",
"We can easily do that by passing in a config.\n",
"This config is meant to contain things are not part of the input (and therefore that we don't want to track as part of the state)."
]
},
{
"cell_type": "code",
"execution_count": 11,
"id": "c01f1e7c-8e8b-4e26-98f7-56ac225077b4",
"metadata": {},
"outputs": [],
"source": [
"from langchain_openai import ChatOpenAI\n",
"\n",
"openai_model = ChatOpenAI()\n",
"\n",
"models = {\n",
" \"anthropic\": model,\n",
" \"openai\": openai_model,\n",
"}\n",
"\n",
"\n",
"def _call_model(state, config):\n",
" m = models[config[\"configurable\"].get(\"model\", \"anthropic\")]\n",
" response = m.invoke(state[\"messages\"])\n",
" return {\"messages\": [response]}\n",
"\n",
"\n",
"# Define a new graph\n",
"workflow = StateGraph(AgentState)\n",
"workflow.add_node(\"model\", _call_model)\n",
"workflow.set_entry_point(\"model\")\n",
"workflow.add_edge(\"model\", END)\n",
"\n",
"app = workflow.compile()"
]
},
{
"cell_type": "markdown",
"id": "7741b75c-55ba-4c78-bbb1-5dc20a210f11",
"metadata": {},
"source": [
"If we call it with no configuration, it will use the default as we defined it (Anthropic)."
]
},
{
"cell_type": "code",
"execution_count": 12,
"id": "ef50f048-fc43-40c0-b713-346408fcf052",
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"{'messages': [HumanMessage(content='hi'),\n",
" AIMessage(content='Hello!', response_metadata={'id': 'msg_01EedReFyXmonWXPKhYre7Jb', 'model': 'claude-2.1', 'stop_reason': 'end_turn', 'stop_sequence': None, 'usage': {'input_tokens': 10, 'output_tokens': 6}}, id='run-1c6feaa0-bd6f-433a-8264-209d72c85db7-0')]}"
]
},
"execution_count": 12,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"app.invoke({\"messages\": [HumanMessage(content=\"hi\")]})"
]
},
{
"cell_type": "markdown",
"id": "f6896b32-9b25-4342-bfd0-29a3d329a06a",
"metadata": {},
"source": [
"We can also call it with a config to get it to use a different model."
]
},
{
"cell_type": "code",
"execution_count": 13,
"id": "f2f7c74b-9fb0-41c6-9728-dcf9d8a3c397",
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"{'messages': [HumanMessage(content='hi'),\n",
" AIMessage(content='Hello! How can I assist you today?', response_metadata={'token_usage': {'completion_tokens': 9, 'prompt_tokens': 8, 'total_tokens': 17}, 'model_name': 'gpt-3.5-turbo', 'system_fingerprint': 'fp_3b956da36b', 'finish_reason': 'stop', 'logprobs': None}, id='run-d41ffb62-e164-45a1-862c-d288c6ad100a-0')]}"
]
},
"execution_count": 13,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"config = {\"configurable\": {\"model\": \"openai\"}}\n",
"app.invoke({\"messages\": [HumanMessage(content=\"hi\")]}, config=config)"
]
},
{
"cell_type": "markdown",
"id": "b4c7eaf1-4ee0-42b3-971d-273a108f205f",
"metadata": {},
"source": [
"We can also adapt our graph to take in more configuration! Like a system message for example."
]
},
{
"cell_type": "code",
"execution_count": 18,
"id": "f0393a43-9fbe-4056-972f-3e91ea329041",
"metadata": {},
"outputs": [],
"source": [
"from langchain_core.messages import SystemMessage\n",
"\n",
"\n",
"def _call_model(state, config):\n",
" m = models[config[\"configurable\"].get(\"model\", \"anthropic\")]\n",
" messages = state[\"messages\"]\n",
" if \"system_message\" in config[\"configurable\"]:\n",
" messages = [\n",
" SystemMessage(content=config[\"configurable\"][\"system_message\"])\n",
" ] + messages\n",
" response = m.invoke(messages)\n",
" return {\"messages\": [response]}\n",
"\n",
"\n",
"# Define a new graph\n",
"workflow = StateGraph(AgentState)\n",
"workflow.add_node(\"model\", _call_model)\n",
"workflow.set_entry_point(\"model\")\n",
"workflow.add_edge(\"model\", END)\n",
"\n",
"app = workflow.compile()"
]
},
{
"cell_type": "code",
"execution_count": 19,
"id": "718685f7-4cdd-4181-9fc8-e7762d584727",
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"{'messages': [HumanMessage(content='hi'),\n",
" AIMessage(content='Hello!', response_metadata={'id': 'msg_01Ts56eVLSrUbzVMbzLnXc3M', 'model': 'claude-2.1', 'stop_reason': 'end_turn', 'stop_sequence': None, 'usage': {'input_tokens': 10, 'output_tokens': 6}}, id='run-f75a4389-b72e-4d47-8f3e-bedc6a060f66-0')]}"
]
},
"execution_count": 19,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"app.invoke({\"messages\": [HumanMessage(content=\"hi\")]})"
]
},
{
"cell_type": "code",
"execution_count": 20,
"id": "e043a719-f197-46ef-9d45-84740a39aeb0",
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"{'messages': [HumanMessage(content='hi'),\n",
" AIMessage(content='Ciao!', response_metadata={'id': 'msg_01RzFCii8WhbbkFm16nUquxk', 'model': 'claude-2.1', 'stop_reason': 'end_turn', 'stop_sequence': None, 'usage': {'input_tokens': 14, 'output_tokens': 7}}, id='run-9492f0e4-f223-41c2-81a6-6f0cb6a14fe6-0')]}"
]
},
"execution_count": 20,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"config = {\"configurable\": {\"system_message\": \"respond in italian\"}}\n",
"app.invoke({\"messages\": [HumanMessage(content=\"hi\")]}, config=config)"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "a5c5f7f4-4b0e-4cde-93a6-c1c6329b8591",
"metadata": {},
"outputs": [],
"source": []
}
],
"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.1"
}
},
"nbformat": 4,
"nbformat_minor": 5
}