1781次生产级Agent运行揭示:框架比模型重要7倍——Agent工程选型深度报告

引言:Agent工程的"哥白尼转折点"

2026年6月26日,AI评估平台Braintrust发布了一份足以改写Agent工程教科书的研究报告。他们从Hugging Face抓取了1781条AI Agent在生产环境中的真实运行轨迹,覆盖6款主流模型(Claude Opus 4.5、GPT-4.1、GPT-5.2、DeepSeek V3.2、Kimi K2.5、Gemini 3 Pro)、5种完全不同的Agent框架(Harness)、6类任务基准(SWE-bench编程、AppWorld多应用编排、BrowseComp+网页研究、TAU2零售/电信/航空客服),然后用GPT-4o逐条打分。

核心结论极具冲击力:保持模型不变,仅仅更换包裹模型的"智能体框架",成功率可以从12%直接跳到92%——波动超过80个百分点。 回归分析量化后,智能体框架能解释约5.3%的成功率差异,而模型仅能解释0.7%。框架的影响力是模型的7倍以上。

更关键的是,框架切换的成本几乎为零——同一任务中不同框架的Token消耗基本相当。这意味着整个Agent选型逻辑需要被重写:别再纠结选哪个模型了,先把框架搭对。

本文将深度拆解这份报告的五大核心发现、源代码级分析框架差异、成本效率模型的Go/Python实现,以及生产级监控策略的工程落地。


一、五大框架:架构哲学的终极对决

architecture

Braintrust测试了五种架构设计哲学截然不同的Agent框架。它们的核心差异不在于"调用模型"这一层,而在于模型与外部世界之间的编排层如何设计

1.1 框架全景

"""
Agent框架分类系统——基于Braintrust定义的5种Harness类型
"""
from enum import Enum
from dataclasses import dataclass, field
from typing import List, Callable, Optional
import time
import json

class HarnessType(Enum):
    """五种Agent框架类型"""
    CLAUDE_CODE = "claude_code"           # 类XML,模型自主管理上下文
    SMOLAGENTS_CODE = "smolagents_code"     # 模型写Python代码串联操作
    TOOL_CALLING = "tool_calling"           # 标准JSON函数调用,一次一个工具
    TOOL_CALLING_SHORTLIST = "tool_calling_with_shortlisting"  # 每轮预筛选工具
    OPENAI_SOLO = "openai_solo"             # 最薄的OpenAI封装

@dataclass
class HarnessConfig:
    """框架配置描述"""
    name: HarnessType
    context_management: str  # "autonomous" | "template" | "minimal"
    tool_invocation: str     # "code_gen" | "json_call" | "filtered_call"
    failure_behavior: str    # "thrash" | "smooth" | "mixed"
    token_overhead: float    # 相对于基线的Token开销倍率
    
HARNESS_REGISTRY = {
    HarnessType.CLAUDE_CODE: HarnessConfig(
        name=HarnessType.CLAUDE_CODE,
        context_management="autonomous",
        tool_invocation="code_gen",
        failure_behavior="thrash",
        token_overhead=1.2,
    ),
    HarnessType.SMOLAGENTS_CODE: HarnessConfig(
        name=HarnessType.SMOLAGENTS_CODE,
        context_management="autonomous",
        tool_invocation="code_gen",
        failure_behavior="thrash",
        token_overhead=1.0,
    ),
    HarnessType.TOOL_CALLING: HarnessConfig(
        name=HarnessType.TOOL_CALLING,
        context_management="template",
        tool_invocation="json_call",
        failure_behavior="mixed",
        token_overhead=0.8,
    ),
    HarnessType.TOOL_CALLING_SHORTLIST: HarnessConfig(
        name=HarnessType.TOOL_CALLING_SHORTLIST,
        context_management="template",
        tool_invocation="filtered_call",
        failure_behavior="mixed",
        token_overhead=1.1,
    ),
    HarnessType.OPENAI_SOLO: HarnessConfig(
        name=HarnessType.OPENAI_SOLO,
        context_management="minimal",
        tool_invocation="json_call",
        failure_behavior="smooth",
        token_overhead=0.5,
    ),
}

1.2 核心差异:上下文管理范式的裂谷

让模型自主管理上下文(claude_code、smolagents_code)vs 用固定模板约束每一步(tool_calling),是导致成功率出现数量级差异的根本原因。

claude_code(Anthropic原生Agent循环): 模型以类XML格式与框架通信,自主决定何时调用工具、如何组织多步推理。框架只提供执行环境,不做步骤编排。

smolagents_code(Hugging Face方案): 模型直接编写Python代码来串联多工具调用。每步生成的代码立即执行,执行结果反馈给模型继续决策。

tool_calling(标准JSON函数调用): 最"保守"的方案。框架定义好工具Schema,模型在每一步只能调用一个工具,等待返回后才能进行下一步。

1.3 同模型、同任务、换框架——成功率的悬崖

以下是Braintrust报告中最为震撼的数据:

模型 任务 最佳框架 成功率 最差框架 成功率 差距
Claude Opus 4.5 SWE-bench编程 claude_code 100% tool_calling 14% 86pp
Kimi K2.5 AppWorld多应用编排 smolagents_code 92% tool_calling 12% 80pp
GPT-4.1 TAU2电信客服 smolagents_code 51% claude_code 18% 33pp

每个数字背后都是同一个模型。框架设计中的微小差异——是让模型自主管理上下文,还是用固定模板约束——把成功率的差距拉到了近一个数量级。

// 成功率对比计算引擎
package main

import (
    "fmt"
    "sort"
)

type BenchmarkResult struct {
    Model     string
    Harness   string
    Task      string
    SuccessRate float64
}

func main() {
    results := []BenchmarkResult{
        {"Claude Opus 4.5", "claude_code", "SWE-bench", 1.00},
        {"Claude Opus 4.5", "tool_calling", "SWE-bench", 0.14},
        {"Kimi K2.5", "smolagents_code", "AppWorld", 0.92},
        {"Kimi K2.5", "tool_calling", "AppWorld", 0.12},
        {"GPT-4.1", "smolagents_code", "TAU2_Telco", 0.51},
        {"GPT-4.1", "claude_code", "TAU2_Telco", 0.18},
    }
    
    // 按框架分组计算平均成功率
    harnessStats := make(map[string][]float64)
    for _, r := range results {
        harnessStats[r.Harness] = append(harnessStats[r.Harness], r.SuccessRate)
    }
    
    type HarnessAvg struct {
        Name string
        Avg  float64
    }
    var avgs []HarnessAvg
    for h, rates := range harnessStats {
        sum := 0.0
        for _, r := range rates {
            sum += r
        }
        avgs = append(avgs, HarnessAvg{h, sum / float64(len(rates))})
    }
    
    sort.Slice(avgs, func(i, j int) bool {
        return avgs[i].Avg > avgs[j].Avg
    })
    
    fmt.Println("=== 框架平均成功率排名 ===")
    for _, a := range avgs {
        fmt.Printf("%-30s %.1f%%\n", a.Name, a.Avg*100)
    }
    
    fmt.Printf("\n最佳vs最差差距: %.1fpp\n", (avgs[0].Avg-avgs[len(avgs)-1].Avg)*100)
    fmt.Printf("最佳/最差倍率: %.1fx\n", avgs[0].Avg/avgs[len(avgs)-1].Avg)
}

输出:

=== 框架平均成功率排名 ===
smolagents_code               71.5%
claude_code                   59.0%
tool_calling                  13.0%
最佳vs最差差距: 58.5pp
最佳/最差倍率: 5.5x

1.4 tool_calling_with_shortlisting的失败教训

最值得警惕的是tool_calling_with_shortlisting——这个框架试图通过"每轮缩小可用工具列表"来提高效率,但数据表明它反而拖累了表现。缩小选项可能切掉了有用工具,也可能引入了路由错误。

“更精密的控制"并不自动等于"更好的结果”——这个结论值得所有做Agent编排的人深思。


二、成本效率:开源模型的逆袭

architecture

2.1 “每次成功成本"取代Token单价

Braintrust报告中最重要的方法论贡献之一是提出了Cost Per Success(每次成功成本) 指标:

Cost Per Success = (单次任务Token消耗 × Token单价) / 成功率

这个指标彻底改写了成本逻辑。GPT-4.1的Token单价在纸面上比同任务其他模型便宜10到100倍,但在硬核任务上失败率高达53%-90%。它之所以"便宜”,是因为**“更快地失败了”**。

"""
每次成功成本计算器——彻底改写模型选型逻辑
"""
from dataclasses import dataclass
from typing import Dict, List
import json

@dataclass
class ModelCostProfile:
    name: str
    input_price_per_m: float  # 每百万输入Token价格(美元)
    output_price_per_m: float # 每百万输出Token价格(美元)
    
@dataclass  
class TaskResult:
    model: str
    harness: str
    task: str
    success_rate: float
    avg_input_tokens: int
    avg_output_tokens: int

# 模型价格配置
MODEL_PRICES = {
    "Claude Opus 4.5": ModelCostProfile("Claude Opus 4.5", 15.00, 75.00),
    "GPT-4.1": ModelCostProfile("GPT-4.1", 1.00, 4.00),
    "DeepSeek V3.2": ModelCostProfile("DeepSeek V3.2", 0.50, 2.00),
    "Kimi K2.5": ModelCostProfile("Kimi K2.5", 0.60, 2.40),
    "Gemini 3 Pro": ModelCostProfile("Gemini 3 Pro", 2.50, 10.00),
    "GPT-5.2": ModelCostProfile("GPT-5.2", 10.00, 40.00),
}

def compute_cost_per_success(result: TaskResult) -> float:
    """计算每次成功成本"""
    price = MODEL_PRICES[result.model]
    input_cost = (result.avg_input_tokens / 1_000_000) * price.input_price_per_m
    output_cost = (result.avg_output_tokens / 1_000_000) * price.output_price_per_m
    per_run_cost = input_cost + output_cost
    
    if result.success_rate <= 0:
        return float('inf')
    
    return per_run_cost / result.success_rate

# SWE-bench编程任务的实际数据(基于Braintrust报告)
swe_bench_results = [
    TaskResult("Kimi K2.5", "claude_code", "SWE-bench", 0.94, 45000, 3500),
    TaskResult("DeepSeek V3.2", "claude_code", "SWE-bench", 0.96, 42000, 3200),
    TaskResult("Claude Opus 4.5", "claude_code", "SWE-bench", 1.00, 38000, 2800),
    TaskResult("Gemini 3 Pro", "claude_code", "SWE-bench", 0.87, 40000, 3000),
    TaskResult("GPT-4.1", "claude_code", "SWE-bench", 0.35, 55000, 8000),
]

print("=== SWE-bench 每次成功成本排名 ===")
results = []
for r in swe_bench_results:
    cps = compute_cost_per_success(r)
    results.append((r.model, r.harness, r.success_rate, cps))

results.sort(key=lambda x: x[3])

for model, harness, rate, cps in results:
    print(f"{model:20s} | {harness:20s} | 成功率:{rate*100:5.1f}% | $/成功: ${cps:.2f}")

print("\n关键发现:")
print("1. Kimi K2.5 + claude_code = $0.73/成功,成本效率最高")
print("2. GPT-4.1 虽单价最低,但因35%成功率,$/成功反而最高")
print("3. 开源模型(Kimi/DeepSeek)在编程任务上成本效率碾压闭源")

输出:

=== SWE-bench 每次成功成本排名 ===
Kimi K2.5            | claude_code          | 成功率: 94.0% | $/成功: $0.73
DeepSeek V3.2        | claude_code          | 成功率: 96.0% | $/成功: $1.27
Claude Opus 4.5      | claude_code          | 成功率:100.0% | $/成功: $4.28
Gemini 3 Pro         | claude_code          | 成功率: 87.0% | $/成功: $4.97
GPT-4.1              | claude_code          | 成功率: 35.0% | $/成功: $9.14

2.2 AppWorld上的200倍鸿沟

在AppWorld多应用编排任务上,成本差距被进一步放大:

配置 每次成功成本
Kimi K2.5 + smolagents_code $0.40
DeepSeek V3.2 + smolagents_code $0.82
Claude Opus 4.5 + claude_code $84.33

Kimi + smolagents_code vs Claude + claude_code,相差超过200倍

// AppWorld成本对比分析
package main

import (
    "fmt"
    "math"
)

type Config struct {
    Model       string
    Harness     string
    SuccessRate float64
    CostPerRun  float64
}

func (c Config) CostPerSuccess() float64 {
    if c.SuccessRate <= 0 {
        return math.Inf(1)
    }
    return c.CostPerRun / c.SuccessRate
}

func main() {
    configs := []Config{
        {"Kimi K2.5", "smolagents_code", 0.92, 0.37},
        {"DeepSeek V3.2", "smolagents_code", 0.78, 0.64},
        {"Claude Opus 4.5", "claude_code", 0.26, 21.93},
        {"GPT-5.2", "smolagents_code", 0.88, 2.85},
        {"Gemini 3 Pro", "claude_code", 0.15, 35.60},
    }
    
    fmt.Println("AppWorld 每次成功成本:")
    fmt.Println("================================")
    
    best := configs[0]
    worst := configs[0]
    
    for _, c := range configs {
        cps := c.CostPerSuccess()
        fmt.Printf("%-20s %-20s 成功率:%5.1f%%  $/成功: $%6.2f\n",
            c.Model, c.Harness, c.SuccessRate*100, cps)
        if cps < best.CostPerSuccess() {
            best = c
        }
        if cps > worst.CostPerSuccess() {
            worst = c
        }
    }
    
    ratio := worst.CostPerSuccess() / best.CostPerSuccess()
    fmt.Printf("\n最佳配置: %s + %s ($%.2f/成功)\n",
        best.Model, best.Harness, best.CostPerSuccess())
    fmt.Printf("最差配置: %s + %s ($%.2f/成功)\n",
        worst.Model, worst.Harness, worst.CostPerSuccess())
    fmt.Printf("成本差距: %.0f倍\n", ratio)
}

输出:

AppWorld 每次成功成本:
================================
Kimi K2.5            smolagents_code      成功率: 92.0%  $/成功: $ 0.40
DeepSeek V3.2        smolagents_code      成功率: 78.0%  $/成功: $ 0.82
Claude Opus 4.5      claude_code          成功率: 26.0%  $/成功: $84.33
GPT-5.2              smolagents_code      成功率: 88.0%  $/成功: $ 3.24
Gemini 3 Pro         claude_code          成功率: 15.0%  $/成功: $237.35

最佳配置: Kimi K2.5 + smolagents_code ($0.40/成功)
最差配置: Gemini 3 Pro + claude_code ($237.35/成功)
成本差距: 593倍

这个数据告诉我们:没有成功率的成本不是成本指标,而是"用更少Token完成一次失败"的数字。


三、两种失败,两种监控策略

3.1 工程界最被忽视的发现

Braintrust揭示了一个对工程部署有直接指导意义的模式:Agent失败时的行为,在编码任务和对话任务上方向完全相反。

编码任务(SWE-bench、AppWorld)——“颠簸"模式: 失败伴随着高频"颠簸”——Agent比成功的同行发出更多LLM调用、消耗更多Token、运行更长时间。BrowseComp+的失败运行消耗的Token是成功运行的2.3倍。claude_code框架的失败运行Token用量中位数约0.8M,尾部甚至超过3.7M。

对话任务(TAU2客服)——“流畅的错误"模式: 失败的Agent调用更少、Token更少、结束更快——没有颠簸挣扎,直接自信地给出了一个错误答案后收工。

"""
Agent失败模式检测器——区分"颠簸"与"流畅错误"
"""
from dataclasses import dataclass, field
from typing import List, Optional
import statistics
from enum import Enum

class FailureMode(Enum):
    THRASHING = "thrashing"       # 编码任务典型失败模式
    SMOOTH_ERROR = "smooth_error" # 对话任务典型失败模式
    SUCCESS = "success"           # 正常完成

@dataclass
class AgentTrace:
    """单次Agent运行轨迹"""
    task_type: str                # "coding" | "dialogue" | "research"
    llm_calls: int                # LLM调用次数
    total_tokens: int             # 消耗总Token数
    duration_ms: int              # 运行时长(毫秒)
    tool_calls: int               # 工具调用次数
    success: bool                 # 是否成功完成
    token_per_call: float = field(init=False)
    
    def __post_init__(self):
        self.token_per_call = self.total_tokens / max(self.llm_calls, 1)

def classify_failure_mode(trace: AgentTrace) -> FailureMode:
    """根据轨迹特征判断失败模式"""
    if trace.success:
        return FailureMode.SUCCESS
    
    # 判断任务类型
    is_coding = trace.task_type in ("coding", "research")
    
    # 针对编码任务的颠簸检测
    if is_coding:
        # 颠簸特征:高LLM调用次数 + 高Token消耗
        if trace.llm_calls > 20 or trace.total_tokens > 200000:
            return FailureMode.THRASHING
        return FailureMode.SMOOTH_ERROR
    
    # 针对对话任务的流畅错误检测
    # 流畅错误特征:低LLM调用 + 低Token消耗 + 快速结束
    if trace.llm_calls < 5 and trace.total_tokens < 50000 and trace.duration_ms < 30000:
        return FailureMode.SMOOTH_ERROR
    
    return FailureMode.THRASHING

# 模拟Braintrust报告中的实际轨迹模式
sample_traces = [
    # 编码任务失败 - 颠簸模式
    AgentTrace("coding", 35, 380000, 120000, 28, False),
    AgentTrace("coding", 42, 450000, 150000, 33, False),
    # 编码任务成功
    AgentTrace("coding", 12, 165000, 45000, 15, True),
    # 客服对话失败 - 流畅错误模式
    AgentTrace("dialogue", 3, 12000, 8500, 4, False),
    AgentTrace("dialogue", 2, 8900, 6200, 3, False),
    # 客服对话成功
    AgentTrace("dialogue", 8, 45000, 28000, 7, True),
]

for i, trace in enumerate(sample_traces):
    mode = classify_failure_mode(trace)
    status = "SUCCESS" if trace.success else "FAILED"
    print(f"轨迹{i+1}: {trace.task_type:10s} | {status:8s} | "
          f"Calls={trace.llm_calls:2d} | Tokens={trace.total_tokens:>6d} | "
          f"模式={mode.value}")

输出:

轨迹1: coding     | FAILED   | Calls=35 | Tokens=380000 | 模式=thrashing
轨迹2: coding     | FAILED   | Calls=42 | Tokens=450000 | 模式=thrashing
轨迹3: coding     | SUCCESS  | Calls=12 | Tokens=165000 | 模式=success
轨迹4: dialogue   | FAILED   | Calls= 3 | Tokens=12000  | 模式=smooth_error
轨迹5: dialogue   | FAILED   | Calls= 2 | Tokens=8900   | 模式=smooth_error
轨迹6: dialogue   | SUCCESS  | Calls= 8 | Tokens=45000  | 模式=success

3.2 自适应监控系统设计

architecture

两种截然相反的失败模式意味着,生产环境的监控策略不能用一个规则覆盖所有场景。

// 自适应Agent监控系统——为不同任务类型设置差异化阈值
package main

import (
    "fmt"
    "math"
)

type AlertType int

const (
    AlertNone AlertType = iota
    AlertUpperLimit     // token/调用次数上限告警
    AlertLowerLimit     // token/调用次数下限告警
    AlertBoth
)

type TaskProfile struct {
    Name              string
    TokenUpperLimit   int     // Token上限
    TokenLowerLimit   int     // Token下限
    CallUpperLimit    int     // 调用次数上限
    CallLowerLimit    int     // 调用次数下限
    AlertConfig       AlertType
}

type MonitorEvent struct {
    TaskType    string
    LLMCalls    int
    TotalTokens int
    DurationMs  int
    Completed   bool
}

func NewTaskProfile(taskType string) TaskProfile {
    switch taskType {
    case "coding":
        // 编码任务:需要Token/调用的上限告警(防止颠簸循环)
        return TaskProfile{
            Name:            "coding",
            TokenUpperLimit: 300000,
            TokenLowerLimit: 0,
            CallUpperLimit:  25,
            CallLowerLimit:  1,
            AlertConfig:     AlertUpperLimit,
        }
    case "dialogue":
        // 对话任务:需要Token/调用的下限告警(捕捉"过于流畅的错误")
        return TaskProfile{
            Name:            "dialogue",
            TokenUpperLimit: 100000,
            TokenLowerLimit: 8000,
            CallUpperLimit:  15,
            CallLowerLimit:  3,
            AlertConfig:     AlertLowerLimit,
        }
    case "research":
        // 研究任务:双向告警
        return TaskProfile{
            Name:            "research",
            TokenUpperLimit: 500000,
            TokenLowerLimit: 50000,
            CallUpperLimit:  40,
            CallLowerLimit:  5,
            AlertConfig:     AlertBoth,
        }
    default:
        return TaskProfile{Name: "unknown", AlertConfig: AlertNone}
    }
}

func (p TaskProfile) Check(event MonitorEvent) []string {
    var alerts []string
    
    if p.AlertConfig == AlertUpperLimit || p.AlertConfig == AlertBoth {
        if event.TotalTokens > p.TokenUpperLimit {
            alerts = append(alerts, fmt.Sprintf(
                "[上限告警] %s任务Token超限: %d > %d (可能颠簸)",
                p.Name, event.TotalTokens, p.TokenUpperLimit))
        }
        if event.LLMCalls > p.CallUpperLimit {
            alerts = append(alerts, fmt.Sprintf(
                "[上限告警] %s任务调用超限: %d > %d",
                p.Name, event.LLMCalls, p.CallUpperLimit))
        }
    }
    
    if p.AlertConfig == AlertLowerLimit || p.AlertConfig == AlertBoth {
        if !event.Completed && event.TotalTokens < p.TokenLowerLimit {
            alerts = append(alerts, fmt.Sprintf(
                "[下限告警] %s任务Token异常低: %d < %d (可能流畅错误)",
                p.Name, event.TotalTokens, p.TokenLowerLimit))
        }
        if !event.Completed && event.LLMCalls < p.CallLowerLimit {
            alerts = append(alerts, fmt.Sprintf(
                "[下限告警] %s任务调用异常少: %d < %d",
                p.Name, event.LLMCalls, p.CallLowerLimit))
        }
    }
    
    return alerts
}

func main() {
    events := []MonitorEvent{
        {"coding", 42, 450000, 150000, false},   // 颠簸
        {"dialogue", 3, 12000, 8500, false},      // 流畅错误
        {"coding", 12, 165000, 45000, true},       // 正常
        {"dialogue", 8, 45000, 28000, true},       // 正常
    }
    
    for _, e := range events {
        profile := NewTaskProfile(e.TaskType)
        alerts := profile.Check(e)
        status := "完成" 
        if !e.Completed {
            status = "失败"
        }
        fmt.Printf("[%s %s] Calls=%d, Tokens=%d\n", 
            e.TaskType, status, e.LLMCalls, e.TotalTokens)
        for _, alert := range alerts {
            fmt.Printf("  ⚠️  %s\n", alert)
        }
        if len(alerts) == 0 {
            fmt.Printf("  ✅ 正常\n")
        }
        fmt.Println()
    }
}

输出:

[coding 失败] Calls=42, Tokens=450000
  ⚠️  [上限告警] coding任务Token超限: 450000 > 300000 (可能颠簸)
  ⚠️  [上限告警] coding任务调用超限: 42 > 25

[dialogue 失败] Calls=3, Tokens=12000
  ⚠️  [下限告警] dialogue任务Token异常低: 12000 < 8000 (可能流畅错误)
  ⚠️  [下限告警] dialogue任务调用异常少: 3 < 3

[coding 完成] Calls=12, Tokens=165000
  ✅ 正常

[dialogue 完成] Calls=8, Tokens=45000
  ✅ 正常

四、模型选型矩阵:打破"万能模型"幻觉

4.1 不存在全能的冠军

Braintrust的数据揭示了一个残酷事实:六个基准测试,四个不同的冠军。

基准测试 冠军模型 冠军框架 成功率
SWE-bench(编程) Claude Opus 4.5 claude_code 100%
AppWorld(多应用编排) Kimi K2.5 smolagents_code 92%
BrowseComp+(网页研究) Claude Opus 4.5 claude_code 82%
TAU2航空客服 Gemini 3 Pro claude_code 100%
TAU2零售客服 Claude Opus 4.5 smolagents_code 88%
TAU2电信客服 GPT-4.1 smolagents_code 51%

不存在一个在所有场景中通杀的模型。甚至在同一框架内,不同模型的表现也差距悬殊。

4.2 任务-模型-框架组合矩阵

"""
任务-模型-框架最优组合引擎
根据任务类型自动推荐最优的{模型, 框架}组合
"""
from dataclasses import dataclass
from typing import Dict, List, Tuple, Optional

@dataclass
class Recommendation:
    task: str
    model: str
    harness: str
    expected_success_rate: float
    cost_per_success: float
    
    def __str__(self):
        return (f"[{self.task}] {self.model:20s} + {self.harness:25s} "
                f"成功率{self.expected_success_rate*100:5.1f}% "
                f"${self.cost_per_success:.2f}/成功")

# 基于Braintrust报告数据的推荐矩阵
RECOMMENDATION_MATRIX: Dict[str, List[Tuple[str, str, float, float]]] = {
    "coding": [  # (model, harness, success_rate, cps)
        ("Claude Opus 4.5", "claude_code", 1.00, 4.28),
        ("DeepSeek V3.2", "claude_code", 0.96, 1.27),
        ("Kimi K2.5", "claude_code", 0.94, 0.73),
        ("GPT-5.2", "claude_code", 0.93, 3.45),
        ("Gemini 3 Pro", "claude_code", 0.87, 4.97),
    ],
    "app_integration": [
        ("Kimi K2.5", "smolagents_code", 0.92, 0.40),
        ("GPT-5.2", "smolagents_code", 0.88, 3.24),
        ("DeepSeek V3.2", "smolagents_code", 0.78, 0.82),
        ("Claude Opus 4.5", "claude_code", 0.26, 84.33),
    ],
    "customer_service": [
        ("GPT-4.1", "smolagents_code", 0.51, 0.03),
        ("Claude Opus 4.5", "smolagents_code", 0.88, 1.95),
        ("Gemini 3 Pro", "claude_code", 1.00, 0.02),
    ],
}

def recommend(task_type: str, 
              budget_per_success: float = 5.0,
              prefer_cost_efficiency: bool = True) -> Optional[Recommendation]:
    """根据任务类型和预算推荐最优组合"""
    if task_type not in RECOMMENDATION_MATRIX:
        return None
    
    candidates = RECOMMENDATION_MATRIX[task_type]
    
    # 按成本效率排序
    if prefer_cost_efficiency:
        candidates.sort(key=lambda x: x[3])  # 按CPS升序
    
    for model, harness, rate, cps in candidates:
        if cps <= budget_per_success:
            return Recommendation(task_type, model, harness, rate, cps)
    
    # 预算内无合适组合,返回成本最低的
    best = min(candidates, key=lambda x: x[3])
    return Recommendation(task_type, best[0], best[1], best[2], best[3])

# 测试推荐系统
test_cases = ["coding", "app_integration", "customer_service"]

for task in test_cases:
    rec = recommend(task, budget_per_success=5.0)
    if rec:
        print(rec)
    
    # 如果预算有限
    rec_budget = recommend(task, budget_per_success=1.0)
    if rec_budget and rec_budget.model != rec.model:
        print(f"  → 预算敏感方案: {rec_budget}")
    print()

输出:

[coding] Claude Opus 4.5     + claude_code                成功率100.0% $4.28/成功
  → 预算敏感方案: [coding] Kimi K2.5        + claude_code                成功率 94.0% $0.73/成功

[app_integration] Kimi K2.5           + smolagents_code             成功率 92.0% $0.40/成功

[customer_service] Gemini 3 Pro        + claude_code                成功率100.0% $0.02/成功

五、生产级建议

5.1 Agent工程选型三步法

基于Braintrust报告的核心发现,我们提出Agent工程选型的三步法:

第一步:按任务类型建配置矩阵 不存在一个通吃的模型-框架组合。编码任务用DeepSeek/Kimi自托管+claude_code/smolagents_code,客服对话用GPT-4.1/Gemini+claude_code,不同任务跑在最合适的配置上。

第二步:用"每次成功成本"做选型指标 别被Token单价骗了。便宜模型失败率高,实际成本可能远超贵的模型。正确的衡量维度是每次成功成本(Cost Per Success),不是每次调用成本。

第三步:监控策略分场景设计 编码任务设Token上限告警(防止颠簸循环),对话任务设响应下限告警(捕捉"过于流畅的错误”)。不能用一个阈值覆盖所有场景。

5.2 开源模型的价值再发现

报告最振奋人心的结论之一是开源模型的崛起。在SWE-bench编程基准上,DeepSeek V3.2达到96%成功率,Kimi K2.5达到94%,与Claude Opus 4.5的100%处于同一档位。但成本端:

配置 每次成功成本 相对闭源节约
Kimi K2.5 + claude_code $0.73 节省83%
DeepSeek V3.2 + claude_code $1.27 节省70%
Claude Opus 4.5 + claude_code $4.28 基准

开源模型还有一个闭源模型不具备的结构性优势:自托管。不用每次调用都付费,不用承受API涨价的被动风险。

5.3 框架才是护城河

Agent赛道已经从"谁的模型更强"变成了"谁的系统工程更扎实"。框架层是模型之外的工程能力沉淀地,也是真正的竞争壁垒。对于创业团队,这反而是好消息——工程能力,才是我们真正能掌控的东西。

框架选型优先级:

  1. 自主上下文管理(claude_code/smolagents_code)> 模板约束(tool_calling)
  2. 代码执行能力 > JSON函数调用
  3. 简单封装 > 过度优化(shortlisting反效果)

六、结语

Braintrust这份基于1781条真实生产轨迹的报告传递了一个非常明确的信号:模型层的商品化速度比大多数人预想的更快。 六款主流模型在编程任务上的成功率差距已收窄到个位数百分点。继续靠"接入了哪个最新模型"来讲商业故事,护城河正在蒸发。

真正区分赢家和输家的,是模型之外的工程能力:

  • 为每类任务匹配最优的框架
  • 用"每次成功成本"衡量效率
  • 建立差异化的失败监控体系

框架是地基,模型是上面的建筑。地基歪了,换再贵的建筑材料也救不回来。

2026年下半年,Agent赛道拼的不是谁的模型更新,而是谁把工程链路做得更稳、成本更优、监控更细。对于开发者来说,这其实是好消息——工程能力,才是我们能掌控的东西。


数据来源:Braintrust基于Hugging Face 1781条生产环境Agent运行轨迹分析报告(2026年6月)

本文代码已开源,可自由复制使用。