Technical note · Agent systems · 中文
我们没有为 Agent Builder
画一条 Workflow
从 Skill-based Agent Creation 到 Coding-Agent Harness:一次关于 Tools、persistent sandbox、validation 与 secrets 的架构迭代。
The design shift
我们不断删掉 boxes,直到只剩边界。
不是让模型更努力,而是让环境、反馈和约束变得可读、可执行。
Workflow we almost built
Harness we shipped
让一个 Agent 帮用户创建另一个 Agent,听起来像一个自然的产品功能。用户上传一份SKILL.md,或者粘贴一个公开 GitHub 仓库;Builder 读取内容、生成配置、运行测试、修复错误,最后发布一个可以直接运行的 Agent。
真正开始设计后,我们发现最困难的不是“让模型生成一个 AgentBundle”,而是决定:什么应该交给模型判断,什么必须由平台确定性地保证。
Agent Builder 不应该是一条预先写好的 Agent 创建工作流。它应该是一个运行在严格 Harness 中的 Coding Agent。
下面记录的不是一次从需求直接走向实现的过程。它更像一系列删除:每当我们准备增加一个 workflow node,就重新问一次——这是平台必须提供的能力,还是模型本来就会做的事情?
01 / Decision
先把 Validation 和 Evaluation 分开
我们最先讨论的是:Builder 和 Evaluator 应该合并,还是拆成两个相互调用的 Agent?直觉上,Builder 负责生成,Evaluator 负责测试,然后 Builder 根据反馈继续修改。
继续往下拆,才发现这里混合了两个完全不同的问题。
Validation
Bundle 是否完整、Tool 是否存在、Credential binding 是否合法、Runtime 能否加载、基础 Test Run 是否成功。
Evaluation
回答是否有用、Tool 选择是否合理、多轮对话是否稳定、输出是否符合用户真正的期待。
Validation 是平台责任,应该是确定性的 Publish gate。Evaluation 则是一个独立、通用而复杂的能力,未来可以评估平台上的任意 Agent,不必绑在 Builder 上。
所以 publish_agent 必须验证当前的确切 revision。失败就返回结构化错误,让 Builder 在 ReAct loop 中继续修复;模型永远不能绕过这道门。
02 / Decision
GitHub 专用 Workflow 是怎么被删掉的
为了支持任意公开 GitHub repo,我们一度设计了 inspect_github_repo、RepoSnapshot、assessment、run_repo_checks 和 candidate extraction。
一个问题让这个设计开始松动:为什么一个确定性读取 Tool,需要模型把自己的 assessment 当作参数再传回来?如果 Tool 的职责是读取,它就应该只读取。语义判断属于模型。
接着,run_repo_checks 被已有的 run_sandbox取代。再往前一步,GitHub Trees、Contents 和 Blob API 虽然可以做出干净的 Repo Reader,但任意仓库真正需要的操作仍然是查看目录、搜索文件、读 README、运行命令、修改文件、重新测试。
git clone --depth 1 <public-repo-url> /work/source这正是 Coding Agent 已经擅长的工作。我们最终不再把 Git 和文件系统拆成更多业务节点,而是让模型在受控 workspace 里自主探索。用户也不需要理解 branch、commit 或 snapshot;默认分支就是工作对象。
“向用户提问”不是失败状态,而是 Agent loop 中的一等行为。
如果还没有 URL,Builder 应该回复“Please paste the public GitHub repository URL”,并且产生零次 Tool call。如果存在多个合理候选,它应该展示并推荐;如果核心能力无法安全转换,它应该解释原因,而不是创建缩水版 Agent。
03 / Decision
Persistent workspace 是能力,不只是优化
早期的 run_sandbox 每调用一次,就创建环境、执行命令,然后销毁。这对一次性代码执行足够,但对 Coding Agent 来说,它意味着每一次错误都要重新安装依赖和重建上下文。
clone → install → test → error
sandbox destroyed
edit → install again → test again
真正的工程工作依赖连续状态。于是 sandbox 被提升为持久化 workspace 的执行环境:同一个 Builder session 可以持续使用 /work 中的源码、依赖、生成 artifacts 和测试结果,同时由 TTL 和清理策略限定生命周期。
对公开仓库,没有必要额外断网;Sandbox 可以访问公开网络,但不能访问 OmniVibe 内部资源,也不会自动获得平台或用户的 Credentials。更重要的是,它始终是 secretless 的。
这与最近 Harness Engineering 的经验一致:模型能力只是其中一部分,持续环境、可检查 artifacts 和明确反馈回路,往往决定长任务能否完成。OpenAI 强调了 Agent legibility 与机械约束;Anthropic 则把可持续 artifacts 作为跨 session 推进的核心。
04 / Decision
Secret 不是数据,而是一项 Capability
平台提供的标准 Tool 很容易保护 Secret:Agent 只看 Tool schema 和返回结果,API Key 始终留在可信平台侧。 真正困难的是用户 Bring Your Own Secret——平台不知道用户要调用什么 API,也不可能提前表达所有认证方式和参数形状。
固定的 credentialed HTTP broker 足够安全,但仍然受限于 Config。转折点来自一个更直接的假设:Builder 本身就是一个有很强代码能力的 Agent,具体 Tool implementation 完全可以由它来写。
关键不是禁止 AI 写代码,而是让它写出的代码永远拿不到 Secret。
Builder 在 workspace 中写入 tool.yaml、Python entrypoint 和 input schema,然后调用 register_agent_tool(path)。平台只做确定性检查:路径、语法、依赖、 Credential binding、entrypoint 和 allowed hosts。
01
Generated code
02
HTTP effect
03
Trusted host
04
External API
05
Replay response
Generated Tool 代码调用 ctx.http.request(...) 时,并不直接发出网络请求。它产生一个 effect;可信 Host 校验 HTTPS、精确 hostname、公开 DNS、redirect、请求大小和 Credential binding,随后在 Sandbox 外注入 Secret。响应再被 replay 回去。
Model context、Tool code 和 Sandbox environment 从始至终都看不到 Credential 本身。
05 / Decision
最后,Builder 只剩 Context、Workspace 和 Tools
收敛之后,Builder 不再需要复杂的预定义 workflow。它只需要三个部分。
Context
Soul 和 Skills 解释平台约束、Bundle 格式、提问时机与停止条件。细节按需读取,而不是塞满 System Prompt。
Workspace
/work 同时是外部工作记忆和可执行 artifact:源码、分析笔记、AgentBundle、Generated Tool 与测试结果都在那里。
Tools
少量稳定原语负责执行、保存、注册、请求授权、验证和发布,但不替模型做 assessment。
run_sandbox
save_agent(path)
register_agent_tool(path)
get_agent_bundle
request_agent_credentials
validate_agent
publish_agent这些 Tool 不负责替模型思考。比如 register_agent_tool只接收 workspace path,不接收 assessment,也不会允许模型声明“这段代码是安全的”。模型负责创造和判断,Tool 负责执行和验证。
LangChain 对 Deep Agents 的定位也很接近:核心仍然是 Tool-calling loop,能力差异来自 filesystem、context management 和 execution harness。他们的后续实验还展示了只修改 Harness、自验证和 tracing 对表现的影响。
06 / Decision
Loop Engineering 不是规定“修三次”
我们最初想过“自动生成测试,然后最多修复三轮”。后来放弃了固定次数。固定三轮只是 workflow 参数,并没有表达真正的停止条件:有些问题一次就能修好,有些需要五次,还有些必须等用户提供信息。
只要错误仍然可操作,而且 Agent 还在取得进展,就继续。真正的停止条件是:需要用户选择、缺少授权、核心能力无法转换、出现平台级错误、资源不再合理,或者模型正在重复同一种失败。
所以 Loop Engineering 的重点不是循环次数,而是错误是否可修、执行结果是否真实可见、workspace 是否保留状态,以及系统能否识别没有新信息的 doom loop。
07 / Decision
AgentBundle 是 Artifact,ValidationRun 是 Event
这次设计还顺手简化了数据模型。我们没有继续引入另一套 AgentRelease,也暂时砍掉了没人使用的 Import/Export。AgentBundle 本身就是 Runtime 的 canonical artifact:它描述 Agent 是什么、有哪些 Skills 与 Tools、如何加载、需要哪些 Credentials。
但 AgentValidationRun 不应该成为 Bundle 里的一个普通 field。同一个 Bundle revision 可以被验证多次,每一次都有时间、日志、错误和执行环境。
AgentBundle 描述状态;ValidationRun 描述某一次发生过的事情。
Bundle 保持稳定、可哈希;ValidationRun 独立保存历史;Publish 只接受已经通过 Validation 的确切 revision。
What survived
- 01不要把模型的智能提前编码成 Workflow。
- 02确定性 Tool 不应该接收语义判断。
- 03向用户提问是一种正常的 Agent action。
- 04Persistent state 是 Agent 能力的一部分。
- 05Secret 应该被建模成 Capability,而不是 Context。
- 06约束边界,而不是约束实现过程。
Conclusion
我们构建的不是一条创建 Agent 的流水线。
真正重要的是边界:模型决定如何理解意图和仓库;Workspace 保存可运行的中间结果;Tools 提供稳定原语;Validation 保证平台不变量;Trusted runtime 控制 Secrets 和外部副作用;用户在真正有歧义的地方重新进入 Loop。
当模型变得更强时,我们不需要重新设计整条 Workflow。更强的模型可以直接在同一个 Harness 中更好地读代码、选择方案、编写 Tool 和修复错误。
我们真正构建的,是一个能够在安全边界内工作的 Agent Engineer。
Further reading