GitHub每日热评|不只是系统提示词:dsh-routing-suite 如何用协议和指标约束 Agent 行为

0 阅读15分钟

GitHub每日热评|不只是系统提示词:dsh-routing-suite 如何用协议和指标约束 Agent 行为

本文基于 yjh051108/dsh-routing-suite 指定仓库快照 e3f00b24db44 进行分析。
项目许可证为 MIT,目标依赖版本为 DSH >=0.1.0-rc.6 <0.2.0。文中关于实验效果的内容来自项目文档,本文未复跑其完整实验集。 作者:Valhalla Matrix治理实验室 评测方式:证据驱动·只读静态源码审阅,无运行时执行,结论可复现

很多 Agent 项目的优化方式,最后都会回到同一个动作:

修改 system prompt
    ↓
运行几次任务
    ↓
感觉模型更认真了

这种方法可以快速试错,但很难回答几个关键问题:

  • 模型究竟在哪个阶段开始偷懒?
  • 任务后半段的工具调用是否明显减少?
  • 修改协议后,模型的行为是否真的发生变化?
  • 不同模型使用同一套提示词,效果是否一致?
  • 一次成功的任务,能不能被别人复算?

dsh-routing-suite 的思路有所不同。它并不只提供一段更长的系统提示词,而是围绕 DSH 运行环境,提供运行时注入、任务感知路由和分级任务协议,并配套会话 JSONL 的测量工具。

它试图把 Agent 的“勤勉程度”从主观感受转换成可观察指标:

运行时行为
    ↓
会话日志
    ↓
指标提取
    ↓
任务前后对照

这类方法未必能证明模型一定变得更强,但至少让讨论从“我感觉有效”向“哪些行为发生了变化”迈了一步。


一、先理解它要解决的问题

长程 Agent 任务通常包含多个阶段:

理解需求
    ↓
读取资料
    ↓
制定计划
    ↓
调用工具
    ↓
检查中间结果
    ↓
修正问题
    ↓
完成交付

在任务早期,模型往往会认真分析上下文、读取文件并调用工具。任务进入后半段后,可能出现一些可观察的问题:

  • 跳过必要的文件读取;
  • 减少工具调用;
  • 直接假设结果正确;
  • 没有完成终验就宣布任务结束;
  • 只执行最短路径;
  • 没有对失败步骤进行复核。

这些现象不能简单归因于“模型变懒”。它们也可能来自:

  • 上下文过长;
  • 任务目标不够明确;
  • 工具描述不清晰;
  • 中间状态没有持久化;
  • 评价指标只看最终文本;
  • 协议要求没有被结构化表达。

dsh-routing-suite 选择的解决方向,是在 Agent 运行过程中增加一层协议和路由机制,对不同任务阶段施加不同约束,并用会话日志进行事后分析。


二、项目提供的三类能力

从仓库结构和文档来看,项目主要由三部分组成:

组件主要职责
injector管理运行时注入、热重载、卸载和路由恢复
preset提供不同的路由预设和模型行为配置
graded用分级任务协议约束计划、执行、验收和审计

三者分别位于不同层面。

injector:如何接入运行时
preset:不同任务如何路由
graded:任务过程如何执行和验收

这比把所有行为规则塞进一段 system prompt 更容易拆分和观察,但也意味着系统复杂度增加了。


三、Injector:运行时注入带来的灵活性与风险

项目中的 injector 主要负责运行时管理能力,包括:

  • 注入配置;
  • 热重载;
  • 卸载;
  • 侧挂路由转正;
  • 路由异常后的恢复。

它解决的是配置变化问题。

传统方式可能需要:

修改配置
    ↓
停止 Agent
    ↓
重新启动
    ↓
加载新配置

运行时注入则希望缩短反馈周期:

修改配置
    ↓
重新注入
    ↓
继续运行或重新测试

对于实验阶段,这种方式很方便。研究者可以快速比较不同路由、不同预设和不同任务协议,而不必频繁重启整个环境。

但运行时修改也会扩大故障范围。需要重点关注:

  • 注入是否影响已经开始的任务;
  • 热重载后旧配置是否完全清理;
  • 卸载失败时是否会残留状态;
  • 路由恢复是否可能重复执行;
  • 多个插件同时注入时,执行顺序如何确定;
  • 日志能否还原某次任务实际使用了哪一版配置。

因此,运行时注入不应该默认用于唯一的生产 Agent。更稳妥的测试顺序是:

独立测试环境
    ↓
复制会话
    ↓
短任务验证
    ↓
长任务验证
    ↓
灰度运行
    ↓
生产环境

四、Preset:路由规则不是越多越好

项目提供了类似以下的预设:

router-standard
router-spec

其基本思路是根据任务类型、模型角色或当前执行阶段,选择不同的行为路由。

可以抽象成:

输入任务
    ↓
识别任务类型
    ↓
选择路由预设
    ↓
注入对应协议
    ↓
执行任务

例如,不同任务可能需要不同的约束重点:

任务类型更关注的行为
信息检索是否读取来源、是否保留引用
代码修改是否检查现有代码、是否运行测试
文件处理是否逐项确认输入和输出
长流程任务是否保存计划、是否进行中间复核
高风险操作是否经过确认和终验

路由的价值在于减少“一套提示词覆盖所有任务”的粗糙做法。

但路由系统也有一个常见风险:规则越来越多,最后没人知道到底是哪一条规则改变了模型行为。

因此,实际使用时建议记录:

任务类型
路由名称
协议版本
注入时间
模型版本
工具集合
最终输出
会话指标

如果缺少这些信息,出现效果变化后就很难定位原因。


五、Graded:把长程任务拆成可检查的阶段

项目中更有辨识度的部分是 graded 协议。

从文档描述看,它把任务拆分为多个阶段:

提出问题
    ↓
规格化计划
    ↓
执行与打卡
    ↓
任务收官
    ↓
最终验收
    ↓
审计记录

这种设计的核心不是让模型生成更多文字,而是要求它在任务过程中留下可验证的状态。

一个抽象示例可以是:

{
  "task": "整理项目文档并生成报告",
  "plan": [
    "读取项目目录",
    "识别关键文件",
    "提取配置和测试信息",
    "生成报告",
    "检查报告中的事实引用"
  ],
  "checkpoints": [
    {
      "name": "读取项目目录",
      "status": "done"
    },
    {
      "name": "检查事实引用",
      "status": "pending"
    }
  ],
  "final_verification": {
    "status": "pending"
  }
}

这里真正有用的是状态,而不是格式本身。

如果任务最终失败,可以进一步判断:

是计划没有制定?
是工具没有调用?
是中间检查被跳过?
还是最终验收没有执行?

相比只检查最终答案,这种分阶段协议更适合分析长流程任务。


六、什么叫“模型偷懒”

“模型偷懒”是一个容易被滥用的说法。

如果没有明确指标,它可能只是人的主观评价。要把它变成可分析的问题,就需要定义可观察行为。

例如可以关注:

  • 每个阶段的工具调用次数;
  • 关键文件的读取次数;
  • 计划项完成比例;
  • 失败后的重试次数;
  • 中间检查是否执行;
  • 最终验收是否执行;
  • 任务后半段的行为密度;
  • 输出与实际工具结果是否一致。

可以定义一些简单指标。

1. 工具调用覆盖率

工具调用覆盖率
=
实际调用过的必要工具数
/
任务要求的必要工具总数

2. 检查点完成率

检查点完成率
=
已完成检查点数量
/
计划中的检查点总数

3. 终验执行率

终验执行率
=
执行最终验证的任务数
/
完成任务总数

4. 后半程行为衰减

可以将任务分为前半段和后半段,比较两部分的工具调用密度:

后半程工具调用密度
=
后半段工具调用次数
/
后半段交互步数

如果这个指标持续下降,同时关键步骤遗漏率上升,才有理由进一步研究是否存在长程执行衰减。

需要强调的是,这些指标只能描述行为,不能单独证明模型“认真”或“不认真”。行为减少也可能是因为任务已经进入无需工具的阶段。


七、项目如何通过会话 JSONL 进行测量

项目提供了类似下面的测量命令:

node scripts/measure.mjs your-session.jsonl

从设计上看,它的输入是 Agent 会话日志,输出经过脱敏的统计结果。

JSONL 适合作为这种分析格式,因为每一行都可以对应一个事件:

{"type":"task_start","task_id":"demo-001"}
{"type":"tool_call","name":"read_file","path":"README.md"}
{"type":"checkpoint","name":"read_project_files","status":"done"}
{"type":"tool_call","name":"run_tests"}
{"type":"task_end","status":"success"}

基于这样的事件流,测量工具可以统计:

任务持续时间
工具调用次数
检查点完成情况
任务阶段分布
终验是否执行
不同会话之间的差异

这类工具的工程价值在于,它可以让评测从手工阅读日志变成批量分析。

例如,比较两组会话:

A 组:不使用 graded 协议
B 组:使用 graded 协议

然后比较:

指标A 组B 组
必要工具调用覆盖率
检查点完成率
终验执行率
任务成功率
平均任务时长
人工返工次数

只有同时观察质量和成本,才知道协议是否真正有用。


八、如何看待项目中的 P1-P23 实验结论

仓库文档提到了一组 P1-P23 的测试或任务实验。

文章中引用这类编号时,需要注意几个问题:

  1. P1-P23 的具体任务定义是什么;
  2. 样本量有多大;
  3. 使用了哪些模型;
  4. 是否控制了 prompt 和工具环境;
  5. 对照组和实验组是否只有一个变量不同;
  6. 成功标准是人工判断还是自动指标;
  7. 是否公开了原始会话;
  8. 是否存在失败样本;
  9. 结论能否推广到其他模型。

如果这些条件没有完全公开,就不应该把“P1-P23 实测”改写成普遍性结论。

更准确的表达方式是:

项目文档提供了 P1-P23 的实验口径和对照结果,说明作者尝试用任务集评估协议效果。但在没有独立复跑、扩大样本和跨模型验证之前,这些结果更适合作为项目内部观测,而不是通用性能结论。

这是技术评测中非常重要的边界。


九、安装与目录布局注意事项

项目支持通过 DSH 插件命令安装,例如:

dsh plugin --profile web add github:yjh051108/dsh-routing-suite

仓库还提供了 install.ps1,用于装配注入器、复制预设和执行目录检查。

其中一个容易踩坑的地方是目录层级。

文档特别提醒,不要把整个 preset 目录直接复制到 .agent-presets。如果形成了多余的一层目录,可能变成:

.agent-presets/preset/router-standard

而 DSH 期望的结构可能是:

.agent-presets/router-standard

当扫描器只检查一级子目录时,前一种结构就可能无法被发现。

这类问题看起来只是路径错误,但它说明插件系统中的“安装成功”和“运行时成功”是两件事:

文件复制成功
不等于
插件已被扫描
不等于
路由已被加载

部署完成后,建议检查:

  • 预设目录是否位于 DSH 扫描路径;
  • 目录名称是否符合约定;
  • 注入器是否被正确加载;
  • 当前会话使用的是哪一个预设;
  • 热重载后配置是否生效;
  • 卸载后是否仍有残留规则。

十、最大风险:依赖 DSH Developer Preview

项目目标依赖版本为:

DSH >=0.1.0-rc.6 <0.2.0

这表明它依赖的是仍处于 Developer Preview 阶段的运行环境。

预览版依赖的主要风险包括:

  • 插件接口可能变化;
  • 目录扫描规则可能变化;
  • 注入生命周期可能变化;
  • 路由字段可能发生 breaking change;
  • 原有插件在升级后无法加载;
  • 文档和实际行为可能暂时不一致。

仓库中的 preset/CHANGELOG.md 还记录了多个预发布版本,例如:

rc.8
0.1.1-rc.2
0.1.2-alpha.1

在生产环境中,不建议直接使用浮动版本。更稳妥的方式是:

锁定 DSH 版本
锁定插件提交
保存配置快照
建立回滚方案

同时为关键任务保留一组固定会话,用于升级后的回归比较。


十一、为什么不建议同时安装多个行为插件

文章中提到的 dsh-anchored-standard 更偏向于通过 Minimal 条件锚定首轮推理轨迹,而 dsh-routing-suite 重点关注任务路由和长程执行协议。

两者并非一定冲突,但同时启用时会出现一个实际问题:

到底是哪一个插件改变了模型行为?

尤其是多个插件都可能修改以下内容:

  • system prompt;
  • developer message;
  • 工具调用约束;
  • 任务状态;
  • 路由字段;
  • 会话生命周期;
  • 首轮执行策略。

因此,进行实验时最好采用单变量方式:

基线环境
    ↓
只启用插件 A
    ↓
恢复基线
    ↓
只启用插件 B
    ↓
恢复基线
    ↓
启用 A+B 并记录组合效果

每次测试都保存:

插件列表
插件版本
配置文件
模型版本
任务输入
会话日志
测量结果

否则最终只能看到“组合后的行为变化”,无法解释具体原因。


十二、如何设计一套更可靠的验证实验

如果准备在自己的 Agent 中测试该项目,可以从一个小型实验开始。

实验目标

验证协议是否降低了长任务中的关键步骤遗漏。

实验变量

项目基线组协议组
模型相同相同
任务相同相同
工具相同相同
最大步数相同相同
任务协议不启用启用
路由默认指定 preset

任务样本

准备 10 到 20 个具有明确检查点的任务,例如:

  • 读取多个源文件后生成报告;
  • 修改代码并运行测试;
  • 分析数据后输出结论;
  • 处理一组文档并进行完整性检查;
  • 调用多个工具完成部署前检查。

观察指标

任务成功率
关键步骤遗漏率
工具调用覆盖率
终验执行率
人工返工次数
平均任务时长
Token 消耗

结果解释

如果协议组的检查点完成率更高,但任务时长和 Token 消耗明显增加,那么它可能适合高可靠任务,却不适合追求低成本的简单任务。

如果协议组工具调用次数增加,但最终正确率没有提高,则说明协议可能增加了形式化动作,却没有改善实际质量。

这比只统计“调用次数变多了”更加可靠。


十三、它适合什么,不适合什么

适合

  • 已经使用 DSH 运行长程 Agent 任务的团队;
  • 需要记录和分析 Agent 行为的人;
  • 想比较不同路由和协议效果的开发者;
  • 对会话 JSONL、审计和回归测试有要求的系统;
  • 需要提高关键检查点完成率的自动化流程。

不适合直接用于

  • 只需要一句话问答的简单任务;
  • 还没有稳定日志格式的 Agent;
  • 没有明确任务成功标准的场景;
  • 对运行时修改风险敏感的生产系统;
  • 需要长期稳定接口,但无法锁定 DSH 版本的项目;
  • 只想复制一段提示词就获得普适效果的使用者。

它并不是万能的模型增强器,更像是一套实验和运行时控制工具。


结语:把“模型变认真”改写成可以验证的问题

dsh-routing-suite 最值得关注的地方,不是它提供了多少条提示词,而是它试图建立一条可复核链路:

任务协议
    ↓
运行时路由
    ↓
会话事件
    ↓
行为指标
    ↓
对照实验

这让一个模糊的问题变得更具体:

模型是不是更认真了?

可以被拆成:

是否读取了必要文件?
是否调用了必要工具?
是否完成了计划中的检查点?
是否执行了最终验收?
后半程是否出现行为衰减?
协议带来的额外成本是多少?

当然,项目仍然存在明显边界:

  • 依赖 DSH Developer Preview;
  • 运行时注入可能影响现有会话;
  • P1-P23 等实验结果尚未在本文中独立复跑;
  • 行为指标不能直接等同于任务质量;
  • 更严格的协议可能增加 Token、工具调用和执行时间;
  • 多个插件同时使用时,归因会变得困难。

因此,比较准确的定位是:

dsh-routing-suite 不是一段更长的 system prompt,而是一套围绕 DSH 的运行时路由、任务协议和会话测量工具。

如果你的 Agent 已经能够稳定输出 JSONL,并且你确实遇到了长任务后半段检查不足、工具调用减少或终验缺失的问题,那么这个项目值得进行小规模对照实验。

实验开始前,先定义成功标准;实验结束后,再根据日志判断协议是否有效。不要因为模型多输出了几段计划,就直接得出“Agent 变可靠了”的结论。