
认识 EinoGo 开发者的 AI 应用工具箱《Eino 实战用 Go 构建 AI 应用与智能体》· 第 01 篇关键词Eino、Go、LLM、组件、流程编排、RAG、ADK、Agent适合读者有 Go 开发基础准备接入大模型或正在把 AI 原型改造成业务应用的开发者。第一次接入大模型时很多 Go 开发者的感受是这似乎没有多难。准备一个 API Key构造几条消息调用模型接口再把返回的文本交给前端。一个能聊天的 Demo可能很快就完成了。但第二批需求往往来得更快回答必须参考公司的知识库不能只靠模型已有知识。用户问工单进度时需要查询真实的业务系统。一个问题可能要调用多个接口下一步做什么取决于上一步的结果。前端要实时展示回答用户关闭页面后后端也应该停止运行。涉及修改数据的操作需要权限检查必要时还要人工确认。出错后要能定位是模型失败、检索失败还是某个业务工具出了问题这时问题已经不再是“怎样发起一次模型请求”而是怎样把模型、数据和业务能力组织成一个可维护的应用Eino 正是为这一层问题提供工具的。这篇文章不急着堆代码。我们先建立一张清晰的地图Eino 是什么它有哪些核心能力组件、编排和 Agent 分别解决什么问题以及什么时候值得引入它。一、Eino 是什么又不是什么Eino 是 CloudWeGo 开源的、基于 Go 语言的大模型应用开发框架。官方给出的发音接近 “i know”。可以先用一句话理解它Eino 帮助 Go 开发者把模型、提示模板、检索器和业务工具组合起来并为流程执行与智能体运行提供统一的开发抽象。这里最重要的词是“应用开发框架”。1. Eino 不是大模型它本身不提供一个能够回答问题的模型也不会因为你安装了 Go 依赖就自动获得推理能力。真正生成回答的是你接入的模型服务例如云端模型 API或者通过适配器访问的本地模型服务。Eino 负责组织这些能力而不是代替它们。2. Eino 不只是某个模型厂商的 SDK厂商 SDK 主要帮助你调用某一家服务的接口发请求、收响应、处理厂商特定参数。Eino 的关注点更靠上如何用统一接口表示模型、工具和检索能力如何让多个组件协作如何处理不同节点之间的类型与流式数据如何运行一个会反复调用工具的 Agent如何在执行过程中注入观测、上下文处理或人工确认具体的模型适配器仍可能在内部使用厂商 SDK。两者不是互相排斥的关系。3. Eino 不会替代业务系统引入 Eino并不意味着可以删掉原有的 Service、Repository、鉴权和事务逻辑。更合理的关系是用户 / 前端 ↓ HTTP 服务身份认证、请求校验、租户识别 ↓ AI 应用层Eino 组件、流程或 Agent ↓ 业务服务授权、业务规则、事务、幂等 ↓ 数据库 / 知识索引 / 第三方接口上图中的职责可以按项目需要调整但有一条边界不应模糊模型可以提出行动业务系统必须决定这个行动是否被允许以及如何正确执行。二、为什么“一次模型调用”会变成工程问题我们用一个贯穿本书的例子来理解企业知识与工单助手。最初它只需要帮助客服把工单描述整理成摘要工单描述 → 模型 → 摘要如果业务始终停留在这里直接使用模型 SDK 完全合理。一个封装良好的 Go 函数也许就足够了。但当助手需要回答“这类问题应该怎么处理”时模型不能凭空知道企业内部的处理规范。你需要加入知识检索用户问题 → 检索企业文档 → 组装上下文 → 模型 → 回答当用户问“我的工单现在处理到哪里了”又需要接入工单查询接口。当用户继续说“如果还没分派就转给网络支持组”你还要处理权限、状态检查和修改操作。此时应用至少存在三种复杂性复杂性典型问题能力接入模型、向量检索和业务接口怎样以稳定方式被调用执行组织哪些步骤必须执行哪些步骤依条件选择何时结束运行治理如何处理流式输出、状态、错误、观测和人工介入这些问题当然可以全部手写。框架的价值不是宣称“没有框架就做不了”而是把反复出现的机制统一起来让业务代码更容易组合、测试和维护。也要承认另一面框架会引入概念和依赖。只有节省的重复工作超过学习与维护成本引入它才划算。三、先记住三个概念组件、编排、ADK理解 Eino可以从三个核心能力域入手。它们不是强制的三层架构你也不必同时使用。能力域回答的问题典型对象组件 Components应用具备哪些基本能力ChatModel、ChatTemplate、Retriever、Tool编排 Composition已知流程怎样连接并执行Chain、Graph、Workflow智能体开发套件 ADK怎样让模型动态决定下一步ChatModelAgent、Runner、Middleware一个只做摘要的应用可以仅使用 ChatModel。一个固定先检索、再回答的知识问答服务可以使用组件加 Chain。一个根据用户目标自主选择知识检索、工单查询和其他工具的助手可以使用 ADK。使用 Eino不等于必须把每个需求都做成 Agent。1. 组件把能力变成可以组合的积木组件的价值是让应用依赖相对稳定的能力接口而不是在所有位置直接依赖某个厂商的请求结构。例如业务层需要的是“根据消息生成回答”并不一定需要知道底层 HTTP 请求如何构造。常见组件可以按用途理解组件主要职责在工单助手中的例子ChatModel接收消息生成完整或流式响应总结工单、生成答复ChatTemplate根据变量组织消息模板组合角色要求、资料和用户问题Document Loader从数据源加载文档读取知识库原文Document Transformer转换或切分文档把长文拆成适合检索的片段Embedding将文本转换为向量表示为语义检索准备向量Indexer将文档写入可检索的索引构建企业知识索引Retriever召回与查询相关的文档找出对应的故障处理说明Tool封装可执行的外部能力查询工单、提交受控修改Lambda将自定义 Go 逻辑接入编排清洗输入、转换结构、校验结果另外ToolsNode是编排中执行工具调用的节点。它与单个Tool不是同一个概念前者负责调度执行后者定义具体能力。统一接口也不代表不同实现完全等价。换一个模型适配器后你仍需要验证工具调用、结构化输出、多模态支持、参数语义和实际效果。2. 编排把积木连接成可执行流程假设知识问答的流程已经确定先检索资料不足时明确说明否则结合资料回答。你可以直接写普通 Go 控制流也可以用 Eino 的编排 API 表达这个流程。编排的价值主要在于统一节点连接、检查类型关系、处理流式数据并提供回调与运行选项等机制。它不是用来取代所有函数而是用于表达值得独立管理的数据流与执行关系。3. ADK管理模型驱动的行动循环ADK 是 Agent Development Kit即智能体开发套件。对于开放式请求开发者可能无法提前写死所有步骤。比如“帮我确认这次连接失败可能是什么原因看看有没有类似工单如果需要升级处理先给我一个建议。”助手可能先检索文档再查询历史工单也可能因为信息不足先追问用户。这时需要的不只是固定步骤而是一个能够反复决策、调用工具、接收反馈并继续推进的运行过程。Eino ADK 中的ChatModelAgent就面向这类场景。四、从一个局部示例看组件接口下面的函数演示如何通过 Eino 的模型抽象生成工单摘要。它是局部调用示例不是可直接执行的完整项目。cm由外部初始化并注入模型接入、配置和启动代码将在下一篇展开。packageassistantimport(contexterrorsstringsgithub.com/cloudwego/eino/components/modelgithub.com/cloudwego/eino/schema)// SummarizeTicket 生成摘要草稿不修改工单。funcSummarizeTicket(ctx context.Context,cm model.BaseChatModel,descriptionstring,)(string,error){ifcmnil{return,errors.New(chat model is required)}descriptionstrings.TrimSpace(description)ifdescription{return,errors.New(ticket description is required)}response,err:cm.Generate(ctx,[]*schema.Message{schema.SystemMessage(你负责生成工单摘要。只整理用户提供的事实缺失信息应明确标注不猜测根因或处理结果。,),schema.UserMessage(description),})iferr!nil{// 本例不记录原始请求或响应错误由调用方按策略处理。return,errors.New(ticket summary generation failed)}ifresponsenil||strings.TrimSpace(response.Content){return,errors.New(model returned no summary text)}returnresponse.Content,nil}这个函数没有构建 Graph也没有创建 Agent。它只是依赖一个BaseChatModel调用其Generate方法。但这个小例子已经体现了几个重要设计选择依赖接口而不是在函数内部固定模型厂商。模型初始化与业务调用可以分别管理。输入先校验再调用外部服务。空描述不需要消耗一次模型请求。传递context.Context。超时和取消策略可由调用方设置再由具体实现传递给下游。模型结果只是草稿。提示词要求“不猜测”不等于模型一定不会猜测关键事实仍需验证。不把原始工单随意写进日志。工单可能包含个人信息、内部地址或其他敏感内容。为了把注意力放在组件关系上本例把模型调用错误转换成了固定错误。真实项目应在保持敏感信息脱敏的前提下保留可诊断的错误类别、请求标识和取消状态而不是简单吞掉所有根因。现在可以记住一个朴素结论你可以从一个函数开始使用 Eino再按需求增加编排和 Agent 能力。五、Chain、Graph、Workflow 应该怎么选Eino 提供三组主要的组件编排 API。它们不是“初级、中级、高级”的等级关系而是适合不同的流程表达方式。1. Chain优先表达向前推进的处理链对于下面这种流程Chain 比较直观输入 → 提示模板 → 模型 → 结果转换Chain 是对 Graph 的封装适合顺序处理也能表达分支和并行组合不能简单理解成“只能是一条直线”。它不支持构建环形拓扑。如果需求主要是把几个组件顺着连起来先考虑 Chain往往比一开始就管理所有节点和边更轻便。2. Graph显式控制节点、连接和分支当你需要更灵活的拓扑比如分支、并行、汇聚或循环时可以使用 Graph。┌→ 检索产品文档 ─┐ 用户问题 → 分类 ──┤ ├→ 整理资料 → 生成答复 └→ 查询历史工单 ─┘Graph 由节点和边表达执行关系也支持根据运行时结果决定分支以及在一次执行中管理状态。这里有一个特别容易被误解的地方预定义 Graph意味着开发者规定了可用的节点和流转规则不意味着每次执行路径、模型回答或外部数据都完全一样。如果分支依赖模型分类同一个问题仍可能进入不同路径。如果节点调用外部系统结果也会随系统状态变化。因此“确定性流程”更准确地说是由开发者显式约束的控制结构而不是输出内容必然确定。3. Workflow突出依赖关系与字段映射compose.Workflow面向有向无环图即 DAG并提供结构体字段级的数据映射能力。例如一个节点输出用户问题另一个节点输出业务分类后续节点需要将这些字段组合成新的输入。相比整块数据传递字段映射可以更直接地表达这种关系。需求特征优先考虑主要是向前推进的组件组合Chain需要灵活拓扑尤其涉及循环Graph流程无环节点依赖与字段映射较重要Workflow还要区分两个同名概念compose.Workflow是组件编排 APIADK 的 SequentialAgent、ParallelAgent、LoopAgent 是智能体组合方式。后者不是前者的别名。4.Compile不是 Go 编译器阅读示例时你会经常遇到Compile(ctx)。这里的“编译”是 Eino 框架在程序运行过程中检查编排结构、验证节点间类型关系并构建可执行对象的过程。它不是执行go build也不是把提示词编译成模型。Go 泛型与框架检查可以帮助发现类型连接问题却不能证明提示词正确、检索命中相关资料或者模型回答符合业务要求。六、Agent 的核心不是“聊天”而是决策循环不少人第一次接触 Agent会把它理解成“有角色设定的聊天机器人”。这不够准确。一个系统有聊天框不代表它就是 Agent。固定执行“检索一次再回答一次”的系统也可以使用聊天界面。在本书讨论的工具型 Agent 中更关键的特征是模型在运行时决定下一步行动并根据行动结果继续决策。Eino ADK 的ChatModelAgent可以用下面这个概念模型理解用户目标 当前上下文 ↓ 模型决策 ↓ 是否需要调用工具 ├─ 否 → 返回回答 └─ 是 → 校验并执行工具 ↓ 工具结果加入上下文 ↓ 再次模型决策这是一种 ReAct 风格的循环模型进行决策通过工具行动再利用反馈继续推进。它不要求应用把模型内部的完整思维过程展示出来。模型“调用工具”实际发生了什么假设模型想查询工单它可能输出类似这样的调用信息{name:get_ticket,arguments:{ticket_id:T-1001}}这是简化后的业务示意不代表某一家模型协议的原始响应格式。模型只是生成了工具名称和参数。真正执行 Go 函数、访问数据库或调用 HTTP 接口的是应用运行时及工具实现。因此工具执行前至少需要回答这个工具是否存在参数是否合法当前用户是否能查看这个工单工单是否属于当前租户如果是修改操作是否满足状态约束是否需要审批权限信息应来自可信的认证上下文而不是因为模型传入了一个user_id系统就相信它有权代表该用户。人工确认也不能替代服务端授权。即使用户点了“确认”服务端仍须验证身份与权限。Runner 和 Middleware 分别负责什么Runner是 ADK 中运行 Agent 的入口。应用通过它发起请求并消费事件处理模型输出、工具调用、错误、中断等运行过程信息。这些事件有助于前端展示进度也有助于诊断。它们不等于模型内部隐藏的完整思维链。Middleware 则提供 Agent 生命周期中的扩展点。例如在模型调用前处理上下文在工具调用环节增加校验或调整输出。ADK 还提供中断与恢复等机制但使用这些能力需要相应的配置和存储设计。Checkpoint 用于恢复运行现场不会自动提供长期业务记忆也不会让写操作天然具备幂等性。七、RAG、Tool 和 Agent 不是三个互斥选项理解 Eino 时经常会同时遇到 RAG、工具调用和 Agent。它们描述的是不同维度。RAG让回答参考外部资料RAG 是 Retrieval-Augmented Generation通常译为“检索增强生成”。常见流程是离线或增量处理 企业文档 → 清洗与切分 → 向量化与索引 在线回答 用户问题 → 检索相关片段 → 组织上下文 → 模型生成回答这里展示的是常见的向量检索路线RAG 也可以使用其他检索方式。重要的是RAG 把资料放进模型当前可用的上下文通常不是把这些资料训练进模型参数。它也不保证回答正确。资料可能过期检索可能召回错误片段模型可能误解资料引用也可能无法支持结论。因此仍需要资料治理、效果评估与必要的人工校验。Tool让应用能够执行外部能力查询工单、检索文档、计算费用都可以被封装为工具。工具不一定涉及写操作也不一定需要另一个 Agent。Agent决定何时使用哪些能力Agent 可以把知识检索作为工具也可以调用业务查询工具。反过来RAG 应用完全可以不使用 Agent按固定流程完成检索与回答。例如可以把一个已经验证过的知识问答 Graph 封装为工具再交给 Agent 按需调用Agent理解目标并选择行动 ├─ 知识问答工具 → 固定检索与回答流程 ├─ 工单查询工具 → 业务服务 └─ 工单修改工具 → 授权、确认与受控执行这种组合保留了两种能力的优势开放式决策由 Agent 处理关键业务流程仍由显式代码和流程约束。八、搞清楚三个仓库少走依赖管理的弯路学习 Eino 时经常需要在三个仓库之间切换。仓库主要内容通常什么时候查cloudwego/eino核心类型、组件抽象、compose 编排、ADK、回调与流处理机制理解接口和核心行为cloudwego/eino-ext模型等组件的具体实现、生态集成、回调集成与开发工具接入模型、数据源和外部服务cloudwego/eino-examples示例应用和常见模式的参考代码查看完整用法与项目组合从导入路径也能看到这个分工github.com/cloudwego/eino/schema github.com/cloudwego/eino/components/model github.com/cloudwego/eino/compose github.com/cloudwego/eino/adk github.com/cloudwego/eino-ext/components/model/openai前几项是框架类型与抽象最后一项是某个模型适配器的实现。还需要注意仓库不等于单一 Go Module。eino-ext的许多集成以独立模块发布例如 OpenAI 模型适配器有自己的go.mod和版本。所以不能假设“核心框架是某个版本全部扩展也应使用相同版本号”。实际项目应检查所用模块的依赖要求固定经过验证的组合并提交自己的go.mod与go.sum。官方文档、示例主分支和你安装的依赖也可能处于不同演进阶段。遇到 API 不一致时先核对版本而不是把所有代码片段混在一起。九、什么时候值得引入 Eino没有必要把“使用框架”当成 AI 项目的默认正确答案。可以从复杂度是否已经出现来判断。适合考虑 Eino 的情况多个 AI 能力需要复用。不止一个接口使用模型、提示模板、检索或工具。流程开始出现分支、并行和循环。普通函数之间的连接和状态传递越来越难管理。流式输出成为正式需求。不只是把文本拼完而要处理中间结果、取消和资源释放。确实需要自主工具选择。下一步行动依赖运行结果难以提前写死全部路径。需要统一治理入口。团队希望以一致方式增加回调、观测、运行选项和上下文处理。可以先不用的情况只有一个简单模型调用输入输出都很清晰。正在做一次性的能力验证还没有形成稳定需求。需要的功能主要是某家模型的特殊接口统一抽象反而增加阻力。团队尚未确定业务目标框架选型只是替代了真正的需求讨论。可以使用下面这张简表辅助判断场景建议起点生成一句文案、完成一次摘要厂商 SDK或单独使用 ChatModel固定“加载资料—生成—校验”流程普通 Go 函数复杂度上升后考虑 Chain / Workflow分支、并行、循环较多的 AI 流程Graph根据目标动态选择工具并多步推进ADK ChatModelAgent已有稳定业务流程需要对话式入口Agent 封装为 Tool 的业务流程这不是性能排名也不是严格边界。优先选择能清楚表达需求、团队能够维护的最简单方案。十、把工单助手的第一版范围定小假设现在就要开始项目我不建议第一天同时引入多 Agent、长期记忆、自动规划和复杂审批系统。一个更容易验证的第一版可以只有三项能力根据工单描述生成摘要草稿。检索企业文档生成带来源的处理建议。在当前用户权限范围内查询工单状态。暂时不允许自主修改工单也不需要多个 Agent。这三个能力足以验证几个关键问题模型能否理解业务语言检索能否找到相关资料工具能否安全接入用户是否真的因此节省时间。怎么知道第一版真的有用在写复杂编排之前就应准备一组覆盖典型情况的样本验证项要观察什么工单摘要是否保留事实是否编造根因或处理结果知识问答资料是否相关引用能否支持结论无依据时是否明确说明工单查询是否返回真实状态越权请求是否被业务层拒绝故障处理模型或业务接口超时时是否有清晰错误与可诊断标识使用成本延迟、模型调用次数和费用是否符合业务预期不要只挑“回答得很好”的问题做演示。至少要覆盖无相关资料、信息缺失、权限不足和外部接口失败等情况。对于调用模型的节点既需要测试确定性的代码逻辑也需要用评测样本检查生成效果。前者不能替代后者。当这些基础能力稳定后再决定是否增加动态工具选择、人工审批或多 Agent 协作。架构升级应该由已经出现的问题驱动而不是由框架提供了多少能力驱动。十一、入门时最容易踩的五个误区误区一接入统一接口后所有模型就可以无差别替换统一接口降低的是应用对实现细节的耦合不会消除模型能力差异。替换后仍要验证工具调用、参数支持、输出格式和实际效果。误区二流程编译成功就说明应用可靠编排检查能帮助发现部分结构与类型问题但不能证明业务逻辑正确更不能证明生成内容可信。误区三把“禁止越权”写进系统提示词就完成了安全设计提示词是行为引导不是授权机制。数据访问和写操作必须经过可信的业务校验。误区四有 RAG就不会产生幻觉检索增强只是改善信息来源。召回错误、资料过期和模型误读都可能导致错误回答。误区五Agent 越自主、数量越多系统越先进自主性会增加执行路径与成本的不确定性多 Agent 还会增加上下文传递、协调和故障定位成本。能用一个组件解决的问题不需要额外增加一个智能体团队。十二、小结先决定谁负责什么再决定用哪个 API认识 Eino最重要的不是背下包名而是建立职责边界。模型提供理解与生成能力。组件把模型、检索和工具等能力抽象成可复用接口。编排表达由开发者约束的流程与数据关系。Agent根据目标和反馈动态选择行动。业务系统负责权限、规则、事务、幂等和真实数据。评估与观测帮助你判断应用是否有效并定位问题。Eino 的价值是为这些能力之间的组合提供一致的开发方式而不是把它们全部变成“模型说了算”。如果本篇只记住一句话可以是从最简单、可验证的模型调用开始流程复杂了再引入编排确实需要动态决策时再使用 Agent始终把业务正确性留在可信代码里。下一篇《搭建开发环境创建第一个 Eino 项目》我们会初始化 Go 项目选择并固定依赖版本安全地读取模型配置运行第一次真实调用并检查常见接入问题。参考资料与版本说明本文参考以下官方资料资料核对日期为2026 年 10 月 9 日Eino 官方概述Eino Components 组件说明ChatModel 使用说明Chain、Graph 与 Workflow 编排功能Agent 还是 GraphAI 应用路线辨析五分钟上手 Eino ADKEino 主仓库Eino 扩展仓库Eino 官方示例仓库本文以核心概念和选型为主不涉及 Beta API。局部 Go 示例按Eino v0.9.21接口编写其验证范围仅包括编译检查不代表真实模型调用或生成效果已经通过验证。