ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

大模型Agent开发实战:规划、记忆与工具调用从零搭建指南

大模型Agent开发实战:规划、记忆与工具调用从零搭建指南 大模型Agent开发这两年从“新鲜词”变成了“绕不开的坎”。我身边不少做后端、做数据、甚至做硬件的朋友都在问同一个问题Agent到底是个啥我能不能上手做答案是可以但前提是你得先搞清楚它和普通大模型调用之间的本质区别。很多人以为接个API、写个提示词就算Agent了结果一跑就发现模型该胡说还是胡说该断片还是断片。问题不在模型本身而在于你没有给它装上“手脚”和“记忆”。这篇内容面向的是有一定编程基础、想从零搭出一个能跑通的大模型Agent的开发者。我会从Agent的核心构成讲起把规划、记忆、工具调用这三块拆开揉碎再给出一套可以直接抄的实操路径。中间会穿插我自己踩过的坑比如工具描述写得太模糊导致模型乱调、记忆窗口爆掉之后响应直接崩掉这类问题。读完你至少能明白一个能用的Agent需要哪些模块每个模块的坑在哪以及怎么用最小的成本把它跑起来。1. 先搞清楚Agent和裸调大模型的本质区别1.1 裸调大模型的天花板在哪大部分人接触大模型的第一步就是在对话框里输入问题、等回复。这种模式叫单轮或多轮对话本质上是一次“输入-输出”的映射。你问“今天天气怎么样”模型根据训练数据里的统计规律给你编一段话。它没有实时数据没有执行能力也不会主动去查任何东西。这种模式的天花板非常明显。第一知识截止问题模型训练完之后发生的事情它不知道。第二无法操作外部系统你让它帮你发一封邮件、查一下数据库、调一个接口它只能告诉你“你可以这样做”但它自己动不了手。第三多步推理容易断链你让它先算A再算B最后得出C中间任何一步出错后面全崩而且它不会自己回头检查。我刚开始做Agent的时候最大的误区就是觉得“模型够强就行了”。实测下来GPT-4级别的模型在纯对话场景确实很强但一旦涉及多步任务编排没有外部框架支撑错误率会指数级上升。这不是模型不行是你让它干了他不擅长的事。1.2 Agent多出来的三样东西Agent和裸调大模型的核心差异可以归纳为三个能力的叠加规划、记忆、工具使用。规划能力让Agent能把一个复杂任务拆成多个子步骤并且决定先做哪一步、后做哪一步。比如你让它“帮我分析一下这份销售数据并生成报告”它会自己拆成读取文件、清洗数据、计算指标、生成图表、撰写文字、整合输出。这个拆解过程不是硬编码的而是模型根据任务描述动态生成的。记忆能力让Agent在多轮交互中保持上下文一致性。裸调模型也有上下文窗口但那个窗口是线性的、有限的。Agent的记忆系统通常分为短期记忆和长期记忆短期记忆存当前任务的中间状态长期记忆存跨会话的知识和用户偏好。我见过太多项目因为没做好记忆管理跑到第五轮对话的时候模型已经忘了第一轮说了什么。工具使用能力是Agent最核心的差异化。模型本身只能生成文本但通过工具调用它可以执行代码、查询数据库、调用API、操作文件系统。工具调用的本质是模型输出一个结构化的调用请求外部系统执行后把结果返回给模型模型再基于结果继续推理。这个循环就是Agent的基本工作单元。1.3 一个最小Agent的组成清单如果你现在就想动手一个能跑的最小Agent需要以下组件大模型接口负责推理和决策可以是云端API也可以是本地部署的模型提示词模板定义Agent的角色、可用工具、输出格式约束工具注册表列出所有可调用的工具及其参数描述执行循环接收模型输出、解析工具调用、执行工具、把结果喂回模型记忆存储至少要有对话历史的存储和截断策略错误处理工具调用失败、模型输出格式错误、超时等情况的兜底逻辑这六个组件缺一不可。我见过有人只写了提示词和工具注册表就上线结果模型返回了一个不存在的工具名整个流程直接卡死。错误处理不是可选项是必选项。2. 规划模块让模型学会“先想再做”2.1 ReAct模式为什么成为主流Agent规划最经典的范式是ReAct也就是Reasoning加Acting。它的核心思想是让模型在每一步都先输出一段推理过程再决定执行什么动作。推理过程是自然语言动作是结构化的工具调用。为什么这个模式好用因为它把模型的“思考”和“行动”显式地分开了。裸调模型是直接给答案ReAct是让模型先说我为什么要这么做然后再做。这个“说”的过程本身就是一种自我校验。实测下来加了ReAct的Agent在复杂任务上的成功率比直接让模型输出结果高出不少。具体实现上提示词里会要求模型按固定格式输出思考我需要先查询当前库存 动作query_inventory 参数{product_id: 12345}然后外部系统解析这个输出执行query_inventory把结果拼回提示词让模型继续下一轮思考。这个循环直到模型输出“最终答案”为止。2.2 任务拆解的粒度控制规划模块最容易出问题的地方是拆解粒度。拆得太粗模型一步完不成会卡住拆得太细步骤太多token消耗爆炸而且中间任何一步出错都会导致整个链条断裂。我的经验是单个子步骤的工作量控制在“一次工具调用能完成”的范围内。比如“分析销售数据”这个任务不要拆成“读取文件、解析CSV、计算总和、计算均值、生成图表、写报告”这么细而是拆成“读取并解析数据、计算关键指标、生成可视化、撰写报告”四个步骤。每个步骤对应一到两个工具调用模型在每一步都有明确的完成标志。另外拆解的时候要给模型留出“回头”的余地。不要设计成线性流水线而是允许模型在某个步骤失败后重新规划。比如读取文件失败模型应该能决定“换个路径再试”或者“告诉用户文件不存在”而不是直接崩溃。2.3 规划失败的常见原因和修复规划失败通常有三种表现模型不拆解、拆解不合理、拆解后不执行。模型不拆解往往是因为提示词里没有明确要求它拆。你需要在系统提示词里写清楚“对于复杂任务你必须先列出步骤再逐步执行。”同时给几个拆解的示例模型会模仿。拆解不合理通常是模型对任务领域不熟悉。解决办法是在提示词里注入领域知识或者提供类似任务的拆解模板。比如做数据分析的Agent可以在提示词里写“数据分析任务通常包括数据加载、数据清洗、指标计算、结果呈现四个阶段”。拆解后不执行多半是输出格式没约束好。模型输出了步骤列表但没有输出结构化的动作指令。这时候需要在提示词里强制要求“每一步必须包含动作和参数格式如下...”3. 记忆系统别让Agent聊着聊着就失忆3.1 短期记忆的窗口管理策略短期记忆就是当前会话的上下文。大模型的上下文窗口是有限的虽然现在动辄128K、200K但token是要花钱的而且窗口越长推理越慢模型对中间内容的注意力也会下降。我常用的策略是滑动窗口加摘要。保留最近N轮完整对话更早的对话压缩成一段摘要。摘要由模型自己生成提示词大概是“请用三句话总结以下对话的核心信息和结论。”这样既保留了关键信息又控制了token消耗。另一个策略是分层记忆。把对话分成“任务状态”和“闲聊内容”两层。任务状态是结构化的比如当前进行到哪一步、已经获得了哪些数据、下一步要做什么。闲聊内容可以大胆截断。这样即使窗口满了任务状态也不会丢。注意滑动窗口的截断点不要选在工具调用和工具返回之间。我踩过这个坑模型发起了工具调用结果历史被截断工具返回的结果找不到对应的调用请求整个流程直接报错。截断前一定要检查最近的对话是否成对出现。3.2 长期记忆的存储和检索长期记忆解决的是跨会话的知识保留问题。比如用户上次说“我偏好用柱状图展示数据”这次再让Agent画图它应该记得这个偏好。实现长期记忆通常用向量数据库。把历史对话、用户偏好、领域知识都转成向量存起来每次新会话开始时根据当前任务检索最相关的记忆片段注入到提示词里。检索的时机很关键太早注入会干扰模型判断太晚注入又来不及影响决策。我的做法是在任务开始时检索一次在每次规划前再检索一次。向量检索的坑在于相似度阈值。阈值太高检索不到东西阈值太低检索出一堆无关内容反而干扰模型。我一般从0.7开始试根据实际效果调整。另外检索结果要去重和排序把最相关的放在最前面因为模型对提示词开头的内容注意力最强。3.3 记忆冲突的处理记忆冲突是指新旧信息矛盾。比如用户上次说“我喜欢红色”这次说“我讨厌红色”。如果两条记忆都检索出来了模型会懵。处理冲突的原则是“新信息优先”。在存储记忆的时候给每条记忆打上时间戳检索时按时间倒序排列并且在提示词里明确告诉模型“如果记忆内容冲突以时间较新的为准。”另外对于用户明确表达的偏好变更应该主动删除或标记旧记忆而不是简单追加。我见过一个更隐蔽的冲突工具返回的结果和长期记忆里的知识矛盾。比如记忆里说“产品A的库存是100”但工具查询返回“库存是50”。这时候应该以工具返回为准因为工具是实时的。提示词里要写清楚优先级实时工具结果 近期记忆 远期记忆。4. 工具调用Agent的手脚怎么装才稳4.1 工具描述怎么写模型才不乱调工具调用的第一步是让模型知道有哪些工具可用。工具描述写得好不好直接决定了模型会不会乱调、错调、漏调。一个好的工具描述包含四要素工具名、功能说明、参数列表、使用示例。工具名要见名知意用动词加名词的格式比如query_inventory、send_email、calculate_metrics。功能说明要一句话讲清楚这个工具做什么、什么时候用、什么时候不用。参数列表要标明每个参数的类型、是否必填、取值范围。使用示例给一两个典型调用场景。我踩过的坑是工具描述太模糊。比如有个工具叫process_data描述写的是“处理数据”。模型完全不知道这个工具能处理什么数据、怎么处理结果要么不用要么乱传参数。后来改成“清洗和格式化CSV数据输入文件路径输出清洗后的DataFrame”调用准确率立刻上来了。另一个坑是工具太多。一个Agent挂二三十个工具模型选择困难错误率飙升。我的建议是单个Agent的工具数量控制在10个以内超过就拆成多个Agent用路由层分发。4.2 参数校验和错误重试模型输出的工具参数不一定符合预期。类型不对、必填项缺失、值超出范围这些都很常见。所以工具执行前必须做参数校验。校验失败后不要直接报错给用户而是把错误信息返回给模型让它重新生成参数。提示词里可以写“如果工具调用失败请根据错误信息修正参数后重试最多重试三次。”这样模型有机会自我修复。重试也要有策略。参数格式错误可以立即重试但如果是网络超时或者外部服务不可用重试前要加退避等待。我一般用指数退避第一次等1秒第二次等2秒第三次等4秒。超过三次就放弃把错误信息返回给模型让它决定是换工具还是告诉用户。4.3 工具调用的安全边界工具调用是Agent最危险的部分因为它真的能操作外部系统。一个没有安全边界的Agent可能删掉你的数据库、给所有联系人发邮件、或者执行恶意代码。安全边界的第一层是权限控制。每个工具都要有明确的权限范围比如文件操作工具只能访问指定目录数据库工具只能执行SELECT不能执行DELETE。第二层是参数白名单对于关键参数比如收件人地址、文件路径要校验是否在允许列表内。第三层是人工确认对于高风险操作比如发送邮件、修改数据先让Agent生成操作预览用户确认后再执行。提示永远不要给Agent直接执行shell命令的权限。如果确实需要执行代码用沙箱环境限制网络访问和文件系统访问。我见过一个Agent因为能执行任意Python代码被提示词注入攻击后把整个项目的环境变量都打印出来了。5. 从零搭一个能跑的Agent完整实操路径5.1 环境准备和模型选型先确定你的模型来源。如果追求效果用云端APIGPT-4、Claude这些在工具调用和规划上表现更稳。如果考虑成本和数据隐私本地部署开源模型比如Qwen、Llama系列7B到14B参数量的模型在简单Agent任务上已经能跑通。本地部署的话显存是硬约束。7B模型量化后大概需要6到8G显存14B需要12到16G。如果显存不够可以用CPU推理但速度会慢很多。我的建议是先用云端API跑通流程再考虑本地化。开发环境用Python核心依赖就几个大模型SDK、向量数据库客户端、HTTP请求库。不需要一上来就上LangChain、AutoGPT这些重框架先用原生代码把循环跑通理解每一步在干什么后面再用框架提效。5.2 核心循环的代码实现Agent的核心循环可以用不到100行代码实现。伪代码逻辑如下def agent_loop(task, tools, max_steps10): messages [{role: system, content: SYSTEM_PROMPT}, {role: user, content: task}] for step in range(max_steps): response call_llm(messages) if response.is_final_answer(): return response.content if response.is_tool_call(): tool_name response.tool_name params response.params if tool_name not in tools: messages.append({role: system, content: f工具{tool_name}不存在}) continue try: result tools[tool_name].execute(**params) messages.append({role: tool, content: str(result)}) except Exception as e: messages.append({role: system, content: f工具执行失败{str(e)}}) return 达到最大步数限制任务未完成这个循环的关键点最大步数限制防止死循环工具不存在时返回错误让模型重新选择工具执行异常时把错误信息喂回模型。每一步的messages都要完整保留因为模型需要看到之前的推理过程。5.3 提示词模板的编写要点系统提示词是Agent的灵魂。我通常按以下结构写第一段定义角色“你是一个数据分析助手擅长处理销售数据并生成报告。”第二段列出可用工具每个工具一行格式统一。第三段规定输出格式“你的每次回复必须包含思考过程和动作指令。如果需要调用工具按以下JSON格式输出...”第四段写约束条件“不要编造工具返回结果。如果工具调用失败根据错误信息修正后重试最多三次。如果无法完成明确告知用户原因。”第五段给一两个完整示例展示从任务到工具调用到最终答案的全过程。提示词不要写太长太长了模型会忽略中间内容。核心约束放在开头和结尾因为模型对这两个位置的注意力最强。5.4 跑通之后的调优方向第一版跑通之后你会发现效果可能不太稳定。调优的方向有几个工具描述的优化。把模型调用错误的case收集起来分析是描述不清还是参数设计不合理针对性修改。提示词的迭代。把失败的对话拿出来看模型在哪一步跑偏在提示词里补充对应的约束或示例。记忆策略的调整。如果发现模型经常忘记之前的步骤检查记忆截断策略是不是太激进或者检索的相关性不够。模型参数的调整。温度调低一点让输出更稳定最大token数调大一点防止推理过程被截断。6. 并发场景下Agent的性能和稳定性6.1 并发请求下的状态隔离单用户跑通之后下一步就是多用户并发。Agent和普通API不一样它是有状态的。每个用户的对话历史、任务状态、记忆数据都是独立的不能混在一起。状态隔离的实现方式有两种一种是每个会话一个独立的Agent实例内存隔离简单但资源消耗大另一种是共享Agent实例但用session_id区分状态存储资源利用率高但实现复杂。我一般用第二种用Redis存会话状态每个请求带上session_idAgent根据session_id读写对应的状态。注意并发场景下最容易出问题的是工具调用的副作用。比如两个用户同时让Agent写同一个文件后写的会覆盖先写的。解决办法是给工具加锁或者让每个会话有独立的文件空间。6.2 超时和降级的处理大模型推理本身就有延迟加上工具调用一个完整的Agent任务可能跑几十秒甚至几分钟。并发上来之后超时是必然要面对的问题。我的做法是分层超时单次模型调用超时10秒单次工具调用超时5秒整个Agent任务超时60秒。任何一层超时都返回当前已完成的部分结果并告知用户任务未完成。不要无限等待用户等不起系统资源也耗不起。降级策略也要准备好。如果模型API不可用降级到规则引擎处理简单任务如果向量数据库挂了降级到只用短期记忆如果某个工具不可用从工具列表中临时移除让模型用其他工具替代。6.3 成本控制的实际手段Agent的token消耗比普通对话高得多因为每一轮都要把完整的历史和工具描述塞进提示词。并发上来之后成本会快速上升。控制成本的手段第一压缩提示词去掉冗余描述工具描述精简到必要信息。第二限制历史长度滑动窗口的N不要设太大摘要要定期生成。第三缓存常用结果比如工具返回的静态数据短时间内重复查询直接走缓存。第四选择合适的模型简单任务用便宜的小模型复杂任务才用大模型。我实测下来一个中等复杂度的Agent任务优化前大概消耗8000到10000 token优化后能压到3000到4000。按这个量级估算日活一千的用户每天的成本是可控的。7. 几个我踩过的坑和对应的解法7.1 模型输出格式不稳定导致解析失败模型有时候不按规定的JSON格式输出多一个逗号、少一个引号、或者干脆用自然语言描述工具调用。解析失败后整个循环就卡住了。解法是双重保障提示词里强调格式要求同时解析器要容错。解析器先尝试标准JSON解析失败后尝试正则提取关键字段再失败就把原始输出返回给模型让它重新按格式输出。另外可以在提示词里给一个格式错误的示例告诉模型“不要这样输出”。7.2 工具调用陷入死循环模型反复调用同一个工具参数几乎一样结果也一样但就是不输出最终答案。这种情况通常是模型陷入了“再试一次”的循环。解法是加调用频率限制。同一个工具在连续三轮内被调用超过两次就强制中断把控制权交还给用户。或者在提示词里写“如果同一个工具连续调用两次结果相同请停止调用并基于已有信息给出答案。”7.3 记忆检索引入无关信息干扰判断向量检索的相似度匹配有时候会召回一些语义相似但实际无关的内容。比如用户问“怎么优化查询速度”检索到了“查询语句怎么写”的记忆虽然语义相关但对当前任务没帮助。解法是加一层重排序。先用向量检索召回Top 20再用一个小的交叉编码器模型对这20条做精排取Top 3注入提示词。交叉编码器比纯向量相似度准得多虽然多了一步计算但值得。7.4 多轮对话中任务目标漂移用户一开始说“帮我分析销售数据”聊了几轮之后变成“顺便把库存也看一下”再几轮之后变成“你觉得哪个产品该下架”。任务目标在不断变化Agent如果一直沿用最初的规划就会跑偏。解法是在每轮对话开始时让模型先判断“当前任务目标是否发生变化”。如果变了重新规划如果没变继续执行。这个判断本身也由模型完成提示词里写“对比当前用户输入和之前的任务描述如果目标发生变化输出NEW_TASK并重新规划否则输出CONTINUE。”8. 从入门到进阶的学习路径建议如果你已经跟着上面的内容跑通了一个最小Agent下一步的进阶方向有几个。第一个方向是多Agent协作。单个Agent的能力有上限复杂任务可以拆给多个专职Agent比如一个负责规划、一个负责执行、一个负责校验。Agent之间通过消息传递协调。这个方向的关键是通信协议的设计和冲突解决机制。第二个方向是Agent安全。随着Agent能操作的系统越来越多安全变得至关重要。提示词注入、工具滥用、数据泄露这些都是真实存在的风险。建议研究一下Agent沙箱、权限最小化、操作审计这几个课题。第三个方向是领域深度定制。通用Agent在特定领域的表现往往不如领域定制Agent。比如做金融分析的Agent需要注入金融知识、接入金融数据源、定制分析工具。领域定制的投入产出比通常比通用Agent更高。第四个方向是评估和可观测性。Agent跑起来之后你怎么知道它好不好需要建立评估体系包括任务成功率、平均步数、工具调用准确率、用户满意度等指标。同时要有日志和追踪每一步的输入输出都要记录出问题能回溯。我个人的体会是Agent开发最难的不是写代码而是理解模型的“脾气”。同样的提示词换个模型效果可能天差地别同样的工具描述换个任务场景可能就不好使了。多跑、多看日志、多分析失败case比看任何教程都管用。另外不要追求一步到位先让Agent能跑再让它跑得稳最后才让它跑得快。顺序反了容易在细节里迷失方向。
返回列表