3 个 Skills + 1 个记忆层,打造能成长的 Agent
摘要很多人给 Agent 加了记忆层以为它就会越来越聪明。结果用了一个月还是老样子。原因不在模型而在系统设计。记忆如果只负责“存”Agent 就只是在反复翻旧聊天记录记忆如果能接住复盘、改写 Prompt、记录工具成败它才会开始积累经验。本文承接上一篇记忆层文章用 3 个最常见也最值得先上的 Agent Skills搭一套真正会“越用越顺手”的进化闭环。文章标签#Agent自进化 #AgentSkills #记忆层 #Reflection #Prompt优化 #ToolUse预计阅读时间11 分钟目录为什么很多 Agent 用久了还是像新来的记忆层不是聊天存档它更像值班日志主流 Agent Skills最后都会落到这三类Skill 1反思让一次对话变成一条经验Skill 2Prompt 自优化把经验写回系统提示Skill 3工具学习给工具调用建立胜负账本一张最小可跑的进化 Agent 架构工程落地时最容易踩的 4 个坑为什么很多 Agent 用久了还是像新来的一个代码审查 Agent第一次看你的仓库批评得很认真变量名不够长注释太少风格不统一你告诉它“我们团队就用短变量名注释只写复杂逻辑别按教科书那套来。”第二天再开一个新会话它还是老一套。这类 Agent 最大的问题不是它记不住而是它不会把记住的东西写回自己的做事方式。它像一个每天下班都不写交接日志的新同事。你昨天刚说过的话今天它又得重来一遍。所以“Agent 自进化”这件事重点从来不是把上下文窗口继续做大也不是把更多聊天记录塞进 Prompt。重点是两步把一次交互里的有效经验提纯出来。把这些经验重新作用到下一次决策里。如果只做第一步那叫“会记事”。两步都做了才叫“会成长”。记忆层不是聊天存档它更像值班日志上一篇我们讲记忆层时重点在“跨会话记住用户事实”。这一步当然重要但还只是地基。真正好用的记忆层更像团队里的值班日志。它不只是记“今天发生了什么”还会记三类对下次有用的东西用户事实技术栈、偏好、禁忌、历史问题行为经验这次回答哪里答偏了哪里答对了策略结果哪个 Prompt 更稳哪个工具更靠谱这样一来记忆层就不再是一个聊天归档盒而是一块持续更新的经验面板。这一层一旦搭好进化就不再神秘。它其实就是一个很朴素的闭环先交互再复盘把复盘写进记忆下次决策前把记忆拿出来用现在很多主流 Agent 框架里名字虽然各不相同但最后都绕不过这个闭环。主流 Agent Skills最后都会落到这三类你去看现在常见的 Agent 系统不管它叫 Skill、Tool Strategy、Critic、Policy Update 还是 Self-Reflection本质上大多能归到三类反思判断这次做得怎么样Prompt 自优化把经验写回行为规则工具学习记住哪个工具在什么场景下更好用这三类之所以值得先做不是因为它们最炫而是因为它们最容易落地而且确实能让 Agent 变顺手。下面直接上工程做法。Skill 1反思让一次对话变成一条经验很多团队做 Agent喜欢把所有精力都放在“回答时怎么推理”。其实真正容易被忽略的是“回答完之后怎么复盘”。反思 Skill 的任务很单纯在每轮对话结束后用一个便宜模型写一条短复盘。别写成长文够用就行。目标不是感动自己是为了给下一轮决策提供素材。这里有个原则很好用反思不求全面只求可执行。与其存一大段抽象点评不如存三条具体结论这次做对了什么这次做错了什么下次遇到类似问题先检查什么importjsonfromdatetimeimportdatetimefromtypingimportAnyfromdotenvimportload_dotenvfrommem0importMemoryfromopenaiimportOpenAI load_dotenv()memoryMemory()llmOpenAI()defcall_json(prompt:str)-dict[str,Any]:responsellm.chat.completions.create(modelgpt-4o-mini,temperature0.2,response_format{type:json_object},messages[{role:user,content:prompt}],)returnjson.loads(response.choices[0].message.content)defreflect_on_conversation(messages:list[dict[str,str]],user_id:str)-dict[str,Any]:compact_history\n.join(f{m[role]}:{m[content]}forminmessages[-6:])promptf 请复盘下面这段对话并只输出 JSON。 目标 1. 找出这次回答中做对的 1-2 点 2. 找出最该修正的 1-2 点 3. 给出下次处理同类问题时的具体动作 对话{compact_history}输出格式 {{ summary: 一句话总结, good: [...], bad: [...], next_actions: [...] }} .strip()reflectioncall_json(prompt)timestampdatetime.now().isoformat(timespecseconds)memory.add((f反思记录\nf总结{reflection[summary]}\nf做对{.join(reflection[good])}\nf做错{.join(reflection[bad])}\nf下次先做{.join(reflection[next_actions])}),user_iduser_id,metadata{type:reflection,created_at:timestamp},)returnreflection比如用户已经说过“代码风格以团队约定为准”但 Agent 还是按通用规范长篇输出。一次好的反思记录大概会长这样总结回答方向基本正确但忽略了团队既有规范。 做对先指出了可读性问题给了修改建议。 做错重复批评了用户已明确接受的短变量名风格。 下次先做先检索历史偏好命中团队规范后再决定是否展开风格建议。你会发现这就已经不是聊天记录了。这是一条经验。Skill 2Prompt 自优化把经验写回系统提示只有反思没有改动Agent 顶多算“会认错”。它还没有进化。第二个 Skill 的作用是把最近几次反思里重复出现的问题重新写回系统 Prompt。你可以把它理解成给 Agent 改 SOP。这个动作不需要每轮都做。实际工程里按批次触发更稳每 5 次对话更新一次或者每天低峰期批量更新一次或者只有用户明确点踩时才触发下面这个实现比较稳妥。它不直接依赖后端的 metadata 精确过滤而是先召回再在应用层筛选兼容性更好。fromhashlibimportsha1defget_memories_by_type(query:str,user_id:str,memory_type:str,limit:int8)-list[dict[str,Any]]:resultsmemory.search(queryquery,user_iduser_id)matched[]foriteminresults:metadataitem.get(metadata)or{}ifmetadata.get(type)memory_type:matched.append(item)returnmatched[:limit]defoptimize_system_prompt(current_prompt:str,user_id:str)-str:reflectionsget_memories_by_type(query反思记录 回答偏差 用户偏好 工具选择,user_iduser_id,memory_typereflection,limit8,)ifnotreflections:returncurrent_prompt notes\n.join(f-{item[memory]}foriteminreflections)promptf 你是资深 Prompt 编辑。请根据下面的反思记录改写当前系统 Prompt。 要求 1. 保留原任务边界 2. 只增强稳定性不改变产品定位 3. 优先吸收高频失误对应的修正规则 4. 直接输出完整 Prompt不要解释 当前 Prompt{current_prompt}反思记录{notes}.strip()new_promptllm.chat.completions.create(modelgpt-4o-mini,temperature0.2,messages[{role:user,content:prompt}],).choices[0].message.content.strip()old_versionsha1(current_prompt.encode(utf-8)).hexdigest()[:8]new_versionsha1(new_prompt.encode(utf-8)).hexdigest()[:8]memory.add((fPrompt 更新\nf旧版本{old_version}\nf新版本{new_version}\nf变更原因最近反思里多次出现同类失误),user_iduser_id,metadata{type:prompt_update,created_at:datetime.now().isoformat(timespecseconds)},)returnnew_prompt这一步一旦跑起来Agent 的系统提示就不再是写死的初始化文本而是会慢慢吸收真实使用中的摩擦。这也是为什么很多人觉得“我明明加了记忆Agent 还是不长进”。因为它只把记忆拿来补充上下文没有拿来改行为规则。Skill 3工具学习给工具调用建立胜负账本第三个 Skill 常常最容易见效。因为很多 Agent 的真实问题不是不会说而是不会选工具。比如查文档时总爱先走慢接口抓网页时明明该用结构化 API却先上浏览器一个工具已经连续超时三次下次还继续试这时候最值钱的不是让模型“更聪明一点”而是先把工具成败记账。defrecord_tool_result(tool_name:str,task:str,success:bool,note:str,user_id:str)-None:outcome成功ifsuccesselse失败memory.add(f工具记录\n任务{task}\n工具{tool_name}\n结果{outcome}\n备注{note},user_iduser_id,metadata{type:tool_result,tool_name:tool_name,success:success,created_at:datetime.now().isoformat(timespecseconds),},)defchoose_tool(task:str,candidates:list[str],user_id:str)-str:recordsget_memories_by_type(queryf{task}工具记录 成功 失败,user_iduser_id,memory_typetool_result,limit12,)ifnotrecords:returncandidates[0]history\n.join(f-{item[memory]}foriteminrecords)promptf 请为当前任务选择一个最合适的工具。 任务{task}候选工具{candidates}历史记录{history}规则 1. 优先选择同类任务中成功率更高的工具 2. 连续失败的工具降权 3. 只输出一个工具名 .strip()answerllm.chat.completions.create(modelgpt-4o-mini,temperature0.1,messages[{role:user,content:prompt}],).choices[0].message.content.strip()returnanswerifanswerincandidateselsecandidates[0]比如天气查询工具tool_a连续超时两次tool_b虽然慢一点但稳定。只要你把这件事写进记忆Agent 下一次就不至于继续撞墙。这类 Skill 很像给团队做值班手册。哪个工具在什么场景下靠谱别靠口口相传直接记账。一张最小可跑的进化 Agent 架构把前面三个 Skills 串起来最小闭环其实不复杂回答前先取用户事实和历史经验回答后生成一条反思反思积累到一定数量更新一次系统 Prompt工具调用结束后把成败写进记忆下面给一个可以直接看懂主流程的整合版本classEvolvingAgent:def__init__(self,user_id:str,system_prompt:str)-None:self.user_iduser_id self.system_promptsystem_prompt self.turn_count0self.history:list[dict[str,str]][]defrecall_context(self,query:str)-str:memoriesmemory.search(queryquery,user_idself.user_id)ifnotmemories:return无相关历史。return\n.join(f-{item[memory]}foriteminmemories[:6])defchat(self,user_query:str)-str:contextself.recall_context(user_query)final_promptf{self.system_prompt}已知历史{context}用户当前问题{user_query}.strip()responsellm.chat.completions.create(modelgpt-4o-mini,temperature0.3,messages[{role:user,content:final_prompt}],)answerresponse.choices[0].message.content.strip()self.history.extend([{role:user,content:user_query},{role:assistant,content:answer},])self.turn_count1memory.add(messagesself.history[-2:],user_idself.user_id)reflect_on_conversation(self.history[-6:],user_idself.user_id)ifself.turn_count%50:self.system_promptoptimize_system_prompt(self.system_prompt,self.user_id)returnanswer这个版本当然还很简化但已经够你把整套机制跑起来。后面要扩展也基本是沿着这三条线继续长反思更细Prompt 更新更稳工具选择更准工程落地时最容易踩的 4 个坑1. 反思写太长最后没人用复盘不是周报。你真正要的是一条下次还能触发的经验而不是一篇情真意切的自我检讨。控制在一句总结加两三条动作最实用。2. Prompt 改得太勤系统会飘很多团队一看到“自动优化”第一反应就是每轮都改。这样很容易把 Agent 改成另一个东西。比较稳的做法是批量更新、保留版本、随时可回滚。3. 记忆越来越肥检索越来越虚经验不是越多越好旧经验还可能误导新决策。实战里建议给反思和工具记录加 TTL只保留最近 30 天或最近 N 次高价值记录。4. 把“自进化”理解成“无人监管”自进化不等于放飞。尤其是 Prompt 更新和工具策略调整最好留一个人工审核开关至少在早期阶段别让它完全自改。最后Agent 自进化这件事说穿了不玄。它不是某个神秘新模型也不是再叠一层宏大框架。多数时候它就是把“这次做得怎么样”“下次该怎么做”“哪个工具别再用了”这三件事认真记下来再真的用回去。所以如果你准备在现有 Agent 上先做一件最有收益的事我建议顺序是先上反思 Skill再接 Prompt 自优化最后补工具学习把这三步接通你的 Agent 才会从“记得你说过什么”慢慢变成“知道下次该怎么做”。系列串联本文承接上一篇《给 Agent 装一个真正能用的记忆层》。如果你还没搭好记忆层建议先看上一篇再回来补这一篇。如果你在做代码 Agent、客服 Agent 或运维 Agent这套结构都能直接套。差别不在框架在你肯不肯把经验真正写回系统。