
在上一篇中,我们介绍了 Agent 从理解目标、制定计划、调用工具到观察结果的运行循环。但无论采用 ReAct、Plan-Execute,还是状态机,循环中的每一次“判断”,本质上都是一次模型调用。
很多 Agent 运行不稳定,并不是框架选错了,而是开发者仍把大模型当成普通 REST API:输入相同参数,就应该得到确定结果。
更准确的理解是:
大模型是一个受上下文、消息结构、生成参数和输出约束共同影响的概率型计算组件。
开发 Agent 不需要先学习模型训练、注意力机制或损失函数,但必须掌握它的输入边界、输出契约和调用方式。
模型并不直接按“字数”处理文本,而是先把文字、代码和符号切分为 Token。一个汉字不一定等于一个 Token,英文单词也可能被拆成多个 Token,不同模型的切分方式还可能不同。
Token 直接影响三个方面:
一次 Agent 调用消耗的内容远不只是用户问题,还包括:
系统指令 + 历史消息 + 工具定义与参数 Schema + 检索结果 + 文件、图片等多模态输入 + 模型输出 + 部分模型的推理 Token
工具定义和 JSON Schema 同样会占用 Token。对于包含图片和文件的请求,也不适合再用“字符数除以某个固定值”进行估算,最好使用模型平台提供的 Token 计数能力。OpenAI 的 Token Counting 文档也明确说明,消息结构、工具、Schema、图片和文件都会影响最终计数。
上下文窗口是单次模型调用能够处理的 Token 总量,通常需要同时容纳输入、输出以及可能存在的推理 Token。OpenAI 的上下文管理说明也将这三部分计入上下文预算。
可以将它简单理解为:
上下文窗口 ≥ 输入 Token + 预留输出 Token + 预留推理 Token
当前部分模型已经支持几十万甚至上百万 Token,但长上下文并不等于可以把所有资料直接塞进去。
例如,让 Agent 分析一份 100MB、128 页的扫描合同,更合理的做法不是把整份文件和全部历史对话反复提交给模型,而是:
文件解析或OCR → 内容切分与索引 → 按问题检索相关内容 → Rerank 精排 → 只把必要证据送入模型
上下文窗口解决的是“模型一次能看到多少”,而不是“系统应该给模型看多少”。无关内容越多,成本越高,也越容易干扰判断。
传统聊天接口通常包含四类消息,它们在 Agent 开发中各有明确分工。
消息类型 | 主要作用 | Agent 开发中的典型内容 |
|---|---|---|
System | 定义长期规则和边界 | 身份、目标、安全限制、输出要求 |
User | 表达当前任务 | 用户问题、业务参数、上传内容 |
Assistant | 保存模型历史行为 | 回答、工具选择、中间状态 |
Tool | 返回工具执行结果 | 查询结果、API 响应、错误信息 |
部分平台还增加了 Developer、Function Result、Reasoning Item 等类型,但核心原则没有变化:必须区分指令、用户输入、模型行为和外部结果。
例如,合同分析 Agent 可以这样组织上下文:
System: 你是合同风险分析 Agent,只能根据提供的合同内容判断,所有风险必须附带页码证据。 User: 分析合同中的付款、违约和解除条款。 Assistant: 请求调用 search_contract 工具。 Tool: 返回第 18、25、31 页的相关条款。 Assistant: 根据工具结果生成风险清单。
其中最重要的一点是:Tool 消息是外部系统返回的数据,不等于新的系统指令。 网页、文档和数据库内容中即使出现“忽略之前规则”,也不应该覆盖 System 层约束。
现代模型接口也正在从单纯的聊天消息数组,演进为包含文本、文件、工具调用和状态的统一交互对象。例如 OpenAI Responses API 和 Gemini Interactions API 都体现了这一变化。
Temperature 用于影响模型生成时的随机程度。
常见参数还包括:
max_output_tokens:限制最大输出长度;top_p:控制候选 Token 的采样范围;stop:遇到指定内容时停止生成;reasoning_effort、thinking_level:控制推理模型投入的推理强度。 对于新一代推理模型,生成控制正在从“调整随机性”转向“分配推理预算”。不同模型对 Temperature 的支持和推荐值并不一致。例如当前 Gemini 3 开发指南建议保留默认 Temperature,并通过 thinking_level 平衡质量、成本和延迟。
因此,不应把一套固定参数复制到所有模型。更可靠的做法是:
使用默认参数作为起点,通过业务评测调整,而不是依靠 temperature=0 获得虚假的确定性。
自然语言适合人阅读,却不适合作为稳定的系统接口。
例如,模型可能输出:
该合同存在较高的付款风险,建议法务复核。
但业务系统真正需要的可能是:
{
"riskLevel": "HIGH",
"riskType": "PAYMENT",
"summary": "预付款比例较高且缺少履约保障",
"evidencePages": [18, 19],
"needReview": true
}这就是 Structured Output:要求模型按照指定结构返回数据。
需要区分三个概念:
方式 | 能保证什么 | 不能保证什么 |
|---|---|---|
提示词要求输出 JSON | 只是表达期望 | 不保证 JSON 合法 |
JSON Mode | 通常保证语法是 JSON | 不保证字段符合业务结构 |
Structured Output | 按 Schema 约束字段与类型 | 不保证业务语义一定正确 |
因此,即使使用 Structured Output,后端仍然需要进行 DTO 映射、字段校验和业务规则校验。
JSON Schema 用于定义结构化数据应包含哪些字段、字段类型、枚举范围和必填条件。
一个简化的合同风险 Schema 可以是:
{
"type": "object",
"properties": {
"riskLevel": { "type": "string", "enum": ["LOW", "MEDIUM", "HIGH"] },
"riskType": { "type": "string", "enum": ["PAYMENT", "BREACH", "TERMINATION", "OTHER"] },
"summary": { "type": "string" },
"evidencePages": { "type": "array", "items": {"type": "integer"} },
"needReview": { "type": "boolean" }
},
"required": ["riskLevel", "riskType", "summary", "evidencePages", "needReview"],
"additionalProperties": false
}它可以进一步映射为 Java DTO、Pydantic Model 或 TypeScript Interface。
不过,Schema 只能约束“数据长什么样”,不能证明“数据是否正确”。evidencePages 即使是合法整数,也可能指向错误页面。因此生产系统仍需检查:
OpenAI Structured Outputs 文档也明确区分了“结构化返回结果”和“通过函数调用连接系统能力”这两类场景。
Function Calling,也称 Tool Calling,用于让模型选择并请求调用外部能力。
它的典型流程是:
应用注册工具 → 模型选择工具并生成参数 → 应用校验参数和权限 → 应用执行真实函数 → 将结果作为 Tool 消息返回 → 模型继续判断或生成答案
例如,Agent 发现合同存在高风险后,可以生成:
{
"name": "create_review_task",
"arguments": {
"documentId": "DOC-20260725-001",
"riskLevel": "HIGH",
"reviewerRole": "LEGAL"
}
}这里必须强调:
模型返回的是一次工具调用请求,不是已经执行完成的业务操作。
真正调用接口、写入数据库或发送消息的仍然是应用程序。应用层至少要负责:
Structured Output 解决“模型怎样返回数据”,Function Calling 解决“模型怎样请求系统执行能力”。两者都可以使用 JSON Schema,但用途不同。Function Calling 官方说明也采用了“模型提出调用—应用执行—结果回传”的基本流程。
随着 Agent 可用工具越来越多,新的接口还开始支持工具搜索和延迟加载:不再把几百个工具定义全部塞进上下文,而是在需要时加载相关工具,从而降低 Token 消耗和工具误选概率。
Embedding 将文本、图片等内容转换为向量,使系统能够按语义相似度进行检索。OpenAI Embeddings 文档将其描述为可通过向量距离衡量内容相关性的数值表示。
例如,用户询问“合同提前解除后,需要承担哪些费用?”,即使合同原文使用的是“单方终止”“剩余服务费”“补偿责任”,向量检索仍可能找到这些语义相关条款。
但 Embedding 检索更擅长“广泛召回”,不一定能把最准确的结果排在最前面。因此常见流程是:
关键词或向量检索 → 召回 Top 30~100 → Rerank 精排 → 选择 Top 5~10 → 交给生成模型
Rerank 会结合当前问题重新判断候选内容的相关性,并给出新的顺序。Cohere Rerank API的输入就是一个查询和一组候选文本,输出为带相关度分数的排序结果。
简单理解:
这两者是 Agent 获取知识的基础组件,并不是 Agent 本身。
非流式调用需要等待完整结果生成后再返回;流式调用则会把文本增量、工具调用参数和状态事件逐步发送给客户端。
当前 HTTP 流式输出通常采用 SSE;对于长时间、频繁工具调用的 Agent,一些平台也开始提供持续 WebSocket 连接。OpenAI Streaming 文档同时介绍了 SSE 和持久化 WebSocket 两种方式。
流式输出的主要价值是降低用户感知等待时间,但它通常不会减少模型实际计算时间。
实现时还要注意:
对于真正耗时几分钟甚至更久的任务,应使用异步任务、状态查询、WebSocket 通知或回调机制,而不是让一个 HTTP 流无限等待。
多模态模型可以根据具体能力接收文字、图片、音频、视频、PDF或其他文件。OpenAI 的视觉能力说明已经将图片理解纳入统一模型调用流程;新的模型接口还开始支持把图片等多模态内容作为工具执行结果再次返回模型。
以扫描合同为例,可以采用:
PDF页面 → OCR提取文字 / 视觉模型识别表格、印章和手写内容 / 文档解析器保留页码与版面关系 → 统一内容对象 → 检索与风险分析
多模态并不意味着可以省略预处理。图片分辨率越高,通常需要的视觉 Token 和处理成本越高;分辨率太低,又可能看不清小字号、表格边框和印章。正确做法是根据页面复杂度选择输入方式,而不是对所有文件使用同一种模式。
模型选择不能只比较排行榜,而要同时考虑:
一个 Agent 通常也不应该只依赖一个模型。
任务 | 建议模型策略 |
|---|---|
意图识别、分类、简单抽取 | 小型、低成本、低延迟模型 |
Embedding 检索 | 专用 Embedding 模型 |
候选内容精排 | 专用 Rerank 模型 |
复杂规划与风险分析 | 推理能力更强的模型 |
格式校验与规则检查 | 程序规则优先,必要时辅助模型 |
最终报告生成 | 根据质量与延迟要求选择生成模型 |
总体成本可以粗略理解为:
总成本 ≈ 输入 Token 成本 + 输出及推理 Token 成本 + Embedding 与 Rerank 成本 + 搜索、代码执行等工具成本
总体延迟则不仅来自模型,还包括检索、工具调用、网络、队列和多轮循环。优化延迟时,减少不必要的模型调用,往往比单纯缩短 Prompt 更有效。OpenAI 的延迟优化指南也将“减少请求次数、并行处理、使用更小模型和流式返回”等作为不同层面的优化手段。
对于包含大量固定系统指令、工具描述和业务规则的 Agent,还可以利用 Prompt Caching 降低重复输入成本,但要尽量保持可复用前缀稳定,把动态内容放在后面。
当用户提出“分析这份扫描合同,找出高风险条款,并创建法务复核任务。”,系统可以这样执行:

开发 Agent 前,真正需要掌握的不是模型如何训练,而是模型如何被可靠地嵌入软件系统。
可以把本篇内容归纳为五个问题:
大模型负责理解、推理和生成;应用系统负责上下文组织、权限控制、工具执行、结果校验和异常处理。
这也是从“调用一次大模型 API”走向“开发一个可运行 Agent”的真正起点。
上一篇回顾:
【第一部分:认识 Agentic AI】4. 智能体的工作循环——从 ReAct 到 Plan-Execute-腾讯云开发者社区-腾讯云
下一篇将进一步介绍:
Prompt Engineering 与 Context Engineering
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。