Unreal Agent 开源:不换模型,Agent 运行层也能显著降本

2026-09-23 27 预计阅读时间: 1 分钟
来源: oschina.net AI 摘要 Original link

Disclaimer: This article is an AI-assisted summary. Read it together with the original source when precision matters. The summary may omit context, version differences, or edge cases and is not official documentation.

预计阅读时间:11 分钟

Unreal Labs 开源了 Agent 运行框架 Unreal Agent。团队给出的核心结果很直接:在真实生产工作负载以及编程、科学类基准中,它相较 Codex 最多可节省 40% 成本,相较 Pi 最多节省 20%,同时没有性能下降。

这项发布值得关注的地方,不只是百分比本身,而是它把优化目标放在了 Agent 的运行层,也就是常说的 harness。模型决定能力上限,harness 则负责把任务、上下文、工具调用、失败重试和最终答案组织成一次完整执行。对于调用量较大的团队,这一层的工程决策会直接反映到 Token 账单、延迟和任务成功率上。

Harness 为什么会影响 Agent 成本

一个生产级 Agent 通常不是向模型发送一次提示词就结束。它可能经历多轮循环:

  1. 读取任务和项目上下文;
  2. 决定调用搜索、Shell、代码编辑器或其他工具;
  3. 获取工具输出并更新上下文;
  4. 检查结果,失败后重试;
  5. 生成最终回答或提交代码修改。

因此,一项任务的真实成本应当近似计算为:

总成本 = 所有模型调用成本
       + 工具与基础设施成本
       + 重试和失败执行成本
       + 人工复核成本

Harness 可以影响前面三项。例如,重复注入大段上下文会增加输入 Token;无效的工具调用会增加执行轮次;过于激进的重试策略则可能让一次失败变成多次昂贵失败。

不过,仅凭现有摘要无法确认 Unreal Agent 具体采用了哪些调度、上下文压缩、缓存或工具选择机制,因此不应把这些常见优化方式直接当成它已经实现的功能。现阶段可以确认的是:Unreal Labs 将成本效率作为该开源框架的核心指标,并报告了相对于 Codex 和 Pi 的对比结果。

“最多节省 40%”应该怎样理解

“最多”意味着结果依赖工作负载。编程任务、科学推理、仓库规模、工具数量和模型价格都可能改变最终数字。在评估这类声明时,至少要同时查看以下指标:

  • 任务成功率:是否真正完成了相同任务,而不是提前停止;
  • 每个成功任务的成本:失败任务也会消耗 Token,不能只比较单次调用价格;
  • 输入与输出 Token:用于判断节省来自哪里;
  • 模型和推理配置:不同模型、上下文长度与推理强度不能直接横向比较;
  • 工具调用次数:少调用不一定更好,关键是是否减少无效调用;
  • 端到端延迟:更便宜但慢数倍,未必适合交互式产品;
  • 结果质量与副作用:代码能通过测试,不代表修改范围、可维护性和安全性相同。

比“每百万 Token 价格”更有业务意义的指标是:

每个成功任务成本 = 全部任务总成本 / 成功任务数

假设方案 A 平均每次只花 0.20 美元,但成功率为 50%;方案 B 每次花 0.30 美元,成功率为 90%。计算后,A 的每个成功任务成本为 0.40 美元,B 约为 0.33 美元。单次运行更贵的方案,反而可能是更经济的生产选择。

可以这样实践:用自己的任务集核算 Agent 成本

在接入 Unreal Agent 或任何新 harness 之前,建议先建立一个与框架无关的评测文件。下面的脚本只使用 Python 标准库,可以汇总多个 Agent 的成功率、平均延迟和每个成功任务成本。

这里做了一个明确假设:每次运行都能导出为一行 JSON,并包含 agentsuccessinput_tokensoutput_tokenslatency_seconds。实际接入时,需要把 Unreal Agent 或现有框架的运行日志转换成该格式。

先创建示例数据:

cat > runs.jsonl <<'EOF'
{"agent":"current","success":true,"input_tokens":12000,"output_tokens":2200,"latency_seconds":48.2}
{"agent":"current","success":false,"input_tokens":18000,"output_tokens":3100,"latency_seconds":71.5}
{"agent":"unreal","success":true,"input_tokens":9000,"output_tokens":1800,"latency_seconds":42.0}
{"agent":"unreal","success":true,"input_tokens":10500,"output_tokens":1900,"latency_seconds":45.7}
EOF

再保存评测脚本:

#!/usr/bin/env python3
import argparse
import json
from collections import defaultdict


def main():
    parser = argparse.ArgumentParser()
    parser.add_argument("file", help="JSONL file containing agent runs")
    parser.add_argument("--input-price", type=float, required=True,
                        help="USD per 1M input tokens")
    parser.add_argument("--output-price", type=float, required=True,
                        help="USD per 1M output tokens")
    args = parser.parse_args()

    stats = defaultdict(lambda: {
        "runs": 0,
        "successes": 0,
        "input_tokens": 0,
        "output_tokens": 0,
        "latency": 0.0,
        "cost": 0.0,
    })

    with open(args.file, "r", encoding="utf-8") as handle:
        for line_number, line in enumerate(handle, 1):
            if not line.strip():
                continue
            row = json.loads(line)
            agent = row["agent"]
            input_tokens = int(row["input_tokens"])
            output_tokens = int(row["output_tokens"])

            cost = (
                input_tokens * args.input_price / 1_000_000
                + output_tokens * args.output_price / 1_000_000
            )

            item = stats[agent]
            item["runs"] += 1
            item["successes"] += int(bool(row["success"]))
            item["input_tokens"] += input_tokens
            item["output_tokens"] += output_tokens
            item["latency"] += float(row["latency_seconds"])
            item["cost"] += cost

    print(
        f"{'agent':<16} {'success':>9} {'total_usd':>12} "
        f"{'usd/success':>13} {'avg_latency':>13}"
    )
    for agent, item in sorted(stats.items()):
        success_rate = item["successes"] / item["runs"]
        cost_per_success = (
            item["cost"] / item["successes"]
            if item["successes"] else float("inf")
        )
        average_latency = item["latency"] / item["runs"]
        print(
            f"{agent:<16} {success_rate:>8.1%} {item['cost']:>12.4f} "
            f"{cost_per_success:>13.4f} {average_latency:>12.1f}s"
        )


if __name__ == "__main__":
    main()

运行时,把价格改成你实际使用模型的输入、输出 Token 单价:

python3 evaluate_agents.py runs.jsonl \
  --input-price 3.00 \
  --output-price 15.00

如果两个 Agent 使用不同模型或不同价格,不要强行套用同一组参数。更稳妥的做法是在每条记录中额外保存 input_priceoutput_price,按运行逐条计算。生产评测还应记录缓存命中 Token、工具费用、超时、重试次数和人工复核时间。

不要只在公开基准上做决定

Coding 和 science benchmark 能提供统一比较基础,但企业工作负载通常包含更多噪声:不完整的需求、私有代码库、陈旧文档、权限失败、长时间运行的测试,以及不能暴露给外部服务的数据。

一个更可信的试点可以这样设计:

  • 从历史任务中抽取 50 至 200 个具有代表性的样本;
  • 固定模型版本、系统提示词、工具权限和最大执行时间;
  • 对不同 harness 使用同一初始环境;
  • 每项任务重复运行多次,减少随机性影响;
  • 由不知道实验分组的工程师审核结果;
  • 同时统计成功率、成本、P50/P95 延迟和危险操作次数。

对于代码 Agent,还应在隔离容器中执行,并限制网络、密钥和文件系统权限。开源并不自动等于安全,运行框架通常能调用 Shell、修改文件甚至访问部署环境,权限边界比模型选择更值得优先审查。

是否值得采用:先验证,再替换

Unreal Agent 的吸引力在于,它将“运行同样能力需要多少钱”放到了与模型质量同等重要的位置。其背后的团队成员拥有 CERN、Meta、Snap、Bloomberg 和 DeepMind 等机构经历,公司也获得了 Sequoia 与 First Round 的投资,但团队背景和融资并不能替代工程验证。

准备试用时,可以按下面的清单推进:

  • 确认开源许可证是否符合公司政策;
  • 检查支持的模型、工具协议和部署方式;
  • 验证日志中是否会保存源码、提示词或密钥;
  • 用内部任务计算每个成功任务的真实成本;
  • 对比质量、延迟和成本,而不是只看 Token 数;
  • 从只读、低权限任务开始,再逐步开放写入和执行能力;
  • 保留现有 harness 作为回退路径。

如果 Unreal Agent 在你的工作负载上也能维持质量并降低 20% 至 40% 的成本,它会是一项非常实际的基础设施优化。但在复现数据之前,更合理的定位是:把它作为值得进入内部基准测试的新候选,而不是仅凭公开百分比立即替换生产系统。


相关推荐