综合调研 已修订

Agent 交互协议全景调研:从模型输入到框架执行的完整解剖

深入六大主流 Agent 交互范式的实际消息格式、系统提示词设计、动作空间与观测空间定义,逐一展示模型真正看到什么、输出什么、框架如何执行、结果如何回传

Agent 交互协议 Function Calling ReAct CodeAct Computer Use SWE-agent MCP

概览

构建 Agent 系统时,最核心的设计决策不是选哪个模型,而是模型与外部世界之间的交互协议——模型收到什么格式的输入、输出什么格式的动作、框架如何解析执行、执行结果如何回传给下一轮。

本报告从协议层面深入解剖六大主流 Agent 交互范式,每一种都给出:

  1. 系统提示词(System Prompt)的实际结构
  2. 模型输入(Observation)的具体格式
  3. 模型输出(Action)的具体格式
  4. 框架执行的解析与调度机制
  5. 结果回传(Observation → 下一轮输入)的格式
  6. 完整交互 trace 示例

第一章 · ReAct:文本交织的思考-行动-观察循环

1.1 起源与定位

ReAct(Reasoning + Acting)是 2022 年由 Yao et al. 提出的 Agent 交互范式,核心思想是让模型在同一个生成过程中交替进行推理(Thought)和行动(Action),每次行动后接收环境返回的观察(Observation),形成闭环。

ReAct 是所有现代 Agent 框架的思想起源——即使是 Function Calling、CodeAct 等后续方案,本质上仍遵循”思考 → 行动 → 观察 → 思考”的循环结构。

1.2 系统提示词结构

You solve problems by interleaving reasoning and actions.

Available tools:
- search(query: str) -> list of snippets
- calc(expression: str) -> number
- lookup(term: str) -> definition
- finish(answer: str) -> terminate the loop

Format each step exactly as:

Thought: <one or two sentences about what to do next>
Action: <tool_name>(<arguments>)
Observation: <result — you will be given this>

Repeat Thought/Action/Observation until done.
When confident, call finish(answer) and stop.

关键设计要素:

  • 明确列出可用工具的签名(名称 + 参数类型 + 返回类型)
  • 严格定义三段式输出格式
  • 必须定义终止动作(finish),否则模型可能死循环
  • 循环指令明确

1.3 单轮交互的消息流

模型输入(第 N 轮):

Thought: The user asked about the population of Tokyo. Let me search.
Action: search("Tokyo population 2026")
Observation: Tokyo's population is approximately 13.96 million (2026 estimate).

Thought: I have the answer. Let me verify the metropolitan area figure.
Action: search("Tokyo metropolitan area population")
Observation: The Greater Tokyo Area has about 37.4 million people.

Thought: [模型在此生成下一步推理]

模型输出:

Thought: I now have both figures. The city proper has ~14M, metro area ~37M.
Action: finish("Tokyo city proper: ~14 million; Greater Tokyo Area: ~37.4 million (2026)")

1.4 框架执行机制

┌─────────────────────────────────────────────┐
│              ReAct Harness                   │
│                                              │
│  1. 将 system prompt + 历史 trace 拼接       │
│     作为完整 prompt 发送给 LLM               │
│                                              │
│  2. 解析 LLM 输出:                          │
│     - 用正则匹配 "Action: xxx(yyy)"         │
│     - 提取工具名和参数                       │
│                                              │
│  3. 路由到对应工具函数执行                    │
│                                              │
│  4. 将执行结果格式化为                        │
│     "Observation: ..." 追加到 trace          │
│                                              │
│  5. 检查是否为终止动作(finish)              │
│     - 是:返回最终答案                       │
│     - 否:回到步骤 1                         │
│                                              │
│  6. 安全检查:步数超限则强制终止              │
└─────────────────────────────────────────────┘

1.5 优缺点分析

维度评价
优点实现简单、对模型无特殊要求(纯文本生成即可)、推理过程透明可解释
缺点纯文本解析脆弱(模型可能输出格式不规范)、无法并行调用工具、工具参数无 schema 验证
适用场景多跳搜索问题、探索性研究、环境不确定的任务
不适用需要精确参数的 API 调用、高并发工具调用场景

第二章 · OpenAI Function Calling:结构化工具调用协议

2.1 核心机制

Function Calling 是当前工业界最主流的 Agent 交互协议。与 ReAct 的纯文本方式不同,Function Calling 在 API 层面定义了结构化的工具调用协议——模型输出的不是自由文本,而是严格符合 JSON Schema 的函数调用对象。

2.2 工具定义格式

{
  "type": "function",
  "name": "search_database",
  "description": "Search the product database by keyword",
  "strict": true,
  "parameters": {
    "type": "object",
    "properties": {
      "query": {
        "type": "string",
        "description": "Search keyword"
      },
      "limit": {
        "type": "integer",
        "description": "Max results to return"
      }
    },
    "required": ["query"],
    "additionalProperties": false
  }
}

关键参数:

  • strict: true:启用严格模式,保证模型输出 100% 符合 schema(token 生成级别的约束,非后验校验)
  • additionalProperties: false:禁止输出未定义的字段
  • description:模型根据描述而非名称来决定调用哪个工具

2.3 完整五步交互流程

步骤一:用户发送请求

messages: [
  { role: "user", content: "帮我查一下库存中有多少台 MacBook Pro" }
]
tools: [search_database 定义, update_inventory 定义, ...]

步骤二:模型返回 function_call(非文本)

{
  "stop_reason": "tool_calls",
  "output": [
    {
      "type": "function_call",
      "call_id": "call_abc123",
      "name": "search_database",
      "arguments": "{\"query\": \"MacBook Pro\", \"limit\": 10}"
    }
  ]
}

注意:stop_reason 是 tool_calls 而非 stop,表示模型认为需要调用工具才能回答。

步骤三:框架解析并执行

tool_call = response.output[0]
args = json.loads(tool_call.arguments)
result = search_database(query=args["query"], limit=args["limit"])

步骤四:将结果回传给模型

messages: [
  { role: "user", content: "帮我查一下库存中有多少台 MacBook Pro" },
  // 模型的 function_call 原样放入
  { type: "function_call", call_id: "call_abc123", name: "search_database", arguments: "..." },
  // 执行结果
  {
    type: "function_call_output",
    call_id: "call_abc123",
    output: "[{\"name\": \"MacBook Pro 16\", \"stock\": 42}, {\"name\": \"MacBook Pro 14\", \"stock\": 67}]"
  }
]

步骤五:模型生成最终回复(或继续调用工具)

{
  "stop_reason": "stop",
  "output": [
    {
      "type": "text",
      "text": "库存中有两款 MacBook Pro:16 寸有 42 台,14 寸有 67 台,共 109 台。"
    }
  ]
}

2.4 并行工具调用

模型可以在单次响应中返回多个 function_call:

{
  "output": [
    { "type": "function_call", "call_id": "call_1", "name": "get_weather", "arguments": "{\"city\": \"北京\"}" },
    { "type": "function_call", "call_id": "call_2", "name": "get_weather", "arguments": "{\"city\": \"上海\"}" },
    { "type": "function_call", "call_id": "call_3", "name": "get_weather", "arguments": "{\"city\": \"深圳\"}" }
  ]
}

框架并行执行三个查询,一次性回传所有结果,模型在下一轮统一处理。这是 ReAct 无法做到的。

2.5 框架执行机制

用户消息 + 工具定义 → API 请求
                       ↓
            模型响应(stop_reason 判断)
            ├─ stop_reason = "stop"     → 返回文本给用户,结束
            └─ stop_reason = "tool_calls" → 解析 function_call
                       ↓
            按 call_id 路由到工具函数 → 执行
                       ↓
            构造 function_call_output(call_id 必须对应)
                       ↓
            拼接到 messages 数组 → 再次请求 API
                       ↓
            ... 循环直到 stop_reason = "stop"

2.6 优缺点分析

维度评价
优点结构化输出(严格 JSON)、支持并行调用、schema 验证保证参数合法、工业标准
缺点工具集必须预定义、无法动态组合工具逻辑(如条件判断)、每次调用需要完整 API 往返
适用场景大多数生产环境 Agent、API 集成、工具数量已知的场景
不适用需要灵活编程逻辑的场景(此时 CodeAct 更优)

第三章 · CodeAct:代码即动作的统一范式

3.1 核心洞察

CodeAct(ICML 2024)的核心洞察是:Python 代码本身就是最好的 action 语言。它既有严格的语法(易于执行),又有无限的表达力(图灵完备),还天然支持工具组合和调试。

与 Function Calling 相比,CodeAct 不需要预定义工具的 JSON schema——任何 Python 函数都是可用工具,任何 Python 逻辑都是可用动作。

3.2 系统提示词

You are a helpful assistant that can interact with a computer to solve tasks.

Available Actions:
You can perform actions by writing Python code enclosed in:
<execute>
your_python_code_here
</execute>

Guidelines:
- You can use any Python libraries available in the environment.
- Each code block will be executed in a stateful Python interpreter
  (like a Jupyter notebook), meaning variables and imports persist
  across turns.
- You will receive the execution output (stdout/stderr) as observations.
- Based on the observations, you can revise your code or take new actions.
- When the task is complete, communicate the final result in natural language.

Interaction Protocol:
- Use <execute>...</execute> for code actions
- Use natural language for communicating with the user
- You can mix code actions and natural language in your responses

关键设计:

  • 有状态解释器(变量跨轮次保持,类似 Jupyter Notebook)
  • <execute> 标签界定代码边界
  • 双通道输出:既能执行代码,也能自然语言交流

3.3 完整交互 trace 示例

═══ 用户 ═══
查询波士顿天气,如果低于 50°F 就在日历添加"带外套"提醒。

═══ Agent Turn 1 ═══
我来查询天气并根据条件设置提醒。

<execute>
weather = get_weather("Boston")
print(f"Temperature: {weather['temp']}°F")
if weather['temp'] < 50:
    result = add_calendar_event(title="带外套", date="today")
    print(f"Reminder set: {result}")
else:
    print("No jacket needed!")
</execute>

═══ Observation ═══
Temperature: 42°F
Reminder set: Event '带外套' added for 2026-04-22

═══ Agent Turn 2 ═══
波士顿今天只有 42°F,我已经在日历中添加了"带外套"提醒。

对比 Function Calling:Function Calling 需要分两次 API 往返(先查天气、再根据结果决定是否加提醒)。CodeAct 在一次代码执行中通过 if 语句完成了条件判断和组合调用。

3.4 自动调试(错误恢复)

CodeAct 的有状态解释器使得自动调试成为可能:

═══ Agent Turn 1 ═══
<execute>
model = SVC(kernal='rbf')  # 拼写错误
model.fit(X_train, y_train)
</execute>

═══ Observation ═══
TypeError: __init__() got an unexpected keyword argument 'kernal'

═══ Agent Turn 2 ═══
参数名拼写错误,应该是 'kernel'。

<execute>
model = SVC(kernel='rbf')  # 修正
model.fit(X_train, y_train)
acc = accuracy_score(y_test, model.predict(X_test))
print(f"Accuracy: {acc:.4f}")
</execute>

═══ Observation ═══
Accuracy: 0.9667

注意 Turn 2 不需要重新导入库或加载数据——有状态解释器保留了 Turn 1 中定义的所有变量。

3.5 框架执行机制

用户请求
   ↓
LLM 生成文本(可能包含 <execute> 代码块)
   ↓
Harness 解析:
├─ 自然语言部分 → 直接展示给用户
└─ <execute> 代码块 → 发送到 Python 解释器
   ↓
Python 解释器执行代码(有状态,变量持久化)
   ↓
捕获 stdout + stderr → 作为 Observation
   ↓
Observation 追加到对话历史 → 下一轮 LLM 调用

3.6 CodeAct vs Function Calling vs ReAct

维度ReActFunction CallingCodeAct
Action 格式自由文本结构化 JSONPython 代码
工具组合不支持(每轮一个工具)并行但无逻辑组合任意组合(if/for/变量传递)
参数验证无JSON Schema 严格验证Python 类型系统
调试能力无无根据 stderr 自动修正
状态管理无(每轮独立)无有状态(变量持久化)
灵活性低中最高(图灵完备)
解析可靠性低(正则匹配)高(API 原生)中(标签解析)

第四章 · SWE-agent ACI:为 LLM 定制的编程界面

4.1 设计哲学

SWE-agent(Princeton, 2024)提出了 Agent-Computer Interface(ACI)的概念:正如 HCI 为人类设计交互界面,ACI 为 LLM 设计交互界面。核心原则是——操作简洁、反馈信息化、错误可恢复。

4.2 系统提示词

SYSTEM MESSAGE:
You are an autonomous programmer working directly in the command line
with a special interface.

The special interface consists of a file editor that shows you 100 lines
at a time. In addition to typical bash commands, you can also use:

COMMANDS:
open <path> [<line_number>]    opens file at given line
goto <line_number>              moves window to show line
scroll_down                      moves window down 100 lines
scroll_up                        moves window up 100 lines
create <filename>               creates and opens new file
search_dir <term> [<dir>]      searches in all files in dir
search_file <term> [<file>]    searches in file
find_file <name> [<dir>]       finds files with given name
edit <start>:<end>
<replacement_text>
end_of_edit                      replaces lines start to end
submit                           submits solution and terminates

RESPONSE FORMAT:
Every response must include exactly ONE thought and ONE command.

DISCUSSION
<Your reasoning here>

COMMAND
<your command here>

IMPORTANT TIPS:
1. Always start by trying to replicate the bug.
2. If a command doesn't work, try a different command.
3. Use goto instead of repeated scroll_down.
4. Always check indentation when editing.
5. Make single, focused changes at a time.

4.3 Observation 格式

文件查看器(窗口化浏览,核心创新):

[File: /repo/src/parser.py (250 lines total)]
(148 more lines above)
149: class InputParser:
150:     def __init__(self, config):
151:         self.config = config
152:         self.buffer = []
153:
154:     def _parse_input(self, raw_data):
155:         # BUG: doesn't handle None input
156:         tokens = raw_data.split(',')
157:         return [t.strip() for t in tokens]
(93 more lines below)

关键设计:固定 100 行窗口防止输出过长、行号标注便于定位、上下文提示告知还有多少行。

搜索结果:

Found 3 matches for "parse_input" in /repo/src:
/repo/src/parser.py (Line 154): def _parse_input(self, raw_data):
/repo/src/parser.py (Line 160): result = self._parse_input(data)
/repo/src/tests/test_parser.py (Line 23): parser._parse_input(test_data)

编辑反馈(含自动语法检查):

File updated. Please review the changes and make sure they are correct.

或失败时:

Your edit has introduced syntax errors:
  File "/repo/src/parser.py", line 156
    return []
         ^
IndentationError: unexpected indent

The file has been reverted to its original state.
Please fix the error and try again.

这是 ACI 的关键安全机制——编辑引入语法错误时自动回滚并提示。

4.4 完整交互 trace

╔══ TURN 1 ══╗

OBSERVATION (System):
We're solving: InputParser crashes when input is None
ENVIRONMENT REMINDER: You have 30 steps remaining.

DISCUSSION:
Let me find the relevant file first.

COMMAND:
find_file "parser.py" src

╔══ TURN 2 ══╗

OBSERVATION:
Found 1 matches: /repo/src/parser.py

DISCUSSION:
Let me open the file and look at the parse_input method.

COMMAND:
open /repo/src/parser.py 150

╔══ TURN 3 ══╗

OBSERVATION:
[File: /repo/src/parser.py (250 lines total)]
(148 more lines above)
149: class InputParser:
...
156:         tokens = raw_data.split(',')
(93 more lines below)

DISCUSSION:
Line 156 calls raw_data.split() without checking for None.

COMMAND:
edit 154:157
    def _parse_input(self, raw_data):
        if raw_data is None:
            return []
        tokens = raw_data.split(',')
        return [t.strip() for t in tokens]
end_of_edit

╔══ TURN 4 ══╗

OBSERVATION:
File updated. Please review the changes...

DISCUSSION:
Fix looks correct. Let me run the tests.

COMMAND:
python -m pytest tests/test_parser.py -v

╔══ TURN 5 ══╗

OBSERVATION:
tests/test_parser.py::test_none_input PASSED
tests/test_parser.py::test_normal_input PASSED
All 5 tests passed.

DISCUSSION:
All tests pass. Submitting.

COMMAND:
submit

4.5 ACI 消融实验结果

组件SWE-bench Lite 提升
原始 Bash(无 ACI)~6% baseline
+ 文件查看器(窗口化)+3%
+ edit 命令+5%
+ 语法检查 + 回滚+2%
+ 搜索命令+2%

每个 ACI 组件都有可测量的贡献,证明了界面设计对 Agent 性能的实质影响。


第五章 · Computer Use:截图驱动的 GUI 交互

5.1 核心机制

Computer Use(Anthropic, 2024)是最接近”像人一样操作电脑”的 Agent 交互方式。模型通过看截图来理解当前屏幕状态,通过输出鼠标/键盘指令来操作电脑。

5.2 工具定义(API 层面)

tools = [
    {
        "type": "computer_20251124",
        "name": "computer",
        "display_width_px": 1024,
        "display_height_px": 768,
        "display_number": 1,
    },
    {
        "type": "text_editor_20250728",
        "name": "str_replace_based_edit_tool"
    },
    {
        "type": "bash_20250124",
        "name": "bash"
    }
]

注意:Computer Use 通常与 text_editor 和 bash 工具组合使用。模型可以自主选择用截图操作 GUI 还是用 bash 命令行。

5.3 交互流程

第一轮:模型请求截图

模型输出:

{
  "type": "tool_use",
  "id": "toolu_001",
  "name": "computer",
  "input": { "action": "screenshot" }
}

框架执行:截取当前屏幕 → 缩放到 API 限制(长边 1568px)→ base64 编码

结果回传:

{
  "type": "tool_result",
  "tool_use_id": "toolu_001",
  "content": [
    {
      "type": "image",
      "source": {
        "type": "base64",
        "media_type": "image/png",
        "data": "<base64 编码的截图>"
      }
    }
  ]
}

第二轮:模型发出操作指令

{
  "type": "tool_use",
  "id": "toolu_002",
  "name": "computer",
  "input": { "action": "left_click", "coordinate": [500, 300] }
}

框架执行:将 API 坐标反向缩放到实际屏幕坐标 → 执行点击

5.4 完整动作集

动作格式说明
screenshot{"action": "screenshot"}截取当前屏幕
left_click{"action": "left_click", "coordinate": [x, y]}左键点击
type{"action": "type", "text": "..."}输入文本
key{"action": "key", "key": "ctrl+s"}按键/组合键
scroll{"action": "scroll", "coordinate": [x,y], "direction": "down", "amount": 3}滚动
drag{"action": "left_click_drag", "start_coordinate": [x1,y1], "coordinate": [x2,y2]}拖拽
double_click{"action": "double_click", "coordinate": [x, y]}双击
zoom{"action": "zoom", "region": [x1, y1, x2, y2]}查看区域原始分辨率
wait{"action": "wait", "duration": 3}等待 N 秒

5.5 坐标缩放处理

高分辨率屏幕的截图会被缩放到 API 限制,框架需要处理坐标映射:

# 计算缩放因子
scale = min(1.0, 1568 / max(width, height))

# 发送截图前:缩放图片
scaled_img = resize(screenshot, scale)

# 模型返回坐标后:反向缩放到实际屏幕坐标
actual_x = model_x / scale
actual_y = model_y / scale

5.6 完整交互 trace

═══ 用户 ═══
Save a picture of a cat to my desktop.

═══ Turn 1 ═══
模型: {"action": "screenshot"}
框架: [截图] → base64 PNG 回传
模型看到: 桌面截图

═══ Turn 2 ═══
模型: {"action": "key", "key": "super"}
框架: 按下 Super 键打开应用启动器
模型: {"action": "screenshot"}
框架: [截图]

═══ Turn 3 ═══
模型: {"action": "type", "text": "firefox"}
框架: 输入 "firefox"
模型: {"action": "key", "key": "Return"}
框架: 按回车

═══ Turn 4 ═══
模型: {"action": "screenshot"}
框架: [截图] → Firefox 已打开

═══ Turn 5 ═══
模型: {"action": "left_click", "coordinate": [400, 50]}  // 地址栏
模型: {"action": "type", "text": "cute cat picture"}
模型: {"action": "key", "key": "Return"}

... (搜索、右键保存、选择桌面路径等后续操作)

═══ 最终 ═══
模型: "I've saved a picture of a cat to your desktop."

5.7 Token 消耗

项目Token 消耗
系统 prompt 额外开销~470 tokens
每个工具定义~735 tokens
每张截图按 Vision 定价(分辨率相关)
一个典型任务(10 步)数万 tokens

第六章 · OSWorld / BrowserGym:环境标准化协议

6.1 OSWorld 观测-动作空间

OSWorld(NeurIPS 2024)为 Agent 与操作系统的交互定义了标准化的接口。

Agent 必须实现的核心方法:

class Agent:
    def predict(self, instruction: str, observation: dict) -> (str, list):
        """
        输入:
          instruction: 任务描述
          observation: {
              "screenshot": bytes,        # PNG 编码截图
              "accessibility_tree": str    # XML 格式无障碍树
          }
        输出:
          response: str     # LLM 原始响应
          actions: list     # 解析后的动作列表
        """

    def reset(self):
        """新任务时清除内部状态"""

四种观测类型:

类型模态格式
screenshot纯视觉base64 PNG
a11y_tree纯结构化TSV(制表符分隔)
screenshot_a11y_tree视觉+文本PNG + TSV(性能最佳)
som标注视觉带数字标签的 PNG

无障碍树(a11y_tree)格式:

tag    name     text           class        position    size
button OK       ""             GtkButton    (100,200)   (80,30)
text   search   "Enter query"  GtkEntry     (50,100)    (200,25)

两种动作空间:

空间格式示例
pyautoguiPython 代码pyautogui.click(500, 300)
computer_13JSON 字典{"action": "left_click", "coordinate": [500, 300]}

6.2 BrowserGym 动作原语

BrowserGym 为 Web Agent 定义了一套基于 bid(Browser element ID) 的操作原语:

# 鼠标操作
click("btn_submit")
dblclick("item_row_3")
hover("menu_dropdown")
drag_and_drop("card_1", "column_2")

# 键盘操作
fill("input_search", "hello world")
clear("input_search")
press("textarea_code", "Control+Enter")
type("input_name", "Maxwell")

# 页面操作
scroll(0, 300)
goto("https://example.com")
go_back()
tab_focus(2)
new_tab()

# 任务完成
send_msg_to_user("The answer is 42")
report_infeasible("Cannot access the required page")
noop(wait_ms=2000)

bid 机制:框架对页面 DOM 元素自动标注唯一 ID,Agent 通过 bid 引用元素而非坐标——比坐标更稳定、更语义化。

6.3 系统提示词选择矩阵

OSWorld 根据观测类型和动作空间的组合自动选择系统提示词:

观测动作对应提示词
screenshotpyautogui视觉输入 + 代码输出
screenshotcomputer_13视觉输入 + JSON 输出
a11y_treepyautogui文本输入 + 代码输出
screenshot + a11y_treepyautogui多模态输入 + 代码输出(效果最佳)
sompyautogui标注视觉 + tag 引用输出

第七章 · MCP:标准化工具接入协议

7.1 定位

Model Context Protocol(MCP, Anthropic, 2024)不是一种 Agent 交互范式,而是一种工具接入标准化协议。它解决的是”如何让任意工具以统一方式对接到任意 LLM”的问题。

7.2 消息格式(JSON-RPC 2.0)

工具列表查询:

// 请求
{"jsonrpc": "2.0", "id": "1", "method": "tools/list", "params": {}}

// 响应
{
  "jsonrpc": "2.0",
  "id": "1",
  "result": {
    "tools": [
      {
        "name": "search",
        "description": "Search the web",
        "inputSchema": {
          "type": "object",
          "properties": {
            "query": {"type": "string"}
          },
          "required": ["query"]
        }
      }
    ]
  }
}

工具调用:

// 请求
{
  "jsonrpc": "2.0", "id": "2",
  "method": "tools/call",
  "params": {
    "name": "search",
    "arguments": {"query": "MCP protocol"}
  }
}

// 响应
{
  "jsonrpc": "2.0", "id": "2",
  "result": {
    "content": [
      {"type": "text", "text": "MCP is an open protocol..."}
    ]
  }
}

7.3 MCP 在 Agent 交互中的位置

LLM ←→ Agent Framework ←→ MCP Client ←→ MCP Server ←→ 外部工具
         (交互协议层)         (标准化接入层)          (实际工具)

MCP 位于交互协议和实际工具之间——Agent 框架(无论用 ReAct 还是 Function Calling)通过 MCP 客户端发现和调用工具,MCP 服务器负责翻译和执行。


第八章 · 对比分析与选型指南

8.1 六大范式核心对比

维度ReActFunction CallingCodeActSWE-agent ACIComputer UseBrowserGym
Action 格式自由文本JSONPython 代码自定义命令JSON + 坐标bid 函数调用
Observation 格式文本JSON/文本stdout/stderr窗口化文本截图(base64)DOM/截图
工具定义prompt 内文本JSON SchemaPython 环境预定义命令集固定三件套预定义原语
状态管理无无有状态解释器Shell 环境屏幕状态浏览器 session
并行调用不支持支持代码内并行不支持不支持不支持
错误恢复手动手动自动调试自动回滚重新截图页面回退
解析可靠性低最高中中高中
表达力低中最高中最高(任意 GUI)高(Web)
Token 效率高高高中低(截图大)中

8.2 选型决策树

你的 Agent 需要操作什么?
├─ 调用 API / 查询数据库
│   ├─ 工具集固定、参数明确 → Function Calling
│   └─ 需要灵活组合多个工具 → CodeAct
├─ 编写/修改代码
│   ├─ 修复 GitHub Issue → SWE-agent ACI
│   └─ 通用编程任务 → CodeAct
├─ 操作网页
│   ├─ 可访问 DOM → BrowserGym
│   └─ 只能看截图 → Computer Use
├─ 操作桌面软件
│   └─ Computer Use
└─ 多跳搜索 / 知识推理
    └─ ReAct

8.3 从数据合成角度的启示

对于构建 Agent 训练数据,每种交互协议对应不同的数据格式需求:

训练目标推荐数据格式数据源
Function Calling 能力messages + tool_calls + tool_results 三元组API 文档 → 自动化生成
ReAct 推理Thought-Action-Observation 轨迹人工标注 + 模型蒸馏
CodeAct 编程execute 代码块 + stdout 观测对Jupyter Notebook 执行记录
SWE-agent 代码修复issue → 修复轨迹 → 测试验证GitHub Issue + PR
Computer Use GUI 操作截图序列 + 坐标动作屏幕录制 + 动作标注
Web AgentDOM/bid + 浏览器动作网站操作录制

第九章 · 演进趋势与展望

9.1 短期趋势(2026-2027)

Function Calling 标准化加速:OpenAI Responses API 统一了 tool calling 格式,MCP 协议提供了工具接入标准。两者结合正在形成事实上的工业标准。

CodeAct 渗透 SWE 领域:OpenHands CodeAct 2.1 已在 SWE-bench Verified 上达到 53%,Function Calling 格式化后可靠性进一步提升。代码执行作为 action space 的优势在软件工程领域已经得到验证。

9.2 中期趋势(2027-2028)

GUI + Code 混合模式:推测 Agent 会发展出自适应的动作空间选择——能用代码直接操作的用代码,必须看界面的用 GUI 操作。Computer Use 和 CodeAct 的融合将成为通用 Agent 的标配。

Observation 压缩技术:截图类 Agent 的 token 消耗是核心瓶颈。视觉 token 压缩(VisionTrim、VisionSelector 等)和选择性截图(只截变化区域)将大幅降低成本。

9.3 长期展望

从交互协议到自适应协议:未来的 Agent 可能不需要固定在某一种交互范式中。模型自己判断当前任务适合用哪种 action space(打字比点击高效就打命令,GUI 比命令直观就点击),动态切换交互方式。

从工具调用到环境理解:当前所有范式的共同假设是”工具是预定义的”。但 Gym-Anything 的方向暗示,未来 Agent 可能具备”理解任意新环境”的能力——不需要预先定义 action space,而是通过观察自行推断可用操作。


核心论文与参考索引

论文/项目年份核心贡献
ReAct (Yao et al.)2022提出 Thought-Action-Observation 交织范式
Toolformer2023模型自主学习何时调用工具
GAIA Benchmark2023通用 AI 助手基准,450 道现实任务
OpenAI Function Calling2023结构化工具调用 API 标准
SWE-agent ACI2024为 LLM 定制的编程交互界面
CodeAct (ICML 2024)2024代码作为统一动作空间
Computer Use (Anthropic)2024截图驱动的 GUI Agent
OSWorld (NeurIPS 2024)2024操作系统级标准化 Agent 接口
BrowserGym2024Web Agent 标准化环境
WebArena2024自托管 Web 环境基准
MCP (Anthropic)2024标准化工具接入协议
OpenHands CodeAct 2.12025代码 Agent SOTA(SWE-bench 53%)
Gym-Anything (CMU)2026自动化环境构建框架