三、LangGraph React智能体记忆管理与多轮对话方法

  在实际进行Agent开发时,还有一项工作至关重要,那就是需要管理智能体的记忆。

Python
from langgraph.checkpoint.memory import InMemorySaver

Python
checkpointer = InMemorySaver()

Python
tools = [get_weather]
model = init_chat_model(model="deepseek-chat", model_provider="deepseek") 

Python
agent = create_react_agent(model=model,
                           tools=tools,
                           checkpointer=checkpointer)

Python
config = {
    "configurable": {
        "thread_id": "1" 
    }
}

Python
response = agent.invoke(
    {"messages": [{"role": "user", "content": "
你好,我叫陈明,好久不见!"}]},
    config
)

Python
response['messages']

Plaintext
[HumanMessage(content='你好,我叫陈明,好久不见!', additional_kwargs={}, response_metadata={}, id='99a94aaa-c095-43db-a944-72b80b97ef4d'),
 AIMessage(content='你好,陈明!确实好久不见了,最近过得怎么样?有什么我可以帮你的吗?', additional_kwargs={'refusal': None}, response_metadata={'token_usage': {'completion_tokens': 19, 'prompt_tokens': 225, 'total_tokens': 244, 'completion_tokens_details': None, 'prompt_tokens_details': {'audio_tokens': None, 'cached_tokens': 192}, 'prompt_cache_hit_tokens': 192, 'prompt_cache_miss_tokens': 33}, 'model_name': 'deepseek-chat', 'system_fingerprint': 'fp_8802369eaa_prod0623_fp8_kvcache', 'id': 'a07cc5e0-069f-4a24-9786-691fb6232064', 'service_tier': None, 'finish_reason': 'stop', 'logprobs': None}, id='run--d36d9cf7-322f-41f2-a4c6-90a8628e771b-0', usage_metadata={'input_tokens': 225, 'output_tokens': 19, 'total_tokens': 244, 'input_token_details': {'cache_read': 192}, 'output_token_details': {}})]

Python
response['messages'][-1].content

Plaintext
'你好,陈明!确实好久不见了,最近过得怎么样?有什么我可以帮你的吗?'

此时记忆就自动保存在当前Agent和线程中:

Python
latest = agent.get_state(config)

Python
latest

Plaintext
StateSnapshot(values={'messages': [HumanMessage(content='你好,我叫陈明,好久不见!', additional_kwargs={}, response_metadata={}, id='99a94aaa-c095-43db-a944-72b80b97ef4d'), AIMessage(content='你好,陈明!确实好久不见了,最近过得怎么样?有什么我可以帮你的吗?', additional_kwargs={'refusal': None}, response_metadata={'token_usage': {'completion_tokens': 19, 'prompt_tokens': 225, 'total_tokens': 244, 'completion_tokens_details': None, 'prompt_tokens_details': {'audio_tokens': None, 'cached_tokens': 192}, 'prompt_cache_hit_tokens': 192, 'prompt_cache_miss_tokens': 33}, 'model_name': 'deepseek-chat', 'system_fingerprint': 'fp_8802369eaa_prod0623_fp8_kvcache', 'id': 'a07cc5e0-069f-4a24-9786-691fb6232064', 'service_tier': None, 'finish_reason': 'stop', 'logprobs': None}, id='run--d36d9cf7-322f-41f2-a4c6-90a8628e771b-0', usage_metadata={'input_tokens': 225, 'output_tokens': 19, 'total_tokens': 244, 'input_token_details': {'cache_read': 192}, 'output_token_details': {}})]}, next=(), config={'configurable': {'thread_id': '1', 'checkpoint_ns': '', 'checkpoint_id': '1f052786-1f80-61ea-8001-0e4e6e89a399'}}, metadata={'source': 'loop', 'writes': {'agent': {'messages': [AIMessage(content='你好,陈明!确实好久不见了,最近过得怎么样?有什么我可以帮你的吗?', additional_kwargs={'refusal': None}, response_metadata={'token_usage': {'completion_tokens': 19, 'prompt_tokens': 225, 'total_tokens': 244, 'completion_tokens_details': None, 'prompt_tokens_details': {'audio_tokens': None, 'cached_tokens': 192}, 'prompt_cache_hit_tokens': 192, 'prompt_cache_miss_tokens': 33}, 'model_name': 'deepseek-chat', 'system_fingerprint': 'fp_8802369eaa_prod0623_fp8_kvcache', 'id': 'a07cc5e0-069f-4a24-9786-691fb6232064', 'service_tier': None, 'finish_reason': 'stop', 'logprobs': None}, id='run--d36d9cf7-322f-41f2-a4c6-90a8628e771b-0', usage_metadata={'input_tokens': 225, 'output_tokens': 19, 'total_tokens': 244, 'input_token_details': {'cache_read': 192}, 'output_token_details': {}})]}}, 'step': 1, 'parents': {}, 'thread_id': '1'}, created_at='2025-06-26T10:29:04.168150+00:00', parent_config={'configurable': {'thread_id': '1', 'checkpoint_ns': '', 'checkpoint_id': '1f052785-f961-6dfd-8000-721e9cd1348b'}}, tasks=(), interrupts=())

当我们再次进行对话时,直接带入线程ID,即可带入此前对话记忆:

Python
response = agent.invoke(
    {"messages": [{"role": "user", "content": "
你好,请问你还记得我叫什么名字么?"}]},
    config
)

Python
response['messages']

Plaintext
[HumanMessage(content='你好,我叫陈明,好久不见!', additional_kwargs={}, response_metadata={}, id='99a94aaa-c095-43db-a944-72b80b97ef4d'),
 AIMessage(content='你好,陈明!确实好久不见了,最近过得怎么样?有什么我可以帮你的吗?', additional_kwargs={'refusal': None}, response_metadata={'token_usage': {'completion_tokens': 19, 'prompt_tokens': 225, 'total_tokens': 244, 'completion_tokens_details': None, 'prompt_tokens_details': {'audio_tokens': None, 'cached_tokens': 192}, 'prompt_cache_hit_tokens': 192, 'prompt_cache_miss_tokens': 33}, 'model_name': 'deepseek-chat', 'system_fingerprint': 'fp_8802369eaa_prod0623_fp8_kvcache', 'id': 'a07cc5e0-069f-4a24-9786-691fb6232064', 'service_tier': None, 'finish_reason': 'stop', 'logprobs': None}, id='run--d36d9cf7-322f-41f2-a4c6-90a8628e771b-0', usage_metadata={'input_tokens': 225, 'output_tokens': 19, 'total_tokens': 244, 'input_token_details': {'cache_read': 192}, 'output_token_details': {}}),
 HumanMessage(content='你好,请问你还记得我叫什么名字么?', additional_kwargs={}, response_metadata={}, id='678a6591-6cbb-4e80-8da1-57be94976a52'),
 AIMessage(content='当然记得!你刚刚告诉我你叫陈明。有什么需要帮忙的吗?', additional_kwargs={'refusal': None}, response_metadata={'token_usage': {'completion_tokens': 16, 'prompt_tokens': 257, 'total_tokens': 273, 'completion_tokens_details': None, 'prompt_tokens_details': {'audio_tokens': None, 'cached_tokens': 192}, 'prompt_cache_hit_tokens': 192, 'prompt_cache_miss_tokens': 65}, 'model_name': 'deepseek-chat', 'system_fingerprint': 'fp_8802369eaa_prod0623_fp8_kvcache', 'id': 'f92c722c-bbe4-4d10-bd09-10838ea68d35', 'service_tier': None, 'finish_reason': 'stop', 'logprobs': None}, id='run--3fbece08-4322-40dd-9b5e-24f2b85cbd06-0', usage_metadata={'input_tokens': 257, 'output_tokens': 16, 'total_tokens': 273, 'input_token_details': {'cache_read': 192}, 'output_token_details': {}})]

Python
response['messages'][-1].content

Plaintext
'当然记得!你刚刚告诉我你叫陈明。有什么需要帮忙的吗?'

Python
latest = agent.get_state(config)
latest

Plaintext
StateSnapshot(values={'messages': [HumanMessage(content='你好,我叫陈明,好久不见!', additional_kwargs={}, response_metadata={}, id='99a94aaa-c095-43db-a944-72b80b97ef4d'), AIMessage(content='你好,陈明!确实好久不见了,最近过得怎么样?有什么我可以帮你的吗?', additional_kwargs={'refusal': None}, response_metadata={'token_usage': {'completion_tokens': 19, 'prompt_tokens': 225, 'total_tokens': 244, 'completion_tokens_details': None, 'prompt_tokens_details': {'audio_tokens': None, 'cached_tokens': 192}, 'prompt_cache_hit_tokens': 192, 'prompt_cache_miss_tokens': 33}, 'model_name': 'deepseek-chat', 'system_fingerprint': 'fp_8802369eaa_prod0623_fp8_kvcache', 'id': 'a07cc5e0-069f-4a24-9786-691fb6232064', 'service_tier': None, 'finish_reason': 'stop', 'logprobs': None}, id='run--d36d9cf7-322f-41f2-a4c6-90a8628e771b-0', usage_metadata={'input_tokens': 225, 'output_tokens': 19, 'total_tokens': 244, 'input_token_details': {'cache_read': 192}, 'output_token_details': {}}), HumanMessage(content='你好,请问你还记得我叫什么名字么?', additional_kwargs={}, response_metadata={}, id='678a6591-6cbb-4e80-8da1-57be94976a52'), AIMessage(content='当然记得!你刚刚告诉我你叫陈明。有什么需要帮忙的吗?', additional_kwargs={'refusal': None}, response_metadata={'token_usage': {'completion_tokens': 16, 'prompt_tokens': 257, 'total_tokens': 273, 'completion_tokens_details': None, 'prompt_tokens_details': {'audio_tokens': None, 'cached_tokens': 192}, 'prompt_cache_hit_tokens': 192, 'prompt_cache_miss_tokens': 65}, 'model_name': 'deepseek-chat', 'system_fingerprint': 'fp_8802369eaa_prod0623_fp8_kvcache', 'id': 'f92c722c-bbe4-4d10-bd09-10838ea68d35', 'service_tier': None, 'finish_reason': 'stop', 'logprobs': None}, id='run--3fbece08-4322-40dd-9b5e-24f2b85cbd06-0', usage_metadata={'input_tokens': 257, 'output_tokens': 16, 'total_tokens': 273, 'input_token_details': {'cache_read': 192}, 'output_token_details': {}})]}, next=(), config={'configurable': {'thread_id': '1', 'checkpoint_ns': '', 'checkpoint_id': '1f05278b-1b95-6ec5-8004-51137ac9cb01'}}, metadata={'source': 'loop', 'writes': {'agent': {'messages': [AIMessage(content='当然记得!你刚刚告诉我你叫陈明。有什么需要帮忙的吗?', additional_kwargs={'refusal': None}, response_metadata={'token_usage': {'completion_tokens': 16, 'prompt_tokens': 257, 'total_tokens': 273, 'completion_tokens_details': None, 'prompt_tokens_details': {'audio_tokens': None, 'cached_tokens': 192}, 'prompt_cache_hit_tokens': 192, 'prompt_cache_miss_tokens': 65}, 'model_name': 'deepseek-chat', 'system_fingerprint': 'fp_8802369eaa_prod0623_fp8_kvcache', 'id': 'f92c722c-bbe4-4d10-bd09-10838ea68d35', 'service_tier': None, 'finish_reason': 'stop', 'logprobs': None}, id='run--3fbece08-4322-40dd-9b5e-24f2b85cbd06-0', usage_metadata={'input_tokens': 257, 'output_tokens': 16, 'total_tokens': 273, 'input_token_details': {'cache_read': 192}, 'output_token_details': {}})]}}, 'step': 4, 'parents': {}, 'thread_id': '1'}, created_at='2025-06-26T10:31:17.975371+00:00', parent_config={'configurable': {'thread_id': '1', 'checkpoint_ns': '', 'checkpoint_id': '1f05278a-f895-6132-8003-d65e4c9f2550'}}, tasks=(), interrupts=())

而如果更新线程ID,则会重新开启对话:

Python
config2 = {
    "configurable": {
        "thread_id": "2" 
    }
}

Python
response2 = agent.invoke(
    {"messages": [{"role": "user", "content": "
你好,你还记得我叫什么名字么?"}]},
    config2
)

Python
response2['messages']

Plaintext
[HumanMessage(content='你好,你还记得我叫什么名字么?', additional_kwargs={}, response_metadata={}, id='cc08c35d-21d8-4439-a343-f64e94cc6b4a'),
 AIMessage(content='目前我还不知道你的名字,但如果你愿意告诉我,我会记住的!你可以告诉我你的名字吗?', additional_kwargs={'refusal': None}, response_metadata={'token_usage': {'completion_tokens': 21, 'prompt_tokens': 225, 'total_tokens': 246, 'completion_tokens_details': None, 'prompt_tokens_details': {'audio_tokens': None, 'cached_tokens': 192}, 'prompt_cache_hit_tokens': 192, 'prompt_cache_miss_tokens': 33}, 'model_name': 'deepseek-chat', 'system_fingerprint': 'fp_8802369eaa_prod0623_fp8_kvcache', 'id': '829a29c3-8dad-42e9-85c1-5434d4b42fcd', 'service_tier': None, 'finish_reason': 'stop', 'logprobs': None}, id='run--d9d1addd-68e4-4506-9c59-943ca59836b2-0', usage_metadata={'input_tokens': 225, 'output_tokens': 21, 'total_tokens': 246, 'input_token_details': {'cache_read': 192}, 'output_token_details': {}})]

更多推荐