一句话
不需要学六个框架。深入理解一个 runtime,从 handler 到部署完全掌控。
问题
大多数 AI 工程师决定认真做 Agent 时,不知道到底该构建什么:
- 有人选 LangChain,因为 multi-agent demo 在 YouTube 上看起来很干净,然后花两周和 Python interop、async runtime mismatch 搏斗,最后全部 scrapping
- 有人从零构建自定义编排层:loop、session store、context assembler——结果基础设施吃掉了时间线,真正的 Agent 从没完成
- 有人复制 hello-world webhook 示例,拿到 JSON response,以为自己懂了,然后 shipped 的东西在会话超过 10 分钟、远程沙箱中途宕机、或上下文窗口填满且没有配置 compaction 时第一次就崩了
结果通常一样:大量 plumbing,没有生产 Agent,没有对生产级 Agent runtime 实际长什么样的心智模型。
目标
如果你要在 2026 年构建和 ship 真正的 Agent,你需要学会:
- 连接三层架构,让 handler 逻辑在 provider 切换和 target 变化时无需 touching agent code
- 正确使用 sessions 和 tasks,让长任务不污染自己的上下文
- 编写 roles 和 skills,塑造模型行为而无需重新编译
- 配置 compaction,让运行两小时的会话不会在一小时开始幻觉
- 将 HttpSessionEnv 指向远程沙箱,让二进制在本地运行而执行在 Linux 上
- 选择正确的 build target(native、node、Cloudflare)而无需重写 agent logic
- 生成 connectors 而非手写 adapters,并理解在真实负载下这个区别为什么重要
代码库结构
agentic-harness/
├── crates/
│ ├── agentic-harness — SDK: AgentApp, sessions, tasks, roles, skills,
│ │ ModelClient, tools, HttpSessionEnv, HTTP/SSE serving
│ └── agentic-harness-cli — CLI: guide, code, new, dev, run, build, serve,
│ host, doctor, dashboard, inspect, sandbox, add, smoke
├── examples/
│ └── hello-world — minimal webhook agent
├── docs/ — architecture, targets, runtime config, HTTP protocol,
│ Cloudflare boundary, deployment guides
├── Formula/ — Homebrew formula
└── scripts/
└── install.sh — tarball install
两个 crate。一个二进制。每个执行目标都是配置选择,不是重写。
- SDK 是拉进任何 Rust 项目的库。CLI 包装它。
cargo build就是整个 pipeline。没有 bundler。没有 transpile。目标机器不需要语言运行时。- 一个自包含的可执行文件 + manifest.json。
核心设计约束
同一个 Agent 二进制应该:
- 在笔记本上以交互模式运行
- 在 GitHub Actions job 中 clone 新 repo 后运行
- 通过 HTTP 对远程 E2B 沙箱运行
- 在 Cloudflare Worker boundary 上运行
无需改变一行 agent logic。
代码库中的每个决策都是为了尊重这个约束。
三层同心圆心智模型
外环:你的 Rust 代码
- 编写 handlers。handlers 接收 AgentContext。
- 调用 sessions。sessions 调用模型、读文件、写文件、运行 shell 命令、spawn tasks、连接 MCP servers。
- 从不直接 touch HTTP client。从不直接解析模型响应。 SDK 处理两者。
中环:Harness
- 管理 agent registry、按 URL path 路由 identity、跨调用持久化 session、context compaction、role 和 skill 发现、模型选择优先级、provider-neutral ModelClient trait。
- 让你在不 touching handler code 的情况下 swap Anthropic ↔ OpenAI ↔ 本地 Ollama。
- 处理所有生产中损坏的东西:session state、context overflow、provider failures、并发请求排序。
内环:执行目标
- 本地文件系统。CI checkout。指向 Daytona 或 E2B 的 HttpSessionEnv。Cloudflare Worker boundary。
- Harness 不关心你用哪个。handlers 也不关心。
- 调用
session.read()和session.write(),harness 翻译成底层 target 需要的任何东西。
这个分离就是全部意义。 E2B 发布新 API 版本时,你更新 connector,不是 agent logic。Anthropic 发布 claude-opus-4-7 时,你更新 runtime.json,不是 handlers。
Runtime 配置
{
"defaultModel": "anthropic/claude-sonnet-4-6",
"openaiCompatibleModels": ["anthropic/claude-sonnet-4-6"],
"providers": {
"anthropic": {
"baseUrl": "https://api.anthropic.com/v1",
"apiKeyEnv": "ANTHROPIC_API_KEY"
}
}
}
放在 .agentic-harness/config.json 或工作区根目录的 agentic-harness.json。load_workspace_context() 自动读取。
模型选择优先级:
PromptOptions::model(...)—— 每次调用覆盖- 选定 role 的 model metadata —— 每 role 默认
defaultModelfrom runtime config —— 工作区默认
关键:模型 ID 必须先注册才能使用。openaiCompatibleModels 是 harness 用来连接内置 chat-completions client 的列表。如果模型不在列表中,启动时得到 clean error,而不是会话中期的 confusing failure。
Agent Identity
没有 agent ID 系统。没有 registry key。没有自己生成的 UUID。
Agent 的 identity 是 POST /agents/<name>/<id>。
# 启动会话或继续现有会话
curl http://localhost:3583/agents/codebot/pr-review-447 \
-H "Content-Type: application/json" \
-d '{"pr_number": 447, "repo": "my-org/my-repo"}'
# 相同 id = 相同会话,历史延续
curl http://localhost:3583/agents/codebot/pr-review-447 \
-H "Content-Type: application/json" \
-d '{"pr_number": 447, "repo": "my-org/my-repo"}'
核心洞察
- 三层分离让 agent logic 免疫于 provider/target churn
- Context compaction 是长会话可靠性的生死线
- Cargo build = whole pipeline,极简部署
- 6 周踩坑经验浓缩为可复制的技术指南
- 生产 Agent 不是 demo,是 handler + harness + target 的协同工程
资源
- X 线程:https://x.com/av1dlive/status/2054238056090325492
- 基于:agentic-harness 代码库
- 灵感来源:@Vtrivedy10 的 harness 概念