想象一个街角的面包店老板娘,她的全部生意都靠 WhatsApp 聊天维系。Priya 发来"1 kg 巧克力松露蛋糕,周日晚上,无蛋",Rahul 说"2 盒布朗尼,明天早上,地址 14B Lakeview Apts",紧接着又补一句"抱歉,改成 3 盒"。Meena 只发了句"晚安阿姨"。Sneha 要 12 个香草纸杯蛋糕加 6 个红丝绒,周六下午 4 点自取,还留了电话。六条消息,中英混杂,有修改、有相对日期、有自取、有纯闲聊。赶上节日旺季,订单翻倍,漏单、数量搞错、顾客不停追问"阿姨,我的蛋糕好了吗?"——这就是 Order Taker 要解决的问题:一个为"擅长烘焙但不擅长表格"的人设计的本地 AI 订单管家。
这个项目的核心思路很朴素:店主把 WhatsApp 聊天记录粘贴(或上传)到应用里,一组小型 AI 助手负责阅读,一个友好的"正在发生什么"提示框用大白话解释每一步。每条订单以卡片形式呈现,店主可以接受、编辑或丢弃,任何异常都会被标记出来,比如"送货还是自取?没有提供地址"。被接受的订单沿着一个大拇指大小的按钮流转:已收到 → 已确认 → 制作中 → 已准备好 → 已送达。每天还有一份备货清单("3 盒布朗尼,2 公斤巧克力蛋糕")和 CSV 导出功能。顾客用手机号和店主通过 WhatsApp 发送的 PIN 码登录,能看到自己订单的进度条,也可以在应用内修改或取消订单。
最让我意外的是它的架构选择:整个应用刻意不部署到任何服务器,只运行在店主的笔记本电脑上,顾客的手机通过同一个 Wi-Fi 访问。顾客的姓名、电话号码和家庭住址永远不会离开这台电脑。这是第一版的设计选择,而不是能力限制——同样的代码可以变成标准的托管 Web 应用。FastAPI 服务,所有机器相关设置都已经是环境变量(ORDER_DB、ORDER_PORT、ORDER_PUBLIC_URL、OLLAMA_URL),数据从 SQLite 迁移到托管 Postgres,AI 保持开放,OLLAMA_URL 可以指向你控制的 GPU 服务器上的开源权重模型,甚至通过私有隧道指回店主自己的笔记本。代价也很诚实:一旦托管,客户数据就存在服务器上,而不是只存在笔记本里。所以项目规格把它视为对"本地优先"规则的刻意改变,店主应该有意识地选择,而不是被动接受。
技术实现上,多智能体摄入流程没有用任何框架。固定管道用纯 asyncio 就足够了(大约 150 行),而且能轻松给每一步附加进度消息。Master 按发送者拆分聊天记录,跳过已处理的消息,这样每天晚上粘贴整个聊天记录,只有新消息会被读取。Extractor(每人一个)只看到那个人的消息和未完成订单,这就是"抱歉,改成 3 盒"能变成对现有订单的修改而不是重复订单的原因。Checker 只是规则:缺日期、缺地址/自取、缺电话、重复。AI 提议,人决定——在店主点击接受之前,什么都不会成为真正的订单。
最有趣的教训是:让代码做代码擅长的事。第一次真实运行时,7B 模型把 Priya 的"周日"读成了周四,把 Sneha 的"周六"读成了周三。小模型不擅长日历计算。所以现在模型只复制顾客写的内容("周日"、"明天"、"10 月 5 日"),Python 里一个小查找表把它转换成日期,从消息发送时间算起。电话号码也一样:正则表达式每次都能找到"我的号码 98450 12345",模型却做不到。
在作者笔记本上的实测数据(模型只能部分放进 GPU,所以 Ollama 一次只处理一个请求):旧方案(一次大调用)首个订单可检查约 41 秒,整个聊天完成约 41 秒,日期、电话、闲聊在样本上不正确;多智能体方案首个订单约 20 秒,整个聊天约 55 秒,日期、电话、闲聊全部正确。所以在普通硬件上,赢的是"到首个订单的时间"和正确性,而不是总时间。在显存更大并设置 OLLAMA_NUM_PARALLEL 的机器上,每个人的轨道真的可以并行运行。仓库里还有 scripts/bench_intake.py,任何人都可以测量自己机器的性能。
另一个值得借鉴的细节:没有"处理中…"的转圈动画。一个转 60 秒的圈会让非技术用户以为应用坏了。取而代之的是进度框逐句播报:"Meena 只是在聊天,没有订单。""还在处理 Priya 的消息,快好了…""53 秒全部完成:3 件待检查,1 件只是闲聊。"这些消息来自固定模板,绝不来自原始模型输出。如果测试中出现"JSON"、"API"、"token"或"Ollama"等词,构建就会失败。
项目还实践了"规格驱动开发":写代码之前,先写了一份简短的章程(本地优先、大白话、AI 提议/人决定、移动优先)和五份带编号验收标准的特性规格。154 个测试中的每一个都标注了它覆盖的标准编号(INT-21、TRK-23…)。当真实模型证明某个规格是错的(就是日期那次),先更新规格再改代码。技术栈是 FastAPI、SQLite、Jinja2、一点原生 JS,以及用于实时推送的 Server-Sent Events,没有 CDN,没有外部调用。
这个思路能直接用到哪些场景?任何"非技术用户 + 非结构化文本输入 + 需要人工确认"的流程都适用:小作坊的订单管理、自由职业者的客户沟通、甚至个人助理式的任务提取。核心方法论有三条:一是让代码做代码擅长的事(日期计算、正则匹配),让模型做模型擅长的事(语义理解、意图识别);二是 AI 提议、人决定,永远保留人工确认环节;三是本地优先,数据隐私可以成为产品卖点。要注意的坑是:小模型的日历计算和数字提取确实不可靠,必须用规则兜底;进度反馈对非技术用户至关重要,一个干转的加载动画会毁掉信任;规格先行能避免"模型行为不可控"带来的返工。

项目封面图,展示 Order Taker 把 WhatsApp 消息变成订单看板的整体概念。

顾客端界面:登录后看到订单进度条,可以修改或取消订单。

架构演进示意图:从单机 SQLite 到托管 Postgres 的迁移路径。

项目仓库界面截图。

作者 Tanay 的个人资料图。

本地模型运行说明:qwen2.5:7b 通过 Ollama 在 4GB GTX 1650 笔记本上运行,每次调用使用结构化输出和 JSON schema,结果用 Pydantic 验证。

多智能体摄入流程图:Master 按人拆分,每人一条轨道并行处理,经过 Sorter、Extractor、Checker 生成草稿卡片。

性能对比表格:旧方案 vs 多智能体方案在首个订单时间、总时间和正确性上的差异。
内容与图片版权归原作者所有 · 原文: https://dev.to/tanay_singh_1005/order-taker-turning-kal-subah-2-box-brownies-into-real-orders-with-open-ai-5h5h