Go 语言架构|Google ADK Go 深入拆解:把 Agent 写进 Go 的工程流水线

Go 语言架构|Google ADK Go 深入拆解:把 Agent 写进 Go 的工程流水线 原文:Agent Development Kit (ADK) for Go 作者:Google ADK Go 团队(Google 官方开源项目维护者) 来源:GitHub,发布于 2025 年 11 月 06 日 我最近重新看了一遍 Google 的 ADK Go。它吸引我的地方,并不是“Go 也有一个 AI 框架”,而是它试图回答一个更实际的问题:一个会调用模型、工具和其他 Agent 的系统,能不能像普通 Go 服务一样被编译、被测试、被部署和被审查? 这篇文章不打算把官方 API 逐个翻译一遍。我会沿着自己的理解,把 Agent、工具、工作流、协议、状态和上下文串起来,也会特别标出 v1 与 v2 的边界。文中的蓝色表示工具或事实,绿色表示我的实践判断,红色表示容易踩的坑,黄色底色表示可以直接拿去用的做法。 先看 ADK Go 为什么值得单独关注。 我认为,ADK Go 的重点不是证明“Go 比 Python 快”,而是让 Agent 代码进入成熟的软件工程流程。Go 项目已有的编译器、静态检查、单元测试、依赖管理、CI 和容器化能力,都可以继续使用。 ...

2026-09-03 · 3 min · 438 words · FunkyGod

AI 编程时代,我愿意用 Go 做后端

AI 编程时代,我愿意用 Go 做后端 AI 编程工具越来越会写代码,但真正把一个 AI 应用跑到线上,难点从来不只是"能不能生成一个接口"。请求超时怎么处理,模型服务失败后怎么重试,流式响应如何关闭,服务占多少内存,镜像怎样发布,出了问题能不能快速回滚,这些才是后端每天要面对的事情。 我越来越愿意把 Go 放在 AI 应用的后端位置:让 AI 负责加快实现,让 Go 负责把边界、资源和部署约束固定下来。这里说的不是把模型训练和推理强行改写成 Go,而是模型外围的 API、网关、任务和编排服务。蓝色文字表示语言和工程特性,绿色文字表示我的实践判断,红色文字表示容易被忽略的风险,黄色底色表示可以直接采用的做法。 一、Go 不会让 AI 更聪明,但会让错误更快暴露 我用 AI 写后端时,最常见的情况不是代码完全不能运行,而是它给出了一条顺利路径,却把失败路径一笔带过。比如调用大模型时,AI 很容易生成下面这种代码: func AskModel(prompt string) string { resp, _ := http.Get("http://model:8080/v1/chat") body, _ := io.ReadAll(resp.Body) return string(body) } 这段代码的问题很多:忽略了网络错误,没有关闭响应体,没有设置超时,也没有检查状态码。它可能在本地演示中返回结果,但一旦模型服务变慢,连接就可能长期占用;一旦服务返回 500,调用方拿到的可能仍然是一段错误页面。 Go 的显式语法会把这些问题推到台面上。error 必须被接收,类型转换必须写明,defer、context 和 goroutine 的生命周期也不会凭空消失。 这对 AI 生成代码形成了一种很有价值的约束:编译器先拦住低级问题,人再检查业务决策。 例如,我会要求模型先生成一个"责任完整的版本": var ErrModelUnavailable = errors.New("model service unavailable") func AskModel(ctx context.Context, client *http.Client, endpoint string, prompt string) ([]byte, error) { payload, err := json.Marshal(map[string]string{"prompt": prompt}) if err != nil { return nil, fmt.Errorf("encode model request: %w", err) } req, err := http.NewRequestWithContext(ctx, http.MethodPost, endpoint, bytes.NewReader(payload)) if err != nil { return nil, fmt.Errorf("create model request: %w", err) } req.Header.Set("Content-Type", "application/json") resp, err := client.Do(req) if err != nil { return nil, fmt.Errorf("call model: %w", err) } defer resp.Body.Close() if resp.StatusCode < http.StatusOK || resp.StatusCode >= http.StatusMultipleChoices { return nil, fmt.Errorf("model returned status %d: %w", resp.StatusCode, ErrModelUnavailable) } body, err := io.ReadAll(io.LimitReader(resp.Body, 4<<20)) if err != nil { return nil, fmt.Errorf("read model response: %w", err) } return body, nil } 这里不是说 Go 写起来没有重复代码,而是每个关键动作都落到具体的代码位置:编码、请求、响应、释放、超时、错误,全都看得见也改得动。 ...

2026-08-24 · 4 min · 666 words · FunkyGod

Go + Python 混合开发:两种语言的协同,我觉得很舒服

Go + Python 混合开发:两种语言的协同,我觉得很舒服 原文:Python 与 Go 混合开发 | 让 Golang 编程更丝滑 作者:原文信息未提供 来源:用户提供原文标题,发布平台及发布日期未详 很多团队并不是在 Go 和 Python 之间二选一,而是在同一个系统里同时使用它们:Python 负责模型、数据和快速试验,Go 负责服务、任务、网络和部署。 这种组合听起来很自然,真正做起来却经常出现另一种结果:两边各自开发都很顺,连在一起就变得不顺。调用延迟、数据转换、错误处理、版本发布和线上排障,很快会把“语言互补”变成“系统加倍复杂”。 原文从开发体验出发讨论 Python 与 Go 的混合使用。本文在这个基础上往前走一步:混合开发的核心不是把两种语言硬塞进一个进程,而是为变化速度不同的模块设计清晰、可观察、可演进的边界。 蓝色文字表示核心判断,绿色文字表示个人开发实践,红色文字表示风险提示,黄色底色表示可以直接执行的建议。 一、先纠正一个误区:混合开发不是“Python 慢、Go 快” 用“Python 负责灵活,Go 负责性能”概括两种语言,虽然容易理解,但不够准确。 Python 的价值不只在于写得快。它连接着成熟的数据处理、科学计算、机器学习和实验工具链。研究人员或业务工程师可以很快把数据读进来,换一个模型,调整参数,观察结果,再决定下一步怎么做。这个阶段最宝贵的是试错速度和生态覆盖面。 Go 的价值也不只是运行速度。它的静态类型、编译器、并发模型、标准库和独立二进制发布方式,更适合承载长期运行的服务和工具。一个网关、任务调度器、文件处理器或消息消费者,往往要面对超时、取消、限流、重试、优雅退出和故障恢复。这些问题的难点不在于写出第一版,而在于运行数月后仍然清楚、稳定、可维护。 所以,合理的分工不是“把慢的代码改成 Go”,而是看模块的主要矛盾是什么: 变化快、需要不断试验、依赖模型和数据生态的部分,优先考虑 Python; 需要长期运行、并发处理、跨平台发布和严格运维的部分,优先考虑 Go; 两者都能完成、但没有明确收益的部分,不要为了“混合”而混合。 语言边界应该服从业务边界。一个稳定的 Python 服务,通常比一个为了追求统一而重写的 Go 服务更有价值;一个需要高并发和强约束的 Go 组件,也不应该因为团队已经熟悉 Python 就继续堆补丁。 二、最常见的协同架构:Python 做变化,Go 做秩序 在 AI、数据和平台型系统中,可以把职责粗略分成四层。 1. Python:模型和数据层 Python 适合放置以下内容: 模型加载、推理和评测; 特征处理、数据清洗和离线任务; 提示词编排、实验脚本和策略验证; 需要频繁调整的业务规则; 对第三方 AI、科学计算或数据工具的适配。 这一层的代码变化频率通常较高。它不一定要承担所有外部流量,也不一定要直接管理复杂的重试和权限体系。 ...

2026-08-20 · 4 min · 656 words · FunkyGod

Go 是 AI 辅助软件工程的理想语言:原文解读与深入思考

Go 是 AI 辅助软件工程的理想语言:原文解读与深入思考 原文:Why Go is an Ideal Language for AI-Assisted Software Engineering 作者:Cameron Balahan(Go 产品组经理)、Richard Seroter(Google Cloud 首席布道师) 来源:Google Developers Blog 发布日期:2026 年 8 月 11 日 本文分两部分:第一部分忠实解读原文,还原文章的论证结构与核心观点;第二部分跳出原文,从批判性视角深入探讨这篇文章没有说透、值得追问的地方。 第一部分:原文解读 1. 文章的出发点:软件工程正在发生范式转移 文章开篇没有直接讲 Go,而是先描述了一个正在发生的行业变化: 过去,我们亲手写大部分代码;现在,我们让 AI 编程助手和智能体替我们生成大量代码。但 AI 需要监督,所以依然是我们人类来阅读生成出来的代码、清理它、并验证它是否真的做了我们想让它做的事。 这是全文的地基。作者想表达的核心是:代码的"生产"变便宜了,但代码的"治理"并没有变便宜。 紧接着,作者补充了一个容易被忽略的事实:AI 只能看到它被喂进去的那点上下文,看不到整个系统的边界。因此,系统架构、服务边界、生产环境的安全与可靠性,仍然必须由人来定义和负责。 这一段的潜台词是:AI 改变了"写代码"这件事,但没有改变、甚至放大了"软件工程"这件事的难度。 2. 第一个核心判断:瓶颈从"写"转向了"审" 作者回顾了历史:过去,人们衡量一门编程语言的生产力,主要看它"好不好写"。 但当 AI 能在几秒钟内生成几百行语法正确的代码时,人类写代码的速度就不再重要了。真正重要的事情变成了三件: Reviewing——评审; Verifying——验证; Maintaining——维护。 文章用了一个形象的比喻:AI 越来越像你的队友(teammate),一个有点我行我素、但仍然算队友的存在。既然如此,最重要的就不再是"我写得有多快",而是"我们作为一个团队如何协作"。 这是全文第一个关键转向:衡量语言的坐标系,从"个人写作体验"切换到了"团队协作体验"。 3. 第二个核心判断:Go 是为"软件工程"而生的 作者指出,二十多年前 Rob Pike、Robert Griesemer 和 Ken Thompson 在 Google 创建 Go 时,别的语言都在快速堆砌特性、扩展表达方式,而 Go 选择的却是一个更大的目标: ...

2026-08-20 · 3 min · 559 words · FunkyGod

Go 语言在 AI 辅助编程时代被谷歌官方力挺:动态语言与 Go 并非对立,而是互补关系

Go 语言在 AI 辅助编程时代被谷歌官方力挺:动态语言与 Go 并非对立,而是互补关系 原文:谷歌官方力挺:为什么 Go 语言是 AI 辅助编程时代的“标准答案”? 作者:场长 来源:21CTO 公众号,发布于 2026 年 7 月 16 日 过去,程序员最关心的问题是:哪门语言写起来更快? 进入 AI 辅助编程时代后,这个问题正在变成:哪门语言更容易让 AI 写对,也更容易让人类看懂、验证、部署和维护? 这不是文字游戏,而是软件生产方式发生变化后的真实转向。AI 可以在几秒钟内生成数百行代码,却无法替人类承担全部架构责任。代码越容易生成,审查、测试、安全和运维的重要性就越高。 谷歌官方力挺 Go,核心并不是说 Python、JavaScript 或 TypeScript 已经过时,而是指出:Go 从诞生之初就偏向大型、长期运行的软件系统。在智能体持续生成代码的今天,这些原本服务于人类团队的设计原则,也恰好成为 AI 协作所需要的“确定性护栏”。 更准确的结论应该是:动态语言负责快速探索和连接生态,Go 负责把经过验证的能力变成稳定运行的服务、工具和基础设施。 一、AI 编程真正改变的,是软件开发循环 很多人提到 AI 编程,首先想到的是代码补全:输入函数名,AI 自动写出函数体;写一段注释,AI 生成一段实现。 这只是最早期、也最简单的用法。 真正的 AI 辅助编程,通常是一个持续循环: 实现 → 构建 → 测试 → 分析失败 → 修改 → 再次构建。 如果是能够自主操作终端和代码仓库的智能体,它还会继续执行:读取日志、搜索依赖、修改多个文件、运行集成测试、启动服务、调用接口,然后根据结果再次修复。 对人类开发者来说,几分钟的编译等待可能只是一次短暂的停顿。对一个需要运行几十轮的智能体来说,每一次等待都会累积成时间、算力和模型调用成本。 这会放大许多过去被忽略的工程摩擦: 构建速度慢:每次修改都要等待更久,智能体的有效迭代次数下降; 依赖关系复杂:环境安装失败后,智能体可能把大量上下文消耗在解决版本冲突上; 错误反馈太晚:问题到运行时才暴露,智能体可能已经在错误基础上写了更多代码; 代码风格不统一:人类和 AI 都要花时间理解不同写法,评审速度自然下降; 部署链路过长:代码虽然生成了,但服务无法稳定启动,任务仍然不能算完成; 生态变化太快:模型根据旧文档生成的代码,可能在今天已经不适用。 过去,这些问题可能每周出现几次。现在,智能体可能在一天内把同一个循环执行数百次。问题没有变,但问题出现的频率变了,成本结构也随之变化。 ...

2026-08-20 · 2 min · 417 words · FunkyGod

Go 项目结构之争:DDD 还是简洁分层?

Go 项目结构之争:DDD 还是简洁分层? Go 项目一开始通常很简单:几个接口、几张表、几个服务函数,按 handler、service、repository 分开就能跑起来。项目变大之后,团队又开始讨论 DDD、领域模型、聚合、应用层和基础设施层。 于是问题变成了:Go 项目到底应该采用 DDD,还是坚持简洁分层? 我的答案是:不要先选择目录结构,要先识别业务复杂度和变化边界。 简洁分层不是低级方案,DDD 也不是高级方案。它们只是解决不同问题的工具。 可以把项目想成一家餐馆。简洁分层像一家小店:前台接单,后厨做菜,仓库取料,路线短,出了问题也容易找到人。DDD 更像一家菜品、库存、会员和结算规则都很复杂的连锁餐厅:重点不是把岗位拆得越多越好,而是让“什么菜能做、什么时候能退单、库存怎么扣”这些规则有明确的负责人。 小店一开始就照搬连锁餐厅的总部制度,会被流程拖慢;连锁餐厅却不能永远把所有事情都交给一个大厨。Go 项目的结构选择,也是同一个道理。 一、争论表面是目录,本质是边界 很多团队讨论架构时,第一步就是贴目录树: internal/ ├── handler/ ├── service/ ├── repository/ └── model/ 或者: internal/ ├── domain/ ├── application/ ├── interfaces/ └── infrastructure/ 但目录本身不会自动带来好的架构。真正重要的是几个问题: 哪些代码属于同一个业务能力? 哪些规则必须始终成立? 哪些变化应该被隔离? 数据库、消息队列等技术细节,是否侵入了业务决策? 一个需求发生变化时,需要修改多少个包? 如果这些问题没有答案,换一套目录只是换了一种命名方式。 架构的价值不在于让目录看起来专业,而在于让变化停留在应该停留的地方。 先用一张图看两种结构的关注点:简洁分层按“技术职责”排队,DDD 更关心“业务规则”应该被谁拥有。 flowchart LR subgraph simple["简洁分层:按技术分组"] S1["请求"] --> S2["handler"] --> S3["service"] --> S4["repository"] --> S5[("数据库")] S3 -. "规则容易集中" .-> S6["变胖的 service"] end subgraph ddd["DDD:按业务边界组织"] D1["请求"] --> D2["应用用例"] --> D3["领域规则"] D2 --> D4["仓储接口"] D4 -. "具体实现" .-> D5["基础设施"] D5 --> D6[("数据库")] end 图中没有“谁更高级”的答案。左边像小餐馆的传菜路线,胜在短;右边像连锁餐厅的岗位边界,胜在业务规则变复杂时,能把变化关在领域边界里。 ...

2026-08-20 · 2 min · 426 words · FunkyGod

技术日报|Linux 7.2 管道性能提升、Go 空指针检查争议、国家级攻击手法分析

💻 技术日报 | 2026-06-27 Linux 7.2 显著提升匿名管道写入性能 来源: Phoronix | 时间:2026-06-27 Linux 7.2 在匿名/无名管道性能上实现大幅提升,特别是针对 shell 管道场景的写操作性能优化。这是近年来针对管道子系统的首次重大改进,对频繁使用管道的高性能场景有直接影响。 技术细节: 优化了内核中管道缓冲区的管理逻辑,减少了锁竞争 对 write() 系统调用的路径进行了简化,降低了上下文切换开销 基准测试显示部分管道密集型工作负载提升超过 30% 意义: 管道是 Unix/Linux 最基础的 IPC 机制之一,这一优化将惠及所有使用 shell 管道、进程池、流水线架构的场景,尤其对 CI/CD、数据处理管道等场景有直接价值。 🔗 Linux 7.2 Improves Anonymous/Unnamed Pipe Performance For Shell Pipelines Go 语言空指针检查争议:过度防御还是必要保障? 来源: Konrad Reiche Blog | 时间:2026-06 一篇关于 Go 语言中「过度空指针检查」现象的技术文章引发开发者社区热议。作者指出,很多 Go 代码中存在对 nil 指针的过度防御性检查,这些检查不仅降低了代码可读性,还可能掩盖真正的逻辑错误。 核心观点: Go 的 nil 和其他语言(Java、C#)的 null 语义不同,不应照搬防御模式 过度检查会让 panic 变成错误返回值,失去了 Go 的「快速失败」设计哲学 正确的做法是在边界的「信任边界」处检查,而非在内部逻辑中处处设防 讨论延伸: 这与 Go 社区近年倡导的「let it crash」理念相呼应,引发了关于错误处理最佳实践的重新思考。 ...

2026-06-27 · 2 min · 220 words · FunkyGod

作为独立开发者,我为什么选择 Eino 来构建 AI 应用(Go语言)

作为独立开发者,我为什么选择 Eino 来构建 AI 应用(Go语言) 独立开发者做 AI 应用,最怕两件事:一是踩坑,二是被框架绑架。 踩坑意味着你花了两周搭的系统,上线后发现根本撑不住并发,或者调试起来像开盲盒;被框架绑架意味着框架的每一次大版本更新都是你的加班夜。 我花了一段时间评估了几个主流选项,最后在自己的项目里选了 Eino。说说理由。我使用的 Eino 版本如下: github.com/cloudwego/eino v0.8.13 你一个人,精力是最稀缺的资源 独立开发者和公司团队最大的区别,不是技术水平,而是精力分配。你同时要管产品、设计、开发、运营,留给"研究框架"的时间极其有限。 这就是为什么框架的设计哲学对你来说比对大公司更重要。一个设计混乱的框架,会把你困在细节里;一个设计清晰的框架,让你专注在真正重要的事上。 Eino 的核心设计思路很简单:把能力拆成组件,把流程描述为图,框架处理所有脏活。 你需要一个 RAG 系统,就把检索、提示词、模型调用几个节点连起来;你需要一个能用工具的 Agent,就把工具注册进去,Agent 的循环调用逻辑框架全包了。 你不需要理解流式数据如何在节点间传递,不需要手写工具调用的解析循环,不需要自己实现多轮对话的上下文管理。这些都是框架该做的事,Eino 做了。 字节跳动帮你提前踩过坑 独立开发者最大的风险之一,是用了一个没有生产验证的框架。看起来文档漂亮,demo 跑得顺,真到线上就各种奇怪问题——并发时状态串了,流式输出在特定场景下卡住了,Token 超限时框架直接崩了。 Eino 在字节跳动内部跑了超过半年,支撑着豆包、TikTok 这类亿级用户的产品。这不是说拿来炫耀的背书,而是一个工程上的实际意义:那些你独自开发时可能要花几个月才踩到的边界 case,字节内部的工程师已经踩过了,并且修掉了。 你站在他们的肩膀上出发,少走很多弯路。 Go 语言是独立开发者的好朋友 很多 AI 框架是 Python 的,Python 当然没有问题,但如果你的后端是 Go 写的——或者你打算用 Go——那嵌入一套 Python 框架会带来真实的运维成本:两套依赖管理、两个运行时、两种调试工具。作为一个人,你付不起这个代价。 Eino 是原生 Go 框架,跟你现有的 Go 服务深度集成,单二进制部署,没有额外的运行时负担。Go 的强类型也意味着很多错误在写代码时就被发现,而不是到线上才暴露——对于没有 QA 团队的你,这一点格外重要。 你不用从零开始集成所有东西 独立开发者做 AI 应用,通常需要接入:某个大模型 API、某个向量数据库、某个可观测性工具。每接一个,都要读一遍 SDK 文档,写一堆胶水代码。 Eino 的扩展库(EinoExt)已经帮你把这些都做了。OpenAI、Claude、Gemini、豆包 Ark、Ollama,开箱可用;Elasticsearch 等向量存储,直接接;OpenTelemetry 的 Tracing,一行配置。你换模型供应商不需要改业务代码,换向量库也一样——因为 Eino 的组件接口是统一的,实现是可替换的。 ...

2026-05-29 · 1 min · 115 words · FunkyGod