Harness² 项目架构

Harness² 是一个面向开放世界专业任务的递归 Agent Harness 优化框架。

AI 摘要

这篇文章适合快速了解什么

Harness² 是一个面向开放世界专业任务的递归 Agent Harness 优化框架。

文章先解释“1. 项目目的:金字塔顶端”,帮助你快速进入主题。

随后会展开“2. 总体架构”,方便直接定位关键方法或判断标准。

核心看点

  • 1. 项目目的:金字塔顶端
  • 2. 总体架构
  • 分层边界
  • 3. 功能分类

1. 项目目的:金字塔顶端

Harness² 是一个面向开放世界专业任务的递归 Agent Harness 优化框架。

它不训练或修改模型权重,而是持续优化模型运行时周边的 Harness:系统提示词、约束、长期记忆、工具指导、子 Agent、Skills、脚本和插件/Hook。目标是让 Agent 在完成一个任务后,根据实际执行证据改进当前任务的执行方式,并将可迁移经验沉淀给同领域的后续任务。

目标:提升 Agent 在陌生专业任务中的执行质量
  └── 方法:递归优化 Agent Harness,而非训练模型权重
      ├── 任务级递归:Propose -> Probe -> Compose
      └── 任务间递归:Adopt -> Reflect -> Library

项目定位是研究型、本地 CLI 实验框架,不是业务 Web 系统:没有项目内前端页面、业务数据库或长期运行的服务集群。

2. 总体架构

flowchart TB Goal["目标:提升 Agent 的专业任务执行质量"] Method["递归 Harness 优化"] Task["任务级递归\nPropose -> Probe -> Compose"] CrossTask["任务间递归\nAdopt -> Reflect -> Library"] CLI["CLI 层\nsetup / check / sweep / judge / report / demo / bridge"] Core["方法核心 core/\n调度、递归、证据、选择、经验、评分、报告"] Adapter["Benchmark Adapter 层\nLAB / JobBench / WorkBuddy-Bench"] Runtime["Substrate 层\nOpenCode / Codex"] External["外部依赖\n模型服务、Docker/Harbor、GitHub、Hugging Face"] Storage["文件系统结果库\nruns/、dependencies/"] Goal --> Method Method --> Task Method --> CrossTask Task --> Core CrossTask --> Core CLI --> Core Core --> Adapter Core --> Runtime Adapter --> External Runtime --> External Core --> Storage

分层边界

层级 职责 关键目录/文件
CLI 层 解析命令参数、构造 adapter、调用预检、启动 sweep/评分/报告 harness2/cli/
方法核心层 实现递归优化方法,不绑定具体 benchmark 或 Agent Runtime harness2/core/
Benchmark Adapter 层 统一任务发现、任务资料、执行、交付物读取、评分等 benchmark 差异 harness2/benchmarks/
Substrate 层 定义 Harness 如何安装到 OpenCode/Codex,并统一轨迹读取 harness2/substrate/
部署与依赖层 下载固定上游版本、打补丁、安装 runner、环境预检 harness2/install.py、harness2/preflight.py

harness2/core/spec.py 中的 BenchmarkAdapter 和 SubstrateLike 协议是核心边界:新增 benchmark 或运行时应通过实现协议接入,而不是修改递归算法。

3. 功能分类

功能类别 作用 主要代码
递归优化 生成、验证、执行、组合 Harness 候选 core/recursion.py
任务调度 按领域组织任务、并发不同领域、顺序处理同领域、恢复中断任务 core/schedule.py
Harness Tree 管理 读取、写入、校验、差异对比、自动补 Skill 触发词 core/tree.py
证据上下文 向改进模型提供任务、资料、轨迹、产物、候选和经验 core/context.py
改进模型调用 调用 OpenCode/Claude CLI,包含缓存、审计、重试和成本记录 core/proposer.py
候选选择与反思 匿名选择最终产物,并提炼可迁移经验 core/selection.py
经验库 存储同领域历史任务的已采用 Harness 和经验 core/library.py
评测和报告 对已选结果评分;汇总分数、通过率和告警 core/judge.py、core/report.py
Benchmark 集成 对接法律、职业、办公/网页/代码任务 benchmarks/lab.py、jobbench.py、workbuddy.py
Runtime 集成 对接 OpenCode 和 Codex 的执行配置、安装和轨迹解析 substrate/opencode.py、codex.py
安装和预检 管理上游代码、补丁、运行环境和凭据 install.py、preflight.py
本地演示 无模型服务地验证完整递归流程 demo.py
Codex API Bridge 将 Vertex 模型通过 LiteLLM 暴露为 Responses API cli/bridge.py

4. Harness 的可编辑面

项目优化的是 Agent Harness 文件树,而不是模型参数。

Harness 部件 OpenCode Codex 目的
系统指令 systemprompt.md AGENTS.md 定义基础行为
约束和长期记忆 guardrails.md、LongTermMEMORY.md AGENTS.md 保留执行规范与经验
工具指导 tool_descriptions/tool_guidance.md AGENTS.md / Skills 指导工具调用
Skills skills/<name>/SKILL.md .agents/skills/<name>/SKILL.md 可按需加载的工作流
子 Agent sub_agents/<name>/AGENT.md sub_agents/<name>/AGENT.md 分工与委派
脚本 scripts/*.py scripts/*.py 可确定执行的辅助能力
插件/Hook plugin/*.ts .codex/hooks.json 在工具循环内施加约束

可编辑面由 harness2/substrate/opencode.py 的 OPENCODE_SURFACE 和 harness2/substrate/codex.py 的 CODEX_SURFACE 定义,通用校验由 harness2/core/tree.py 的 validate() 完成。

5. 递归核心:代码定位

5.1 递归入口和调度

递归阶段 文件 方法 职责
Sweep 入口 harness2/cli/run_sweep.py _main() 创建 adapter、预检环境、创建 Proposer、调用 schedule.run_sweep()
全量调度 harness2/core/schedule.py run_sweep() 按 domain 并发执行;一个 domain 内任务保持顺序
领域递归 harness2/core/schedule.py run_domain() 为每种递归模式创建领域经验库,并逐任务传递经验
单任务入口 harness2/core/schedule.py run_task() 执行基础 rollout、启动每种模式、选择最终 Harness、写入摘要
单模式执行 harness2/core/schedule.py _run_one_mode() 调用递归算法、构建选择池、执行选择与反思、写入经验库

5.2 任务级递归:Propose -> Probe -> Compose

核心实现全部在 harness2/core/recursion.py。

阶段 方法 说明
模式分发 run_mode(mode, ...) 根据 agg 或 seq 分派到并行或串行递归
并行递归 run_parallel(...) 从相同基础证据生成 k 个通用候选和 k 个领域候选,执行后生成 k 个组合候选
串行递归 run_sequential(...) 连续执行 k 轮,每轮继承上一轮组合后的 Harness 和历史证据
提案阶段 _run_stage(...) 构建上下文、调用改进模型、读取改动后的 Harness、验证失败时重试一次
Probe 执行 _roll(...) 将 Harness Tree 落盘后调用 adapter 执行一次 rollout
并发 Probe _roll_many(...) 并发执行独立候选 rollout,再按稳定顺序写入账本
提案验证 _accept_tree(...) 自动补 Skill 触发词、校验可编辑面、验证 benchmark 约束、阻止评分泄漏
成本账本 _record_sessions(...) 将改进会话的成本、缓存命中、重试次数写入 ledger

5.3 并行递归的精确流程

harness2/core/recursion.py::run_parallel():

基础 Harness 的 k 次 rollout
  -> 并发生成 k 个 INV(通用)候选
  -> 并发生成 k 个 DOM(领域)候选
  -> 并发执行全部 2k 个候选
  -> 基于候选 Harness 与其执行证据,生成 k 个 AGG(组合)候选
  -> 并发执行 k 个 AGG 候选
  -> AGG1..AGGk 作为最终选择池

其中:

  • INV:不依赖特定领域的通用行为改动。
  • DOM:针对当前领域的行为改动。
  • AGG:根据前两类候选的实际执行差异组合出的最终 Harness。

5.4 串行递归的精确流程

harness2/core/recursion.py::run_sequential():

第 1 轮:base -> inv1 + dom1 -> c1
第 2 轮:c1   -> inv2 + dom2 -> c2
...
第 k 轮:c(k-1) -> invk + domk -> ck

c1..ck 是可供选择的最终 checkpoint。

两种模式均从 k 次基础 Harness rollout 开始。每种模式每任务预算为:

R = 4k 次 executor rollout
P = 3k 次 improver session

预算账本在 harness2/core/ledger.py,其一致性校验由 run_parallel() 和 run_sequential() 末尾的 ledger.assert_identity() 执行。

6. 递归中的证据、选择和经验闭环

flowchart LR Base["基础 Harness 执行"] --> Context["构建证据目录"] Context --> Propose["改进模型提出 Harness 改动"] Propose --> Validate["Tree 校验"] Validate --> Probe["Adapter 执行候选"] Probe --> Compose["组合候选 Harness"] Compose --> Select["匿名选择最终产物"] Select --> Adopt["采用 Harness"] Adopt --> Reflect["反思并提炼经验"] Reflect --> Library["同领域经验库"] Library --> Context
环节 文件和方法 交互说明
证据构建 core/context.py::build() 写入任务、源资料、轨迹、产物、当前 Harness、候选池和领域经验库
改进模型调用 core/proposer.py::Proposer.call() 使用 claude_cli 或 opencode 通道调用模型,并保存审计记录和缓存
选择池 core/selection.py::selection_pool() 只使用最终组合候选,不将基础 rollout 放入正常选择池
匿名选择 core/selection.py::run_selection() 将候选结果匿名为 A/B/...,让选择器只基于产物作选择
单候选快捷路径 core/selection.py::trivial_selection() 当 k=1 时不发起选择器模型会话,直接采用唯一 final
反思 core/selection.py::reflect_adoption() 基于被采用的 Harness、候选执行差异和选择原因生成经验
经验提炼 core/selection.py::_distil() 生成 cue、lesson、evidence、confidence 等结构化经验
经验保存 core/library.py::Library.add() 保存完整已采用 Harness 与 EXPERIENCE.md,重建领域索引

7. Benchmark 和 Runtime 的交互

Benchmark Adapter

每个 benchmark 实现 BenchmarkAdapter 协议,向核心算法提供:

tasks()                发现任务
domain_of()            获取任务所属领域
task_prompt()          提供去除评分标准后的任务描述
task_files()           提供任务原始资料
execute()              执行基础或优化后的 Harness
trajectory()           读取执行轨迹
deliverable_text()     读取产物文本
base_harness()         提供原始 Harness
validate_tree()        执行 benchmark 专属校验
score()                对最终选择结果评分
Benchmark Adapter 任务特点 执行环境
LAB benchmarks/lab.py::LabAdapter 法律任务,按 practice area 分组 上游 LAB runner
JobBench benchmarks/jobbench.py::JobBenchAdapter 职业任务,按 occupation 分组 上游 JobBench runner
WorkBuddy-Bench benchmarks/workbuddy.py::WbAdapter office/web/code,按 role 或 category 分组 Docker + Harbor 批处理

Substrate

Runtime 实现 Harness 安装方式
OpenCode substrate/opencode.py::OpencodeSubstrate 根据 benchmark 使用 workspace、home Jinja 或 workspace config 模式
Codex substrate/codex.py::CodexSubstrate 将 AGENTS.md、.agents、scripts、.codex 安装到工作区根目录

Adapter 负责“做什么任务、怎么真正执行”,Substrate 负责“怎么把 Harness 变成该 Agent Runtime 能加载的形式”。

8. 评分、报告和结果保存

harness2
  -> 生成/选择 Harness 和 rollout
  -> 写 summary.json、selection.json、reflection、Harness Tree

harness2-judge
  -> core/judge.py::judge_selections()
  -> 仅评分已选择的 rollout
  -> 写 judged.json

harness2-report
  -> core/report.py::summarise()
  -> core/report.py::render()
  -> 输出指标、选择来源、回退和未评分告警

评测结果不会反馈给 Propose、Probe、Compose 或选择过程。core/judge.py 明确要求评分失败返回未评分,而不是零分;报告时未评分数据不进入分母。

主要结果目录:

runs/
  <benchmark>/
    adapt/<namespace>/<task>/
      summary.json
      harnesses/
      context/
      selection/
      reflection/
    library/<benchmark>/k<k>-<runtime>/<mode>/<domain>/
      INDEX.md
      harnesses/<task>/harness/
      harnesses/<task>/EXPERIENCE.md
    _audit/
    _sweeps/
    judged.json

9. 安全、可复现与运行约束

安全边界

  • core/context.py::assert_no_leak_paths() 阻止 benchmark 指定的答案文件进入改进模型上下文。
  • core/context.py::assert_no_grader_verdicts() 阻止 judge verdict 或通过率等结果进入模型上下文。
  • core/tree.py 会在 Harness 被执行和保存前再次校验,避免评分信息随 Harness 被传递到后续任务。

可复现性

  • core/schedule.py::stream_order() 按 seed 生成稳定的领域和任务顺序。
  • cli/run_sweep.py::_check_identity() 将模型、任务集、seed、端点等写入 config.json,阻止不兼容实验复用同一结果目录。
  • core/schedule.py::_resume() 校验已选 Harness 指纹、运行目录和产物,确保恢复运行不是盲目复用缓存。
  • install.py 固定上游 commit、打 patch、复制 runner overlay,减少外部依赖漂移。

外部风险

执行器默认网络不受限,公开 benchmark 的 rubric 可能可从 GitHub 或 Hugging Face 获取。正式评测需要在网络层限制执行器访问这些站点;项目本身不会自动做网络隔离。

10. 一句话总结

Harness² 是一个以 Benchmark Adapter + Agent Runtime Substrate + Recursive Harness Optimizer 为核心的实验框架:它用真实执行行为验证 Harness 改动,通过匿名选择采用更优结果,再将经过证据支持的经验保存给同领域后续任务,从而让 Agent 的运行外壳持续演进。

11. Agent 底座:安装、接入与运行

11.1 什么是底座

在 Harness² 中,Agent Runtime 通过 Substrate(底座)接入。底座不是模型供应商配置;它负责让 Harness² 能将可优化 Harness 安装到实际 Agent Runtime,并发起执行、读取轨迹和进行运行前检查。

当前原生底座:

底座 实现 Runtime 实际加载的 Harness
OpenCode harness2/substrate/opencode.py::OpencodeSubstrate 系统提示、guardrails、记忆、工具指导、Skills、子 Agent、脚本、TypeScript 插件
Codex harness2/substrate/codex.py::CodexSubstrate AGENTS.md、.agents/skills/、子 Agent、脚本、.codex/hooks.json

DSH、OpenCode2 等其他 Runtime 当前不是已注册底座。若其文件格式或启动协议与 OpenCode/Codex 不完全兼容,应新增独立 Substrate,而不是直接复制配置文件。

11.2 第一步:安装并配置 Runtime

先让 Runtime 能在本机、容器或远程服务中被调用;这一步本身不等于 Harness² 已能驱动它。当前项目将安装逻辑集中在 harness2-setup,其入口为 harness2/cli/setup.py,具体安装动作位于 harness2/install.py。

OpenCode 的实际安装和运行

uv venv --python 3.12 .venv
source .venv/bin/activate
uv pip install -e '.[render]'

harness2-setup lab
harness2-check --bench lab
harness2 --bench lab --substrate oc --k 1 --mode parallel
harness2-setup 动作 安装位置或结果
拉取固定 OpenCode commit dependencies/opencode/
安装固定 Bun 运行时 dependencies/tools/node_modules/.bin/bun
安装 OpenCode 源码依赖 dependencies/opencode/node_modules/
拉取 benchmark、打 patch、复制 runner dependencies/<benchmark>/
建立 benchmark Python 环境及下载数据 对应 benchmark checkout 内

当前项目从源码通过 Bun 启动 OpenCode,并非依赖全局安装的 OpenCode CLI。若“OpenCode2”指不同主版本或不同产品,必须验证其 Harness 文件格式、插件机制、启动命令和日志格式与当前 OpenCode 是否兼容。

Codex 的实际安装和运行

Codex 除了安装 CLI,还需要一个兼容 Responses API 的模型端点。项目可通过 harness2-bridge 用 LiteLLM 将 Vertex 模型暴露为该端点。

uv pip install -e '.[render,bridge]'

# 单独终端启动;将输出的 HARNESS2_CODEX_* 配置写入 .env。
harness2-bridge

harness2-setup lab --substrate cx
harness2-check --bench lab --substrate cx
harness2 --bench lab --substrate cx --k 1 --mode parallel
harness2-setup --substrate cx 动作 安装位置或结果
npm 安装固定版本 Codex CLI dependencies/codex/
提取 Codex 发行文件 dependencies/codex/dist/
写入模型 provider 配置 dependencies/codex/home/config.toml
保留 benchmark 的通用安装动作 上游 benchmark、runner、依赖和数据仍会安装

harness2-bridge 是模型服务 Bridge,不是新的 Agent Runtime。它只解决“Codex 使用哪个模型端点”的问题。

DSH 的预期安装体验

DSH 目前未被实现为底座。完成接入后,期望用户使用统一命令:

# 以下是接入 DSH 后的目标命令,不是当前仓库可执行命令。
harness2-setup lab --substrate dsh
harness2-check --bench lab --substrate dsh
harness2 --bench lab --substrate dsh --k 1 --mode parallel
DSH 的发布形态 harness2-setup --substrate dsh 应做的事
npm CLI 在 dependencies/dsh/ 安装固定 npm 版本
Python SDK 使用 uv pip install 安装固定依赖版本
二进制 CLI 下载固定版本,校验 hash,写入 dependencies/dsh/bin/
Docker Runtime 拉取或构建固定 image digest
远程 HTTP Agent 服务 不下载 Runtime;校验 URL、API Key、版本和连通性
公司预装 Runtime 校验版本、路径、权限和认证,不重复安装

因此,DSH 若需在本机或容器中运行,应在 harness2/install.py 增加类似 install.dsh() 的安装函数,并由 harness2/cli/setup.py 在 --substrate dsh 时调用;若 DSH 是远程服务,则实现配置和预检即可。

11.3 第二步:接入一个新底座的协议

新 Runtime 应实现 harness2/substrate/base.py::Substrate:

class Substrate(Protocol):
    name: str

    def surface(self) -> SurfaceSpec: ...
    def materialise(self, tree_dir, spec, ctx) -> Install: ...
    def execute(self, task_ref, install, run_ids, timeout) -> list[Path]: ...
    def read_trajectory(self, stream_path, *, obs_trunc, max_chars, args_trunc=400) -> str: ...
    def preflight(self) -> None: ...
接入步骤 新底座要提供的能力 Harness² 的开发内容 是否必需
环境预检 CLI、SDK 或 HTTP API;认证和版本信息 实现 preflight(),检查二进制、端点、凭据和依赖 是
Harness 定义 Runtime 如何加载系统提示、Skill、脚本、插件和 Hook 定义 SurfaceSpec,即该 Runtime 的可编辑文件面 是
Harness 物化 Runtime 的目录、配置或 API 参数格式 实现 materialise(),把通用 Harness Tree 转为 Runtime 原生格式 是
任务启动 CLI 命令、SDK 或容器启动方式 实现 execute(),或由 benchmark 传入专属 launcher 是
轨迹采集 JSONL、事件流、OTel trace 或日志 实现 read_trajectory(),转为统一证据格式 是
结果读取 最终文本、输出目录、生成文件 在 Benchmark Adapter 中读取产物和判断是否交付 是
生命周期 Hook 工具调用前后、任务开始/停止、模型回复等事件 映射为原生 Hook、Plugin 或执行 wrapper 视 Runtime 能力
CLI 接入 Runtime 名称 在 cli/_common.py 增加例如 dsh 的选项和构造逻辑 是
Benchmark 绑定 各 benchmark 的具体启动方式 在 LabAdapter、JobBenchAdapter、WbAdapter 中接入 launcher 按目标 benchmark
测试和文档 最小任务、固定轨迹与预期结果 增加 substrate、adapter 和端到端测试;补充安装说明 是

建议的新文件为 harness2/substrate/dsh.py,参考 opencode.py 和 codex.py。若 DSH 支持 Codex 的 AGENTS.md、Skills、Hook 和 JSONL 轨迹格式,可复用部分 Codex 逻辑;但只有验证其加载语义一致后才能复用。

11.4 第三步:底座实际运行流程

flowchart LR A["预检:CLI、凭据、端点"] --> B["Harness 物化:Tree -> Runtime 原生配置"] B --> C["启动 Runtime 执行任务"] C --> D["Agent 进行模型推理和工具循环"] D --> E["收集轨迹、产物和运行目录"] E --> F["递归选择、反思和经验库"] F --> G["Benchmark 评分与报告"]
生命周期阶段 主要责任方 说明
预检 Harness² + Runtime preflight() 在实际消耗模型资源前检查环境
Harness 物化 Substrate materialise() 把优化后的文件树写成 Runtime 可识别的形式
任务执行 Benchmark Adapter + Substrate Adapter 提供任务和 benchmark 专属 launcher;Substrate 提供 Runtime 行为
模型循环 Runtime Runtime 决定系统提示、工具、Skill、插件和 Hook 如何加载与执行
证据读取 Substrate + Adapter Substrate 解析 Agent 事件;Adapter 读取任务交付物
选择和经验 Harness² Core selection.py 与 library.py 选择结果并沉淀经验
评分 Benchmark Adapter 评分只发生在选择之后,评分结果不会回流给改进流程

11.5 第四步:Runtime 正确加载不等于 Agent 一定使用

“Runtime 正确加载”指 Codex、OpenCode 等执行器确实在预期目录、预期启动参数和权限配置下加载了 Harness 文件。例如,Codex 必须以包含 AGENTS.md 的工作目录启动;若启动目录错误,或 Hook 未被 Runtime 信任,文件存在也不会生效。

但正确加载只代表组件可用,不代表模型一定主动使用。应区分三层:

层级 含义 是否保证执行
可用 Runtime 已识别文件、工具、插件或配置 否
可发现 常驻系统提示或 Skill 描述告诉模型何时使用 否,模型仍可能忽略
强制执行 Runtime Hook、Plugin 或执行 wrapper 自动执行 是,前提是 Runtime 正确实现该机制
组件类型 默认行为 推荐控制方式
系统提示 / AGENTS.md 自动进入模型上下文 写清晰、可执行的规则;但仍属于概率性遵循
Guardrail / Memory / Tool Guidance 通常与常驻上下文一同加载 明确约束和调用条件
Skill 按需读取,不会天然执行 在系统提示中声明触发条件
Script 不会自动运行 由系统提示或 Skill 明确要求执行
Subagent 不会自动委派 规定委派条件、角色和产出要求
MCP Tool 工具可调用,不等于一定调用 提供工具描述;关键路径应补充强制校验
Plugin / Hook 在对应事件上自动执行 适合不能允许模型跳过的控制逻辑

core/tree.py::autotrigger() 会在新增 Skill 未被常驻文本提及时,尝试在 OpenCode 的 guardrails.md 或 Codex 的 AGENTS.md 自动补充触发语句。core/tree.py::validate() 会拒绝没有被常驻文本提及的 Skill,避免出现模型无法发现的“死组件”。

11.6 插件、工具和模型服务的不同接入方式

接入对象 接入层 是否可以成为递归优化对象 推荐方式
完整 Agent Runtime,例如 DSH Substrate 可以 新建 Substrate + benchmark launcher
Runtime 原生 Plugin Harness Tree 可以 放入 SurfaceSpec 定义的插件目录
Runtime Hook Harness Tree 可以 配置原生 Hook;用于强制约束
Skill、脚本、子 Agent Harness Tree 可以 通过常驻提示定义触发条件
MCP Server、外部工具 Runtime 配置或基础设施 可以,但需额外设计 注入 MCP 配置;用 Skill/Hook 管控调用策略
模型供应商/API Runtime 配置或 Bridge 通常不作为 Harness 编辑对象 配置端点,或使用 API bridge
Docker Sidecar、浏览器、沙箱 Benchmark launcher/基础设施 通常不作为 Harness 编辑对象 通过容器镜像、挂载和网络配置接入
Benchmark Judge Benchmark Adapter 不可以 必须与递归证据隔离,防止评分泄漏

项目中的 harness2-bridge 属于模型服务 Bridge,而不是新 Agent Runtime:它使用 LiteLLM 将 Vertex 模型暴露为 Codex 所需的 Responses API。WorkBuddy 的 Docker/Harbor 接入属于 benchmark 执行基础设施,也不是新底座。

11.7 如何选择接入方案

Runtime 条件 推荐方案 接入复杂度
完全兼容 Codex 或 OpenCode 的 Harness、Hook 和日志协议 复用或扩展现有 Substrate 低
有 CLI 和结构化日志,但配置格式不同 新建 Substrate 中
只有 SDK/HTTP API 新建 API 型 Substrate,持久化调用、工具事件和产物 中高
无原生 Hook/Plugin 用 CLI/SDK wrapper 或 sidecar 处理关键生命周期事件 中高
只有最终文本,无工具调用轨迹 可以执行,但递归证据质量较差,需要补 trace 采集 高
需进入 WorkBuddy 等容器 benchmark 增加容器镜像、挂载、网络与凭据传递 高

对“建议性行为”可使用系统提示和 Skill;对“绝不能跳过”的行为,如敏感信息扫描、发布前校验、权限检查或工具调用阻断,应使用 Hook、Plugin、服务端策略或执行 wrapper,不能只依赖模型遵循提示词。

12. Hook 生命周期:最后的强制控制层

Hook 是 Agent Runtime 在固定事件发生时自动调用的程序或命令。它不是模型“想起来才执行”的提示词,也不是一个需要模型主动加载的 Skill。

sequenceDiagram participant U as 用户/任务 participant R as Agent Runtime participant M as 模型 participant H as Hook participant T as 工具 U->>R: 提交任务 R->>H: SessionStart R->>M: 注入系统提示和任务 M->>R: 请求调用工具 R->>H: PreToolUse H-->>R: 允许或阻断 R->>T: 执行工具 T-->>R: 返回工具结果 R->>H: PostToolUse H-->>R: 校验结果或补充反馈 R->>M: 返回观察结果 M->>R: 最终回答 R->>H: Stop

12.1 Hook 在什么时候运行

当前 Codex 底座在 harness2/substrate/codex.py::CODEX_SURFACE 中声明可配置的生命周期事件:

Hook 事件 发生时机 典型用途
SessionStart Agent 会话刚创建 初始化目录、写审计信息、加载运行配置
UserPromptSubmit 用户任务刚提交 任务安全检查、注入补充上下文
PreToolUse Agent 请求工具调用,但工具尚未执行 阻止危险命令、权限检查、强制前置校验
PostToolUse 工具执行完成后 校验输出、扫描敏感信息、记录结果
PermissionRequest Agent 请求额外权限 允许、拒绝或要求人工确认
PreCompact / PostCompact Runtime 压缩上下文前后 保存关键上下文、恢复摘要
SubagentStart / SubagentStop 子 Agent 启动或结束 管理子 Agent、记录成本和产出
Stop 会话即将结束 最终产物校验、清理临时文件、生成审计报告

12.2 Hook 与提示词、Skill 的区别

机制 谁触发 什么时候执行 模型能否跳过
系统提示词 Runtime 注入,模型理解 每轮上下文中存在 可以不遵守
Skill 模型主动读取 模型判断需要时 可以不加载
Script 模型或 Skill 调用 被显式调用时 可以不调用
Hook Runtime 自动触发 指定生命周期事件发生时 不能跳过该事件
Plugin Runtime 加载中间件 工具循环或内部事件中 通常不能跳过

例如,“生成报告前检查敏感信息”若仅写入系统提示,模型可能忘记执行;若在 Stop Hook 中执行扫描脚本,扫描失败可阻断结束并将原因反馈给模型,直到其修复产物。

12.3 Hook 覆盖范围

Hook 只在它监听的事件发生时执行。若 Hook 只监听 PreToolUse 且只匹配 Bash:

模型调用 Bash 工具  -> Hook 执行
模型调用 Write 工具 -> Hook 不执行
模型只输出文本     -> Hook 不执行

因此应根据约束目标选择事件:

目标 推荐 Hook
禁止危险 Shell 命令 PreToolUse,匹配 Bash
每次文件修改后检查格式 PostToolUse,匹配 Write/Edit/Patch
最终交付前验证文件 Stop
子 Agent 必须记录任务 SubagentStart / SubagentStop
会话开始时准备环境 SessionStart

若 DSH 提供原生生命周期事件,应将其映射到上述 Hook 概念并放入 DSH 的可编辑 Harness Surface;若 DSH 没有 Hook/Plugin,则可用 CLI/SDK wrapper、容器 sidecar 或最终产物校验模拟部分强制控制,但无法获得相同的工具循环覆盖度。

13. 模型服务 Bridge:协议桥接开发层

Bridge 是模型服务的 HTTP 协议适配器,不是手机通信,也不是 Agent Runtime 底座。它解决的是“某个 Agent Runtime 如何调用模型”的问题;Substrate 解决的是“Harness² 如何安装、运行和观测该 Agent Runtime”的问题。

flowchart LR Runtime["Agent Runtime\nCodex 或 DSH"] Bridge["Bridge\nHTTP API 协议与认证适配"] Model["模型服务\nVertex AI / 其他 Provider"] Runtime -->|"Runtime 期望的模型 API"| Bridge Bridge -->|"Provider 原生 API"| Model

13.1 当前项目中的 Bridge

harness2-bridge 的实现位于 harness2/cli/bridge.py。它启动本地 LiteLLM HTTP 服务,使 Codex 可通过 OpenAI Responses API 访问 Vertex AI 模型。

Codex CLI
  -> HTTP Responses API
  -> harness2-bridge(LiteLLM)
  -> Vertex AI API
  -> Gemini 或其他可用 Vertex 模型

它会:

  1. 读取 GOOGLE_CLOUD_PROJECT 和 Google Application Default Credentials。
  2. 生成并保存本地服务端口和访问密钥。
  3. 写入 LiteLLM 的模型路由配置。
  4. 输出 HARNESS2_CODEX_BASE_URL、HARNESS2_CODEX_API_KEY 和 HARNESS2_CODEX_MODEL,供 Codex 配置使用。
  5. 对 WorkBuddy 容器场景,支持监听 0.0.0.0,并提供容器访问宿主机的 URL。

该 Bridge 是 HTTP 请求/响应服务,不使用 WebSocket 长连接。

13.2 Bridge、Substrate 与 Harness 的边界

层级 解决的问题 DSH 接入时是否一定要开发
Harness 提示词、Skill、脚本、Hook 如何影响 Agent 行为 通常需要按 DSH 格式映射
Substrate 如何安装 Harness、启动 DSH、读取轨迹和产物 是,除非 DSH 与既有 Runtime 完全兼容
Bridge DSH 如何以某种 API 协议调用模型服务 仅在协议或认证不兼容时需要
模型服务 实际执行模型推理 可复用 Vertex AI、OpenAI、Anthropic 或内部服务

即使 DSH 完全复用现有 Bridge,仍需要 DSH 的 Substrate;反之,DSH 已有可用模型端点,也不代表它已经接入 Harness²。

13.3 DSH 对现有 Bridge 的复用判断

DSH 调用模型的方式 是否能复用 harness2-bridge 所需工作
支持 OpenAI Responses API 通常可以直接复用 将 DSH endpoint 配为 bridge 地址;无需改 Bridge 核心
支持 OpenAI Chat Completions API LiteLLM 通常可支持,但当前 bridge 配置需要确认 扩展模型路由或新增 DSH 配置输出
直接调用 Vertex AI 不需要 Bridge 在 DSH 配置或 SDK 中使用 Vertex 凭据
使用自定义 HTTP/SDK 协议 不能直接复用 Codex 专用配置 新增 DSH 协议适配层或独立 Bridge
在 Docker 容器中调用 可以复用,但须保证容器可访问 配置监听地址、容器 URL、网络与密钥传递
需要不同认证方式 取决于 LiteLLM 和 DSH 支持情况 扩展认证配置或在 Bridge 中实现认证转换

13.4 开发 DSH Bridge 的工作清单

若 DSH 不能直接复用现有 Bridge,建议保持 harness2-bridge 的职责边界,新增独立的 DSH bridge 配置或启动入口,而不要将 DSH 的 Runtime 执行逻辑混入 Bridge。

开发项 内容 典型位置
请求协议适配 接收 DSH 的请求格式,转换为模型服务格式 harness2/cli/dsh_bridge.py 或通用 bridge 模块
响应协议适配 将模型返回、工具调用和流式结果转换为 DSH 期待格式 Bridge 服务层
模型路由 指定模型 ID、Provider、区域和推理参数 .env、LiteLLM 配置或 DSH 配置
认证转接 将 DSH API Key、ADC、服务账号或内部 token 映射给模型服务 Bridge 环境变量和密钥管理
容器网络 为 Docker/Harbor 内的 DSH 提供可访问 URL 0.0.0.0 监听、host.docker.internal、网络策略
健康检查 在运行实验前验证端点、鉴权和模型路由 DshSubstrate.preflight()
安全控制 限制监听地址、保护 bridge key、避免暴露内部模型端点 文件权限、网络策略、短期 token

13.5 DSH 的完整操作链路

1. harness2-setup ... --substrate dsh
   -> 安装或校验 DSH Runtime
   -> 安装或配置 DSH 所需的 Bridge

2. harness2-check ... --substrate dsh
   -> 检查 DSH CLI/SDK、Harness 加载、Bridge 连通性、认证和模型路由

3. harness2 ... --substrate dsh
   -> DshSubstrate 将 Harness Tree 物化为 DSH 配置
   -> benchmark launcher 启动 DSH
   -> DSH 通过 Bridge 或原生 API 调用模型
   -> Harness² 读取 DSH 轨迹、产物并进入递归优化流程

站点信息

关于这篇内容的来源与维护方式

这篇文章由 ToolsHub 公开发布,站点持续维护 AI 工具、在线文档、技术教程和效率实践内容。

我们优先保证公开页面可直接阅读、可分享、可被搜索引擎与 AI 正确理解。