2.4 Action 行动模块:动作空间与执行接口


2.4 Action 行动模块:动作空间与执行接口

Planning 决定「做什么」,Action 决定「怎么做」。这一跃看似简单,却是 Agent 从「能说」到「能做」的关键一公里——也是 Agent 风险最高的模块。规划错了顶多绕远路,行动错了可能转错账、发错邮件、删错数据。

2.4.1 Action 在做什么:从决策到执行

Action 模块接收 Planning 输出的「下一步动作」,把它翻译成对真实世界的操作,再把结果(观察)回传给 Memory 与下一轮 Planning。

输入: Planning 输出的动作指令 (如 "调用搜索工具,query=财报") ↓ [Action 行动模块] ├── 1. 解析动作 (工具名 + 参数) ├── 2. 校验权限 (是否允许调?参数合法?) ├── 3. 执行动作 (调用工具/运行代码/直接回答) └── 4. 提取观察 (结果格式化 + 成功判定) ↓ 输出: 观察结果 (写回 Memory,喂给下一轮 Planning)

注意 Action 模块内部的 4 个子步骤——这不是「调用一下就完事」,而是包含解析、校验、执行、提取的完整流水线。其中校验这一步常被新手忽略,却是 Agent 安全的关键闸门(见 2.4.4)。

💡 Action 与工具的关系:Action 是 Agent 的「模块」,工具(Tool)是 Action 调用的「资源」。一个 Action 模块可以管理成百上千个工具;每个工具是一个可被 LLM 调用的函数/API/能力。Action 模块的工作,是把 LLM 的「调用意图」安全地落到具体工具上

2.4.2 动作空间:Action 的三类形态

Agent 能执行的动作可分三类,风险与复杂度递增:

动作类型 实现方式 副作用 风险 详见
直接回答 LLM 生成文本,不调工具 极低
工具/函数调用 调用预注册的 API/函数 视工具而定 第 6.1-6.2 节
代码执行 在沙箱里运行 LLM 生成的代码 第 6.3 节
<svg viewBox="0 0 720 360" xmlns="http://www.w3.org/2000/svg"> <!-- 三层风险金字塔 --> <polygon points="360,40 540,160 540,320 180,320 180,160" fill="#dcfce7" stroke="#16a34a" stroke-width="2"/> <polygon points="360,40 540,160 180,160" fill="#fef9c3" stroke="#ca8a04" stroke-width="2"/> <polygon points="360,40 450,100 270,100" fill="#fce7f3" stroke="#db2777" stroke-width="2"/> <text x="360" y="70" font-size="14" fill="#831843" text-anchor="middle" font-weight="bold">代码执行</text> <text x="360" y="135" font-size="14" fill="#713f12" text-anchor="middle" font-weight="bold">工具调用</text> <text x="360" y="240" font-size="14" fill="#14532d" text-anchor="middle" font-weight="bold">直接回答</text> <text x="100" y="100" font-size="12" fill="#db2777">↑ 风险/能力</text> <text x="100" y="300" font-size="12" fill="#16a34a">↑ 频率</text> <text x="360" y="345" font-size="11" fill="#475569" text-anchor="middle">能力越强,风险越高,使用频率越低</text> </svg>

类型一:直接回答

最简单的动作——LLM 信息已足够,直接生成最终答案文本,不调用任何工具。

  • 场景:解释、建议、闲聊、知识问答。
  • 风险:极低(无副作用)。
  • 判定:Planning 模块判断「无需外部信息」时选择。

类型二:工具/函数调用

调用预注册的工具(API、函数、数据库查询),获取信息或改变状态。

  • 场景:查天气、查股价、发邮件、写数据库。
  • 风险:视工具而定——只读工具低风险,写操作高风险。
  • 实现:通过 Function Calling 协议(第 6.1 节)。

类型三:代码执行

让 LLM 生成代码(通常 Python),在沙箱里运行,处理复杂数据分析或计算。

  • 场景:数据分析、复杂计算、批量处理、可视化。
  • 风险:高——代码能做任何事,必须有强沙箱隔离。
  • 实现:Code Interpreter(第 6.3 节)。

⚠️ 代码执行是 Agent 能力最大的双刃剑。它让 Agent 几乎能做任何事——但「能做任何事」也意味着「能搞砸任何事」。一个没有沙箱的代码执行模块,等于把整台服务器交给 LLM。代码执行必须配套沙箱、权限、人类在环三重保障,这是第 6.4 节的核心主题。

2.4.3 执行接口:动作如何落地

Action 模块需要一个执行接口(Execution Interface) 把 LLM 的动作指令翻译成实际调用。这个接口的设计是 Agent 工程的核心。

工具的三要素

每个工具都需要向 LLM 描述三件事:

要素 含义 例子
名称与描述 工具是干什么的 search_stock_price(ticker): 查询股票实时价格
参数 Schema 接受什么参数、什么类型 ticker: string (股票代码,如 AAPL)
返回 Schema 返回什么结构 {price: float, currency: string, timestamp: int}

LLM 根据这三要素判断「该不该调这个工具、怎么调」。这就是 OpenAI Function Calling、Anthropic Tool Use、MCP 协议等标准化的核心——让 LLM 用结构化的方式理解工具。第 6.1 节会展开。

工具注册表

一个 Agent 通常有多个工具,统一由工具注册表(Tool Registry) 管理:

工具注册表 (Tool Registry) ├── 信息查询类 │ ├── search(query) # 网页搜索 │ ├── get_stock(ticker) # 股价 │ └── get_weather(city) # 天气 ├── 数据处理类 │ ├── run_python(code) # 代码执行 │ └── sql_query(sql) # 数据库查询 ├── 通信类 │ ├── send_email(to,subj) # 发邮件 │ └── post_message(chan) # 发消息 └── 系统类 ├── read_file(path) └── write_file(path,data)

工具一多,新的问题就来了:LLM 怎么知道该用哪一个? 这是「工具检索(Tool Retrieval)」问题——当工具数量超过几十个,不能把它们全部塞进 Prompt(会冲淡注意力),需要按当前任务动态检索最相关的几个工具。第 6.2 节会详细讨论。

💡 工具数量与能力的悖论:工具越多,Agent 理论上能力越强;但工具太多,LLM 反而会选错、混淆。生产实践通常是「按场景分组 + 动态检索」——总库几百个工具,但每次只暴露与当前任务相关的 5-10 个给 LLM。

2.4.4 安全闸门:Action 的两道防线

Action 是 Agent 风险最高的模块,必须有明确的安全闸门。本书反复强调两条铁律:

铁律一:能力最小化(Least Privilege)

给 Agent 的权限刚好够完成任务,多余的一点不给

原则 做法 例子
按任务授权 只给当前任务需要的工具 财务分析 Agent 不给发邮件工具
只读优先 能用只读工具就不用写工具 查股价用 get_stock,不用 trade_stock
范围限定 工具内嵌范围约束 read_file 只允许 /data/ 目录
时效授权 权限随会话结束而失效 临时授权不持久化

铁律二:高危确认(Human-in-the-Loop)

任何不可逆操作必须人类确认后才能执行。

操作类型 可逆性 处理
读数据、查询 可逆 直接执行
写数据、改配置 部分可逆 视情况确认
发邮件、发消息 不可逆 必须确认
转账、删除、提交 不可逆且高影响 双重确认

⚠️ 「能做」不等于「该做」。Agent 工程最常见的灾难,不是 Agent 不会做,而是它做了不该做的事。一道「不可逆 → 必须确认」的闸门,能挡掉绝大多数生产事故。这条闸门的成本只是一次人类点击,收益是避免一次无法挽回的损失——性价比极高,生产 Agent 必须标配

2.4.5 观察提取:把结果喂回去

Action 执行完后,结果不能直接丢给 LLM——需要经过观察提取(Observation Extraction):把工具返回的原始数据,转成 LLM 能高效消化的结构化文本。

为什么需要观察提取

问题 例子
数据过大 API 返回 500 个字段,全塞进 Prompt 会爆窗口
格式不友好 嵌套 JSON、二进制、HTML,LLM 难直接读
噪声过多 返回含大量无关元数据
缺少判定 工具返回成功/失败,但没说「离目标多近」

提取的三步动作

原始返回 → [字段筛选] → [格式化] → [判定注入] → 观察文本
步骤 做法
字段筛选 只留决策相关的关键字段
格式化 转成 LLM 易读的键值对或表格
判定注入 附加「执行成功?离目标多近?」

一个例子

工具返回 (原始): { "request_id": "abc-123", "meta": {"api_version": "v3", "server": "us-east-1", ...100 个字段...}, "data": {"price": 187.5, "currency": "USD", "timestamp": 1721400000}, "warnings": [] } 观察提取后: [工具: get_stock_price] 执行成功 价格: 187.5 USD 时间: 2026-07-20 09:30 UTC 判定: 已获取所需数据,可继续分析

💡 观察提取的质量直接决定 Agent 的收敛速度。一个糟糕的提取层会让 LLM 在「差不多成功了」和「其实还差一步」之间反复横跳。这是 Agent 工程最容易被低估、却最影响实际效果的细节之一。

2.4.6 错误处理与重试

工具调用不可能 100% 成功——API 会超时、参数会出错、权限会拒绝。Action 模块必须有明确的错误处理策略

错误类型 处理
网络超时 重试 N 次(指数退避)
参数错误 把错误信息回喂 LLM,让其修正参数
权限拒绝 不重试,直接报告 Planning 换路径
结果异常 触发 VLM/规则验证,判断是否真成功
服务不可用 切换备用工具或降级

⚠️ 错误处理的核心原则:错误信息要回喂给 LLM。很多新手在工具失败时直接吞掉错误或返回空——这会让 Agent 困惑地继续走,最终任务失败却不知道为什么。正确的做法是把错误信息格式化后送回 Planning,让 LLM 自己决定「重试、换参数、换工具、还是求助」。这正是 ReAct 范式(第 4 章)的核心循环。

2.4.7 Action 与其他模块的耦合

Action 处于 Agent 与外部世界的交界,耦合关系明确:

耦合对象 耦合点
Planning 接收 Planning 的动作指令,返回观察供其再决策
Memory 观察写回 Memory;Memory 提供「上次类似工具的返回」
Profile Profile 决定「可用工具范围」,Action 强制执行该范围

最关键的是 Action ↔ Planning 的循环:Action 不是终点,而是「为下一轮 Planning 提供观察」的中间环节。没有观察回传的 Action 是断头路——Agent 无法迭代纠错。这个紧密循环正是第 4 章 ReAct 的精髓。

2.4.8 Action 设计的反模式

反模式 表现 后果 正确做法
给所有工具不给沙箱 代码执行无隔离 灾难 强制沙箱
无人类在环 不可逆操作直接执行 事故 高危确认
吞掉错误 工具失败返回空 Agent 困惑 错误回喂 LLM
观察不提取 原始 JSON 直塞 Prompt 窗口爆+注意力稀释 三步提取
工具过宽授权 给一堆用不上的工具 误调用 能力最小化
只读与写操作混用 一个工具既能读又能删 误操作 读写分离

本节小结

  • Action 模块把 Planning 的动作指令翻译成对真实世界的操作,内部含「解析、校验、执行、提取」四步流水线,不只是「调一下工具」。
  • 动作空间分三类:直接回答(无副作用)、工具调用(中风险)、代码执行(高风险)。风险与能力成正比、与使用频率成反比。
  • 工具用「名称描述+参数 Schema+返回 Schema」三要素向 LLM 描述;多工具由工具注册表管理,工具过多时需「按场景分组+动态检索」。
  • 安全两条铁律:能力最小化(权限刚好够用)+ 高危确认(不可逆操作必须人类在环)。这两条是生产 Agent 的强制标配。
  • 观察提取把工具返回转为 LLM 易消化的结构化文本(字段筛选+格式化+判定注入),直接决定 Agent 收敛速度。
  • 错误处理的核心是错误信息回喂 LLM,让 Planning 自主决定重试/换参数/换工具/求助。吞掉错误是最坏的反模式。

第 2 章结语:单体 Agent 完整工程架构图

把本章四节串起来,一张完整的单体 Agent 工程架构图就浮现出来:

这张图是后续所有章节的「总参考」。读者可以从任意一节回看这张图,找到该模块在整体中的位置:

  • 第 3 章 深化图中的 Planning 模块(思维链、思维树、任务分解)。
  • 第 4 章 深化图中的 Planning↔Action 紧密循环(ReAct)。
  • 第 5 章 深化图中的 Memory 模块(短期、长期、RAG、遗忘)。
  • 第 6 章 深化图中的 Action 模块(函数调用、代码解释器、沙箱安全)。
  • 第 7 章 把这张单体图复制多份并互联(多智能体)。
  • 第 8 章 讨论这张图如何落到具体框架(LangChain、AutoGen 等)。

作者与出处
来源:灏天文库
整理: 灏天文库整理
由灏天文库平台收录,内容或由平台用户上传,仅供学习交流
发布者: 作者: 会发光的石头的小龙虾 转发
评论区 (0)
U