利用函数式事件溯源消除业务逻辑 Bug Nadeem Bitar 2026-05-04 4.7 KB 27.5K 201 ☆ 收藏 𝕏 文章列表 文章介绍了一种基于函数式事件溯源(Functional Event Sourcing)的库,旨在让业务逻辑 Bug 在结构上不可能发生。作者通过定义可组合的状态机,在类型层统一描述状态转换,自动生成决策逻辑和演化逻辑,从而避免两者不一致。此外,该库还能自动生成 Mermaid 流程图,并利用 SMT 求解器验证业务不变性,大幅提升代码的健壮性和可维护性。 函数式编程事件溯源状态机领域驱动设计SMT形式化验证架构设计代码质量Haskell 77 值得读 ▶ 文章展示了一种利用类型级状态机结合函数式事件溯源来消除业务逻辑Bug的创新方法,结合Haskell代码与SMT验证器,技术细节丰富且极具时效性。 # Making Business-Logic Bugs Structurally Impossible **作者**: Nadeem Bitar **日期**: 2026-05-03T15:41:22.000Z **来源**: [https://x.com/shinzui/status/2050963939060838501](https://x.com/shinzui/status/2050963939060838501) ---  I've been building a library that aims to make business-logic bugs almost impossible to ship, even when the code is generated by a coding agent. The foundation is functional event sourcing which we've been using in production for a few years. In functional event sourcing your business logic lives in a small pure module: trivial to test, trivial to debug, trivial to reason about. ``` data Decider c e s = Decider { decide :: c -> s -> [e] , evolve :: s -> e -> s , initialState :: s , isTerminal :: s -> Bool } ``` …and you write it by hand: ``` userReg :: Decider UserCmd UserEvent UserState userReg = Decider { decide = \cmd s -> case (s, cmd) of (PotentialCustomer, Start d) -> [RegistrationStarted d.email d.confirmCode d.at] (RequiresConfirmation r, Confirm d) | d.code == r.confirmCode -> [AccountConfirmed r.email d.at] | otherwise -> [] (RequiresConfirmation r, Resend d) -> [ConfirmationResent r.email d.code d.at] (RequiresConfirmation r, Gdpr d) -> [AccountDeleted r.email d.at] _ -> [] , evolve = \s ev -> case (s, ev) of (PotentialCustomer, RegistrationStarted email code at) -> Registering { email, confirmCode = code, registeredAt = at } (Registering r, ConfirmationEmailSent _) -> RequiresConfirmation r (RequiresConfirmation r, AccountConfirmed _ at) -> Confirmed r { confirmedAt = at } (RequiresConfirmation r, ConfirmationResent _ code at) -> RequiresConfirmation r { confirmCode = code, registeredAt = at } (_, AccountDeleted _ at) -> Deleted at (s, _) -> s , initialState = PotentialCustomer , isTerminal = \case Deleted{} -> True; _ -> False } ``` The catch is that hand-written deciders carry their share of bugs. Missed branches. decide and evolve quietly drifting out of sync, so a freshly produced event no longer round-trips through replay and invariants are violated. So over the last few weekends I've been working on a library that aims to make those bugs structurally impossible to write. Workflows are composable state machines defined at the type level. You describe each edge once, and both decide and evolve are derived from that single definition, so they can never disagree. A small DSL hides the type-level machinery, so day-to-day code looks like the decider: ``` userReg = buildTransducer PotentialCustomer emptyRegs do from PotentialCustomer do onCmd inCtorStart \d -> do slot @"email" .= d.email slot @"confirmCode" .= d.confirmCode slot @"registeredAt" .= d.at emit wireRegistrationStarted goto Registering from RequiresConfirmation do onCmd inCtorConfirm \d -> do requireEq d.confirmCode #confirmCode slot @"confirmedAt" .= d.at emit wireAccountConfirmed goto Confirmed onCmd inCtorResend \d -> do slot @"confirmCode" .= d.code slot @"registeredAt" .= d.at emit wireConfirmationResent goto RequiresConfirmation onCmd inCtorGdpr \d -> do slot @"deletedAt" .= d.at goto Deleted ``` Notice what's missing: there is no separate evolve. Replay is generated from the same edge definition that produced the event, so the two directions can't fall out of sync. Two more things fall out for free. 1) Mermaid diagrams generated straight from the code, so you can visually verify what you actually wrote, in code review or a design doc:  2) An SMT-backed checker you can run on CI. Encode a business invariant ("no path reaches Confirmed without the code-equality guard firing," "every started registration eventually reaches a terminal state," "deletedAt is never set on a non-terminal vertex") and the solver either proves it or hands you the counter-example trace. The kind of bug a code review will not easily catch. Really happy with what I have so far. Still a fair bit of work before I'd use it at work, but the core is there. ## 相关链接 - [Nadeem Bitar](https://x.com/shinzui) - [@shinzui](https://x.com/shinzui) - [12K](https://x.com/shinzui/status/2050963939060838501/analytics) - [11:41 PM · May 3, 2026](https://x.com/shinzui/status/2050963939060838501) - [12.5K Views](https://x.com/shinzui/status/2050963939060838501/analytics) - [View quotes](https://x.com/shinzui/status/2050963939060838501/quotes) --- *导出时间: 2026/5/4 11:40:58* --- ## 中文翻译 # 从结构上杜绝业务逻辑 Bug **作者**: Nadeem Bitar **日期**: 2026-05-03T15:41:22.000Z **来源**: [https://x.com/shinzui/status/2050963939060838501](https://x.com/shinzui/status/2050963939060838501) ---  我正在构建一个库,旨在让业务逻辑 Bug 几乎不可能被带上线,即使代码是由编程代理生成的。其基础是函数式事件溯源,我们已经在生产环境中使用它几年了。 在函数式事件溯源中,你的业务逻辑位于一个微小的纯模块中:极易测试,极易调试,极易推理。 ``` data Decider c e s = Decider { decide :: c -> s -> [e] , evolve :: s -> e -> s , initialState :: s , isTerminal :: s -> Bool } ``` ……并且你需要手写它: ``` userReg :: Decider UserCmd UserEvent UserState userReg = Decider { decide = \cmd s -> case (s, cmd) of (PotentialCustomer, Start d) -> [RegistrationStarted d.email d.confirmCode d.at] (RequiresConfirmation r, Confirm d) | d.code == r.confirmCode -> [AccountConfirmed r.email d.at] | otherwise -> [] (RequiresConfirmation r, Resend d) -> [ConfirmationResent r.email d.code d.at] (RequiresConfirmation r, Gdpr d) -> [AccountDeleted r.email d.at] _ -> [] , evolve = \s ev -> case (s, ev) of (PotentialCustomer, RegistrationStarted email code at) -> Registering { email, confirmCode = code, registeredAt = at } (Registering r, ConfirmationEmailSent _) -> RequiresConfirmation r (RequiresConfirmation r, AccountConfirmed _ at) -> Confirmed r { confirmedAt = at } (RequiresConfirmation r, ConfirmationResent _ code at) -> RequiresConfirmation r { confirmCode = code, registeredAt = at } (_, AccountDeleted _ at) -> Deleted at (s, _) -> s , initialState = PotentialCustomer , isTerminal = \case Deleted{} -> True; _ -> False } ``` 问题在于,手写的决策器难免带有一些 Bug。遗漏分支。`decide` 和 `evolve` 悄悄地步调不一致,导致新生成的事件在重放时无法正确地进行往返,不变量因此被破坏。 所以在过去几个周末,我一直在开发一个库,旨在从结构上让这些 Bug 根本无法被写出来。工作流是在类型层级定义的可组合状态机。你只需描述一次每条边,`decide` 和 `evolve` 都是从这唯一的定义中派生出来的,所以它们永远不可能不一致。一个小型的 DSL 隐藏了类型层级的机制,使得日常代码看起来就像决策器一样: ``` userReg = buildTransducer PotentialCustomer emptyRegs do from PotentialCustomer do onCmd inCtorStart \d -> do slot @"email" .= d.email slot @"confirmCode" .= d.confirmCode slot @"registeredAt" .= d.at emit wireRegistrationStarted goto Registering from RequiresConfirmation do onCmd inCtorConfirm \d -> do requireEq d.confirmCode #confirmCode slot @"confirmedAt" .= d.at emit wireAccountConfirmed goto Confirmed onCmd inCtorResend \d -> do slot @"confirmCode" .= d.code slot @"registeredAt" .= d.at emit wireConfirmationResent goto RequiresConfirmation onCmd inCtorGdpr \d -> do slot @"deletedAt" .= d.at goto Deleted ``` 请注意少了什么:这里没有单独的 `evolve`。重放逻辑是从产生事件的同一条边定义中生成的,所以这两个方向不可能步调不一致。 此外,还免费获得了另外两个功能。 1) 直接从代码生成 Mermaid 图,这样你可以在代码审查或设计文档中直观地验证你实际写的内容:  2) 一个支持 SMT 的检查器,你可以在 CI 中运行它。编码一个业务不变量(“没有路径能在不触发 code-equality 守卫的情况下到达 Confirmed 状态”,“每个已开始的注册最终都会到达终止状态”,“deletedAt 从不会在非终止节点上被设置”),求解器要么证明它,要么给你反例轨迹。这正是代码审查很难发现的那类 Bug。 我对目前的进展非常满意。虽然距离在工作中使用还有一些工作要做,但核心功能已经实现了。 ## 相关链接 - [Nadeem Bitar](https://x.com/shinzui) - [@shinzui](https://x.com/shinzui) - [12K](https://x.com/shinzui/status/2050963939060838501/analytics) - [11:41 PM · May 3, 2026](https://x.com/shinzui/status/2050963939060838501) - [12.5K Views](https://x.com/shinzui/status/2050963939060838501/analytics) - [View quotes](https://x.com/shinzui/status/2050963939060838501/quotes) --- *导出时间: 2026/5/4 11:40:58*
C Context Infrastructure: Architectural Lessons From the Data Lakehouse 文章提出上下文基础设施正出现一种新模式:尽可能保存原始历史数据(对话、工具调用、事件、Agent 工作记录),之后再按需构建摘要、知识图谱、嵌入等派生视图。这一架构借鉴了数据湖屋(Lakehouse)的经验,如 Databricks 的青铜/白银/黄金分层架构。作者对比了写入时即做压缩决策的内存系统(如 CrewAI),指出其风险在于丢失未来可能重要的信息;并介绍了 CortexDB、Statewave、Supermemory、Zep 等产品的实践:以不可变事件为事实来源,将记忆作为可重建的视图。文章最后提醒需防范上下文沼泽,建议写侧优化保存、读侧优化实用性。 技术 › Agent Josh Rosen 2026-09-16 上下文工程数据湖屋Agent记忆知识图谱CortexDBZepDatabricks架构设计LLM事件溯源
循 循环智能体的失效与图架构改造指南 作者分享了将单一的“循环”智能体重构为“图”架构的实战经验。文章指出,当生产输出的智能体同时负责自我评估时,会导致审核机制失效(橡皮图章)。为解决此问题,作者将任务拆分为研究员、作者和审核员三个独立节点,严格限制各节点对状态数据的读写权限,并引入条件路由进行质量把控。改造后,初稿通过率从45%提升至82.5%,有效提升了系统可靠性。 技术 › Agent Gipp 2026-08-07 AI Agent图架构智能体状态管理LLM代码质量工作流自动化架构设计
S State Machines: From Loops to Graphs (Explained) 文章阐述了状态机理论及其在软件开发中的应用。作者指出Agent框架从链条到循环再到图形的演变,本质上是有限状态机(FSM)的体现。通过将分散的逻辑迁移到明确的转换函数中,状态机能消除不可能状态,避免竞态条件,并提供类型级安全保障。文章展示了基于查找表和Switch语句的实现方式,强调了其在代码审查、测试及系统可靠性方面的优势。 技术 › 后端 vixhaℓ 2026-07-21 状态机FSM编程范式Agent架构设计
A Agent 工程的四个深坑:Demo 到生产没有捷径 作者分享了将 AI Agent 从 Demo 推向生产环境过程中遇到的四个“深坑”:Function Calling 的不可预测性需加代码校验兜底;多步任务必须引入状态机和 checkpoint 防止重复执行或死无对证;记忆管理需分层以解决 token 爆炸和“丢失中间”问题;权限控制是最大风险,需防范 prompt injection 并建立分级审计机制。 技术 › Agent 老金 2026-05-16 AgentLLM架构设计生产环境Function Calling状态机陷阱防御性编程
从 从任务板到文件协议:两个 Agent 协作系统的边界与互补 本文探讨了多 Agent 协作系统中的架构设计问题。作者对比了基于 IPC 的“任务板”模式与自研的“文件协议+状态机”模式,阐述了为何选择文件系统作为任务真理源以实现跨 Session 的可恢复性与可审计性。文章提出了一种混合架构,利用 IPC 处理高频进程心跳,同时保留文件层作为核心状态与证据链的存储,最终实现了稳定、解耦且支持异步长任务的自动工程流。 技术 › Agent 周 周.乙 2026-05-02 Agent多Agent协作架构设计文件协议状态机IPCDevOpsOpenAI Symphony工程实践自动化
3 35个鲜为人知的 Claude Code 技巧与工作流 文章分享了作者数月来每日使用 Claude Code 总结出的 35 个高效技巧,旨在将 Claude Code 从基础辅助工具转变为极致的生产力引擎。内容涵盖核心命令(如计划模式、压缩上下文、持久化记忆)、生产力工作流(如增量构建、测试先行、截图调试)以及架构层面的审计与模式执行技巧。作者强调这些实战技巧能显著减少 Bug 并提升代码质量。 技术 › Claude Code Khairallah AL-Awady 2026-04-21 Claude CodeAI编程工作流开发效率技巧命令行架构设计Debug代码质量Prompt技巧
A AI 早报:Anthropic 交付架构、LangChain 设计智能体与 Ai2 新颖性裁判研究 本期早报围绕智能体系统建设展开:一是 Anthropic 负责人解释 Claude 交付架构,将会话记录、运行框架与沙箱执行环境分离,使失败恢复不影响工作连续性;二是 LangChain 分享设计智能体的实践,将设计师的审美判断沉淀为技能与知识库,中位费用从 8 美元降至 0.50 美元;三是 Ai2 研究检验 LLM 判断研究想法新颖性的可靠性,发现提示词变化可导致准确率剧烈波动。此外还涵盖 Google A2UI 推理格式、Optiver 模型接入平台、小红书 AllSpark 数据管线及 K2 Lab 垂直 AI 产品等内容。 技术 › LLM ginobefun 2026-10-28 AnthropicLangChainAi2AgentLLM架构设计智能体模型评测自动化科研早报
如 如何构建成本降低 80% 的编码 Agent:Jev + Opus 5.5 完整架构 文章指出当前编码 Agent 在简单决策(如选择加载哪些笔记、任务路由、工具失败处理、测试优先级)上滥用昂贵的前沿大模型,造成成本浪费。作者提出三层架构:Opus 5.5 负责规划、写代码、调试等开放性推理;Jev(TypeSafe 出品,毫秒级响应、输入 $0.042/百万 token、输出免费)负责从固定选项中做小决策并返回概率;Harness 层构建选项、校验概率阈值并在低置信度时回退到 Opus。文章给出四个具体决策点及代码实现:按标题分块并用 Jev 并行评分筛选相关笔记(将 30k token 降至 6k)、任务路由、工具失败处理、测试优先级选择。实测一个功能开发会话成本从 $6.42 降至 $2.00,降低 69%,且架构可作为函数调用插入现有 Agent 循环,无需重写。 技术 › Agent CyrilXBT 2026-10-26 编码Agent成本优化Claude CodeOpus架构设计模型路由上下文管理Harness Engineering
O OpenAI Dots: 7x24小时运行GPT-6 Astra,成为只做监督的独立开发者完整指南 文章介绍如何在OpenAI发布Dots常驻Agent和GPT-6 Astra(百万token记忆)后,搭建一个24/7自主运行的AI工作流。核心难题是常驻Agent会高频产生大量简单决策,用前沿模型成本高昂。解决方案是TypeSafe推出的System One模型Jev:它只能输出结构化决策(是/否、选择、评分)并附带置信度,单价仅$0.042/百万token,使百万次决策成本约$42。文章展示了将Jev作为低层决策器、Astra作为高阶思考引擎的组合架构,让独立开发者从写代码转变为定义任务、设限并审核产出的监督者角色。 技术 › Agent Noisy 2026-10-26 OpenAIGPT-6Agent常驻AI成本优化架构设计独立开发JevDots自动化
从 从单兵作战到舰队协同:我的 Grok Bot 架构全拆解 作者分享了自己搭建的 Grok Bot 舰队体系,解决单兵使用 AI 时多设备割裂、记忆难沉淀、多模型协调成本高三大痛点。架构分为四层技术底座:核心层以总控「乐乐大王」调度四端执行节点;同步层用 Obsidian + GitHub 私库实现统一知识底座;额度层通过分流机制将重负载任务派给独立计费的工程师 Bot;运维层借助开机自检与 Wake on Done 实现自动化。业务上采用 1 个总控 + 6 个分组共 29 个 Bot 的精细化分工,覆盖研发、情报、自媒体、内容创作与生活辅助,形成完整的任务执行与知识沉淀闭环。 技术 › Agent 木渡川 2026-10-21 Grok Bot多Agent协同架构设计知识管理Harness任务调度自动化运维ObsidianGitHub效率工具
从 从 Pi Durable 看 Harness 的演进 文章以 Pi coding agent 的 Durable 版本为切入点,拆解 Harness 架构的演进。传统 Harness 将持久化系统、agent loop 和执行环境耦合在同一个 Node.js 进程中并强依赖 VM,而 Durable 将持久化外置为 SQLite 存储、执行环境与操作系统解耦,并实现无损状态恢复,使 agent 可部署在 serverless 等更灵活的计算节点上。文章还介绍了 pi 的 MCP 原生支持、codemode(通过 QuickJS 批量调度工具)以及 server/client/protocol 分离等变化,最后设计了一套可扩展的长期 Harness 架构,目标是硬件资源消耗降低一个数量级。 技术 › Agent Ludamn 2026-10-10 Harness EngineeringAgentDurableMCPcodemodeNode.jsSQLiteServerless架构设计
H How to Build a Multi-Model Team of AI Agents in 2026 本文介绍 2026 年构建多模型 AI Agent 团队的完整方法。作者指出使用单一模型会导致高成本低效、专业能力受限以及单供应商故障/盲点风险,主张按任务步骤选择合适模型。文章梳理了 2026 年 9 月的主流模型阵容(Claude Opus/Sonnet/Haiku/Fable 5.1、GPT-6 Astra、TypeSafe Jev)及定价,提出五层架构:路由器、编排器、专家模型、评审者(critic)和纯代码层,并讲解如何先对工作负载分类(决策、简单生成、真实工作、难题),再为每层选择最划算的模型。文中附有统一封装多供应商 API 的示例代码,涵盖 effort 参数与 thinking block 处理细节。 技术 › Agent Khairallah AL-Awady 2026-10-10 多模型Agent路由模型编排ClaudeOpenAI成本优化LLM架构设计