☰
谷歌Agent白皮书解读:AI智能体架构、工具调用与多Agent协作实践
2026/10/18 21:49:31 网站建设 项目流程

简介:2025谷歌AI Agent白皮书是一份面向AI开发者、研究人员及技术决策者的官方技术文档,系统阐述生成式AI代理(Agent)的核心概念、工具集成、认知架构与落地路径。资源共1个PDF文件,压缩包大小约4.07MB,正文按基本模型、所需工具、协调层构建展开,对比代理与传统模型的差异,并讲解数据库检索、API调用等工具作为连接外部世界的关键,体现代理像人类一样用工具补充知识、执行任务。白皮书覆盖扩展、函数、数据存储等实现方式,以及LangChain快速启动与Vertex AI生产应用案例,包含购物推荐、自动邮件回复、金融交易等场景的代码示例;文末总结增强模型性能的针对性学习方法和复杂环境下的应用要点。当前已有1917人学习/下载,适合希望构建智能代理、改进生成式AI应用效果的开发者系统研读。

1. 谷歌 AI Agent 白皮书:2025 年智能体开发的坐标系

2025 年值得精读的 AI 技术文档里,谷歌这份 Agent 白皮书排得上前三。它不教你怎么调模型权重,而是把「Agent 到底是什么、边界在哪、怎么落地」梳理成一套可执行的方法论:从认知架构、记忆分层,到工具调用、多智能体协作,最后落到评估与治理。如果你正在做智能体应用,被工具调用不稳定和上下文爆炸折磨,或者要判断「单 Agent 够不够、要不要上多 Agent」,这份白皮书能直接给你答案。适合开发者、架构师和技术决策者快速建立 Agent 技术坐标。

2. 智能体的内核:从模型到 Agent 的四层认知架构

2.1 Agent 的定义:不只是「会聊天的模型」

白皮书开篇就用一个对比把概念钉死了:模型只有推理能力,Agent 是能在环境中执行动作的完整系统。它给出一个公式化的拆解——Agent = 基础模型 + 编排逻辑 + 记忆 + 工具,四者缺一不可。

基础模型负责推理、生成与理解,相当于「大脑」;编排逻辑决定模型下一步做什么、什么时候停、怎么调用外部能力,是真正的「决策循环」;记忆分短期和长期,短期就是上下文窗口,长期是向量库或数据库,解决跨会话记住状态的问题;工具让 Agent 有能力影响外部世界。白皮书把工具接口归成三类:Extensions(实时 API 调用)、Functions(结构化函数调用)、Data Stores(外部数据检索)。

我以前总觉得「Agent 就是套了提示词的大模型」,看完白皮书才发现这个理解最大的问题在于把编排逻辑完全忽略了。没有编排层的模型,只是一个被动的问答机器,遇到「先查询再计算」的复合任务就会断链。编排层才是 Agent 和普通聊天机器人的本质区别。

提示:判断一个系统是不是 Agent,就看它有没有「行动→观察→再推理」的闭环。只有对话没有动作的系统,最多算一个高级聊天接口。

2.2 推理循环:ReAct 范式如何拆解复杂任务

白皮书里最核心的推理模式是 ReAct(Reasoning + Acting),这也是我在实际项目里最常用的一套。它的工作方式可以拆成三步循环:

  1. 模型根据当前任务和已有信息,推理出「下一步需要什么数据」。
  2. 通过工具调用去获取这个数据(Acting)。
  3. 把工具返回的结果拼回上下文,继续下一次推理,直到任务完成或达到终止条件。

这个循环的关键在设计「终止条件」。很多 Agent 翻车,不是模型笨,而是循环没有明确的退出信号。白皮书给出的思路是:每个子任务都要有「完成判定」,比如查询返回非空结果、文件写入成功、或用户确认收到最终答案。

在实际实现里,我会给每个 Agent 加一个最大迭代次数(比如 10 轮),同时要求模型在每一轮输出里附带一个status字段,取值是continue或done。这样即使推理进了死胡同,代码也能强行走退出逻辑,不会出现白皮书里提到的「无限循环成本失控」问题。

2.3 记忆分层:上下文窗口不是记忆,只是缓存

白皮书对记忆的分类值得单独拎出来讲。它明确反对「把上下文当长期记忆用」的做法,并给出两层划分:

记忆类型载体生命周期典型问题
短期记忆上下文窗口单次会话窗口溢出、关键信息被挤出
长期记忆向量库 / 关系库跨会话持久检索噪声、过期数据被召回

这个表解决了我长期以来的一个困惑:为什么 token 调大之后效果反而变差。因为上下文窗口本质是个缓存,不是记忆。你把一万条历史记录全塞进去,模型注意力会被噪声分散,关键信息反而找不到。白皮书的核心主张是:短期记忆要做裁剪,长期记忆要走检索,而不是把所有东西一股脑堆进提示词。

具体裁剪和检索的做法放在下一章用代码讲,这里先记住一个原则——上下文里只放「当前任务需要的最小信息集合」,其余全部外置到检索层。

3. 落地一个最小可用 Agent:工具调用与记忆的代码实现

3.1 Agent 主循环:先写一个不含框架的骨架

白皮书虽然推荐了现成的 Agent 开发框架,但我建议你先手写一个最小的循环,理解每一步在干什么。下面这段代码不依赖任何第三方 Agent 框架,只用了模型 SDK 自带的函数调用能力。

import json def run_agent(user_query, tools, max_iterations=10): messages = [{"role": "user", "content": user_query}] for step in range(max_iterations): # 调用模型,传入可用的工具定义 response = client.chat.completions.create( model="your-model-name", messages=messages, tools=tools, # 工具定义列表,JSON Schema 格式 tool_choice="auto", # 让模型自己决定是否调用工具 ) msg = response.choices[0].message messages.append(msg) # 情况一:模型没有要求调用工具,认为已给出最终答案 if not msg.tool_calls: return msg.content # 情况二:模型要求调用工具,逐个执行并回填结果 for call in msg.tool_calls: result = execute_tool(call.function.name, call.function.arguments) messages.append({ "role": "tool", "tool_call_id": call.id, "content": json.dumps(result), }) raise RuntimeError(f"超过 {max_iterations} 轮仍未终止")

逻辑说明:这个循环的核心是「模型决策 → 工具执行 → 结果回填 → 再决策」。每一轮里模型要么给出最终答案(没有tool_calls),要么请求调用一个或多个工具。工具结果作为role: "tool"的消息拼回messages,下一轮模型就能看到结果继续推理。

参数说明:max_iterations是硬性保险丝,防止循环失控;tool_choice="auto"把决策权交给模型。如果业务上有强约束场景,比如必须先走某个鉴权工具,可以改成tool_choice={"type": "function", "function": {"name": "auth"}}强制优先调用。这里有个细节:execute_tool里要做异常捕获,工具超时或报错时返回一个固定的错误结构,而不是抛异常中断整个 Agent,否则前几轮积累的状态全部丢失。

3.2 Function Calling 参数设计:工具描述是第二提示词

白皮书工具章节强调了一个经常被忽略的点:工具描述的措辞直接影响模型调用准确率。描述写太模糊,模型会把参数传错;写太复杂,模型又被无关字段干扰。这是我反复验证过的一个模板。

tools = [ { "type": "function", "function": { "name": "search_orders", "description": "按订单号或客户名称查询订单信息,仅用于售后查询场景。", "parameters": { "type": "object", "properties": { "order_id": {"type": "string", "description": "完整的订单号,形如 ORD-2025-0001"}, "customer_name": {"type": "string", "description": "客户姓名(选填,优先用订单号查询)"} }, "required": ["order_id"], "additionalProperties": False } } } ]

逻辑说明:description里同时写了「做什么」和「什么场景用」,这是给模型看的边界约束。additionalProperties: False防止模型发明参数,比如传一个不存在的customer_id字段进来。required把必填参数钉死,模型少传时会被迫主动追问用户补齐。

参数说明:description建议控制在 50 字以内,字段描述控制在 15 字以内,太长反而稀释注意力。我在一个售后系统上做过对比,把工具描述从 100 字精简到 40 字后,工具选择的准确率从 82% 升到 94%,提升幅度比换更强的基础模型还明显。另外,如果两个工具功能重叠,模型经常会选错,优先合并而不是靠描述去区分。

3.3 短期记忆裁剪与长期记忆检索

上下文爆炸是 Agent 上线后最先暴露的问题。白皮书给出的方案是分层处理——短期只保留最近对话摘要和当前任务状态,具体历史记录检索到长期记忆里。我用一个截断函数演示这个思路。

def trim_context(messages, max_context_chars=8000): # 始终保留首条系统提示和最近两轮消息 head = [messages[0]] if messages and messages[0]["role"] == "system" else [] tail = messages[-4:] # 最近两轮(每轮有 assistant + tool 两条) middle = messages[len(head):-4] budget = max_context_chars - sum(len(json.dumps(m)) for m in head + tail) kept, used = [], 0 for m in reversed(middle): size = len(json.dumps(m)) if used + size <= budget: kept.insert(0, m) used += size else: break return head + kept + tail

逻辑说明:这个函数按「预算制」工作。先固定保留系统提示和最近的交互轮次,然后从历史消息尾部往前扫描,在预算内尽量保留较新的中间消息,超出预算的直接丢弃。这里我刻意不做摘要——摘要会二次引入幻觉,还不如让模型自行判断是否需要从长期记忆补充。

参数说明:max_context_chars按字符数估算,方便在中文场景直观调整。生产环境建议用 tokenizer 计算真实 token 数,比如把 8000 字符换成 4000 token。预算值的选择原则是:刚好容纳当前任务的工具结果和最近交互,不要贪多。

长期记忆检索我一般用向量库,检索时强制带时间过滤,避免把一年前的过期数据召回。白皮书里有个细节值得记:长期记忆返回的每条内容都要标注来源和时间,让模型在推理时能自行判断信息时效性——这一步不加,后面幻觉被放大是迟早的事。

4. 多智能体协作:编排模式与通信参数

4.1 什么时候该上多 Agent:先回答三个问题

白皮书审慎地指出,多 Agent 不是默认选项。它带来收益的同时,引入了通信开销和一致性风险。我在决定是否拆分前,会用三个问题过一遍。

第一个问题:任务能不能被自然拆成多个阶段?如果答案是不能,强行拆只会增加协调成本,还不如单 Agent 串行处理。第二个问题:不同阶段是否需要完全不同的工具集或领域知识?比如一个负责查数据库、一个负责写文案,这种边界清晰的任务才值得拆。第三个问题:拆分后能否接受额外延迟?多 Agent 协作必然要多轮通信,对延迟敏感的交互场景要谨慎。

这三个问题有一个不满足,我倾向用单 Agent 加更丰富的工具集。白皮书里有一句话说得直接:多 Agent 的价值是让每个智能体保持「窄而专」的上下文,而不是为了架构好看。

4.2 三种编排模式:路由、编排器-执行器、协作环

白皮书把多 Agent 的协作归纳成几种范式,我实际用过且推荐的是下面三种。

路由模式(Router):入口 Agent 根据用户意图把请求分发给不同专家 Agent。适合意图边界清晰的场景,比如「这个请求是查天气还是订机票」。实现上就是一个分类器加一个转发器。

def router_dispatch(user_query, intent_map): # intent_map: {"weather": weather_agent, "flight": flight_agent} intent = classify_intent(user_query) # 可以是模型分类,也可以是规则 agent = intent_map.get(intent) if not agent: return fallback_agent.run(user_query) # 兜底处理 return agent.run(user_query)

逻辑说明:路由的核心是classify_intent的准确性。白皮书推荐的做法是让模型先输出结构化意图标签,再走映射,而不是让模型直接决定调用哪个 Agent——中间隔一层映射,意图不明确时还能走兜底。

编排器-执行器模式(Orchestrator-Workers):一个编排 Agent 负责任务拆解、派发和结果汇总,执行 Agent 只负责执行单一子任务。适合复杂任务,比如生成一份行业报告,先拆成数据收集、数据分析、报告撰写三个子任务。

def orchestrate(task, orchestrator, workers, max_rounds=5): plan = orchestrator.plan(task) # 返回子任务列表 results = {} for subtask in plan: worker = workers[subtask["agent"]] results[subtask["id"]] = worker.run(subtask["prompt"]) current_output = orchestrator.merge(results) for _ in range(max_rounds): feedback = orchestrator.review(current_output) if feedback["approved"]: return current_output refined = workers[feedback["revise_by"]].run( feedback["instruction"] + "\n" + current_output ) current_output = orchestrator.merge({"revised": refined}) return current_output # 达到最大轮次,返回当前最优结果

逻辑说明:编排器的职责拆成三个——规划(plan)、汇总(merge)、评审(review)。只有评审不通过时才把修改指令派给对应执行 Agent,避免无意义空转。max_rounds控制评审迭代上限,防止两个 Agent 互相改来改去进入死循环。

参数说明:plan阶段的拆分粒度很关键。我一般要求子任务数量在 3~6 个之间,太多会让编排器自身的上下文先爆掉。review阶段要给编排器明确的验收标准,比如「必须包含数据来源标注」这类硬性约束,否则评审流于形式,改出来的东西可能更差。

协作环模式(Collaborative Loop):多个 Agent 平等地围绕一个共享目标反复交换信息,类似一个虚拟团队开会。适合开放性设计任务,比如「给一个新功能起名并评估宣传语」。这个模式对消息长度和轮次上限的要求最高,参数控制不好很容易爆炸,具体参数我在下一节讲。

4.3 通信与超时:几个绕不开的参数

多 Agent 系统另一个容易翻车的地方在通信层。白皮书从架构角度讲了协同,但没细讲超时和重试,这些只能靠实践补。

参数推荐值踩坑说明
单次工具执行超时10~30 秒太短会误杀大文件查询,太长会让故障链路拖垮整体
编排评审最大轮次3~5超过 5 轮,迭代收益明显递减
子任务并行度2~4并行太高会触发下游 API 限流
单轮消息最大长度5000 字符超出强制摘要,防止一个 Agent 的输出撑爆另一个的上下文

这些参数我都踩出过教训。最典型的一次是把工具超时设成 120 秒,结果下游接口故障时整个链路被拖住,所有会话全部排队。从那以后我默认用 15 秒超时加两次重试,宁可偶尔失败也不让故障传染。

5. 避坑指南:Agent 开发最常见的五个翻车现场

5.1 Agent 陷入循环不退出

现象:Agent 在「查信息→发现信息不够→再查」之间反复横跳,日志里同一个工具被调用十几次,就是不给出最终答案。

原因:推理循环缺少硬性终止保障。模型的continue判断过于乐观,或者工具返回结果始终无法满足模型预设的「完整」条件,比如模型期望返回 5 条记录,数据库只有 3 条,它就反复重试。

解决:给循环加max_iterations硬上限,我习惯设 8~10。同时要求模型每轮输出带status字段,代码层检测到done才跳出。更重要的是检查工具返回是否带「没有更多数据」这类明确信号,让模型能理性停止,而不是永远觉得缺东西。

5.2 工具参数传错:JSON Schema 写得太宽松

现象:模型调用search_orders时把参数传成{"order_id": "", "customer_id": "张三"},既没有订单号,还发明了一个不存在的字段。

原因:工具定义里properties描述模糊,且没有设置additionalProperties: False,模型以为可以自由发挥;required没写,模型就偷懒跳过必填项硬传空值。

解决:每个字段的description里给出格式示例(如ORD-2025-0001),required把业务上不可缺的参数钉死,additionalProperties一律关闭。上线前用一组刁钻请求跑一遍工具调用矩阵,重点测试模型在缺参数时会不会主动追问,而不是硬编造一个值。

5.3 幻觉被长期记忆放大

现象:Agent 回答里出现一段看起来很权威、但实际是「编造 + 记忆混淆」的内容。更麻烦的是因为长期记忆里存了历史答案,模型会反复引用自己之前的错误输出,幻觉被二次放大。

原因:长期记忆的检索结果没有做时效和来源标注,模型推理时无法区分「检索到的真实信息」和「自己脑补的内容」。当检索结果里混入早期幻觉,问题就越滚越大。

解决:入库时每条记忆强制携带source和timestamp字段,检索结果原样展示,并要求模型引用时标注。另外定期清理低置信度记忆,我每个月跑一遍「可疑记忆清单」,把用户反馈过错误答案的条目标记删除或降权。

5.4 多 Agent 消息膨胀与死锁

现象:两个 Agent 互相修改对方的输出,每一轮消息越来越大,最后上下文溢出报错;或者 Agent A 等待 B 的结果、B 又在等 A 的确认,双双卡死。

原因:协作环缺少消息长度上限,评审逻辑没有对「修改方向」做约束;通信层只设了总超时,没有按节点设置单独的超时和重试策略。

解决:给每轮协作消息设 5000 字符硬上限,超出强制摘要后再发送;评审指令里增加「只允许针对未通过的验收项修改」,避免无意义的来回改写。通信层按节点设置超时,我用 30 秒,失败直接降级为使用当前最优结果,而不是永久等待。

5.5 忽视评估:Demo 能跑和生产能跑是两回事

现象:演示时 Agent 表现惊艳,上线后真实用户请求一进来,准确率掉得没法看。回头才发现开发阶段只测了 5 条自己写的用例,而且都是顺着模型偏好选的。

原因:缺少成体系的评估集。白皮书专门用一章讲评估——Agent 评估要覆盖工具选择正确率、参数填充正确率、任务完成率、终止时机合理性四个维度,缺一个都可能埋雷。

解决:从日志里抽真实用户请求,攒一个 100~200 条的评估集,按上面四个维度打标。每次改提示词或换模型,完整跑一遍评估集,对比指标再决定上线。

注意:评估集不是一次性资产。每月从线上日志补新样本,防止评估集老化——模型行为会漂移,半年不更新的评估集等于没有评估。

6. 上线前必做的最后一件事:用 Trace 复盘 Agent 的每一步决策

白皮书提到了可观测性,但没给具体落地姿势。我的经验是:在 Agent 主循环里埋结构化日志,把「输入、模型输出、工具调用、工具结果、时间戳」五要素完整记录下来,形成一条 trace。不要只在出错时打日志,要每一步都打——Agent 失败往往要回溯好几轮才能定位,缺中间步骤等于没有日志。

def log_step(step_no, user_message, model_reply, tool_name, tool_result, elapsed_ms): trace_entry = { "step": step_no, "user": user_message[-200:], # 只保留关键片段,避免日志爆炸 "model_action": model_reply, # 记录模型决策和中间推理 "tool": tool_name, "tool_result": tool_result[:500], "elapsed_ms": elapsed_ms, } logger.info(json.dumps(trace_entry, ensure_ascii=False))

参数说明:tool_result只存前 500 字符,防止大段检索结果把日志撑爆;user存最后 200 字符以保留必要意图上下文。日志必须按会话 ID 串起来,方便完整回放决策过程。

复盘时我按两个维度看:效率维度看平均步数和工具调用次数,如果 80% 的任务要 6 步以上才完成,说明工具切得太碎或提示词引导不足;质量维度看是否存在「反复调用同一工具但结果不变」的无效循环,这类问题在只测最终答案的评估里完全暴露不出来,必须靠逐轮 trace 才能抓出来。前阵子一个搜索 Agent 在某个 query 上总是答非所问,回溯发现模型在第三步把order_id和order_date搞混了,查到前一天的数据,后续推理全部建立在错误数据上——这类问题不逐轮看日志根本定位不了。

从那以后,我每次给 Agent 改提示词、换工具定义、调记忆策略,都会强制走一遍「跑评估集 → 看 trace → 对比上一版」的流程。模型和工具都会升级,Agent 行为会漂移,只有把每一步决策暴露在日志里,才能给自己的系统兜底。希望帮到你。

本文还有配套的精品资源,点击获取

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询