用 Effect 构建可靠 AI 客服代理:一线 CTO 的实战方法论
正在加载视频...
视频章节
来自 14.ai 联合创始人兼 CTO Michael Fester 的真实经验,系统讲述如何用 TypeScript 的 Effect 库,在充满不确定性的 LLM 场景中构建可预测、可观测、可扩展的 AI 客服代理系统。
用 Effect 构建可靠 AI 客服代理:一线 CTO 的实战方法论
来自 14.ai 联合创始人兼 CTO Michael Fester 的真实经验,系统讲述如何用 TypeScript 的 Effect 库,在充满不确定性的 LLM 场景中构建可预测、可观测、可扩展的 AI 客服代理系统。
为什么“能跑”远远不够:AI 客服系统的真实复杂度
这场分享一开始,Michael Fester 就明确了他的立场:他们做的不是实验性 Demo,而是“直接和真实用户交互、在生产环境中依赖大语言模型”的客服系统。这意味着系统必须在不可靠 API、非确定性模型输出、复杂依赖关系和长时间运行的工作流下依然保持稳定。正如他所说:“TypeScript 本身给了我们很好的基础,但当你开始处理不可靠的 API 或非确定性行为时,它就开始力不从心了。”
这是 14.ai 选择 Effect 的背景。Effect 是一个用于构建健壮、类型安全、可组合系统的 TypeScript 库,本质上把函数式编程中处理副作用、不确定性和错误的能力,带入了现实世界的工程实践。Michael 强调,他们并不是为了“更优雅”,而是为了在复杂度不断上升的情况下,依然能对系统行为保持信心。
在他看来,LLM 应用的核心挑战并不是模型本身,而是“如何把一个不可靠、不可预测的组件,安全地嵌入到一个必须可靠的系统中”。Effect 提供的并发、重试、中断、结构化错误建模和依赖注入,让他们可以明确表达“这里可能失败”“这里可以重试”“这里必须中断”,而不是把这些逻辑散落在 if/try-catch 中。这种显式建模,是他们应对不确定性的第一层防线。
一套从前端到数据库的 Effect 架构
在架构层面,14.ai 几乎把 Effect 用到了“全栈”。前端是 React,既承载仪表盘,也承载 Agent 的交互界面、知识管理、分析工具和 SDK;前后端通信通过基于 Effect RPC 的内部 RPC 服务完成,前端结合了修改过的 TanStack Query。
对外的公共 API 则使用 Effect HTTP,并且通过带注解的 Schema 自动生成 OpenAPI 文档。数据处理引擎负责从 CRM、文档和数据库中同步数据,用于实时分析和报告。即便是数据库访问,他们也使用 Effect SQL 来处理 Postgres 中的结构化数据和向量存储。
最有意思的是 Agent 工作流部分。Michael 提到,他们构建了一个基于 Effect 的自定义 DSL(领域特定语言),用来同时表达确定性和非确定性行为。比如一个工作流可以是严格的多步骤流程,而其中的某个步骤又可能调用 LLM、存在不确定输出。Effect 的组合能力,让这些差异在代码层面是“可见的”。这套架构的关键并不是新奇,而是一致性:同一套 Schema、错误模型和依赖注入机制,贯穿了整个系统。
把 Agent 当成“规划器”:Actions、Workflows 与 Sub-agents
在 14.ai 的系统里,Agent 并不是一个“全能黑盒”,而是被拆解成清晰的层次。Michael 用了一个非常工程化的定义:“我们的 agents 基本上是规划器(planners)。”它们接收用户输入,制定计划,选择合适的动作或子代理,执行后再根据结果继续循环,直到任务完成。
最底层的是 Actions:小而专注的执行单元,比如“获取支付信息”或“搜索日志”。你可以把它们理解为 LLM 的 tool calls。再上一层是 Workflows:确定性的多步骤流程,例如取消订阅,可能包含收集原因、提供挽留方案、检查资格、最终执行取消等步骤。再往上是 Sub-agents,它们把一组相关的 actions 和 workflows 封装成领域模块,比如账单代理或日志检索代理。
所有这些结构,都通过 Effect Schema 建模。这带来了几个直接好处:运行时校验、编码/解码、安全的输入输出处理,以及“免费”的自动文档。Michael 特别强调,这种 Schema 驱动的方式,让系统在扩展时不容易失控,也让新成员更容易理解复杂的 Agent 行为。
在失败中前进:模型降级、流式输出与可测试性
当系统变得“任务关键(mission critical)”,失败不再是异常,而是常态。Michael 分享了一个非常具体的做法:如果一个 LLM 提供商失败,他们会自动回退到性能相近的替代方案,比如“GPT‑4 mini 可以回退到 Gemini Flash 2.0,用于工具调用”。这些回退逻辑通过带状态的重试策略建模,避免反复重试已经失败的提供商。
在用户体验上,他们大量使用流式输出。为了同时满足用户和内部分析的需求,Token 流会被复制:一份直接推送给用户,一份用于内部存储和分析。Michael 提到,Effect 的 streaming 和 concurrency 能力让这种“分流”实现得非常自然。
测试同样是他们投入很多精力的地方。通过依赖注入,他们可以在不修改系统内部逻辑的情况下,用 mock 的 LLM 提供商来模拟各种失败场景。这让他们能够系统性地测试“如果模型挂了会发生什么”,而不是等事故发生后再补救。正如他提醒的那样:“Effect 很强大,但它不是魔法,你还是得认真思考错误是怎么流动的。”
真实教训:学习曲线、纪律性与渐进式采用
在分享的后半段,Michael 并没有粉饰 Effect 的代价。他直言,Effect 的生态很大,概念很多,学习曲线是真实存在的。尤其是在错误处理上,如果工程师只关注“happy path”,很容易在某个上游无意中 catch 掉错误,导致重要失败被悄悄吞掉。
依赖注入在规模化后也可能变得难以追踪:服务到底在哪一层被提供,有时并不直观。但他的结论并不是“谨慎使用”,而是“需要纪律”。一旦团队形成了对 Schema、错误和依赖的共同理解,系统的可维护性会呈指数级提升。
最重要的一点是:你不需要一开始就 all in。Michael 反复强调,Effect 可以渐进式采用,从一个服务或一个端点开始。对 LLM 和 Agent 系统来说,可预测性和可观测性比“写得快”重要得多,而 Effect 恰好提供了这样一套现实可用的工具。
总结
这场分享的价值,不在于介绍了多少新工具,而在于展示了一种面对 AI 不确定性的工程态度。Michael Fester 和 14.ai 的选择很明确:承认不可靠的存在,并在系统层面正面建模它。Effect 并不能替你做决策,但它迫使你把决策说清楚。对于正在构建 LLM 或 Agent 系统的团队来说,这种“把复杂性显式化”的思路,或许比任何框架本身都更重要。
关键词: Effect, TypeScript, AI Agent, 大语言模型, 系统可靠性
事实核查备注: Michael Fester(14.ai 联合创始人兼 CTO);Effect(TypeScript 库);Effect RPC、Effect HTTP、Effect SQL;React、TanStack Query、Postgres;Schema 驱动建模;GPT-4 mini、Gemini Flash 2.0(模型回退示例);Agent 结构:Actions、Workflows、Sub-agents;流式 Token 复制;依赖注入与 Mock 测试