大家有没有发现一个奇怪的现象:现在的大模型聊起天来头头是道,写代码、做翻译、答数学题样样在行,可一旦把任务拉长到十几分钟、几十分钟,让它像一个真实员工那样“从头到尾负责一件事”,模型就开始掉链子:做到一半忘了前面说过什么,工具调用顺序混乱,中间被一条新信息打断后就彻底跑偏。
最近看到一份关于长时程 AI 任务评测的结果,数据很直观:顶尖模型在长时程任务上的综合表现,只有人类水平的 27.3%。这个数字放在当前大模型遍地“屠榜”的氛围里,显得非常扎眼。它说明一个很现实的问题:模型的能力上限已经从“会不会做一件事”转移到了“能不能长时间稳定地做完一件事”。
这篇文章我想围绕“长时程 AI 任务评测”做一个系统拆解。我们会先从概念入手,弄清楚到底什么是长时程任务、为什么它比单轮问答难这么多;然后给出一个可以本地运行的评测脚手架,包含任务状态跟踪、长时程一致性评分、记忆窗口管理等核心代码;最后结合我自己的工程经验,聊聊长时程任务失败的主要原因、排查思路,以及做 Agent 评测时的最佳实践。
如果你正在做大模型应用、Agent 开发、AI 自动化流程设计,或者想搞清楚为什么自己的 Agent 一到复杂任务就“半途而废”,这篇文章应该能给你一个比较完整的参考答案。
1. 长时程任务评测:到底在测什么
1.1 什么是长时程 AI 任务
长时程任务(Long-Horizon Task)是指需要模型在较长的时间跨度内,通过多步交互、多次工具调用、多轮状态更新才能完成的复杂任务。
它和我们平时见到的测试题有本质区别。日常的智能问答、文本分类、代码补全,可以理解为“一次性任务”:输入一句话,输出一个答案,任务就结束了。而长时程任务更像是“项目型任务”:
- 目标是固定的,但中间路径是开放的;
- 模型需要自己决定先做什么、后做什么;
- 中间结果需要被保留,并且会影响到后续决策;
- 任务执行过程中会插入新的信息,模型需要判断是继续原计划还是调整计划;
- 最终结果要能用客观标准校验。
举个例子:让人工智能帮你“规划并预订一次出差行程”。这就不只是一个对话问题了,它可能包括查航班、比价格、看酒店、确认会议室、协调多个人的时间、最后生成一份行程单。每一个子步骤都会产生中间状态,而后续子步骤又依赖前一步的状态。
在长时程任务评测里,模型不再是“回答一个问题”,而是在“执行一项工作”。
1.2 长时程任务的四个典型特征
要设计或理解长时程任务评测,首先得抓住这类任务的四个核心特征:
| 特征 | 说明 | 普通任务 vs 长时程任务 |
|---|---|---|
| 多步性 | 必须经过多个子步骤才能完成 | 单步问答 vs 多阶段流程 |
| 状态依赖 | 后一步依赖前一步的结果 | 独立输出 vs 状态连续传递 |
| 长跨度 | 执行时间或上下文长度显著增加 | 秒级响应 vs 分钟级甚至小时级执行 |
| 抗干扰性 | 中间可能插入噪音信息,需要保持主目标 | 无干扰 vs 需要抵御干扰和漂移 |
这四个特征也是评测指标设计的出发点。如果一个评测任务只测“多步”,但每一步之间完全没有状态依赖,那它本质上还是多个单步任务拼在一起;真正考验模型的是第三和第四点。
1.3 27.3% 这个数字意味着什么
回到文章开头那份评测。报道的结论是:顶尖模型在长时程任务上的综合表现只达到人类水平的 27.3%。
这个数字之所以重要,是因为它和大众体感之间存在巨大反差。大家用 ChatGPT、Claude 等模型时,觉得什么都能聊、什么都能写,为什么一到长时程评测就只有人类的四分之一?
原因在于:长时程任务测的其实是模型的“系统能力”,而不是“单点能力”。
单点能力指:模型知识全不全、推理强不强、代码熟不熟。这一点当前顶尖模型已经很强了。但系统能力指:在大时间跨度里,模型能不能保持目标专注、能不能准确记忆历史状态、能不能控制误差累积、能不能在异常分支出现时自我纠偏。这些能力不是“下一个 token 预测得准”就能解决的。
27.3% 并不是说模型“什么都不会”,而是说它在“长时间负责任务”这件事上还很弱。这给我们的工程启示也很直接:在设计 AI Agent 时,不能默认模型可以独立撑起一个长流程,必须在架构上引入外部记忆、任务分解和校验机制。
2. 长时程任务评测的标准设计
聊完概念,我们来看评测本身。如果你想搭建一套长时程 AI 任务评测方案,核心不是“找一堆题让模型做”,而是要把任务的执行过程拆成可以量化打分的维度。
2.1 评测维度拆分
我建议把长时程任务评测拆成五个维度:
目标完成度(Goal Completion)最终结果是否达到目标描述中的验收标准。这是最核心的指标,通常采用 0-1 分或按子目标加权计分。
步骤正确率(Step Accuracy)把任务拆解为标准步骤后,检查模型执行每一步时是否正确。长时程任务尤其关注“关键路径”上的步骤,这些步骤一旦错误,后面全错。
状态一致性(State Consistency)模型在整个执行过程中,是否对任务的当前状态保持一致的认知。比如前面已经选好航班,后面的行程安排是否仍然基于这个航班,而不是中途换了一个没查过的航班。
错误恢复能力(Error Recovery)当某个步骤执行失败或返回异常数据时,模型能否发现错误、尝试修复、或者明确告知用户。很多 Agent 在面对工具报错时,要么反复重试相同请求,要么直接放弃,这一步得分通常很低。
效率与成本(Efficiency)完成任务消耗的步数、调用次数、Token 数量、时间。两个模型如果完成度相同,步数更少、成本更低的那个应该得分更高。
2.2 评测数据的组织方式
一套标准的长时程评测集,建议采用如下数据组织:
task_id: "task_001" task_type: "travel_planning" description: "根据需求预订一次从杭州到深圳的三天出差行程" goal: - "确定出发日期和返程日期" - "筛选性价比最高的航班" - "预定距离客户公司 3 公里以内的酒店" - "生成包含时间、地点、费用的行程表" steps: - step_id: 1 description: "解析需求中的日期和地点" check_type: "contains" expected: ["深圳", "三天"] - step_id: 2 description: "搜索航班" check_type: "tool_call" expected_tool: "search_flight" - step_id: 3 description: "根据时间和价格选择航班" check_type: "reasoning" expected_keys: ["flight_no", "price", "departure_time"] state_checkpoints: - checkpoint_id: 1 after_step: 2 check_type: "state_consistency" description: "选定的航班必须来自搜索结果,不能凭空生成" human_baseline: score: 0.95 steps: 14 tokens: 3200这种数据组织方式有几个好处:
- 支持自动化评分,不需要人工看完整个执行过程;
- 能定位模型具体在哪个环节失败;
- 可以对比不同模型的步骤级表现;
- 也能复现同一模型多次运行时的稳定性差异。
2.3 评分方法
长时程任务不建议只看最终完成度,因为两个模型可能都完成了任务,但中间失败次数完全不同。更合理的评分是加权求和:
final_score = w1 * goal_completion + w2 * step_accuracy + w3 * state_consistency + w4 * error_recovery - w5 * normalized_cost在实际评测中,权重需要根据任务类型调节。比如“数据分析报告生成”这种任务,目标完成度权重应最高;而“客户对话处理”这种任务,状态一致性和错误恢复能力权重甚至应该超过目标完成度,因为过程正确比结果正确更重要。
3. 环境准备与评测脚手架
接下来进入实战部分。我们会搭建一个轻量级的“长时程任务评测原型”,不需要昂贵的大模型 API,也能把评测流程跑通。你可以把它当成一个模板,后续接入 OpenAI API、本地模型或任何 Agent 框架。
3.1 环境说明
本文示例使用 Python 3,重点演示评测逻辑和数据结构,不涉及具体的模型调用。核心依赖只有 Python 标准库,方便你把代码直接复制到任何环境运行。
我自己测试时的环境参考如下:
Python 3.10+ 操作系统:Linux / macOS / Windows 均可 依赖:标准库(json, time, random, collections, dataclasses)如果你想把评测脚本接入真实模型,只需要在execute_agent函数里替换成你实际使用的模型或 Agent 框架。
3.2 项目结构
建议按下面结构组织评测工程:
long_horizon_eval/ ├── tasks/ # 评测任务数据 │ └── task_001.json ├── agent/ # 被测 Agent 实现 │ └── dummy_agent.py ├── evaluator/ # 评测逻辑 │ ├── metrics.py # 指标计算 │ ├── state_tracker.py # 状态跟踪 │ └── runner.py # 评测主流程 ├── results/ # 评测结果输出 │ └── run_20250101.json └── main.py # 入口这套结构一眼就能看出分层关系:任务数据独立、被测 Agent 独立、评测逻辑独立。在真实项目中,建议始终保持这种解耦,因为长时程评测的 Agent 和任务集都会频繁更新。
3.3 安装依赖
由于使用标准库,无需额外安装依赖。如果你后续要调用外部模型,再根据实际 SDK 安装即可。例如调用 OpenAI 兼容接口时:
pip install openai不过我建议核心评测逻辑不要绑定具体 SDK,可以统一封装成 Agent 接口,这样换模型时评测代码不用动。
4. 核心评测代码实现
下面我会逐步实现一个可运行的长时程任务评测原型。代码包含四个核心部分:
- 状态跟踪器:模拟 Agent 执行过程中的状态流转;
- 记忆窗口:限制 Agent 只能看到最近 N 步信息,模拟长时程任务中的记忆压力;
- 评测指标:计算目标完成度、状态一致性和步骤正确率;
- 运行器:串联整个评测流程。
4.1 状态跟踪器
长时程任务最关键的是状态管理。一个没有状态管理能力的 Agent,本质上无法完成多步任务。我们先用一个StateTracker类模拟“Agent 记忆”:
# 文件路径:evaluator/state_tracker.py import json import time from collections import deque from datetime import datetime class StateTracker: """模拟 Agent 的状态跟踪与记忆窗口管理。 核心能力: - 记录每一步执行后的状态快照 - 通过滑动窗口限制可访问的历史信息 - 检测状态是否发生异常漂移 """ def __init__(self, max_memory_steps: int = 5): # 最大记忆步数,超过该步数的状态会被“遗忘” self.max_memory_steps = max_memory_steps self.steps = [] self.states = [] self.memory = deque(maxlen=max_memory_steps) self.started_at = None self.finished_at = None def start(self): self.started_at = datetime.now() def finish(self): self.finished_at = datetime.now() def record_step(self, step_id, action, state_snapshot, extra=None): record = { "step_id": step_id, "action": action, "state_snapshot": state_snapshot, "extra": extra or {}, "timestamp": datetime.now().isoformat(), } self.steps.append(record) self.states.append(state_snapshot) self.memory.append(record) def get_memory(self): """返回当前滑动窗口内可见的历史记录。""" return list(self.memory) def current_state(self): """返回最近一次的状态快照。""" if not self.states: return {} return self.states[-1] def detect_drift(self, key: str, expected_value): """检测某个关键状态是否和预期一致。""" current = self.current_state() actual = current.get(key) return actual == expected_value, actual def elapsed_seconds(self): if self.started_at is None: return 0 end = self.finished_at or datetime.now() return (end - self.started_at).total_seconds()这里的关键点是deque(maxlen=max_memory_steps)。它模拟的是长时程任务中常见的“记忆窗口”机制:Agent 不是无限期记住每一步,而是只保留最近 N 步。当 N 比较小时,模型就必须依赖外部存储或自我总结,否则就会出现“做到后面忘了前面”的情况。
这个设计对评测很有意义。你可以通过调整max_memory_steps来制造不同难度的任务环境:窗口越小,任务对记忆能力的要求越高。
4.2 模拟 Agent
为了不依赖具体模型,我们写一个“模拟 Agent”。它内置一个简单的决策规则:优先从当前可见记忆中寻找线索,如果记忆为空就按固定顺序执行步骤。
# 文件路径:agent/dummy_agent.py from evaluator.state_tracker import StateTracker class DummyAgent: """一个基于规则的最小 Agent 实现,用于评测流程演示。 真实使用时,可以把 run() 方法内部替换成 LLM + 工具调用的流程。 """ def __init__(self, name: str = "dummy", memory_steps: int = 5): self.name = name self.tracker = StateTracker(max_memory_steps=memory_steps) def run(self, task: dict): self.tracker.start() # 模拟任务解析 description = task.get("description", "") goal = task.get("goal", []) self.tracker.record_step( step_id="parse", action="parse_task", state_snapshot={"description": description, "goal": goal}, ) # 模拟步骤执行 steps = task.get("steps", []) for step in steps: # 模拟决策:从记忆中提取当前是否已执行过该步骤 memory = self.tracker.get_memory() already_done = any( item.get("extra", {}).get("processed_step") == step.get("step_id") for item in memory ) # 如果记忆窗口较小,早期步骤可能已被“遗忘” if already_done: action = "repeat_step" else: action = "execute_step" state_snapshot = { "processed_step": step.get("step_id"), "description": step.get("description"), "check_type": step.get("check_type"), "expected": step.get("expected"), } self.tracker.record_step( step_id=step.get("step_id"), action=action, state_snapshot=state_snapshot, extra={"processed_step": step.get("step_id")}, ) # 模拟结果生成 final_output = { "summary": f"{self.name} 完成 {description} 的模拟执行", "steps_executed": len(self.tracker.steps), } self.tracker.record_step( step_id="finalize", action="generate_final_output", state_snapshot=final_output, ) self.tracker.finish() return { "agent_name": self.name, "steps": self.tracker.steps, "states": self.tracker.states, "final_output": final_output, }这个 DummyAgent 本身不是一个聪明的 Agent,但它能完整演示状态跟踪、记忆窗口和步骤记录的机制。在真实项目中,你只需要保留这个类的外部接口,把run()里面的实现替换成真实的模型调用链即可。
4.3 评测指标计算
接下来是评测指标。这部分是长时程任务评测的核心逻辑,我会实现三个关键指标:目标完成度、状态一致性、步骤正确率。
# 文件路径:evaluator/metrics.py from typing import Dict, List def compute_goal_completion(output, goal: List[str]) -> float: """计算目标完成度。 策略:把最终输出转成字符串,依次检查每个目标关键词是否存在。 完整版本可以换成 LLM 评判或规则引擎。 """ if not goal: return 1.0 output_str = str(output) hit = 0 detail = [] for g in goal: if isinstance(g, str): ok = g in output_str else: ok = False detail.append({"goal": g, "achieved": ok}) if ok: hit += 1 return hit / len(goal), detail def compute_step_accuracy(expected_steps: List[Dict], actual_steps: List[Dict]) -> float: """计算步骤正确率。 这里使用简化策略:检查实际执行中是否出现了所有期望步骤。 """ expected_ids = {str(s.get("step_id")) for s in expected_steps} actual_ids = set() for step in actual_steps: step_id = step.get("step_id") if step_id is not None: actual_ids.add(str(step_id)) hit = expected_ids & actual_ids accuracy = len(hit) / len(expected_ids) if expected_ids else 1.0 return accuracy, {"expected": sorted(expected_ids), "actual": sorted(actual_ids), "hit": sorted(hit)} def compute_state_consistency(states: List[Dict], max_memory_steps: int) -> float: """计算状态一致性。 思路:如果滑动窗口很小,但关键状态又发生了变化,说明 Agent 可能丢失了重要上下文。 这里用“最近状态中关键字段是否稳定”作为代理指标。 """ if not states: return 1.0 # 提取所有状态中的关键字段 key_fields = set() for state in states: key_fields.update(state.keys()) if not key_fields: return 1.0 inconsistent = 0 total_checks = 0 for key in key_fields: values = [state.get(key) for state in states] # 去除 None 和无意义值 meaningful = [v for v in values if v is not None and v != {}] if len(meaningful) < 2: continue # 检查最后一个有效值和前一个有效值是否一致 for i in range(1, len(meaningful)): total_checks += 1 if meaningful[i] != meaningful[i - 1]: inconsistent += 1 if total_checks == 0: return 1.0 return 1.0 - (inconsistent / total_checks) def compute_final_score( goal_completion: float, step_accuracy: float, state_consistency: float, memory_steps: int, elapsed: float, w1=0.4, w2=0.3, w3=0.2, w4=0.1, ) -> Dict: """计算加权综合得分。 这里 w4 是效率维度。我们把 memory_steps 和耗时转换成一个简单的 0-1 成本分数。 实际项目可以根据成本、Token 量、工具调用次数继续细化。 """ # 效率分数:步数越少、耗时越短,得分越高 # 这里用一个简化公式,实际使用时应结合任务基准值 efficiency = 1.0 / (1.0 + elapsed / 100.0) final_score = ( w1 * goal_completion + w2 * step_accuracy + w3 * state_consistency + w4 * efficiency ) return { "final_score": round(final_score, 4), "goal_completion": round(goal_completion, 4), "step_accuracy": round(step_accuracy, 4), "state_consistency": round(state_consistency, 4), "efficiency": round(efficiency, 4), "memory_steps": memory_steps, "elapsed_seconds": round(elapsed, 4), }指标计算上有几个细节需要说明:
目标完成度并不只是简单判断输出里有没有关键词。在真实评测中,我会用“关键实体验证 + LLM 评判”的组合方式,避免关键词匹配带来的误判。这里为了演示采用关键词匹配。
步骤正确率要区分“步骤是否被调用”和“步骤结果是否正确”。理想评测会记录每个工具的参数,而不仅仅是步骤 ID。建议实际项目中把工具参数也纳入状态快照。
状态一致性的判定最难。这里我用了简化逻辑:如果某个关键字段在前后状态中发生变化,就算不一致。但真实场景下,状态变化可能是合理的(比如任务本来就要更新状态),所以需要设计状态转移图来判断“哪些变化是合法的”。这是一个可以深度优化的方向。
4.4 评测主流程
最后,我们用runner把任务数据、Agent、指标计算串起来:
# 文件路径:evaluator/runner.py import json from agent.dummy_agent import DummyAgent from evaluator.metrics import ( compute_goal_completion, compute_step_accuracy, compute_state_consistency, compute_final_score, ) TASK_TEMPLATE = { "task_id": "task_001", "task_type": "travel_planning", "description": "根据需求预订一次从杭州到深圳的三天出差行程", "goal": [ "确定出发日期和返程日期", "筛选性价比最高的航班", "预定距离客户公司 3 公里以内的酒店", "生成包含时间、地点、费用的行程表", ], "steps": [ {"step_id": 1, "description": "解析需求中的日期和地点", "check_type": "contains", "expected": ["深圳", "三天"]}, {"step_id": 2, "description": "搜索航班", "check_type": "tool_call", "expected_tool": "search_flight"}, {"step_id": 3, "description": "根据时间和价格选择航班", "check_type": "reasoning", "expected_keys": ["flight_no", "price"]}, {"step_id": 4, "description": "搜索酒店", "check_type": "tool_call", "expected_tool": "search_hotel"}, {"step_id": 5, "description": "生成行程表", "check_type": "final_report", "expected_keys": ["date", "flight", "hotel", "cost"]}, ], } def run_evaluation(agent_name="dummy", memory_steps=3): task = TASK_TEMPLATE agent = DummyAgent(name=agent_name, memory_steps=memory_steps) result = agent.run(task) goal_score, goal_detail = compute_goal_completion( result.get("final_output", {}), task.get("goal", []) ) step_score, step_detail = compute_step_accuracy( task.get("steps", []), result.get("steps", []) ) state_score = compute_state_consistency( result.get("states", []), memory_steps ) elapsed = agent.tracker.elapsed_seconds() score_summary = compute_final_score( goal_completion=goal_score, step_accuracy=step_score, state_consistency=state_score, memory_steps=memory_steps, elapsed=elapsed, ) report = { "task_id": task["task_id"], "task_type": task["task_type"], "agent_name": agent_name, "memory_steps": memory_steps, "scores": score_summary, "goal_detail": goal_detail, "step_detail": step_detail, "steps": result["steps"], "final_output": result["final_output"], } return report if __name__ == "__main__": report = run_evaluation(agent_name="dummy-3step-memory", memory_steps=3) print(json.dumps(report, ensure_ascii=False, indent=2))运行方式:
python -m evaluator.runner预期会输出一个包含总体得分、分项得分、步骤级明细的 JSON 报告。你可以修改memory_steps参数,观察记忆窗口大小对状态一致性和最终得分的影响。
4.5 接入真实模型时的改造点
如果你要把这个评测脚手架接入真实模型,核心改造点只有两个:
第一个是DummyAgent.run()。把它替换成真正的 Agent 循环,例如:
while not task_finished: observation = call_llm_with_memory(memory) action = parse_action(observation) result = execute_tool(action) memory.append({"action": action, "result": result}) tracker.record_step(...)第二个是goal_completion的判定逻辑。把简单的关键词匹配替换成“LLM 评判 + 规则校验”,例如让评测模型判断 Agent 的最终输出是否达到了目标描述中的每个验收点。
这样改造后,你就拥有了一套可用于真实模型对比的长时程任务评测框架。
5. 长时程任务失败的核心原因分析
有了评测框架,我们再回头看 27.3% 这个成绩单。为什么顶尖模型在面对长时程任务时表现这么差?我在实际评测和项目落地中的观察,原因可以分为下面四类。
5.1 上下文漂移导致“目标感丢失”
长时程任务往往有很长的中间过程。模型在开始阶段还能记住原始目标,但执行了十几步、交互了很多轮之后,注意力被中间细节分散,最终输出可能已经偏离原始需求。
我见过一个典型案例:任务是“整理一份关于智能客服系统的竞品分析报告”,Agent 开始时做得很好,但在检索竞品资料时被一篇技术方案吸引了注意力,最后生成的报告变成了一篇“客服系统技术架构设计”,虽然内容很完整,但和目标完全不符。
这种“目标感丢失”在评测中对应的就是目标完成度指标偏低。模型不是没能力做,而是“忘了自己要做什么”。
5.2 误差累积导致“一步错、步步错”
长时程任务中,早期步骤的错误会像滚雪球一样被放大。单步任务中,模型出错后影响是局部的;但多步任务中,一个中间环节的错误值会成为后续所有步骤的输入。
最典型的就是数值计算和代码生成场景:第一步取错了字段名,后面所有引用该字段的位置都会报错。虽然模型可能在最后报错时发现问题,但修复成本已经很高了。
这解释了为什么长时程评测中“步骤正确率”和“错误恢复能力”高度相关。只盯着最终结果是不够的,早期中间步骤的错误同样致命。
5.3 规划与复盘能力不足
长时程任务非常考验模型的“任务规划能力”和“自我复盘能力”。模型需要周期性地停下来问自己:
- 当前进度和计划是否一致?
- 哪些已完成,哪些待完成?
- 是否有更优路径?
- 当前状态和已知信息是否矛盾?
目前的模型在“规划”上有一定能力,但在“复盘”上非常薄弱。大多数模型都是一路执行到底,不会主动检查中间状态是否有异常。而人类员工在长时间工作时,会下意识地做进度检查和纠偏,这正是差距来源之一。
5.4 评测设计中的“冷启动”难题
另一个值得注意的问题是:长时程任务评测本身也有设计缺陷。很多评测集的数据是从少量人工任务扩充而来,任务类型不够多样;或者评测只关注最后结果,忽略了过程质量。
这会造成“评测分数和真实能力不完全对应”的情况。比如一个模型虽然完成了任务,但用了数倍于人类的步骤,按理说它不应该得到和高效率模型一样的分数,但如果评测不统计成本,就会高估模型能力。
所以 27.3% 这个数字,我个人倾向于理解为“在特定评测框架下模型与人类的综合差距”。不同评测设计下,这个数字会有波动,但方向是一致的:长时程能力是目前大模型最大的短板之一。
6. 常见问题与排查思路
在实际搭建长时程任务评测时,你可能会遇到一些典型问题。这里整理成排查清单:
| 问题现象 | 常见原因 | 解决思路 |
|---|---|---|
| 模型任务做到一半就“失忆” | 上下文长度不足或未做记忆持久化 | 引入外部向量库或记忆压缩摘要,将关键状态持久化到存储,而不是只依赖上下文窗口 |
| 评测分数很高,但实际部署效果差 | 评测只关注最终结果,不关注中间步骤 | 增加步骤正确率、状态一致性、错误恢复能力等过程指标 |
| 同一任务多次运行分数波动大 | 模型生成有随机性,评测任务步骤阈值设置不合理 | 增加多次运行的均值与方差统计,建议每个任务至少运行 3-5 次取平均 |
| 模型反复调用同一个失败工具 | 缺少错误恢复机制,模型无法从错误输出中学习 | 在 Agent 中加入异常分支处理逻辑,明确错误后的重试策略和回退策略 |
| 步骤数据难以自动校验 | 步骤类型设计得过于抽象 | 将步骤定义为可验证的原子操作,优先使用工具调用参数、SQL 结果、文件内容等客观数据进行校验 |
| 评测任务过少,结论不充分 | 单独一个任务类型不具备统计意义 | 至少准备 10 个以上跨类型任务,覆盖规划、检索、代码、对话、数据分析等场景 |
6.1 一个常见的评测实现错误
我见过很多刚开始做 Agent 评测的同学,会写出类似下面的代码:
# 错误示例:只统计步骤是否执行,不验证执行质量 def evaluate_steps(agent_result, expected_steps): passed = 0 for step in expected_steps: if step["step_id"] in [s["step_id"] for s in agent_result["steps"]]: passed += 1 return passed / len(expected_steps)这个逻辑的问题在于:只要 Agent “调用过”某个步骤就算通过,哪怕调用时传参完全错误。比如任务要求搜索“杭州到深圳”的航班,Agent 却搜索了“杭州到北京”,步骤 ID 一样,但结果完全没用。
正确的做法是校验步骤的输入参数和输出结果:
# 正确示例:验证步骤的工具调用参数 def evaluate_step_call(step, agent_step): expected_params = step.get("expected_params", {}) actual_params = agent_step.get("params", {}) for key, value in expected_params.items(): if actual_params.get(key) != value: return False return True这个问题的本质是:评测的粒度决定了评测的有效性。粒度太粗,评测就会失效;粒度太细,成本又太高。建议在真实项目中,对关键路径步骤做“参数级校验”,对非关键步骤做“存在性校验”。
7. 长时程 Agent 的工程优化方向
了解评测结果后,更重要的任务是做出改进。下面是我在长时程 Agent 工程化中比较推荐的几个方向,既有架构层面,也有评测层面。
7.1 把记忆从“上下文”搬到“外部存储”
第一个工程建议是:不要让模型只依赖上下文窗口承载长期记忆。
长时程任务中,上下文窗口即使足够长,也会面临信息冗余、注意力分散、成本上升等问题。更可靠的做法是:
- 把任务目标、已完成步骤、关键结果、当前待办事项,持久化到一个外部状态存储中;
- 每执行完一步,主动更新状态;
- 在模型决策前,从状态存储中构造一个“高信息密度的提示词”,而不是把完整历史全部丢给模型。
这种思路类似于人类工作时的“工作日志 + 任务面板”。评测框架中的StateTracker核心就是这种思想,只是生产环境需要换成 Redis、数据库或向量数据库。
7.2 任务分解与渐进式规划
长时程任务很难一步规划到底。我建议采用“渐进式规划”策略:
- 先只规划前 2-3 步;
- 执行完这 2-3 步后,基于新状态重新规划;
- 周期性检查整体目标是否偏移。
这和长时程评测中的“state_checkpoint”思想一致。在评测任务里设置状态检查点,目的就是强制 Agent 在执行过程中停下来对齐目标。工程落地时,建议在 Agent 框架中加入同样的检查点机制,每隔 N 步触发一次自我总结和目标对齐。
7.3 在线评测与回归能力
如果你在持续迭代 Agent 或模型,一定要建立“长时程评测回归机制”。每次改动后,不只跑几条常规 QA 数据,还需要跑一批长时程任务集。
我的经验是:单轮能力评测波动小,长时程能力评测波动大,因为长时程任务的每个分支都可能触发不同的失败模式。建立自动化回归后,你能快速发现某次改动是否让状态管理能力退化。
7.4 安全、成本与部署注意事项
长时程任务在生产环境落地时,还需要额外关注安全和成本问题:
- 最小权限原则:Agent 如果需要调用工具,尽量只授予完成当前任务所需的最小权限,避免长时间任务中权限被滥用;
- 人工确认点:涉及支付、删除、发送消息、修改数据库等敏感操作时,必须在流程中设置人工审批节点;
- 成本熔断:长时程任务可能消耗大量 Token,建议设置单任务成本上限,例如累计调用次数超过某个阈值就自动终止并人工介入;
- 审计日志:完整记录每一步的输入、输出、工具调用和状态变更,方便事后追查和评测复盘;
- 测试环境验证:任何 Agent 流程在生产环境执行前,先在测试任务集上完整跑通,尤其是失败分支和高负载场景。
8. 最佳实践与评测体系设计建议
最后,总结一下我在长时程 AI 任务评测方面的最佳实践建议,希望对你构建自己的评测体系有直接帮助。
第一,评测指标必须分层。不要只看一个总分,要把“最终目标完成度、步骤正确率、状态一致性、错误恢复能力、成本效率”分开统计。总分相同的两个模型,分项表现可能有很大差异。我见过一个模型总分很高,但靠的是“暴力重试最后侥幸成功”,这种模型并不适合长期稳定使用。
第二,评测任务要覆盖多种任务类型。长时程任务不能只测“旅行规划”或“代码生成”,至少应该覆盖:
- 信息收集与报告生成
- 多步骤工具调用
- 带异常注入的流程式任务
- 需要长期对话和记忆的客服场景
- 需要操作真实文件或数据库的任务
第三,引入人工标注基线。评测长时程任务时,建议对每类任务采集人类执行数据作为基线。只有对比人类基线,才能判断模型的绝对表现。27.3% 这个数字之所以有说服力,就是因为它有清晰的人类参照物。
第四,注意指标可信度。自动评分规则越简单越容易出现误判。建议对高分样本进行抽样人工复核,统计自动评分和人工评分的一致性。如果一致性低于 90%,说明评测指标需要重新设计。
第五,评测要支持可复现。记录模型版本、Prompt 版本、随机种子、运行时间、任务数据版本。长时程任务对随机性非常敏感,同一模型两次运行可能一次成功一次失败,没有版本信息的评测结果是不可信的。
9. 最后的建议
长时程 AI 任务评测这个方向,本质上是把 AI 能力从“答题能力”推向“工作能力”。27.3% 的成绩说明现在的大模型离“可靠员工”还有很大距离,但这个方向的价值也正在这里:只要评测标准明确、工程手段到位,我们是可以系统性提升模型的长时间任务能力的。
如果你现在正准备搭建自己的 Agent 应用,我的建议是先从上面的评测脚手架开始。不需要一上来就接入复杂框架,先把“状态跟踪→记忆管理→步骤校验→指标计算”这条链路跑通,再逐步加入真实模型调用。这样你就能清楚地看到,自己的 Agent 到底是在哪一步开始出错的——是记忆丢失、步骤错误、还是目标漂移。
希望这篇文章对你有帮助。你可以把示例代码保存下来,改造成自己的长时程任务评测工具,也欢迎在实际项目中验证这些方法和思路。