用 vLLM Semantic Router 做 Agent Crew 路由评测:per-agent 与 per-call 模型选择的四种对照实验 后端API网关模型推理服务AI Agent【免费下载链接】semantic-routerAn open, programmable decision layer for models and compute.项目地址https://gitcode.com/gh_mirrors/sem/semantic-router点击查看免费下载导读bench/agent_crew是 semantic-router 仓库中的一个四智能体代码评审 Crew 对照实验同一个由 planner、summarizer、reviewer、writer 组成的工作组对同一份携带 6 个预设缺陷的 Pull Request 评审四次唯一变量是每个智能体发送的模型名——是固定用frontierxAI Grok、固定用localOllama llama3.2:3b还是统一发送MoM交给路由器逐次调用决策。读完本文你将掌握如何在本仓库一键启动这套评测路由器配置、四臂运行、盲评与报告生成、如何读懂x-vsr-*系列路由观测头与/metrics指标以及路由器「按调用粒度选模型」与「按智能体手工分配模型」两种策略在成本与缺陷检出上的差异是如何被量化出来的。评测背景为什么需要「每次调用」级别的路由对比传统做法中多智能体系统的模型分配是静态的架构师预先为每个 Agent 固定一个模型per-agent例如「重要角色用强模型、其余用弱模型」。而 semantic-router 这类可编程决策层提供的是更细的粒度——每一次模型调用都经过路由器由路由策略根据请求内容如关键词信号动态选择模型per-call。两种思路的成本与质量差异正是本评测要回答的问题。本目录bench/agent_crew/README.md实现的评测采用单一对照变量设计四个智能体、同一份 PR、同一套系统提示词仅改变各智能体发送的模型名即可得到四个实验臂臂Arm各智能体发送的模型名衡量目标all-frontier全部发送frontier质量上限及其成本per-agentreviewer 用frontier其余用local手工调优的基线per-call全部发送MoM由路由器逐调用决策all-local全部发送local成本下限及其质量损失值得强调的是所有测量数据都来自路由器本身每个响应的x-vsr-selected-model实际选中的模型、x-vsr-selected-decision命中的决策名、x-vsr-routing-latency-ms路由决策耗时、x-vsr-cost按配置定价计算的路由器侧成本加上每次运行前后的/metrics差值。Crew 自身不做任何统计。同时 README 明确划定了证据边界这份 PR fixture 及其种子缺陷只是用于「在完全相同的工作上对比不同臂」的开发夹具不是代码评审基准其结果不得作为基准成绩对外报告。启动路由器crew.yaml 配置拆解评测的路由器配置位于 bench/agent_crew/configs/crew.yaml启动命令为cd bench/agent_crew/configs vllm-sr serve --minimal --config crew.yaml该配置定义了一个local模型、一个frontier模型和一条「仅对并发或安全代码上的缺陷搜索进行升级」的关键词路由策略。crew.yaml默认要求 Ollama 提供llama3.2:3b并在启动终端中导出XAI_API_KEY。任何 OpenAI 兼容后端都可以替换修改frontier模型的backend_refs与pricing块即可四个实验臂与上报成本会随之变化。providers 段双模型与定价providers: defaults: model: local models: - name: local provider_model_id: llama3.2:3b pricing: currency: USD prompt_per_1m: 0.0 completion_per_1m: 0.0 backend_refs: - name: ollama endpoint: host.docker.internal:11434 protocol: http weight: 100 - name: frontier provider_model_id: grok-4.20-0309-non-reasoning pricing: currency: USD prompt_per_1m: 1.25 cached_input_per_1m: 0.20 completion_per_1m: 2.50 backend_refs: - name: xai base_url: https://api.x.ai/v1 provider: openai api_key_env: XAI_API_KEY要点local模型定价为 0因此all-local臂构成成本地板frontier使用非推理版 Grok避免隐藏思考 token 干扰价格为配置时读取的公开定价正式运行前应重新核对pricing块是x-vsr-cost与/metrics中llm_model_cost_total的成本来源也就是说上报成本是「按配置定价的估算值」并非厂商账单配置中注释还给出两个可切换的frontier备选Groq 免费层的openai/gpt-oss-120b、OpenAI 的gpt-4.1切换前建议先运行check_provider.py验证。routing 段关键词信号与决策routing: modelCards: - name: local modality: text - name: frontier modality: text signals: keywords: - name: defect_search operator: OR case_sensitive: false keywords: - find the defects - name: subtle_code operator: OR case_sensitive: false keywords: - threading - asyncio - multiprocessing - concurrent - subprocess - pickle - password - secret_key decisions: - name: deep-review description: Searching concurrency or security code for defects earns the frontier model. priority: 200 rules: operator: AND conditions: - type: keyword name: defect_search - type: keyword name: subtle_code modelRefs: - model: frontier use_reasoning: false - name: default-local description: Everything else stays local. priority: 10 rules: operator: AND conditions: [] modelRefs: - model: local use_reasoning: false这里的设计非常精巧defect_search只在 reviewer 的系统提示词中出现find the defectssubtle_code覆盖threading、asyncio、multiprocessing、pickle、password等并发/安全关键词两条关键词信号取AND即只有「正在找缺陷 且 涉及并发/安全代码」的调用才被升级到frontierdeep-reviewpriority 200其余调用落入default-localpriority 10留在本地。注释点明了策略意图策略空档表现为漏检缺陷而不是账单膨胀——fall-through 永远落在本地模型上。配置还显式关闭了两处干扰项response_cache关闭缓存命中会跳过模型导致没有成本可上报以及全部嵌入模型、分类器、Prompt 防护等模块路径留空确保仅用关键词信号、不下载任何分类器模型这也是vllm-sr serve --minimal的由来。运行四个实验臂路由器启动后逐个臂运行同一 Crewbench/agent_crew/crew.pypython bench/agent_crew/crew.py --arm all-local --repeat 3 \ --router-metrics-url http://127.0.0.1:9190/metrics python bench/agent_crew/crew.py --arm per-call --repeat 3 \ --router-metrics-url http://127.0.0.1:9190/metrics python bench/agent_crew/crew.py --arm per-agent --repeat 3 \ --router-metrics-url http://127.0.0.1:9190/metrics python bench/agent_crew/crew.py --arm all-frontier --repeat 3 \ --router-metrics-url http://127.0.0.1:9190/metrics必须一次只运行一个臂/metrics计数器覆盖整个路由器第二个客户端会把计数混入总量破坏对照。四臂的模型分配映射从 crew.py 的源码可以看到所谓「臂」就是一张agent - 模型名的映射表ARMS { all-frontier: dict.fromkeys(AGENTS, frontier), per-agent: { planner: local, summarizer: local, reviewer: frontier, writer: local, }, per-call: dict.fromkeys(AGENTS, MoM), all-local: dict.fromkeys(AGENTS, local), }每个智能体都配有独立的系统提示词planner 先看 PR 再写逐文件检查计划summarizer 给每个变更文件写一句话摘要reviewer 逐个文件查找真实缺陷要求给出行号、问题与修复并可调用read_file工具查看同 PR 其他文件writer 基于计划、摘要和 findings 汇总成不超过 300 词的最终评审意见crew.py。任务流程是planner → 每个文件的 summarizer → 每个.py文件的 reviewer → 一个 writercrew.py。工具调用的沙箱保护Crew 给智能体暴露了list_changed_files与read_file两个工具且read_file做了路径沙箱目标路径必须解析到fixture/pr/目录内否则返回错误crew.py。对应测试 test_crew.py 验证了../../defects.json这类越权读取会被拒绝——这保证了评审只能基于 PR 内部文件防止智能体直接读到答案。每次调用的观测记录crew.py对每次模型调用记录一条 JSONcrew.py字段包括run_id、arm、agent、step、turn、requested_model、selected_model优先取自x-vsr-selected-model头缺失时回退为请求名、decision、prompt/completion/cached/reasoning tokens、finish_reason、工具调用次数、总延迟、routing_latency_ms、cost、cost_currency、replay_id等。失败调用同样被记录error字段不会中断运行——这保证了对照数据完整。产出文件每次运行在runs/arm/run/下写出四个文件crew.pycalls.jsonl每行一条调用记录agent、step、请求/实际选中的模型、决策、tokens、路由毫秒数、成本conversations.json完整对话与工具调用轨迹review.md最终评审意见summary.json运行汇总含按智能体/按模型的 token 分布、决策计数、/metrics前后差值按模型分货币的成本、路由决策数、路由延迟均值。其中/metrics差值逻辑在 crew.py把运行前后的 Prometheus 文本抓下来解析计算llm_model_cost_total{model,currency}的增量与llm_model_routing_latency_seconds_sum/count的增量得出本轮运行的路由决策总数与平均路由延迟。这也解释了为什么必须串行运行各臂。盲评grade.py 与缺陷答案键python bench/agent_crew/grade.py --ungraded --blindgrade.py 的行为--ungraded自动找出所有尚未生成grades.json的runs/*/*/目录--blind打乱运行目录顺序并在界面隐藏臂名评委只看到评审文本避免先入为主随后逐条缺陷提示评审员found? [y/n]交互回答后写入该目录的grades.json含逐缺陷命中与defects_found计数。答案键是 defects.json内含 6 个种子缺陷每个都给出文件、行号、缺陷描述与只用于提示评审员判断的关键词 hints。判分规则很严格README 明确举例缺陷只有在评审明确指出该文件中的该问题时才计数——consider error handling 不算命中裸except而 the bare except hides failed line items 才算。hints 只是提示词最终由人判断。6 个种子缺陷来自 fixture/pr/ 下的三个文件ID文件缺陷D1counter.pyL15-16total读写未持锁并发record()丢失递增D2counter.pyL18errors 1同样未同步D3billing.pyL6parse_amount对 None/空串抛异常D4billing.pyL15-16裸except: pass静默吞掉明细行D5billing.pyL6,11,14金额用float而非Decimal计算D6pagination.pyL7切片start page_size - 1导致每页丢最后一行off-by-one例如 fixture/pr/billing.py 中的except: pass正是 D4fixture/pr/counter.py 的RequestCounter.record在锁外做 read-modify-write 正是 D1/D2fixture/pr/pagination.py 的rows[start : start page_size - 1]正是 D6。你可以直接对照源码验证答案键的准确性。汇总报告report.pypython bench/agent_crew/report.py --figuresreport.py 只读取summary.json、calls.jsonl与grades.json不需要再调用模型反复运行即可重建在runs/results.md生成四张表四臂总表report.py每次任务的模型调用数、由 frontier 服务的调用数、失败调用、prompt/completion token、墙钟时间、每任务成本优先用/metrics差值回退到x-vsr-cost头、检出缺陷数of 6、截断调用数全部以中位数 跨运行范围呈现智能体 × 模型表report.py每个臂中四个智能体分别由哪些模型服务跨运行中位数缺陷明细表report.py逐缺陷列出各臂「N of M」次检出路由耗时表report.pyx-vsr-routing-latency-ms的样本数、p50/p95/max、/metrics均值、中位模型调用时长以及「路由耗时占墙钟时间的百分比」——用来回答「路由决策开销是否可忽略」。--figures额外产出三张图需 matplotlibcall-tape.pngper-call 臂一次任务的调用序列色带绿local、紫frontier、arms.png各臂成本与检出缺陷的双轴柱线图、tokens-by-agent.png四智能体 token 占比堆叠条。测试零依赖的桩路由器验证python -m pytest bench/agent_crew/test_crew.py bench/agent_crew/test_check_provider.py这两组测试使用桩路由器test_crew.py 中内置的FakeRouter不需要模型、密钥或网络。FakeRouter模拟了真实路由器的关键行为MoM请求按「用户消息含find the defects且含threading」判deep-review/default-local并在响应头回填x-vsr-*系列观测头同时用do_GET提供/metrics。测试断言了典型对照结果例如 per-call 臂一次任务共 13 次调用、reviewer 的 6 次评审调用中仅 2 次并发/安全文件被路由到 frontier、总成本 $0.002、13 次路由决策、p50 路由延迟 0.25mstest_crew.py。这正是「路由器只升级并发/安全缺陷搜索」策略在每次调用粒度的可验证落点。接入新后端前的体检check_provider.pypython bench/agent_crew/check_provider.py \ --base-url https://api.x.ai/v1 \ --api-key-env XAI_API_KEY \ --model grok-4.20-0309-non-reasoningcheck_provider.py 直接调用厂商用路由器严格解码器的字段白名单检查返回体路由器不认识某个字段时会把整个回复变成 502。脚本会发两次请求普通回复 一次带工具调用逐字段列出会被路由器拒绝的项。字段清单对齐 canonical chat 响应契约逐对象白名单定义在 check_provider.pyresponse / choice / message / tool_call / usage / cost_details 等嵌套对象结构在CHILDREN中测试 test_check_provider.py 明确以src/semantic-router/pkg/protocolcodec/testdata下的编解码器 fixtures 为契约基准保证「路由器能解码的回复不会在这个检查里无声挂掉」额外校验规则包括stop_reason必须是 int64 范围内的整数或非空字符串、system_fingerprint长度 1–256、service_tier枚举值、若干字段必须为 null 等check_provider.pyPASS 是强信号而非保证若厂商配置了匹配的 vendor 策略路由器会丢弃其多余字段而非拒绝因此出现 vendor 装饰字段的 FAIL 时应先核对该厂商的配置再判定例如 Groq 的x_groq字段在白名单中正是这类 vendor 特例。脚本对 URL 请求还设置了自定义 user-agentvllm-sr-check-provider/1.0因为 Cloudflare 前置的 API如 Groq会以错误 1010 拦截 urllib 默认 UAcheck_provider.py。评测方法的边界与可迁移性从这套夹具可以得到几条方法论层面的沉淀均以仓库内证据为支撑对照变量单一四臂只改变「请求的模型名」系统提示词、PR 内容、工具集完全相同差异可归因于模型选择策略本身成本口径明确所有成本均来自路由器的配置定价x-vsr-cost头与/metrics的llm_model_cost_total差值README 与 report.py 都注明「不是厂商账单」零成本模型local不会推动计数器空增量本身就是真实的 $0证据边界清晰PR 夹具与种子缺陷是开发夹具而非基准bench/agent_crew/README.md结果不得作为基准成绩引用可迁移把crew.yaml的frontier.backend_refs换成任意 OpenAI 兼容后端并核对pricing或把fixture/pr/换成你自己的 PR 快照即可在相同流程上复测——换后端前先跑一遍check_provider.py。这套 bench 直接回答了语义路由落地中最实际的问题把决策粒度从「每智能体」细到「每次调用」能省多少钱、会不会漏缺陷——而答案不是靠猜而是靠x-vsr-*观测头、/metrics差值和一份盲评得出的可复现数字。赞分享后端API网关模型推理服务AI Agent【免费下载链接】semantic-routerAn open, programmable decision layer for models and compute.项目地址https://gitcode.com/gh_mirrors/sem/semantic-router点击查看免费下载相关推荐vLLM Semantic Router 语义化工具选择基于上下文感知路由的 AI Agent 工具裁剪实践vLLM Semantic Router 语义化工具选择基于上下文感知路由的 AI Agent 工具裁剪实践 当 Agent 连接的工具从几十个膨胀到数千个时后端API网关模型推理服务AI Agentagent 的 per-agent 运行时字段应该放 SKILL.md 的 metadata 还是独立 per-agent adapteragent 的 per agent 运行时字段应该放 SKILL.md 的 metadata 还是独立 per agent adapter 在 agent sAI 技能开发工具AI 评测BenchmarkvLLM Semantic Router 实战深入解析 request accounting、invoice export 与分页导出的 PR 变更及其 Agent Crew 代码评审vLLM Semantic Router 实战深入解析 request accounting、invoice export 与分页导出的 PR 变更及其 Ag后端API网关模型推理服务AI Agent上一篇3步解锁音乐自由qmcdump音频转换全指南下一篇在 Jetson 上基于 PlantCLEF 数据集迁移学习重训 ResNet-18 植物识别模型并部署到 TensorRT 的完整实战指南创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考