Go 重写 Py 智能体服务后 QPS 从 200 飙到 1200。但 Eino、LCGo、ADK-Go 三个框架怎么选?从 API 设计、架构取舍到生产踩坑,一次横向拆解。
去年年底接手一个内部运维自动化项目时,团队决定用 Go 重写原来的 Py 智能体服务。理由很简单:线上 12 个 goroutine 跑 ReAct loop,Py 版单实例撑不过 200 QPS,CPU 先到 90%。换成 Go 后,同一台 4C8G 机器轻松跑到 1200 QPS,p99 从 1.8s 压到 320ms。问题来了——Go 生态里该用哪个框架?
2026 年 Q1,字节跳动 CloudWeGo 团队的 Eino 在 GitHub 上拿到 10K+ Stars,成为 Go 生态最活跃的 LLM 应用开发框架。同期,G 厂的 ADK 发布 v1.0 GA,Py 生态的 Go 移植版 LCGo 也维持着稳定更新。三个框架,三种设计哲学。本文从 API 设计、架构取舍、生产踩坑三个维度做一次横向拆解。
| Eino(云wego/字节) | LCGo(Py 生态移植) | ADK-Go(GCP) | |
|---|---|---|---|
| 定位 | 工程化 Go 原生框架 | Py 生态的 Go 移植 | GCP 官方 SDK |
| Star | 10K+ | ~6K | ~3K(较新) |
| 编排模型 | 图编排 + 组件抽象 | Chain / Executor | Tool + A2A 协议 |
| 流式处理 | 框架级自动处理 | 手动 Callback | 事件驱动 Streaming |
| 中断/恢复 | 原生 Checkpoint + Resume | 无原生支持 | Session 级别 |
| A2A 协议 | 无 | 无 | 原生支持 |
| MCP 集成 | 通过 eino-ext 逐步支持 | 社区插件 | 原生 |
| 学习曲线 | 中(需理解有向图) | 低(接近 Py 版 API) | 中 |
| 生产案例 | 字节豆包/抖音/扣子数百服务 | 社区项目居多 | GCP 客户 |
拿最基础的使用场景——「装配一个搜索工具,让模型自主决策搜不搜、搜几次」——看三个框架的核心差异。
Eino 装配式 API 最简洁。先创建大模型实例(一行 openai.NewChatModel),然后用 adk 包的装配函数把模型和 Tool 绑定在一起——一个嵌套结构体传参,编译期检查类型。ReAct 循环(调模型 → 判 ToolCall → 执行 → 回传)全部在框架内部闭环,开发者只需通过 Runner 的迭代器消费事件流。
LCGo 直接映射 Py 版的 agents.NewExecutor(agents.NewOpenAIFunctionsAgent(...)),创建完直接 executor.Call(ctx, prompt)。好处是 Py 开发者几乎零学习成本。坏处是 Call 同步阻塞——要做流式输出必须额外注册 StreamingCallback,Tool 的函数签名也比 Py 版啰嗦不少。
G 厂的 ADK 接口完全不同。哪怕只跑一个智能体,也要走 agent.New(...) → NewSupervisor() → AddAgent(...) → supervisor.Run(...) 的层级。Tool 通过 agent.WithTools(agent.NewTool(...)) 注册,输出是事件 channel。核心理念是「多智能体优先」——单模块场景也需要 Supervisor,扩展到多模块时零重构。
三者最关键的差异在于流式处理。Eino 在框架层自动处理流的拼接、合并和分发,LCGo 靠手动 Callback,G 厂的方案靠事件 channel。如果你的场景涉及 3 个以上 Tool 的串联调用且需要实时输出,字节方案在代码简洁性上的优势会非常明显。
三个框架用了完全不同的抽象思路,这比 API 层面的差异更影响长期维护成本。
Py 移植版(LCGo):继承了 Py 生态的面向对象思路。llms.LLM 是接口,chains.Chain 是基类,Executor 继承自 Chain。Go 没有继承,靠组合 + 接口模拟,导致类型嵌套深、泛型使用多、IDE 追踪链路困难。debug 一个「Tool 为什么没被调用」大概率要在 4-5 层抽象里跳转。
G 厂的 ADK:走标准化路线。一切围绕模块 + 工具 + 会话三个核心抽象,通过 A2A 协议做跨服务协作。设计上很像 gRPC——先定义能力契约,再决定谁调用谁。适合已有 GCP 基础设施的团队,脱离该云平台后 MCP 和 A2A 需要额外适配。
字节的 Eino:走 Go 社区最认可的「接口 + 组合」路线。核心抽象只有三个——Component(大模型组件 / Tool / Retriever / Embedding)、Compose(有向图 / Chain / Workflow 编排)、ADK(开箱即用的装配式模块/DeepAgent)。流式处理、Callback 切面、中断恢复全部在框架层统一处理——组件实现者不用关心横切关注点。这套设计直接来源于字节内部数百个 AI 服务的实战经验。
举个例子:在 Eino 里写一个 ReAct 智能体,底层是约 50 行的有向图编排——大模型节点 → Branch 判断是否有 ToolCall → Tools 节点 → 回到大模型。要加「人工审批节点」,只需在 Tools 节点后加 AddLambdaNode("approval", ...) 然后改 Branch 逻辑。框架管流的拼接、状态的 Checkpoint、超时重试。在 Py 移植版里实现同等需求,Callback 叠加只会更重。
这里展示一个接近生产的场景:主控模块拆解任务,调度「研究员」做信息检索,「代码执行」模块跑数据分析脚本,最后汇总成报告。
// 创建子模块:装配大模型 + 专属工具
researcher, _ := adk.NewChatModelAgent(ctx, &adk.ChatModelAgentConfig{
Model: llm, Name: "researcher",
Description: "搜索和分析信息,产出结构化摘要",
})
coder, _ := adk.NewChatModelAgent(ctx, &adk.ChatModelAgentConfig{
Model: llm, Name: "coder",
Description: "编写和执行数据处理脚本",
})
// 主控自动分配任务给子模块
master, _ := deep.New(ctx, &deep.Config{
ChatModel: llm,
SubAgents: []adk.Agent{researcher, coder},
MaxSteps: 15,
})
几个生产部署时必须注意的点:
MaxSteps 必须设。我们一个客户压测时忘了限制,一个复杂任务被拆成 47 步,token 烧了 $3.8 才停下来。Name 和 Description 对主控的分派准确率影响巨大。用「researcher / coder / reviewer」这种动词命名,比「agent1 / agent2」准确率高约 30%(内部 A/B 测试数据)。event.Message.Content 拼接,超过 64K token 的长任务建议引入外部向量存储裁剪历史。问:Go 的 AI 生态不如 Py,用 Go 写智能体会不会缺工具?
工具链方面确实有差距。2026 年大部分 MCP Server 参考实现还是 Py 先出。但 LLM 调用的核心路径——大模型、Tool、Embedding、向量检索——三个框架都已覆盖。字节方案的 eino-ext 持续补充 OpenAI / Claude / Gemini / Ollama / Elasticsearch 等官方实现。如果你需要的是「稳定跑在生产上的智能体服务」而非「快速实验最新 paper」,Go 的类型安全 + 编译期检查带来的是更少的半夜告警。需要 MCP 集成可以参考我们另一篇 Go 语言 MCP Server 实战。
问:从 Py 移植版迁移到 Eino 的成本多大?
取决于用了哪些模块。如果只用了大模型 + Executor + 简单 Tool,迁移基本是「改 import + 改配置结构体」,半天内能搞定。如果深度用了 Memory 和自定义 Chain,需要重新用有向图编排实现——时间翻倍。建议新项目直接用字节方案,存量逐步切。
问:三个框架的性能差距大吗?
在 LLM API 调用耗时占主导(通常 2-8s)的场景下,框架开销可以忽略。有差异的场景在「高并发 Tool 执行」——100 个并发请求同时调搜索 API。字节方案的流处理自动做 goroutine 池化,Py 移植版默认同步调 Tool 需手动开 goroutine。我们的基准测试:100 并发、每个请求 3 次 Tool 调用,Eino 的 p99 比前者低约 18%。G 厂的方案因为事件驱动模型,在此场景下接近 Eino。
问:A2A 协议到底有没有用?
如果系统全部跑在一个进程里,A2A 是多此一举。它的真正价值场景是:研究员模块部署在 A 集群(GPU 节点),执行模块部署在 B 集群(权限隔离沙箱),通过 A2A 跨服务协作。该协议于 2025 年 4 月公布,2026 年 Q1 随 G 厂 Go SDK v1.0 正式稳定。目前字节方案和 Py 移植版都不原生支持,跨服务编排需自己用 gRPC / 消息队列补。
问:有没有推荐的渐进式上手路径?
先用装配式模块跑通单模块 ReAct 任务(含 2-3 个 Tool),这个阶段基本不需要理解有向图。等需求变成「Tool A 的输出需要清洗后再给 Tool B」,再学 compose.NewGraph 做精确节点编排。最后上 DeepAgent 做多模块协同。三步走,每一步对应真实的业务复杂度增长。详细的代码教程可参考 Eino 从入门到多智能体编排。
| 场景 | 推荐框架 | 原因 |
|---|---|---|
| 高并发 API 服务,需流式 + Checkpoint | Eino | 框架级流处理,原生中断恢复,goroutine 池化 |
| 团队刚从 Py 生态转 Go | LCGo | API 风格一致,迁移心智负担最低 |
| 已在 GCP,需跨服务智能体协作 | G 厂 ADK | A2A 原生支持,Gemini 深度集成,Vertex AI 开箱即用 |
| 多智能体协同 + 复杂 Tool 编排 | Eino | DeepAgent + 图编排覆盖全谱 |
| 快速原型验证想法 | LCGo / CrewAI(Py) | 生态丰富,第三方 Tool 接入快 |
| 微服务架构,AI 能力作为中台服务暴露 | Eino | CloudWeGo 生态(Hertz/Kitex)天然适配 |
一句话总结:团队主力语言已经是 Go,新项目起智能体服务直接上 Eino——它是目前 Go 生态里唯一一个经数百个内部服务验证、覆盖「简单 ReAct → 复杂多智能体」全谱的框架。必须跑在 GCP 且需要跨服务 A2A 协作,选 G 厂的 ADK。LCGo 适合快速原型和 Py 向 Go 的过渡期,但生产复杂度上来后其抽象层级会让你踩不少坑。我们在 智能体工程化 95% 失败率分析 中详细讨论过,框架选错只是失败的起点,工程化能力才是决定因素。如果团队需要 Go 后端整体外包,也可以看 Go 后端开发外包选型指南。