06|Actions:JSON 工具调用与 Code Agent
比较 JSON 动作与代码动作,并理解停止和解析策略。
比较 JSON 动作与代码动作,并理解停止和解析策略。
框架像自动挡,手写循环像拆开变速箱;理解每一圈发生什么,才知道卡死、超支和幻觉从哪里来。

本课交付物
用 TypeScript 写最多五轮的计算器 Agent,加入未知工具、超时和轮次上限。
核心讲解
提示:
在本节中,我们将探讨 AI 智能体 (AI agent) 与其环境交互的具体步骤。我们将介绍动作 (actions) 如何被表示(使用 JSON 或代码),停止和解析方法 (stop and parse approach) 的重要性,以及不同类型的智能体。
动作是AI 智能体 (AI agent) 与其环境交互的具体步骤。
无论是浏览网络获取信息还是控制物理设备,每个动作都是智能体执行的一个特定操作。
例如,一个协助客户服务的智能体可能会检索客户数据、提供支持文章或将问题转交给人工代表。
智能体动作的类型 (Types of Agent Actions)
有多种类型的智能体采用不同的方式执行动作:
| 智能体类型 | 描述 |
|---|---|
| JSON 智能体 (JSON Agent) | 要执行的动作以 JSON 格式指定。 |
| 代码智能体 (Code Agent) | 智能体编写代码块,由外部解释执行。 |
| 函数调用智能体 (Function-calling Agent) | 这是 JSON 智能体的一个子类别,经过微调以为每个动作生成新消息。 |
动作本身可以服务于多种目的:
| 动作类型 | 描述 |
|---|---|
| 信息收集 (Information Gathering) | 执行网络搜索、查询数据库或检索文档。 |
| 工具使用 (Tool Usage) | 进行 API 调用、运行计算和执行代码。 |
| 环境交互 (Environment Interaction) | 操作数字界面或控制物理设备。 |
| 通信 (Communication) | 通过聊天与用户互动或与其他智能体协作。 |
智能体的一个关键部分是在动作完成时能够停止生成新的标记 (tokens),这对所有格式的智能体都适用:JSON、代码或函数调用。这可以防止意外输出并确保智能体的响应清晰准确。
大语言模型 (LLM) 只处理文本,并使用它来描述它想要采取的动作以及要提供给工具的参数。
停止和解析方法 (The Stop and Parse Approach)
实现动作的一个关键方法是停止和解析方法。这种方法确保智能体的输出具有结构性和可预测性:
- 以结构化格式生成 (Generation in a Structured Format):
智能体以清晰、预定义的格式(JSON或代码)输出其预期动作。
- 停止进一步生成 (Halting Further Generation):
一旦动作完成,智能体停止生成额外的标记。这可以防止额外或错误的输出。
- 解析输出 (Parsing the Output):
外部解析器读取格式化的动作,确定要调用哪个工具,并提取所需的参数。
例如,需要检查天气的智能体可能输出:
Thought: I need to check the current weather for New York.
Action :
{
"action": "get_weather",
"action_input": {"location": "New York"}
}
然后框架可以轻松解析要调用的函数名称和要应用的参数。
这种清晰的、机器可读的格式最大限度地减少了错误,并使外部工具能够准确处理智能体的命令。
注意:函数调用智能体的操作方式类似,通过构造每个动作,使指定的函数能够使用正确的参数被调用。
我们将在未来的单元中深入探讨这些类型的智能体。
代码智能体 (Code Agents)
另一种方法是使用代码智能体。
这个想法是:代码智能体不是输出简单的 JSON 对象,而是生成一个可执行的代码块——通常使用 Python 等高级语言。
这种方法提供了几个优势:
- 表达能力 (Expressiveness): 代码可以自然地表示复杂的逻辑,包括循环、条件和嵌套函数,提供比 JSON 更大的灵活性。
- 模块化和可重用性 (Modularity and Reusability): 生成的代码可以包含在不同动作或任务中可重用的函数和模块。
- 增强的可调试性 (Enhanced Debuggability): 使用明确定义的编程语法,代码错误通常更容易检测和纠正。
- 直接集成 (Direct Integration): 代码智能体可以直接与外部库和 API 集成,实现更复杂的操作,如数据处理或实时决策。
例如,一个负责获取天气的代码智能体可能生成以下 Python 代码片段:
# Code Agent Example: Retrieve Weather Information
def get_weather(city):
import requests
api_url = f"
response = requests.get(api_url)
if response.status_code == 200:
data = response.json()
return data.get("weather", "No weather information available")
else:
return "Error: Unable to fetch weather data."
# Execute the function and prepare the final answer
result = get_weather("New York")
final_answer = f"The current weather in New York is: {result}"
print(final_answer)
在这个例子中,代码智能体:
- 通过API调用获取天气数据,
- 处理响应,
- 并使用print()函数输出最终答案。
这种方法也遵循停止和解析方法,通过明确划定代码块并表明执行完成的时间(在这里,通过打印 final_answer)。
我们了解到动作通过执行清晰、结构化的任务(无论是通过 JSON、代码还是函数调用)来连接智能体的内部推理和其现实世界的交互。
这种深思熟虑的执行确保每个动作都是精确的,并通过停止和解析方法准备好进行外部处理。在下一节中,我们将探索观察 (Observations),看看智能体如何捕获和整合来自其环境的反馈。
在此之后,我们将最终准备好构建我们的第一个智能体!
本站实战工作台
先拆开变速箱,再使用框架
最小循环只有消息、模型、工具表、观察和停止。手写一次能让你看到“卡死”并非神秘:可能是模型反复选同一工具、观察没有进入下一轮、错误被当成功,或没有轮次上限。
五轮计算器 Agent
type Call = { name: string; arguments: unknown }
type Reply = { text?: string; toolCall?: Call }
const tools = {
calculate: async (input: unknown) => {
const { a, b, op } = CalcInput.parse(input)
if (op === 'divide' && b === 0) return { ok: false, code: 'DIVIDE_BY_ZERO' }
return { ok: true, value: op === 'add' ? a + b : a / b }
}
}
for (let turn = 1; turn <= 5; turn++) {
const reply: Reply = await model(messages, toolSchemas)
if (reply.text && !reply.toolCall) return reply.text
const call = reply.toolCall
if (!call || !(call.name in tools)) {
messages.push({ role: 'tool', content: JSON.stringify({ ok:false, code:'UNKNOWN_TOOL' }) })
continue
}
const observation = await withTimeout(tools[call.name](call.arguments), 2000)
messages.push({ role: 'tool', name: call.name, content: JSON.stringify(observation) })
}
throw new Error('TURN_LIMIT')
示例省略了具体模型 SDK,却保留了框架必须解决的核心控制流。生产代码还要验证模型响应、捕获异常、记录 trace 与预算。
跑四条轨迹
计算 12+30 应一次工具后回答;10/0 应解释不可计算;调用 search 应收到 UNKNOWN_TOOL 后纠正;让假模型持续调用 calculate,系统应在第五轮停止。每条轨迹记录 turn、call、observation 与 stopReason。
为什么观察必须结构化
“工具失败了”不能指导下一步。错误码、是否可重试和安全消息让策略可控。不要把内部异常堆栈交给模型,也不要把失败包装成自然语言成功。
框架会替你做什么
Agent 框架通常提供消息适配、工具注册、状态持久化、流式事件和 tracing。理解手写循环后再选框架,你能判断它的默认重试、停止和错误语义是否适合任务,而不是把控制权交给黑箱。
本课通过标准是四条轨迹都在有限轮次内得到明确结果或明确停止,没有无限递归,也没有未验证参数触达执行器。