![]()
一个邮件通知功能,值得烧掉一整轮大模型推理吗?Google Cloud开发专家最近算了一笔账:用传统LLM Agent发邮件,每次调用要吞掉几千Token,而换成纯代码实现的确定性Agent,成本直接归零。
这套方案藏在Google Agent Development Kit(ADK)的文档深处,开发者社区直到最近才大规模注意到。它的核心思路很反直觉——不是所有"智能"任务都需要智能。格式化Markdown、调用SMTP接口、发送固定模板,这些操作用代码写死比让AI"思考"更快、更便宜、更可预测。
邮件Agent的"身份危机"
故事要从一个多Agent决策系统说起。这套系统负责评估项目是否适合采用Agent架构,最终输出一份推荐报告。报告生成后,需要干两件事:返回给前端展示,同时邮件通知管理员。
最初的方案很"AI原生":写一个LlmAgent,给它工具调用权限,让它自己决定怎么发邮件。指令大概长这样——"请根据session state中的推荐内容,生成邮件正文,调用邮件工具发送给管理员"。
问题立刻暴露。每次发邮件都要经历:LLM解析指令→理解session结构→生成邮件文本→结构化输出→触发工具。一轮下来,输入输出Token轻松破千,延迟按秒计,而且AI偶尔会"发挥创意",把邮件格式改得面目全非。
Google工程师的解法是把邮件功能从LLM Agent降级为BaseAgent。这是一个纯代码实现的自定义Agent,零Token消耗,执行时间以毫秒计。它从session state直接读取推荐文本和摘要,用marked库把Markdown转成HTML,再用nodemailer推送到SMTP服务器。没有推理,没有幻觉,没有账单。
决策树的"分层治理"
这套系统的完整架构值得细看。整个决策树包含7个Agent,按"是否需要思考"被明确分层。
![]()
上层四个是LLM Agent:Project Agent解析项目描述,Anti-patterns Agent识别常见陷阱,Decision Agent做最终判断,Recommendation Agent生成建议,Synthesis Agent整合输出。这些确实需要Gemini的推理能力,调用Vertex AI上的gemini-3-flash-preview模型。
下层三个是确定性Agent:Audit Trail Agent记录日志,Cloud Storage Agent处理文件,Email Agent负责通知。它们只干一件事——精确执行外部API调用,不掺杂任何生成式操作。
这种分层不是技术炫技,而是成本控制的刚需。以Email Agent为例,如果每次通知都走LLM,按Gemini 3 Flash的定价,单次约0.15美元。假设系统每天处理1000个项目评估,一年就是5.5万美元。换成BaseAgent后,这部分成本 literally 归零——只付SMTP服务器的基础费用。
代码层面的"确定性保障"
实现这套方案的关键依赖很克制。核心包是@google/adk和@google/adk-devtools,辅助marked处理格式转换,nodemailer对接邮件服务,zod做类型校验。所有依赖都用--save-exact锁定版本,避免企业级部署时的版本漂移。
配置环节需要区分两套环境变量。Gemini相关配置走Vertex AI通道,因为Gemini在香港地区被屏蔽,作者选择了全球可用的Vertex AI端点。SMTP配置则指向本地MailHog做测试,生产环境切到真实邮件网关。
BaseAgent的编写范式与LlmAgent截然不同。后者需要设计提示词工程、定义工具Schema、处理结构化输出;前者就是标准TypeScript类,实现run方法,操作session state,返回AgentResponse。代码即文档,行为可单元测试,调试时不用猜AI在想什么。
一个细节是session state的传递机制。上层LLM Agent生成的推荐内容,通过ADK的会话状态自动流转到Email Agent。后者不需要重新理解业务逻辑,只管取数据、格式化、发送。这种"接力赛"模式让各Agent职责单一,也避免了LLM反复处理相同上下文。
反模式的边界在哪
![]()
这个案例戳中了当前AI开发的一个普遍误区:用LLM的"锤子"砸所有"钉子"。Google ADK的设计哲学是Agent多样性——框架同时支持LlmAgent、WorkflowAgent、LoopAgent和BaseAgent,让开发者按任务特性选型。
判断标准很实际:任务是否需要推理?输出是否必须可预测?成本是否敏感?邮件通知显然三样全占。反过来,如果邮件内容需要根据用户画像动态生成个性化文案,那LLM Agent就是合理选择。
作者提到一个有趣的测试场景。早期原型确实试过让LLM写邮件,结果出现"尊敬的undefined先生"这类经典幻觉。切换到BaseAgent后,模板变量从session state直接注入,渲染失败会直接抛异常,而不是生成一封尴尬的邮件。
这种"失败显式化"是确定性系统的隐性收益。LLM Agent的故障往往是静默的——格式歪了、称呼错了、链接少了,系统照样运行。BaseAgent则会在编译期或运行早期暴露问题,符合企业级应用的可观测性要求。
部署层面的考量同样务实。确定性Agent没有模型加载延迟,冷启动时间趋近于零,适合Serverless场景。LLM Agent则需要预热模型实例,首调延迟可能达到数秒。对于邮件这类通知功能,用户显然更关心"立刻收到"而非"邮件写得像莎士比亚"。
这套方案目前已在Google Cloud的示例仓库开源。开发者可以直接复制Email Agent的实现,替换自己的SMTP配置。更激进的玩法是把更多"伪智能"任务从LLM迁移到BaseAgent——数据校验、格式转换、简单聚合,这些占掉真实工作流中相当比例的Token消耗。
ADK的文档里埋着一句容易被忽略的话:"BaseAgent是构建自定义Agent的起点,不是退路。"换句话说,框架设计者的本意就是鼓励混合架构。LLM负责需要判断力的环节,代码负责需要可靠性的环节,两者通过统一的Agent协议协作。
最后一个值得玩味的细节:作者特意提到用Vertex AI而非直接调用Gemini API,原因是"regional availability"。这种工程妥协背后,是全球化部署的真实约束——再先进的技术栈,也得服从网络拓扑和合规边界。BaseAgent的确定性在此又显优势:它不挑模型供应商,换一套API凭证就能迁移,不会被某个地区的封锁策略卡脖子。
如果你正在搭建多Agent系统,现在可能需要重新审视架构图——哪些节点真的需要"思考",哪些只是需要"执行"?
特别声明:以上内容(如有图片或视频亦包括在内)为自媒体平台“网易号”用户上传并发布,本平台仅提供信息存储服务。
Notice: The content above (including the pictures and videos if any) is uploaded and posted by a user of NetEase Hao, which is a social media platform and only provides information storage services.