【三个月 AI Agent 实战学习】Day 40:记忆与工具调用整合 —— 让 Agent 拥有“记忆感知”能力
Day 40记忆与工具调用整合 —— 让 Agent 拥有“记忆感知”能力欢迎来到第四十天过去四天我们逐步构建了完整的记忆系统短期记忆管理、Embedding 检索优化、自动记忆抽取、记忆更新与遗忘。但这些组件目前还是“独立”的——它们没有和 Agent 的工具调用深度整合。今天我们将把记忆系统嵌入到 Agent 的核心循环中让 Agent 能够在对话中自动查询记忆、利用记忆做决策、在适当时机更新记忆。这是构建一个真正“有记忆”的智能客服的关键一步。一、今日学习目标理解记忆与 Agent 整合的三种模式记忆作为工具、记忆作为上下文注入、记忆作为后处理。掌握将记忆系统封装为 LangChain Tool 的方法让 Agent 自主决定何时查询和更新记忆。学会在 Agent 执行前自动注入相关记忆到系统提示词中。实现一个完整的“记忆感知型 Agent”它能在多轮对话中记住用户信息并做出个性化回复。通过实战测试观察 Agent 如何结合记忆、工具和推理完成复杂任务。二、详细实现步骤步骤 1理解记忆与 Agent 的三种整合模式模式说明优点缺点适用场景记忆作为工具将记忆的查询和更新封装为 ToolAgent 自主调用灵活Agent 可决定何时使用增加工具调用次数可能延迟复杂 Agent需要精细控制记忆作为上下文注入每次对话前自动检索相关记忆注入到 System Prompt无额外工具调用响应快可能注入无关记忆消耗 Token客服、个人助手等高频场景记忆作为后处理Agent 回复后自动抽取并更新记忆不干扰 Agent 主流程更新延迟可能遗漏所有场景的补充最佳实践组合使用。上下文注入负责“读”后处理负责“写”工具调用作为补充如 Agent 需要主动查询特定记忆时。步骤 2环境准备与基础组件确保已安装所有必要库并初始化模型、Embedding、向量库。importosimportuuidfromdatetimeimportdatetimefromdotenvimportload_dotenvfromlangchain_openaiimportChatOpenAI,OpenAIEmbeddingsfromlangchain_community.vectorstoresimportChromafromlangchain_core.toolsimporttoolfromlangchain_core.promptsimportChatPromptTemplate,MessagesPlaceholderfromlangchain_core.messagesimportHumanMessage,AIMessage,SystemMessage,ToolMessagefromlangchain_core.documentsimportDocumentfromlangchain.agentsimportcreate_react_agent,AgentExecutorfromlangchain_core.promptsimportPromptTemplatefromtypingimportAnnotated load_dotenv()llmChatOpenAI(modeldeepseek-chat,api_keyos.getenv(DEEPSEEK_API_KEY),base_urlhttps://api.deepseek.com,temperature0.1)embeddingsOpenAIEmbeddings(modelembedding-2,api_keyos.getenv(ZHIPU_API_KEY),base_urlhttps://open.bigmodel.cn/api/paas/v4)vectorstoreChroma(collection_nameagent_memories,embedding_functionembeddings,persist_directory./agent_memory_db)步骤 3将记忆查询封装为 Tool虽然我们会自动注入记忆但 Agent 有时需要主动查询特定记忆如“帮我查一下我之前说的偏好”。我们定义两个工具recall_memory检索记忆和save_memory保存记忆。tooldefrecall_memory(query:Annotated[str,查询关键词或问题用于检索相关记忆])-str:从长期记忆中检索与查询相关的信息。当你需要回忆用户之前提到过的偏好、事实或事件时使用此工具。resultsvectorstore.similarity_search(query,k3,filter{status:active})ifnotresults:return未找到相关记忆。lines[]fordocinresults:mem_typedoc.metadata.get(memory_type,unknown)lines.append(f[{mem_type}]{doc.page_content})return\n.join(lines)tooldefsave_memory(content:Annotated[str,要保存的记忆内容简洁明确],memory_type:Annotated[str,记忆类型fact事实、preference偏好、event事件])-str:将重要信息保存到长期记忆中。当你发现用户提供了值得记住的新信息时使用此工具。memory_idstr(uuid.uuid4())docDocument(page_contentcontent,metadata{user_id:current_user,memory_type:memory_type,importance:3,timestamp:datetime.now().isoformat(),status:active,memory_id:memory_id,access_count:0})vectorstore.add_documents([doc])returnf已保存记忆{content}步骤 4实现自动记忆注入在每次调用 Agent 之前根据用户输入检索相关记忆并注入到 System Prompt 中。这样 Agent 无需主动调用工具就能“知道”用户的背景信息。defretrieve_and_format_memories(user_input:str,user_id:strcurrent_user,k:int3)-str:检索相关记忆并格式化为文本resultsvectorstore.similarity_search(user_input,kk,filter{user_id:user_id,status:active})ifnotresults:return暂无相关记忆。lines[]fordocinresults:mem_typedoc.metadata.get(memory_type,unknown)lines.append(f[{mem_type}]{doc.page_content})return\n.join(lines)defbuild_system_prompt_with_memories(user_input:str)-str:构建包含记忆的系统提示词memories_textretrieve_and_format_memories(user_input)returnf你是一个智能客服助手名叫小智。你能够记住用户的信息并提供个性化服务。 以下是你当前知道的关于该用户的信息来自长期记忆{memories_text}请根据这些信息以及用户当前的问题提供准确、个性化的回复。如果记忆中没有相关信息不要编造。 步骤 5构建记忆感知型 Agent我们将记忆注入、工具调用和 AgentExecutor 整合起来。每次对话时根据用户输入检索记忆注入 System Prompt。运行 AgentAgent 可以调用工具包括记忆工具。Agent 回复后自动抽取新记忆并更新。# 定义工具列表tools[recall_memory,save_memory]# ReAct 提示词模板react_template{system_prompt} 你可以使用以下工具 {tools} 工具名称列表{tool_names} 使用以下格式进行推理和行动 问题用户提出的问题 思考你应该思考接下来要做什么 行动要使用的工具名称必须是 [{tool_names}] 中的一个 行动输入传递给工具的输入 观察工具返回的结果 ...这个思考/行动/行动输入/观察可以重复 N 次 思考我现在知道最终答案了 最终答案对用户问题的最终回答 开始 问题{input} 思考{agent_scratchpad}promptPromptTemplate.from_template(react_template)defcreate_memory_aware_agent(user_input:str):创建一个带记忆注入的 Agent 并执行# 1. 构建带记忆的系统提示system_promptbuild_system_prompt_with_memories(user_input)# 2. 创建 Agentagentcreate_react_agent(llm,tools,prompt)executorAgentExecutor(agentagent,toolstools,verboseTrue,handle_parsing_errorsTrue,max_iterations5)# 3. 执行resultexecutor.invoke({input:user_input,system_prompt:system_prompt})returnresult[output]步骤 6实现后处理记忆更新Agent 回复后自动从对话中抽取新记忆并存入长期记忆。复用 Day 38 的抽取逻辑但简化为直接调用 LLM。extract_promptChatPromptTemplate.from_messages([(system,从以下对话中抽取值得长期记住的用户信息。只输出 JSON 数组每个元素包含 content、memory_type、importance。 memory_type 可选fact、preference、event。 importance 为 1-5。 如果没有值得记住的信息输出 []。 示例 用户我的订单号是 12345。 AI好的我记下了。 输出[{content: 用户的订单号是 12345, memory_type: fact, importance: 4}] ),(human,用户{user_input}\nAI{ai_response})])extract_chainextract_prompt|llm|StrOutputParser()defpost_process_memories(user_input:str,ai_response:str):后处理抽取新记忆并存入向量库try:resultextract_chain.invoke({user_input:user_input,ai_response:ai_response})importjson memoriesjson.loads(result)formeminmemories:# 去重检查简化检索相似度existingvectorstore.similarity_search_with_score(mem[content],k1,filter{status:active})ifexistingandexisting[0][1]0.15:# 距离很小说明重复continuedocDocument(page_contentmem[content],metadata{user_id:current_user,memory_type:mem.get(memory_type,fact),importance:mem.get(importance,3),timestamp:datetime.now().isoformat(),status:active,memory_id:str(uuid.uuid4()),access_count:0})vectorstore.add_documents([doc])print(f [记忆更新] 存入{mem[content]})exceptExceptionase:print(f记忆抽取失败{e})步骤 7整合完整对话流程defchat(user_input:str,user_id:strcurrent_user):完整的记忆感知对话流程print(f\n用户{user_input})# 1. 记忆注入 Agent 执行ai_responsecreate_memory_aware_agent(user_input)# 2. 后处理抽取新记忆post_process_memories(user_input,ai_response)returnai_response步骤 8测试完整流程模拟一个多轮对话场景观察 Agent 如何利用记忆if__name____main__:# 第一轮用户提供信息response1chat(你好我叫张三我的订单号是 12345我喜欢科幻小说。)print(f小智{response1})# 第二轮Agent 应该记住用户信息response2chat(你还记得我叫什么吗我的订单号是多少)print(f小智{response2})# 第三轮Agent 应该能利用偏好推荐response3chat(推荐一本我可能喜欢的书。)print(f小智{response3})# 第四轮用户更新偏好response4chat(其实我现在更喜欢历史小说了。)print(f小智{response4})# 第五轮验证偏好更新response5chat(我现在喜欢什么类型的书)print(f小智{response5})预期观察第一轮Agent 回复并自动抽取记忆姓名、订单号、偏好。第二轮Agent 从注入的记忆中看到用户信息直接回答。第三轮Agent 结合偏好推荐科幻书籍。第四轮Agent 更新偏好记忆。第五轮Agent 检索到更新后的偏好回答“历史小说”。三、常见问题与调试Q1记忆注入导致 System Prompt 过长Token 消耗大。→ 限制检索记忆的数量k3并在格式化时截断每条记忆的长度如最多 80 字。也可以只注入重要性 3 的记忆。Q2Agent 同时使用记忆工具和自动注入造成信息重复。→ 可以在 System Prompt 中说明“以下信息已自动提供无需再次调用 recall_memory 工具”或者只在 Agent 明确需要查询特定记忆时才使用工具。Q3后处理抽取的记忆与已有记忆重复。→ 在存入前做相似度检查距离小于阈值如 0.15则跳过。也可以让抽取 Prompt 参考已有记忆列表但这会增加 Token 消耗。实践中简单的相似度去重已经足够。Q4Agent 在回复中“假装”记得用户信息但实际记忆库中没有。→ 这可能是模型幻觉。在 System Prompt 中强调“只根据提供的记忆回答如果记忆中没有相关信息请明确说不知道”。同时降低温度减少模型自由发挥。Q5多用户场景下如何隔离记忆→ 每个用户有独立的user_id所有记忆操作都带filter{user_id: user_id}。在对话开始时根据用户登录信息确定user_id。当前代码中硬编码了current_user实际项目中应从会话中获取。Q6如何让 Agent 主动询问用户是否要记住某条信息→ 可以在 System Prompt 中加入规则“当你发现用户提供了重要信息如订单号、偏好可以在回复中确认‘我已记住’”。这样用户有感知也便于纠错。Q7记忆注入的检索时机是什么→ 我们在每次用户输入时检索。如果用户输入很短如“嗯”“好的”可以跳过检索复用上一轮的记忆减少不必要的调用。四、今日总结与作业今天你完成了✅ 理解了记忆与 Agent 整合的三种模式工具、上下文注入、后处理。✅ 将记忆查询和保存封装为 LangChain Tool。✅ 实现了自动记忆注入让 Agent 在对话前就“知道”用户背景。✅ 实现了后处理记忆抽取让 Agent 在对话后自动学习。✅ 构建了完整的“记忆感知型 Agent”并通过多轮对话验证了效果。今日作业必做修改build_system_prompt_with_memories增加一个参数include_types可以只注入特定类型的记忆如只注入preference和fact不注入event。测试不同组合的效果。实现一个get_user_profile(user_id)函数从向量库中汇总用户的活跃记忆生成一个结构化的用户画像如{name: 张三, preferences: [科幻小说], facts: [订单号 12345]}。设计一个测试场景用户先问“我的订单到哪了”Agent 没有订单查询工具只能依赖记忆。观察 Agent 是否能从记忆中检索到订单号并做出合理回复如“您的订单号是 12345但我目前无法查询物流请稍后”。思考题在客服 Agent 中记忆注入和后处理抽取都会调用 LLM 或 Embedding增加了延迟。你如何优化这个流程使其在生产环境中保持低延迟请列出至少三个优化方向。明日预告我们将学习如何为客服 Agent 添加真实世界工具——查询订单数据库、调用物流 API、创建退款工单。这将让 Agent 从“能聊天”升级为“能办事”。有任何问题欢迎随时提问

相关新闻

BrowserSkill 深度解析:AI Agent 如何通过技能化浏览器操作实现自主自动化

BrowserSkill 深度解析:AI Agent 如何通过技能化浏览器操作实现自主自动化

1. BrowserSkill 到底解决了什么问题第一次听到 BrowserSkill 这个名字,很多人会以为它又是一个浏览器自动化脚本库,或者某个 Playwright 的封装。但真正用过之后你会发现,它想做的事情比"自动化"要大一层:它把浏览器操…

2026/10/18 22:51:00 阅读更多 →
Redux实战:组件状态管理全解析

Redux实战:组件状态管理全解析

成熟的项目中,会在src文件目录里,新建redux用于集中管理关于redux的操作;在redux中新建actions文件夹用于集中管理redux_action的操作;新建reducers文件夹用于集中管理诸多reducer。一、组件Person组件import React, { Component …

2026/10/18 22:51:00 阅读更多 →
Agentic多模态检索分析平台实战:用Hologres统一检索与分析架构

Agentic多模态检索分析平台实战:用Hologres统一检索与分析架构

如果你过去两三年一直在跟“检索分析”这两类需求打交道,应该能明显感觉到,AI应用大规模落地之后,数据平台的玩法彻底变了。以前做实时数仓,无非是把日志、交易、用户行为倒进来,跑跑指标,出出报表&#xf…

2026/10/18 22:51:00 阅读更多 →

最新新闻

三则AI新闻揭示应用临界点:轻量模型、免费旗舰与团队回迁

三则AI新闻揭示应用临界点:轻量模型、免费旗舰与团队回迁

10月8日早上,我的朋友圈和几个技术群几乎同时被三则AI新闻刷屏:一家主流模型厂商发布了新的轻量快速模型H 5.5,另一家巨头把第六代旗舰模型向普通用户免费开放,还有一个此前把部分团队搬到外地的智能体产品团队,宣布要…

2026/10/18 23:39:35 阅读更多 →
语言模型中的语法伪相关:模型为何学错教训?

语言模型中的语法伪相关:模型为何学错教训?

看到标题里的“Syntactic-Domain Spurious Correlations”,我第一反应是想起自己踩过的一个坑:训练文本蕴含模型时,验证集上“矛盾”标签的准确率一路飙升到95%以上,当时我还以为模型真的学会了推理。结果我把一个用规则改写出来的…

2026/10/18 23:39:35 阅读更多 →
恒星级AI时代:AI短剧生产管线与数字分身序章

恒星级AI时代:AI短剧生产管线与数字分身序章

1. 从“恒星级AI”说起:这个标题到底在讲什么“恒星级AI时代降临”这个说法,第一次看到的时候我愣了一下。恒星级的能量量级是什么概念?太阳每秒释放的能量大约是3.8乘以10的26次方瓦,人类目前全球总发电功率大概在3乘10的12次方瓦…

2026/10/18 23:39:35 阅读更多 →
OpenSpec:规范优先开发的工程实践与CI/npm落地指南

OpenSpec:规范优先开发的工程实践与CI/npm落地指南

1. OpenSpec 是什么:一个被低估的规范优先开发实践工具链OpenSpec 不是一个 npm 包名,也不是某个具体开源项目的代号——它是一套正在快速成型的、以机器可读规范(Spec)为唯一事实源(Single Source of Truth&#xff0…

2026/10/18 23:38:35 阅读更多 →
空间复用与数据对齐实战:内存池、缓存行与SIMD优化指南

空间复用与数据对齐实战:内存池、缓存行与SIMD优化指南

空间复用和数据对齐这两件事,很多人是在踩了坑之后才回头补课的。我刚开始接触算法实现时,习惯把所有临时数据都放在堆上现申请现释放,结构体字段怎么顺手怎么排,跑起来也没觉得有什么问题——直到有一次把数据规模抬到千万级&…

2026/10/18 23:38:35 阅读更多 →
Sakurairo WordPress 主题指南:从零到一搭出你的多彩博客

Sakurairo WordPress 主题指南:从零到一搭出你的多彩博客

Sakurairo WordPress 主题指南:从零到一搭出你的多彩博客 【免费下载链接】Sakurairo A WordPress theme that is built with AI-assisted reading features, colorful, user-friendly, well-rounded, and rich in functionalities. Support Chinese, English, Japa…

2026/10/18 23:38:35 阅读更多 →

日新闻

基于GMM的语音识别系统原理与MATLAB实现详解

基于GMM的语音识别系统原理与MATLAB实现详解

说到基于高斯混合模型(GMM)的语音识别系统,很多人第一反应就是一堆数学公式,觉得门槛很高。但如果你真的在MATLAB里把它落地跑通,会发现核心其实就是三件事:把声音变成特征向量,用GMM给每个类别…

2026/10/18 0:00:55 阅读更多 →
数字图像处理入门:反白、灰度化、调色板修改与导出txt实践

数字图像处理入门:反白、灰度化、调色板修改与导出txt实践

数字图像处理这四个字听起来挺唬人,但落到具体操作上,无非就是让计算机按你的想法“摆弄”像素。我在一个模拟项目X里用了一套特别经典的基础处理流程:对图像做反白、改调色板、彩色转灰度,最后把像素数据导出成txt文件。单看每一…

2026/10/18 0:00:55 阅读更多 →
机器人大脑技术盘点:具身智能的感知、决策与数据闭环

机器人大脑技术盘点:具身智能的感知、决策与数据闭环

如果你的信息流最近也天天刷到“机器人大脑”这个词,你会发现一个很有意思的现象:每个人说的“大脑”根本不是同一个东西。有人指的是大语言模型,有人指的是运动控制系统,还有人指的是能理解物理世界的端到端模型。在2026年这个时…

2026/10/18 0:00:55 阅读更多 →

周新闻

基于GMM的语音识别系统原理与MATLAB实现详解

基于GMM的语音识别系统原理与MATLAB实现详解

说到基于高斯混合模型(GMM)的语音识别系统,很多人第一反应就是一堆数学公式,觉得门槛很高。但如果你真的在MATLAB里把它落地跑通,会发现核心其实就是三件事:把声音变成特征向量,用GMM给每个类别…

2026/10/18 0:00:55 阅读更多 →
数字图像处理入门:反白、灰度化、调色板修改与导出txt实践

数字图像处理入门:反白、灰度化、调色板修改与导出txt实践

数字图像处理这四个字听起来挺唬人,但落到具体操作上,无非就是让计算机按你的想法“摆弄”像素。我在一个模拟项目X里用了一套特别经典的基础处理流程:对图像做反白、改调色板、彩色转灰度,最后把像素数据导出成txt文件。单看每一…

2026/10/18 0:00:55 阅读更多 →
机器人大脑技术盘点:具身智能的感知、决策与数据闭环

机器人大脑技术盘点:具身智能的感知、决策与数据闭环

如果你的信息流最近也天天刷到“机器人大脑”这个词,你会发现一个很有意思的现象:每个人说的“大脑”根本不是同一个东西。有人指的是大语言模型,有人指的是运动控制系统,还有人指的是能理解物理世界的端到端模型。在2026年这个时…

2026/10/18 0:00:55 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/18 0:55:02 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/17 17:22:31 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/18 12:16:16 阅读更多 →