
字节笔记本
2026年10月24日 · 约 11 分钟读完
单二进制 Agent 平台:agents-server 总览

本文是《从 0 写 Agent》系列第 34 章。这个系列基于开源项目 agents-go(OpenAI Agents SDK 的 Go 移植版),用 Go 从零实现一个生产级 Agent 运行时;本章讲「agents-server:单二进制平台总览」。
前 33 章,我们拆了 Agent 的所有组件,内核、Session、HITL、Tracing、MCP、Sandbox。但这些都是"零件"。
Part VI 把它们组装成一辆"车",agents-server,一个完整的 Agent Web 平台。单二进制部署、内嵌前端、SQLite、开箱即用。这一章是 Part VI 的总览,看它怎么把所有零件装配起来。
引子:从零件到产品
你能写出 Agent 内核了(Part I-III),也懂了工程化(Part IV-V)。但如果让你做一个"用户能在浏览器里配 Agent、跑对话、看 trace"的 Web 平台,怎么搭?
agents-server 就是答案,它用 agents-go SDK 做底层,上面套了一层 Web 应用。它是"SDK 怎么变成产品"的范本。

四层架构
agents-server 分四层 + 一个协议层 + 一个桥接层:
cmd/ 入口(cobra CLI)
└── cmd/root.go 启动装配:建 DB、装 store、装 bridge、装 handler、起 server
internal/
├── server/ HTTP/WS 引擎层(Gin 路由、鉴权、静态文件、WS)
├── handler/ HTTP/WS 请求处理(13 个 handler,每个对应一个资源域)
├── store/ 持久层(bun ORM + SQLite):models、泛型 CrudStore
├── bridge/ SDK 桥接层:DB 配置 → SDK Agent、跑流式、OAuth
├── protocol/ WS 消息信封与 payload 类型
└── web/ go:embed 前端静态资源各层职责
| 层 | 职责 | 关键设计 |
|---|---|---|
| server | HTTP/WS 引擎、鉴权、SPA fallback | Gin + Token 中间件 |
| handler | 处理 HTTP/WS 请求 | 每个 handler 一个结构体 + 一组方法 |
| store | 持久化 | 泛型 CrudStore + JSON 扩展列 |
| bridge | 连接 DB 和 SDK | 把 AgentConfig 组装成 SDK Agent |
| protocol | WS 消息类型 | 事件信封 |
| web | 前端 | go:embed + 零构建 |
装配:手动依赖注入
agents-server 不用 DI 框架(Wire、Dig),手动装配。cmd/root.go 的 run() 函数(root.go:51)是核心:
// cmd/root.go:51(骨架)
func run() error {
// 1. 数据库
db := store.NewSQLiteDB("data.db")
store.CreateSchema(db)
// 2. 构造 11 个 store(每个资源一个)
sessionStore := store.NewSessionStore(db)
agentConfigStore := store.NewAgentConfigStore(db)
// ... 9 个更多
// 3. 构造 bridge 层(SDK 桥接)
mcpManager := bridge.NewMcpManager(...)
sandboxManager := bridge.NewSandboxManager(...)
runner := bridge.NewRunner(...)
// 4. 构造 13 个 handler(注入 store 和 bridge)
sessionHandler := handler.NewSessionHandler(sessionStore)
agentConfigHandler := handler.NewAgentConfigHandler(agentConfigStore)
// ... 11 个更多
// 5. 装配路由(把 handler 方法挂到 Gin)
srv := server.New(token)
srv.RegisterRoutes(server.Routes{
ListSessions: sessionHandler.List,
CreateSession: sessionHandler.Create,
// ... 所有路由
})
// 6. 起服务
srv.Serve(":8080")
}手动装配的好处,依赖关系一目了然(看 run() 函数就知道谁依赖谁),没有魔法。代价,run() 函数会很长,加新功能要改装配代码。但对中等规模项目,手动 DI 比框架 DI 更清晰。
Routes 结构体注入
注意 RegisterRoutes 接收一个 Routes 结构体,所有 handler 方法作为函数值塞进去:
srv.RegisterRoutes(server.Routes{
ListSessions: sessionHandler.List, // 函数值
CreateSession: sessionHandler.Create,
// ...
})server 层只认 gin.HandlerFunc,不依赖具体 handler 类型。 这是"装配在 root、解耦在 server"的干净分离。
bridge 层:DB 配置 → SDK Agent
bridge 是最关键的一层,它把数据库里的配置(AgentConfig)转换成 SDK 能跑的 *agents.Agent:
用户在 UI 配置 Agent(存 DB)
→ bridge.BuildFullAgent(agentConfig)
→ 读 model/instructions/tools/handoffs/guardrails
→ 构造 *agents.Agent
→ 挂 MCP servers、sandbox、guardrails
→ 返回可运行的 Agenthandler 不直接碰 SDK,它通过 bridge。这让 handler 只管 HTTP 进出,bridge 只管 SDK 组装。职责清晰。
单二进制部署
agents-server 编译出一个二进制,包含一切:
agents-server(一个二进制)
├── Go 后端(Gin + SDK)
├── 前端静态文件(go:embed 进二进制)
├── SQLite 数据库文件(运行时生成)
└── 无外部依赖部署就是 ./agents-server --port 8080。 不用装 Python、不用配数据库、不用 nginx、不用 Docker(虽然也能 Docker 跑)。这是 Go 单二进制的终极优势。
第 38 章详讲 go:embed 怎么把前端打进二进制。
启动流程
完整的启动(root.go:51-221):
- 日志,zerolog + ConsoleWriter
- 数据库,SQLite WAL 模式(并发读友好),建全部 10 张表
- store,11 个 store
- bridge,MCP manager(自动重连)、Sandbox manager、OAuth coordinator
- handler,13 个
- token,没配则自动生成 16 字节随机 hex
- server,注册路由、挂静态文件、监听 127.0.0.1:port
- 优雅关闭,SIGINT/SIGTERM → 5 秒超时 Shutdown
第 35-39 章会分别深入数据库、WebSocket、HITL、前端、OAuth。
小结
读完这一章,你应该理解 agents-server 的全局:
- 四层架构,server(引擎)/ handler(请求)/ store(持久化)/ bridge(SDK 桥接)
- 手动 DI,run() 函数装配一切,清晰无魔法
- bridge 是核心,DB 配置 → SDK Agent 的转换层
- 单二进制,后端 + 前端 + SQLite 全在一个文件
agents-server 是"SDK 变成产品"的范本。 接下来五章深入它的关键实现。
下一篇
第 35 章,数据库设计:10 张表与 JSON 扩展列。agents-server 用 bun ORM + SQLite,10 张表,大量 JSON 列承载扩展性。泛型 CrudStore 让 CRUD 不重复。
本文是《从 0 写 Agent》系列第 34 章,案例代码基于开源项目 agents-go(OpenAI Agents SDK 的 Go 移植版)。全系列目录见总览。

