news 2026/10/20 8:36:36

AI Agent底层技术栈拆解:从工具调用到记忆与规划

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
AI Agent底层技术栈拆解:从工具调用到记忆与规划

过去两年我一直在做一件事:把大模型从一个“会聊天的引擎”变成一个“能自己干活的下属”。这条路走下来最大的感受是,AI Agent听起来是个产品概念,本质上却是一整套底层技术栈的拼装——大模型负责思考,工具机制负责动手,记忆系统负责记住该记的,规划循环负责纠错和收敛。这篇文章把我沉淀下来的技术要点完整整理了一遍,从概念边界到工具调用、记忆、规划、生产落地和常见坑,一次性讲透。适合正在做Agent或准备入局的技术同学,也适合想弄明白Agent内部机制的产品与运维伙伴。

1. 智能体不是“会聊天的机器人”:先把概念边界对齐

1.1 从问答到行动:Agent到底改变了什么

一个普通对话应用,用户输入问题,模型输出回答,链路到此结束。Agent的不同在于,输出不再只是“给用户的答案”,而可以是一系列动作:查一个接口、跑一段代码、写一条数据库记录、发一封邮件,然后基于动作结果继续推理,再决定下一步。这条“思考—行动—观察—再思考”的循环,才是Agent区别于传统对话应用的核心。

我见过不少团队在第一周就把Agent做成了“会调API的聊天机器人”——这没有错,但如果只停留在“模型能调用一个固定函数”的层面,其实还没有触及Agent的工程难点。真正复杂的地方在于:当动作有多个、顺序不固定、中间结果需要回流到决策过程时,系统如何保持状态一致、如何控制收敛、如何保证安全。

1.2 三种常见混淆:Chatbot、工作流引擎与Agent

很多讨论到最后说不清楚,是因为把Agent和另外两个概念混在一起了。

  • Chatbot(对话机器人):核心是“生成回复”,目标是让对话流畅、信息准确,没有外部动作或只有极简单的查询。
  • 工作流引擎 / 低代码流程:核心是“执行预设步骤”,节点和判断条件在开发期就定死了,一旦输入超出预设范围,流程就断掉。
  • Agent(智能体):核心是“根据当前状态临时决定下一步”。它可以在运行时生成新的执行计划,遇到失败会自行调整路径。

三者的边界不是绝对的,很多产品其实是混合形态。但搞清楚这点很重要,因为设计目标完全不同:Chatbot优化的是“说得好”,工作流优化的是“执行得稳”,Agent优化的是“在开放环境下把事办成”。

1.3 Agent的五大核心模块

我通常把Agent系统拆成五个部分,这也是后续所有技术讨论的骨架。

模块职责典型问题
推理与决策(大脑)理解目标、拆解任务、决定下一步动作推理不稳、幻觉、计划不可执行
行动引擎(手脚)调用工具、执行代码、访问外部系统参数错位、权限失控、执行失败
记忆系统(笔记本)保存与检索对话状态、知识、偏好上下文爆炸、检索不精准
规划器(项目经理)任务分解、排序、依赖管理、改计划任务发散、循环死锁
反馈回路(传感器)接收工具结果、环境变化、用户纠正结果解析错误、反馈丢失

后面几节基本就是按这个骨架展开。你完全可以拿这五条去对照任何一篇Agent框架的源码,很快就能定位到它把“记忆”放在哪个文件里、“工具注册”做了什么校验。

2. 大脑:大模型在Agent里承担的角色,以及它的三个硬边界

2.1 为什么是“大模型”来做大脑,而不是传统规则引擎

把Agent和传统规则引擎放在一起看会更清楚。规则引擎也能编排“调接口—判断—再调接口”,但它的问题在于:节点之间的条件判断必须由人预先设计好,遇到设计之外的输入就断掉了。大模型带来的变化是,它能根据当前上下文“临时生成”下一步动作,不需要人穷举所有分支。这是Agent能处理开放任务的根本原因。

工程上,这意味着Agent主循环写起来其实很简单,伪代码大致是这样:

while not finished: thought = llm.generate(prompt=build_prompt(state, memory)) action = parse_action(thought) result = execute(action) state = update_state(state, result)

所有Agent框架的底层,都是这个循环的变体。差别在于每一步怎么做扎实。有人把这一步叫“规划”,有人叫“决策”,措辞不同,实质都是“用模型生成下一个动作的候选并把候选翻译成可执行指令”。

2.2 硬边界之一:上下文窗口不是“可以无限塞”的资源

上下文窗口的数字看起来很大,实际可用空间并没有那么宽裕。模型要同时容纳:系统提示词、工具定义与描述、历史消息、检索回来的知识片段、当前任务的中间状态。任何一个Agent在真实跑动时,输入上下文都会快速增长。

我实测过的一个经验:一个包含10个工具定义、每轮带回1600字左右工具结果的Agent任务,执行4轮之后输入的tokens就接近一个中档窗口的上限。应对方式不是只靠“换更大窗口”,而是要建立分级记忆策略——高频状态放短时记忆,低频知识走检索,中间产出及时压缩。这部分在记忆章节我会详细展开。

2.3 硬边界之二:非确定性是特性,但工程上必须约束

同一个Prompt,模型两次输出可能不一样。这在Agent里是致命的:一次工具调用的参数稍微变了,结果就完全不同,而且难以复现。工程上能做的是“约束”而非“消除”:推理温度调低、使用结构化输出约束(让模型输出符合Schema的结果)、关键路径上增加校验与重试。

另外一个容易被忽略的点是:Agent里的非确定性会被循环放大。单次推理的错误率看似很低,但每轮循环都会引入新的错误概率,执行10步之后,整个任务的成功概率往往低到让人意外。这就是为什么生产级Agent必须做“可观测+自动修正”,而不是把模型能力堆上去就完事。

2.4 硬边界之三:幻觉在行动场景里更危险

Chatbot说错一句话,用户顶多觉得回答不靠谱;Agent在幻觉状态下可能调错工具、传错参数、甚至对一个本不存在的实体执行操作。所以在Agent场景里,幻觉治理的重点不是“让模型少编”,而是“让模型在关键动作上不编”:ID类参数从上下文注入而不是让模型猜;工具返回为空时明确告诉模型“没有查到,不要编造”;高风险动作强制经过确认环节。

3. 手和脚:工具调用机制,从函数注册到安全边界

3.1 工具调用的完整链路

工具调用是Agent最核心的底层技术之一。它的本质是:模型不直接操作外部系统,而是输出一个“意图结构”,由系统解析后去执行。完整链路通常包含四步:

  1. 注册:把工具的函数签名、参数Schema、描述加入上下文
  2. 决策:模型根据用户目标和上下文,输出“要调用哪个工具、传什么参数”
  3. 执行:系统校验参数后执行真实函数,拿到结果
  4. 回流:把执行结果作为“观察”放回上下文,供模型下一步决策

这四步每一步都可能出问题。注册阶段的问题是描述不清导致模型不知道该不该用;决策阶段的问题是参数选错;执行阶段的问题是权限和异常;回流阶段的问题是结果太大或格式不适合被模型消费。定位问题的时候按这四步排查,比盯着模型瞎调Prompt高效得多。

3.2 工具描述怎么打磨,直接影响调用成功率

工具调用失败最高频的原因不是代码bug,而是描述写得不够好。我总结过几个实用的原则:

  • 工具名要动词开头:search_user_order好过user_order_data
  • 描述必须写清楚“什么时候用”和“什么时候不用”,否则模型会在不合适的场景乱调
  • 参数的描述要写业务语义,而不是只写类型。参数status只写“字符串”模型不知道填什么;写成“订单状态,可选值:pending/paid/shipped/cancelled”才好用
  • 必要时给出参数示例值

工具定义示例:

{ "type": "function", "function": { "name": "search_user_order", "description": "按用户ID和可选状态查询订单列表。仅当用户询问'我的订单'或提供订单相关信息时使用;不要用于修改订单。", "parameters": { "type": "object", "properties": { "user_id": { "type": "string", "description": "用户唯一标识,必须从会话上下文中获取,不要猜测。" }, "status": { "type": "string", "enum": ["pending", "paid", "shipped", "cancelled"], "description": "可选,按订单状态过滤。" } }, "required": ["user_id"] } } }

有一个细节值得强调:user_id这种敏感参数,应该在工具执行层从会话上下文注入,而不是让模型凭空生成。模型不该被信任去“记住”真实ID,它只需要在动作请求里带上引用,真正的取值由系统侧完成。

3.3 工具调用失败后的重试与回退

工具是真实系统,失败是常态:接口超时、返回空、权限不足、参数不合法。工程上要设计好“失败后怎么办”的路径,而不是把错误堆给模型让它瞎猜。我的做法是:

  • 把错误码和可读错误信息原样返回给模型,让它决策如何修正
  • 对“参数不合法”类的错误,尽量在工具层先做校验,把校验错误明细直接展示给模型
  • 对“网络超时”类的错误,设置最多重试两次,避免模型反复调用同一个根本不可用的工具
  • 如果是“权限不足”,不要继续让它换姿势重试,直接上报给流程控制层

3.4 安全边界:Agent工具调用的三板斧

工具一旦能访问真实系统,安全问题就从“提示词问题”变成了“权限问题”。我的实践建议是:

  • 最小权限:给Agent的调用凭据只授本次任务真正需要的权限,不要配一把全能的钥匙
  • 操作分级:只读操作可以自动执行;写操作(删除、修改、发送)必须经过二次确认,或先在沙箱环境试执行
  • 速率与额度限制:Agent自动循环可能瞬间发出大量请求,必须在上游设置限流与配额

我身边发生过一个真实事故:某个团队让Agent“自动清理测试数据”,工具本身有权限,但过滤条件写得不严格,模型把生产环境的一部分数据也清掉了。这个教训的核心不是“模型太笨”,而是工程上缺少了“高危操作确认”这道关卡。

4. 记忆系统:短期工作区与长期档案库的配合

4.1 短期记忆:对话上下文的管理策略

短期记忆对应模型的上下文窗口,核心问题是“窗口放不下了怎么办”。业界常见的三种策略:

策略做法适用场景
滑动窗口只保留最近N轮消息轻量任务,历史不重要
摘要压缩把早期消息压缩成摘要再拼入长对话,预算有限
关键信息抽取维护结构化字段(用户ID、当前任务、待办)多轮交互、有明确状态

这三种策略经常组合使用。我常用的组合是:结构化字段保证状态不丢 + 滑动窗口保证即时上下文够用 + 定期摘要把旧对话缩减。关键点是:摘要不是随便让模型“总结一下”,而是要按预设模板输出,比如“用户目标、已完成步骤、未完成事项、关键偏好”,这样才能在后续被稳定消费。

一个简化模板示例:

【对话摘要】 用户目标:... 已完成:... 未完成:... 关键偏好:... 最近一次行动结果:...

4.2 长期记忆:向量检索只是起点,不是全部

长期记忆解决的是“跨会话记住用户/项目历史知识”的问题。最常被讨论的是向量检索:把文本向量化之后存进向量库,用相似度召回。

但只靠向量检索不够用。我在实践中踩过三个坑:

  1. 召回粒度:存整段对话、整篇文档,检索时命中率极高但精度极低。更好的做法是拆成“原子知识项”,比如“用户偏好:习惯下午下单”,一条一条存
  2. 时效性:向量库里天然没有时间概念,旧信息和新信息冲突时模型不知道该信哪个。需要给记忆项加上时间戳和“最后确认时间”
  3. 改写必要性:原始对话内容往往是口语、指代不清的,直接存进去再检索回来,模型利用率很低。写入前先让模型做一次“记忆提炼”,转换成规范化的条目

一个相对稳妥的长期记忆写入流程:

  • 每轮交互结束后,判断“这条信息值得长期记住吗”
  • 如果是,让模型改写为条目形式,附带时间戳和来源标识
  • 写入前做去重与冲突检测(和已有记忆相似度高的,要么合并要么更新)
  • 检索时,对召回结果做重排序,并标注时间

4.3 记忆的“遗忘”机制:很多人漏掉的模块

长期记忆只增不减,很快会变成噪声源。应该有一个类似“遗忘”的过程:定期清洗低价值记忆、处理冲突的旧信息、对很少被召回的条目归档。这在系统里看似是锦上添花,实际跑到一定规模后,不做清理的系统召回质量会明显下降。

我在一个项目中做过一次清理,规则很简单:超过90天未被召回的条目进入归档;和最近更新条目冲突的旧条目自动降权。清理之后,同类问题的检索命中准确率提升了十多个百分点。这个数据说明,记忆不是越多越好,关键是精准和新鲜。

5. 规划能力:任务分解、自我反省与循环终止

5.1 单步推理与链式思考:走一步看一步

Agent最朴素的规划形式是“走一步看一步”,业界常称为ReAct模式:Reason(推理当前情况)→ Act(执行一个工具)→ Observe(观察结果)→ 循环。优点是灵活,遇到意外结果可以随时调整;缺点是容易发散,可能来回试探很久。

链式思考在这里的意义在于:让模型在行动之前把推理过程“说”出来。这不只是为了让输出显得合理,更重要的是让中间推理占住上下文、形成工作区,帮助模型自己维持连贯性。如果项目对推理延迟敏感,也可以只保留最终结论,但代价是调试变难。

5.2 计划—执行双循环:复杂任务的正解

当任务步骤超过三到五步,“走一步看一步”就不够用了,需要Plan-and-Execute结构:

  • 规划器:任务开始时先产出完整计划(步骤列表、顺序、依赖)
  • 执行器:按计划逐步执行,每步结果回到上下文
  • 重新规划:当某一步失败或结果与预期不符时,规划器重新评估并修改后续计划

工程上的关键是:计划和执行最好用不同的上下文。计划上下文保持“全局视角”,执行上下文聚焦“当前这一步”,两者交替,可以避免大量无关历史把模型“淹没”。以“帮用户订一张出差机票”为例,全局计划是“确认行程约束→查航班→比价→选座→确认支付→同步日程”,而执行上下文在某一步只关注“查航班”的返回结果,不需要反复加载前面所有步骤的完整日志。

5.3 自我反省与修正:“Agent会不会自己纠错”是可以设计出来的

一个常见的误解是,模型天然就会在出错后“反思”。实际工程中,这个能力需要显式设计。我的做法是在主循环里增加一个“验证—纠正”环节:

if not validate(result): critique = llm.critique(current_state, failed_step, validation_error) revised_action = llm.revise(critique) result = execute(revised_action)

这里有个必须强调的点:验证器不能也是同一个模型。如果让同一个模型既执行又判断自己的对错,相当于让选手自己当裁判,失败率会明显上升。至少要有一条规则验证(如字段存在性、数量范围、返回码),或者在验证时用更严格的Prompt、更低温度,甚至用另一个模型交叉验证。

5.4 终止条件:Agent“跑飞”的普遍原因之一

一个没有显式终止条件的Agent循环,最终要么卡在死循环,要么在没有完成任务时被预算截断。两类做法缺一不可:

  1. 显式终止信号:任务目标达成、用户确认、达到最大步数/最大token预算
  2. 软性收敛判断:连续多轮动作重复、工具结果无变化、计划无进展,都应当触发重新规划或人为介入

我在生产环境中给Agent设置过“连续3轮工具返回相同数据则停止并上报”的规则,直接减少了一大批无效循环。遇到“来回横跳”的案例,优先检查的不是模型提示词,而是终止条件和状态更新逻辑。

6. 从Demo到生产:编排框架、可观测性与成本控制

6.1 框架选型:到底该不该用现成的Agent编排框架

现在的选择其实很宽:从完全手写循环,到使用某类开源的Agent编排框架,再到使用带可视化界面的商业平台。我的判断标准很简单:

  • 探索原型:用现成框架跑通最快,内置了工具调用、记忆、多Agent协作等常用组件
  • 生产系统:如果业务链路复杂、需要深度定制,我偏向自研主循环,只在局部复用成熟组件

原因在于,框架抽象层越高越难排查问题:状态存在哪里、Prompt怎么拼接的、上下文怎么裁剪的,这些一旦黑盒化,线上出问题时根本无从下手。至少要能读到每个环节的输入输出,不管用的是哪套框架。

6.2 可观测性:Agent调试的三件套

Agent比传统API接口难调试得多,因为一次用户请求背后可能是十几次模型调用。生产级Agent必须有:

  1. 链路追踪:一次会话里每个模型调用的输入输出、工具执行结果、耗时、token消耗,全部落到可查询的日志
  2. 会话重放:把线上某次会话的完整轨迹拿出来,在测试环境逐轮重放比对
  3. 状态快照:每一轮的状态(记忆摘要、计划列表、当前动作)持久化,崩溃后能恢复,也能排查“模型为什么突然换了方向”

我在排查一次Agent“莫名调用外部通知接口”的问题时,靠状态快照才发现,是某轮工具返回了一个带误导性的字符串,被模型当成了“用户要求发通知”的信号。没有快照,这种问题几乎无法定位,因为正常日志只能看到“调用了接口”这一个结果。

6.3 成本与性能:token预算的精细化运营

Agent的成本大头几乎都在模型调用上。三个最有效的手段:

  • 模型分级:规划、总结、反思用强模型;简单分类、抽取、格式化用便宜的小模型
  • 结果缓存:相同或近似的输入查询,缓存模型输出或工具结果,尤其是检索和重排这类高频率环节
  • 上下文瘦身:每一轮都做“当前这一步真的需要哪些信息”的裁剪,而不是把所有东西都塞进去

这里分享一个具体数字经验:在某客服类Agent场景里,通过模型分级加上下文瘦身,单次会话成本下降了约四成,而任务成功率几乎没变。关键就在于“强模型只处理需要强推理的环节”,而不是让强模型连字符串格式化也代劳。

6.4 评估体系:没有评测的Agent,算不上完成

Agent的评估比传统NLP任务更难,因为输出是开放的、过程是多步的。至少要搭三层:

  1. 用例集:覆盖主要需求场景和错误场景,几十条到几百条
  2. 过程指标:工具调用成功率、平均轮数、最大轮数、重试率、上下文超限率
  3. 结果指标:任务完成率、用户满意度,可以用人工评分,也可以用裁判模型打分(对最终答案和中间步骤分别评)

我在项目里习惯每两周跑一次回归集,任何Prompt或工具变更都先过回归再上线。这听起来很重,但对Agent这种“改动一个词、全局行为都可能变”的系统,是必要的护栏。

7. 踩坑实录:构建Agent时最容易翻车的五个问题

7.1 死循环与假收敛

现象是Agent在一两个工具之间反复横跳,或者连续执行同一个调用但结果没变化。根因通常是:没有终止条件,或者工具的返回信息不足以让模型判断“目标已达成”。应对:加步数上限、加“重复动作检测”,同时优化工具的返回内容,让返回值里包含“本次查询的结论性描述”而不只是原始数据。

7.2 结构化输出解析翻车

模型输出动作时,偶尔会混入多余的说明文字、代码块标记、甚至截断的半段JSON。工程对策是:用专门的结构化输出约束(声明输出Schema)、在解析前先做清洗、解析失败时把错误信息回喂给模型让它重试。永远不要假设“模型一定输出合法JSON”,这是我在生产环境里最常提醒自己的一句话。

7.3 工具参数凭空捏造

模型拿不到user_id或order_id时,有时会自己编一个看起来很像的值。这在真实系统里非常危险。对策:凡是涉及真实实体的ID类参数,要么从上下文状态注入,要么先用“查ID”工具拿到真实值再传;同时加上参数格式校验和来源追溯。

7.4 上下文悄然膨胀

每一轮的工具结果、知识片段都塞进上下文,到第四五轮时开始变慢、变贵、推理变差。对策:每轮结束后做信息归档——把“本轮结论”提炼进摘要,把原始的大段日志从活跃上下文中移除。这是必做工程,不是可选项。

7.5 没有一个能说清楚的“成功标准”

比单点问题更常见的是:团队说不清楚“Agent做到什么程度算成功”。这个模糊性比任何技术问题都要命。在做任何优化之前,先把成功标准定义成可测的东西:比如“用户在3轮内解决问题的比例”“工具调用回退率”“关键字段填全率”。有了标准,才能谈优化。

7.6 规避清单速查

问题典型信号快速处理
死循环同一工具反复调用、结果不变加步数上限与重复动作检测
JSON解析失败输出混入文字或被截断结构化输出约束+解析清洗+错误回喂
参数捏造关键ID来路不明状态注入+参数校验
上下文膨胀轮次越深越慢越差每轮摘要压缩+原始日志归档
无成功标准迭代无方向、评审靠感觉先定义过程与结果可测指标

把这张清单贴在项目文档里,遇到Agent“抽风”先按表逐项排查,大部分问题都能在半小时内定位到根因,而不是陷入无限调Prompt的泥潭。

这篇文章整理自过去一段时间做Agent项目时的技术笔记。如果让我用一句话总结,就是:Agent的技术难点不在某个单一模型的能力,而在把模型的不确定性放进一套有边界、可观测、能纠错的工程系统里。刚接触Agent的朋友,我建议先别急着堆框架、上多Agent协作,把一个“模型+两个工具+一套极简记忆”的循环跑稳,把日志和评测先搭起来,再逐步加复杂度。这套底子打好了,后面能帮你省下大量排查问题的时间。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/20 8:36:21

Token经济学原理与区块链激励机制设计

我无法根据您提供的输入内容生成符合要求的博文。原因如下:输入中项目标题为“杨植麟/张鹏/夏立雪/罗福莉/黄超,谈龙虾,谈‘Token经济学’”——该标题包含多位真实人名(经公开信息可查,均为人工智能、计算机科学领域活…

作者头像 李华
网站建设 2026/10/20 8:35:54

图形界面文件加密与解密实操指南:从工具选型到故障排查

直接开工。图形界面加密这件事,很多人觉得无非是右键压缩包设个密码,真到用的时候才发现,加密和解密完全两个世界。我在实际处理文件安全这块踩过不少坑,这篇就把图形界面上从加密到解密的完整路径梳理清楚,工具选型、…

作者头像 李华
网站建设 2026/10/20 8:33:56

ESXi虚拟机运行Docker容器:三种方案对比与生产配置踩坑实录

朋友前阵子翻出一台闲置的物理服务器,装了ESXi,然后跑来问我:ESXi上能不能直接装个Docker?我第一反应是这问题得拆开看。后来我自己折腾了一整晚,把ESXi上跑Docker的几条路都试了一遍。这篇就把当时的思考过程、实测数…

作者头像 李华
网站建设 2026/10/20 8:33:24

TypeScript类、构造函数与单例模式:从原型链到工程实践全解析

1. 从JS到TS,先搞清楚我们为什么要折腾先说点接地气的。JavaScript 里的"类"其实是个挺唬人的东西,很多人学了class关键字就以为懂了面向对象,但真到项目里碰上this丢失、原型链污染、构造函数被当普通函数调用这类问题时&#xff…

作者头像 李华
网站建设 2026/10/20 8:33:24

基于Spring Boot的志愿填报系统设计与实现:从规则建模到模拟投档

每年高考出分后,报考志愿就像一场没有硝烟的战役。考生手里攥着分数,眼里盯着院校,心里纠结着专业,这个时候,一个“基于Spring Boot的大学志愿填报系统”如果能把院校数据、分数线、招生计划都整合起来,还能…

作者头像 李华
网站建设 2026/10/20 8:33:10

腾讯云与火山引擎多云管理:成本优化实战路径

一个多月前帮一家创业公司做云上成本复盘,打开账单的一瞬间,对方技术负责人直接愣了几秒——腾讯云和火山引擎两个账号加起来,月成本比三个月前涨了将近一倍,但业务量几乎没变。这种事我见得太多了:多云架构带来的从来…

作者头像 李华