Agent 类应用正在快速进入生产环境,但一个尴尬的问题越来越明显:大家都在讨论 Agent 如何规划、如何调用工具,却很少有人认真回答一个更基础的问题——你的 Agent 在真实业务里到底表现得好不好?这不仅取决于模型能力,更取决于评测方式。过去评测 LLM 只要丢一堆问答对算准确率,但评测 Agent 远远不是这么简单,因为它涉及多轮交互、工具调用、状态变化和结果验证。如果评测场景本身不真实、不完整,那么跑出来的分数就没有参考价值。
Agent Seer 这个方向,正是为了解决 Agent 评测场景的“源头供给”问题:不再靠人工手写一堆模拟用户提问,而是让系统从工具规格(Tool Spec)出发,理解工具能做什么、参数怎么约束、流程怎么编排,再自动合成贴近真实业务的高质量评测场景。
这篇文章我会说清楚 Agent Seer 到底解决什么问题、它的核心原理是什么、和传统评测有什么本质差别,以及如果你想在自己的 Agent 项目里落地这类“从工具规格合成评测场景”的思路,应该怎么做、有哪些坑。
1. 这篇文章真正要解决的问题
先看一个真实场景。假设你在开发一个天气查询 Agent,它需要调用两个工具:一个是查实时天气,一个是查未来 15 天预报。为了评测它,你可能会写这样几个测试用例:
用户:北京今天天气怎么样? 用户:上海明天会下雨吗? 用户:广州后天多少度?这些用例看起来没问题,但细想会发现很多关键场景根本没覆盖到。比如,用户把城市和日期混在一起说,Agent 能不能正确拆解?用户问“这周末适合去杭州吗”,Agent 需不需要先查预报再结合日期判断?用户只说了“今天”,工具要求传入具体日期,Agent 会不会自己去查当前日期?用户问的城市在工具支持范围之外,Agent 是礼貌拒绝还是强行编造结果?
这些都不是靠几个手写用例就能覆盖的。评测场景需要围绕工具的能力边界、参数约束、组合逻辑和异常情况来系统化生成。而这正是 Agent Seer 的核心思想:评测场景不应该只来自“人想怎么问”,更应该来自“工具能怎么被调用”。
这里要给出一个明确判断:Agent 评测的瓶颈已经从“模型跑分”转移到了“场景供给”。如果你的评测场景是零散的、拍脑袋的、只覆盖 happy path 的,那你评测出来的 Agent 能力数字,本质上是不可复现、不可外推的。Agent Seer 试图用“从工具规格理解中合成评测场景”的方式,把这个供给过程自动化、系统化。
这篇文章适合谁读?第一类是正在做 Agent 应用开发的工程师,你想知道怎么科学地验证自己的 Agent 效果;第二类是做 LLM 评测平台、数据合成、AI Infra 的研发同学,你需要理解场景合成的基本方法和落地路径;第三类是技术管理者,你需要判断团队投入多少资源在 Agent 评测上才算合理。
读完这篇文章,你会理解 Agent Seer 的底层逻辑,能够判断自己的项目中是否需要引入类似方案,并且照着文章里的步骤,用最少成本跑通一个“从工具规格到合成评测场景”的最小示例。
2. Agent Seer 是什么:从工具规格到评测场景
Agent Seer 并不是某一个开源框架的名字,它更像是一个研究方向和技术范式的总称。核心目标可以概括成一句话:让系统理解工具的描述文件,自动推导出用户可能提出的各种请求,再把这些请求连同期望的工具调用序列和答案约束,组织成评测场景。
要理解这个概念,先要拆开三个关键词。
2.1 工具规格(Tool Spec)
工具规格是 Agent 能够调用的外部能力的结构化描述。常见形式包括 OpenAPI/Swagger 定义、JSON Schema、函数签名文档等。它至少包含三部分信息:
- 工具的功能描述:这个工具是干什么的,在什么业务场景下使用。
- 输入参数定义:每个参数的名称、类型、是否必填、取值范围、默认值、约束条件。
- 输出结果定义:返回数据结构、成功标志、错误码、可能出现的异常。
举例来说,一个“查询订单”工具规格可能是这样的:
{ "name": "query_order", "description": "根据订单ID查询订单详情,适用于已登录用户查询自己的订单", "parameters": { "type": "object", "properties": { "order_id": { "type": "string", "description": "订单编号,格式为ORD开头加10位数字" }, "include_items": { "type": "boolean", "description": "是否返回订单商品明细,默认为false" } }, "required": ["order_id"] } }从这个规格里,系统能读到的关键信息包括:order_id 是必填参数且有格式要求;include_items 是可选的;工具本身描述里强调“已登录用户”,说明评测时可能需要考虑未登录场景。
这些信息,就是合成评测场景的最重要原料。
2.2 合成评测场景
评测场景不能简单理解成“一条测试问题”。一个完整的 Agent 评测场景应该包含:
- 用户请求文本,或者一段多轮对话的起始消息。
- 期望的 Agent 行为序列,包括应该调用哪些工具、以什么顺序调用、传什么参数。
- 可能的约束条件,比如某些参数必须从用户输入中抽取,某些参数需要 Agent 通过系统时间或上下文推理得到。
- 期望的输出形式,比如最终给用户什么样的回答,失败时如何兜底。
合成(Synthetic)意味着这些场景不是人工逐条编写的,而是由程序根据工具规格、业务规则和生成策略自动产生的。它和人工用例最大的区别是:合成场景可以做到可枚举、可覆盖、可扩展。只要工具规格更新,评测场景可以立刻重新生成,避免“工具变了但测试集还停留在三个月前”的窘境。
2.3 Agent Seer 的“理解”能力
这里需要特别强调“理解”两个字。Agent Seer 不是简单地把工具参数随机填值生成一堆查询,它需要真正理解工具规格中的语义。
同样是工具里有一个 date 参数,不同描述会导致完全不同的评测场景:
- 描述为“查询日期,格式 YYYY-MM-DD”:评测场景会重点看 Agent 是否能把用户口语里的“今天”“明天”“下周一”转成对应日期。
- 描述为“比赛开始日期,如果查询日期早于开赛日,需要返回未开始状态”:评测场景会重点看 Agent 是否理解业务时间约束,并且主动处理“查询时间早于开赛时间”这种边界。
- 描述为“账单生成日期,默认当天”:评测场景会看 Agent 是否在用户没提供日期时正确使用默认值。
同一个参数,语义不同,评测重点完全不同。所以 Agent Seer 的难点不在生成,而在“理解规格中的隐含语义”。
从技术路径上看,Agent Seer 的实现可以依赖两种能力:一种是用 LLM 作为语义理解引擎,读取工具规格后生成候选场景;另一种是通过规则引擎和语法解析,从参数类型、枚举值、描述文本中提取约束并组合生成。更成熟的方案会两者结合:先用规则保证生成场景的合法性和可执行性,再用 LLM 提升场景的语义真实度和多样性。
3. 传统 Agent 评测为什么不够用
在具体讲 Agent Seer 的实现前,有必要对比一下传统评测方式的问题。这样你才能判断:现有方案哪里不够用,Agent Seer 的改进到底改在哪里。
传统 LLM 评测的核心是“问题-答案对”。一个数据集包含大量问题和参考答案,评测时把问题丢给模型,计算模型输出与参考答案的相似度或命中率。这种模式对纯文本问答有效,但对 Agent 评测来说有三个致命问题。
第一,缺少工具调用过程验证。Agent 不是直接输出最终答案,它需要先生成“调用哪个工具”的决策,再生成参数,等待工具返回结果,最后基于结果组织回答。传统问答评测只关心最终文本,无法验证 Agent 的工具选择是否合理、参数是否填充正确。一个 Agent 可能结果说得很漂亮,但内部流程完全错误,比如应该查实时价格却调用了历史价格接口。
第二,场景覆盖不系统。人工编写用例时,很难穷举参数的组合关系、边界值和异常情况。比如一个工具有五个参数,其中两个必填、两个可选、一个条件必填,人工最多写几十条用例,但参数组合和业务分支可能成百上千。没有系统生成,评测覆盖就只能靠运气。
第三,场景和工具版本脱节。工具接口调整了参数名,或者新增了一个参数,人工测试用例往往不会同步更新。评测集越来越旧,评测结果越来越不能反映真实水平。而 Agent Seer 因为是从工具规格出发,工具规格一更新,评测场景可以立刻基于新规格重新合成,保持同步。
有人可能会说,我们可以先让 Agent 跑一遍真实用户日志,提取真实问题来做评测。这确实是很重要的数据来源,但真实日志也有问题:新上线的 Agent 没有日志;日志中的场景分布天然偏向常见问题,罕见边界覆盖不足;而且从日志提取评测场景涉及用户隐私和脱敏,很多团队处理不好。合成评测场景最大的价值,就是可以在没有历史数据时,从工具定义本身出发,快速生成覆盖度更高的评测集,并作为真实数据评测的有效补充。
4. Agent Seer 的核心流程拆解
理解了概念,我们来看一个可落地的 Agent Seer 实现流程。整体可以分成五个阶段:工具规格解析、场景意图推导、参数实例化、结果约束生成、评测集组装。
4.1 工具规格解析
这一步的目标是把原始工具描述文件转换成结构化中间表示。如果是 OpenAPI 规范,可以直接解析paths、parameters、requestBody、responses;如果是 JSON Schema,可以递归解析properties、required、enum、format、description。重点是从描述文本中提取出隐含的业务规则。
解析后的中间表示可以设计成类似这样的结构:
@dataclass class ToolParam: name: str type: str required: bool enum: list[str] | None = None format: str | None = None description: str = "" default: object = None @dataclass class ToolSpec: name: str description: str params: list[ToolParam]这一步是整个流程的基础。如果规格解析不完整,后面生成的场景就会缺失重要维度。建议在解析阶段做一次字段级别的校验,确保每个参数的类型、必填、枚举、描述至少有一项非空,否则生成时要跳过或标记为低置信度。
4.2 场景意图推导
理解了工具有什么参数之后,需要推导出“用户为什么要调用这个工具”。一个工具往往服务于多种意图。
以“查询天气”工具为例,可能的意图包括:
- 查询当前天气状态。
- 查询未来某一天的天气。
- 比较两个城市的天气。
- 根据天气规划出行建议。
- 查询一周天气趋势。
这些意图从工具的 description 和参数语义中可以推导出来。实现时,可以让 LLM 读取工具规格并输出候选意图列表;也可以用一套模板规则,例如“参数中有 date 且有 city,那么意图可能是查询某城市某日天气”。
这里有一个容易踩的坑:生成意图时不要偏离工具能力边界。天气工具只能查天气,不能因为 LLM 发散就生成“查询航班”意图。稳妥的做法是,让 LLM 生成意图的同时,要求每个意图必须引用工具描述中的原始句子,作为“证据”,再经过规则校验过滤。
4.3 参数实例化
有了意图,下一步要为该意图生成具体的参数值,进而反推用户请求文本。参数实例化需要遵循工具规格中的类型和约束。
构造参数值的方法包括:
- 从枚举值中随机选择或遍历选择。
- 从 format 中生成符合格式的模拟值,比如日期、邮箱、手机号、金额。
- 针对文本描述生成语义合理的值,比如城市名、商品名、订单号。
- 故意构造边界值,比如空字符串、超长字符串、缺失必填参数、含特殊字符。
在合成评测场景时,参数实例化不只是生成“合法值”,还要生成“非法值”和“模糊值”。非法值用于测试 Agent 是否能识别工具约束并正确拒绝,模糊值用于测试 Agent 是否能从自然语言中正确抽取参数。比如工具要求 date 格式是 YYYY-MM-DD,但用户说“后天下午”,Agent 能否正确转成日期字符串?这种场景就需要在参数实例化时同时生成“用户口语表达”和“期望的规范化参数值”。
4.4 结果约束生成
评测场景不能只有输入,还要有可验证的期望。结果约束可以选择以下几种形式:
- 期望工具调用序列:一个 JSON 数组,标识 Agent 应该依次调用哪些工具。
- 期望参数值:针对每次工具调用,期望传递的参数键值对。
- 期望最终回答的类型:比如“包含天气信息”“包含温度数值”“包含失败说明”,但不限定具体措辞。
- 期望拒绝行为:比如“当城市不在支持列表时,告知用户无法查询”。
对于结果约束,建议使用结构化 JSON 而不是自然语言描述。因为结构化约束可以直接写断言脚本,自然语言描述还需要二次解析,容易产生误差。
4.5 评测集组装
最后,把生成的所有场景按维度组织成评测集。建议为一个 Agent 建立至少三个评测子集:
- 基础能力集:覆盖工具基本调用的 happy path。
- 边界能力集:覆盖参数边界、缺失、歧义、组合异常。
- 业务语义集:覆盖工具描述中隐含的业务规则和跨工具编排。
评测集一般保存为 JSONL 格式,每个场景一行,方便后续增量更新和版本管理。
5. 完整示例:用 Python 实现一个最小 Agent Seer
这一节我们动手实现一个简化版场景合成器。目标很简单:给定一个工具规格,自动生成若干条评测场景。示例使用 Python 3.10+,依赖 OpenAI SDK 作为 LLM 语义理解引擎。为了可运行,这里使用openai库,并假设已有合法的 API Key;如果你使用本地模型或其它兼容 OpenAI 协议的推理服务,只需要修改 base_url 和 model 名称。
5.1 环境准备
创建项目目录和虚拟环境:
mkdir agent-seer-demo cd agent-seer-demo python3 -m venv venv source venv/bin/activate pip install openai pydantic说明:openai用于调用 LLM;pydantic用于定义和校验数据结构。如果你的网络环境无法访问外部服务,可以把 LLM 调用部分替换成规则生成,后面会提到。
5.2 定义工具规格数据结构
在demo.py中定义最小数据结构:
# 文件路径:agent-seer-demo/demo.py from typing import Optional, Any from pydantic import BaseModel, Field class ToolParam(BaseModel): name: str = Field(description="参数名") type: str = Field(description="参数类型,例如 string/integer/boolean") required: bool = Field(default=False, description="是否必填") enum: Optional[list[str]] = Field(default=None, description="枚举值列表") format: Optional[str] = Field(default=None, description="参数格式,例如 date/email") description: str = Field(default="", description="参数描述") class ToolSpec(BaseModel): name: str = Field(description="工具名称") description: str = Field(description="工具功能描述") params: list[ToolParam] = Field(default_factory=list, description="参数列表")这个模型可以直接从 JSON Schema 转换而来。真实项目中,你可能还要增加operation_id、server_url、responses等字段,最小示例暂不需要。
5.3 调用 LLM 生成评测场景
我们让 LLM 基于工具规格生成评测场景的 JSON 列表。为确保输出格式稳定,用函数调用的方式让模型返回结构化结果:
# 文件路径:agent-seer-demo/demo.py 继续追加 import json from openai import OpenAI client = OpenAI( api_key="YOUR_API_KEY", base_url="YOUR_BASE_URL" # 如果是本地模型,替换为对应地址 ) def generate_scenes_by_llm(spec: ToolSpec, num_scenes: int = 10) -> list[dict]: spec_text = json.dumps(spec.model_dump(), ensure_ascii=False, indent=2) prompt = f"""请根据下面的工具规格,生成 {num_scenes} 条 Agent 评测场景。 要求: 1. 每条场景必须包含 user_query:用户最可能的自然语言请求。 2. 必须包含 expected_tool_calls:期望调用的工具列表,每个元素包含 tool_name 和 parameters。 3. 必须包含 expected_type:期望的回答类型,可选值为 success / refusal / clarification。 4. 场景要覆盖正常调用、参数缺失、参数歧义、边界值、业务规则冲突等情况。 5. 输出 JSON 数组,不要输出其他内容。 工具规格: {spec_text} """ response = client.chat.completions.create( model="gpt-4o-mini", # 或你选择的模型 messages=[{"role": "user", "content": prompt}], temperature=0.7, ) content = response.choices[0].message.content or "" # 容错处理:如果模型输出了 ```json 包裹,去掉标记 content = content.strip() if content.startswith("```"): content = content.split("```")[1] if content.startswith("json"): content = content[4:] scenes = json.loads(content) return scenes这里有几个要点。第一,YOUR_BASE_URL要替换成你的服务地址,OpenAI 官方地址可以留空,本地兼容服务要填写实际地址。第二,LLM 输出 JSON 不稳定时,可以把响应格式设成response_format={"type": "json_object"},并要求返回一个带scenes字段的对象,这样更稳定。第三,temperature建议不要太高,否则生成场景容易偏离工具规格。
5.4 加一层规则校验
LLM 生成的场景不一定完全符合工具规格,比如参数名写错、必填参数缺失但期望类型却是 success。所以最稳妥的方式是加一层朴素校验器:
# 文件路径:agent-seer-demo/demo.py 继续追加 def validate_and_fix_scene(spec: ToolSpec, scene: dict) -> dict: param_names = {p.name for p in spec.params} required_names = {p.name for p in spec.params if p.required} for call in scene.get("expected_tool_calls", []): if call.get("tool_name") != spec.name: scene["expected_type"] = "refusal" scene["_warnings"] = scene.get("_warnings", []) + ["工具名称不匹配"] params = call.get("parameters", {}) # 检查必填参数 missing = required_names - set(params.keys()) if missing and scene.get("expected_type") == "success": scene["expected_type"] = "clarification" scene["_warnings"] = scene.get("_warnings", []) + [ f"必填参数缺失: {missing}" ] # 检查参数名是否存在于规格中 for key in params.keys(): if key not in param_names: scene["_warnings"] = scene.get("_warnings", []) + [ f"未知参数: {key}" ] return scene这一步的价值在于:让“模型建议”变成“可执行的评测场景”。即使 LLM 生成了超出规格的内容,标记为 warning,也不会直接污染评测集。
5.5 运行示例
现在我们构造一个“航班查询”工具规格,然后运行整个流程:
# 文件路径:agent-seer-demo/demo.py 继续追加 flight_spec = ToolSpec( name="search_flight", description="根据出发城市、到达城市和日期搜索航班信息,支持往返搜索", params=[ ToolParam(name="departure_city", type="string", required=True, description="出发城市,例如 北京"), ToolParam(name="arrival_city", type="string", required=True, description="到达城市,例如 上海"), ToolParam(name="date", type="string", required=True, format="date", description="出发日期,格式 YYYY-MM-DD"), ToolParam(name="return_date", type="string", required=False, format="date", description="返程日期,如果查询往返航班需要填写"), ToolParam(name="trip_type", type="string", required=False, enum=["oneway", "roundtrip"], default="oneway", description="行程类型:单程或往返"), ], ) if __name__ == "__main__": scenes = generate_scenes_by_llm(flight_spec, num_scenes=10) validated = [validate_and_fix_scene(flight_spec, s) for s in scenes] for i, scene in enumerate(validated, 1): print(f"场景 {i}: {scene['user_query']}") print(f"期望类型: {scene.get('expected_type')}") print(f"期望调用: {scene.get('expected_tool_calls')}") if scene.get("_warnings"): print(f"警告: {scene['_warnings']}") print("-" * 60)运行方式:
python demo.py预期输出是一组包含用户查询、期望工具调用和期望类型的 JSON 结构化数据。如果调用 LLM 失败或没有 API Key,也可以把generate_scenes_by_llm替换成基于规则的随机生成器,逻辑是遍历参数值组合,从预置的模板中生成用户请求,比如“帮我查一下 {city1} 到 {city2} 的机票”,然后补上合理的参数值。
6. 运行结果与效果验证
很多人做完场景合成后,直接就把生成的 JSON 丢给评测框架,但这样会漏掉一个重要环节:验证合成场景本身是否合理、是否可执行、是否具备区分度。
验证合成的评测场景,可以从三个维度检查。
第一是格式合法性。所有场景都必须能被评测框架正确解析,参数名必须存在于工具规格中,期望工具调用必须是被测 Agent 支持的工具,期望类型必须是枚举值之一。上面的示例中,校验器已经覆盖了部分内容,但生产环境建议写成独立的测试脚本。
第二是语义合理性。可以把生成场景展示给业务同学,看用户查询是否像真实用户会说的话。这里容易发现 LLM 生成内容的“AI 味”,比如用户查询太书面、太长、太完整。真实用户不会说“请帮我查询从北京市到上海市的2024年6月1日的航班”,而更可能说“6月1号北京到上海的机票看看”。如果合成场景缺乏这种口语化变形,用评测结果反推出的 Agent 能力会虚高,因为 Agent 在真实场景中面对的是更模糊的表达。
第三是覆盖有效性。记录生成场景中哪些参数值被覆盖、哪些分支被覆盖。可以简单统计一下:
# 文件路径:agent-seer-demo/check_coverage.py import json from collections import Counter with open("scenes.jsonl", "r", encoding="utf-8") as f: scenes = [json.loads(line) for line in f if line.strip()] covered_cities = set() covered_dates = set() expected_types = Counter() for scene in scenes: for call in scene.get("expected_tool_calls", []): params = call.get("parameters", {}) if "departure_city" in params: covered_cities.add(params["departure_city"]) if "date" in params: covered_dates.add(params["date"]) expected_types[scene.get("expected_type")] += 1 print("覆盖城市:", covered_cities) print("覆盖日期:", covered_dates) print("期望类型分布:", dict(expected_types))如果发现expected_type全部是 success,说明生成策略过于保守,边界场景没有覆盖。如果日期全是同一天,说明参数实例化没有做多样性。合理的目标是:每个参数枚举值至少被覆盖一次,必填参数在部分场景中缺失,日期覆盖最近一周、特殊日期、非法格式三种情况。
当评测集验证通过之后,就可以把它接入你的 Agent 评测框架,跑出基线分数。后续工具规格修改时,重新生成评测集并重新跑分,才能看到真实的回归变化。
7. 常见问题与排查思路
在实现 Agent Seer 的过程中,大多数人会遇到下面几类问题。这里整理成表格,方便直接对照排查。
| 问题现象 | 可能原因 | 排查方式 | 解决方案 |
|---|---|---|---|
| LLM 生成的 JSON 频繁解析失败 | 模型输出包含 Markdown 代码块或多余文本 | 打印原始输出内容,检查前后缀 | 使用response_format强制 JSON;增加解析容错函数;改用更大模型 |
| 生成的场景全是 happy path,没有边界情况 | 提示词未强调边界覆盖,temperature 过低 | 统计expected_type分布 | 在提示词中增加边界场景占比要求;补充规则生成器强制构造非法参数 |
| 场景中用户提问过于书面化,不像真人 | LLM 按照工具规格直译生成,缺少口语化改写 | 人工抽看生成样本 | 增加对话风格改写步骤,要求模型将请求改写成口语、短句、带省略的形式 |
| 期望工具调用参数与真实工具参数不一致 | 工具规格更新后没有同步生成评测集 | 检查工具规格版本 | 在 CI 中检测工具规格变化,触发评测集重新生成 |
| 生成的场景数量过大,评测成本无法接受 | 参数组合爆炸,没有做采样 | 查看生成场景总量 | 按覆盖维度采样,控制每个维度的最大场景数;使用去重和聚类 |
| 工具描述信息太少,LLM 无法理解语义 | 工具规格本身写得含糊 | 检查原始 description 是否说明业务规则 | 完善工具描述,补充输入输出示例;或者在解析阶段加入人工补充规则 |
这里最重要的排查思路是:先分清楚问题出在“工具规格解析”还是“场景生成”还是“场景校验”。如果解析阶段输出的中间结构有问题,后面所有生成都不可信。建议在生成前先打印解析后的ToolSpec,人工确认参数和描述是否正确。
另外,不少人会问:能不能完全不用 LLM,只靠规则生成?可以。规则生成适合参数结构简单、枚举值明确的工具,但对描述型语义理解无能为力。实际项目中更推荐混合策略:用规则生成基础覆盖集,用 LLM 生成语义复杂场景,再用规则做过滤。
8. 最佳实践与工程建议
如果要把 Agent Seer 的思路落地到真实的 Agent 评测体系中,建议从下面几个维度来设计。
8.1 工具描述规范先行
工具规格是场景合成的输入,输入质量直接决定输出质量。团队里应该有统一的工具描述规范,至少包含:
- 工具负责的业务范围,一句话说清楚。
- 每个参数的业务含义,说明它对应真实世界中的哪个概念。
- 参数的格式、单位、取值范围,能写枚举就写枚举。
- 常见边界情况,比如空值、超范围值、业务约束。
工具描述写得越具体,Agent 在真实运行时的工具选择也会越准确,同时合成评测场景时的语义理解也会越可靠。这属于一次投入长期受益的工程改进。
8.2 评测场景要版本化
把合成评测场景当成代码资产来管理。建议每个评测集文件都带一个版本号,并在文件中记录生成所使用的工具规格版本、生成策略参数、LLM 模型名和 temperature。这样当评测分数变化时,你能判断是 Agent 变好了还是评测集变了。
一个 JSONL 场景记录的元信息示例:
{ "scene_id": "scene-00042", "tool_spec_version": "v20240601", "generator": "llm+gpt-4o-mini", "user_query": "周五上海飞深圳的票还有吗", "expected_tool_calls": [ { "tool_name": "search_flight", "parameters": { "departure_city": "上海", "arrival_city": "深圳", "date": "2025-06-06", "trip_type": "oneway" } } ], "expected_type": "success" }有了这些元信息,你才能在迭代中做归因分析。
8.3 引入多级评测机制
合成场景适合做第一轮回归和持续集成,但不要作为唯一标准。建议分三层:
- 第一层:合成评测集,覆盖工具规格可见的边界和业务规则,用于 CI 快速回归。
- 第二层:真实交互日志,从生产环境中脱敏采样,用于评估真实用户场景分布。
- 第三层:人工评测,针对高价值场景和复杂编排任务,由专家进行最终判定。
三层互补,才能得到完整的 Agent 能力视图。Agent Seer 的价值是让第一层从“人工手写”变成“自动化供给”,但它不替代后两层的必要性。
8.4 安全与权限边界
在合成评测场景时,需要注意一个容易被忽视的问题:生成的用户查询可能涉及虚构的敏感信息,比如订单号、手机号、身份证号。评测阶段处理这些数据同样要遵循最小化原则。对需要验证 Agent 脱敏能力的场景,建议用明显的假数据生成器,比如ORD0000000001或13800000000,而不是使用类似真实数据的随机值。此外,评测系统访问 Agent 所依赖的外部工具时,应使用专用测试账号和沙箱环境,避免评测请求污染生产数据。
8.5 评测指标要与场景类型绑定
不要用一个总正确率概括所有 Agent 能力。不同expected_type的场景应该分开统计:
- success 类场景看工具调用准确率和参数准确率。
- refusal 类场景看是否没有调用不该调用的工具。
- clarification 类场景看在信息不足时是否主动追问,而不是强行猜一个答案。
只有分维度看指标,你才能知道 Agent 目前的短板是“不会拒绝”还是“不会澄清”还是“参数抽取不准”。这个分析结果也反过来指导场景合成的重点方向。
9. 总结与后续学习方向
Agent Seer 的价值不在于发明了复杂的模型,而在于改变了一个被很多人忽略的评测思路:评测场景的源头应该是工具规格,而不是人为拍脑袋写出的问题列表。工具规格里写清楚了参数、约束和业务语义,Agent Seer 就负责把这些静态描述转化成一棵覆盖正常路径、边界路径和异常路径的场景树。这样一来,评测集不再是一次性的人力投入,而是可以随工具迭代自动再生的工程资产。
如果你正在做 Agent 应用评测,可以先从一个小工具入手,把它的 JSON Schema 整理好,用本文的最小示例生成 20 到 30 条场景,然后观察这些场景是否覆盖了你手工没有写到的情况。这一步跑通后,再逐步增加场景复杂度、真实日志校验和多轮对话支持。
后续值得深入的方向包括:多工具组合场景的自动生成、多轮对话中的 hidden state 建模、基于合成场景的反例挖掘、以及把场景合成与强化学习训练数据合成统一起来的实践。无论往哪个方向走,核心原则是一致的:先理解工具的边界,再设计评测的任务;把规格当输入,评测集当输出,Agent 能力才会被真正衡量清楚。