把 Clawdbot 改成 Moltbot,不是心血来潮换皮。这大半年的迭代让我想明白一件事:很多人(包括最早的我)把“接入 Claude”当成了“做 AI Bot”,结果做出来的东西只会聊天,一旦要它去办正事就立刻拉胯。Moltbot 这个名字就是这次转型的宣言——molting,蜕皮,把原来那层“聊天玩具”的壳蜕掉,变成一个真正能接任务、跑流程、出结果的 AI Bot。换句话说,这篇文章记录的就是:Claude 如何不再只是一个聊天的对象,而变成一个真正可落地的 AI Bot。
这篇不是产品发布会通稿,而是我在这个项目上踩坑、重构、再踩坑的记录。我会拆开讲:为什么改名、整体怎么设计、核心代码怎么落地、以及一路踩到的典型坑。适合两类人看:一是想用 Claude 之类的大模型做自动化工具,但还停留在套壳聊天阶段的开发者;二是已经在做 Agent 项目,却总感觉“能用但不好用”的人。如果你是纯产品背景,也能从“人机分工”那节得到一些启发。
1. 为什么改名:从对话玩具到任务执行器
1.1 旧名字暴露的定位问题
Clawdbot 这个名字现在看挺幼稚的。它来自“Claude”和“bot”的拼接,一开始我给它的定位就是“一个能和 Claude 聊天的机器人”。最早的版本就是一次 HTTP 调用——用户发消息,我把它交给对话接口,返回的文字贴回聊天框。如果只是做一个陪聊 bot,这个方案确实够用,五六十行代码就能跑起来。
但问题在于,把同样的架构放到真实任务里,马上会露馅。举个例子,最初有个用户想让我做一个“能查天气然后帮你安排日程的助手”。理想中的流程应该是:助手先拿到天气信息,再判断第二天要不要带伞,最后往日历里插一条提醒。但 Clawdbot 只会干一件事——把“帮我看看明天天气”这句话原封不动发给模型,模型也老老实实回一句“我无法直接获取实时天气”。它不会想到去查接口,因为没有工具;它不会主动更新日历,因为没有对应的能力。归根结底,这个 bot 只有一张嘴,没有手。
这个差距不是模型不够聪明,而是套壳聊天和可落地 Bot 之间隔着一条很深的鸿沟。模型擅长的是“理解和生成”,不擅长的是“主动行动”。只要你没有给它行动的能力,它再聪明也只是一个顾问,不是一个执行者。Clawdbot 恰恰就停在顾问这一步。
1.2 改名的真实动机:被项目逼着转型
我真正下决心重构,是在接手一个内部自动化项目的需求之后。需求本身不复杂:从邮件里提取订单信息,填入系统,再回复确认。但用原来的 Clawdbot 逻辑做,根本没法跑——邮件格式五花八门,光靠 prompt 让模型输出 JSON 不够稳定,经常是格式对了但字段对不上;填系统需要调第三方接口,模型不知道怎么调;回复确认前还需要人工复核,旧架构里没有这个环节。
所以改名 Moltbot 不是说换个好听的名字,而是我把整个项目重写了。Moltbot 不再是一个“聊天机器人”项目,而是一个“任务执行框架”。Claude 依然在里面扮演核心角色,但只是大脑——负责理解、推理、决策;真正干活的是一系列工具层、状态层、校验层。这个架构变化反映在名字上:Clawd 变成 Molt,意味着重点从“模型名字”变成了“蜕变过程”本身。名字只是一个符号,但我需要这个符号提醒自己——别再做一个只会聊天的壳了。
1.3 新定位:Claude 是大脑,不是嘴
Moltbot 现在的定位,一句话概括:让大模型负责“想”,让工程代码负责“做”,两者通过严格的协议边界连接。它适合的任务有三个特征:有一定开放性(没有固定步骤)、信息分散在多个系统(需要查这个查那个)、结果需要被记录或回写(不只是说一句“好的”)。
也正因这个定位,Moltbot 不是要替代现成的 RPA(机器流程自动化)或低代码平台。RPA 适合完全固定的流程,Moltbot 适合“流程有骨架但每单都不一样”的场景。比如填报表,不同用户传来的 Excel 表头都不一样,这种情况写死规则很痛苦,交给大模型做字段映射很合适,但映射完之后的数据录入必须用确定的代码去执行,不能靠模型“感觉对就好”。这个认识是 Moltbot 架构里最核心的一条原则。
2. 整体设计思路:一个 Bot 的最小闭环
2.1 核心循环:意图理解 -> 工具调用 -> 结果校验
Moltbot 架构围绕一个循环:模型先理解当前状态和意图,决定要不要调用某个工具;工具执行完返回结果;模型再基于新结果继续决策,直到任务完成或者需要人类介入。这个循环看着像 Agent 的主流做法,但落地时很容易做成假的——也就是把工具列表丢给模型,然后祈祷它调用正确。
我的做法是给循环加了一个配件:每轮模型输出后,不由模型直接执行工具,而是由调度器校验它的调用意图。比如模型说“我要调用 get_weather”,调度器会先检查参数完整吗、这个工具在这个状态允许吗、是不是重复调用。校验通过才真正执行。这个设计想解决一个常见问题:模型经常会在连问三个问题之后,突然冒出一个错误的工具调用。如果每次都信它,迟早把系统搞乱。调度器就是那个在模型和工具之间把关的守门员。
2.2 工具层的设计:如何给模型一双可靠的手
工具层是 Moltbot 的核心资产。我的经验是,工具定义的说明书比工具本身的实现重要得多。一个工具函数本身可能就 20 行代码,但它的 description 和参数 schema 往往要花更多心思去写。因为模型是靠这些描述来理解“什么时候该用它”的,描述写得不清楚,模型就容易在错误的时机调用它。
工具描述要遵守三个原则。第一,说清楚“触发条件”而不是“功能泛称”,比如“当用户想查询天气并且提供了城市名称时使用,如果没有城市就先追问”,这比“查询天气”好用得多。第二,参数尽量少而明确,能用枚举就写枚举,别让模型自由发挥。第三,给工具按业务分组,避免一次塞给模型上百个工具,太多选项会让决策质量明显下降。我实测下来,一个任务循环里同时提供给模型的工具控制在 5 到 10 个最舒服,超出这个数量模型开始挑花眼。
2.3 记忆与上下文管理:模型不是数据库
不少第一次做 Bot 的人会犯一个错误:把每次对话的全部历史无脑塞给模型。结果就是上下文越来越长,模型越来越糊涂,费用也越来越高。Moltbot 的处理方式是区分三类信息:短期会话记忆、业务状态、长期知识。
短期会话记忆只保留最近几轮对话摘要;业务状态存放在独立的状态对象里,比如“当前订单填到哪一步了”“已确认的字段有哪些”,每次需要时作为结构化输入注入;长期知识(比如业务术语表、历史偏好)放向量库或配置文件,只在需要时检索。这就像一个员工的脑子——他不会把十年前见过的每个 Excel 都记住,但会把当前手头这项业务的状态理得清清楚楚。上下文管理做得好,Bot 的稳定性会明显上一个台阶。
2.4 人机协作边界:关键决策留给人
Moltbot 从 v2 开始加入了一个设计:关键步骤必须人工确认。不是因为模型不可信,而是因为很多业务场景里,错误决策的代价远高于确认成本。比如自动回复客户之前,即使模型认为邮件已经没问题了,也要先发给负责人确认;比如要删除一条数据之前,必须停下来问一遍。
这个“人机协作”不是简单的加一个 confirm 弹窗,而是要在任务定义时就标注好哪些节点是“人必须介入点”。我见过不少 Agent 项目把“完全自动化”当成目标,结果上线后没人敢用。真正好用的 Bot 应该是一个“该自动的自动,该请示的请示”的助手,而不是一个自作主张的执行器。这个边界一开始就要设计好,否则后面再改流程会伤筋动骨。
3. 实操过程:从零实现 Moltbot 的核心链路
3.1 环境准备与依赖选择
先说技术栈。Moltbot 主体用 Python 3.11,主要依赖是异步 HTTP 库和 Pydantic。不引入重框架,Agent 的核心逻辑自己写,因为工具调用循环的每一步都有可能要定制,框架封装得越厚,越难排查问题。数据库用了 SQLite 起步,等业务量起来再换 PostgreSQL。消息队列用的是 Redis 的 Stream 特性,足够应付几千个任务的队列。
依赖选择上有一条经验:尽量不要在一开始就上编排框架。我最早用过现成的 Agent 库,确实五分钟能跑一个 demo,但一旦涉及自定义工具校验、人工确认节点、断点续跑,这些库的抽象反而成了枷锁。后来我把循环逻辑拆成自己维护的两百多行代码,改动起来舒服得多。这不是说框架不好,而是“跑通 demo”和“生产可用”之间的差距,往往不是靠框架补上的,而是靠对自己业务的深入理解。
3.2 用 Python 实现第一个工具调用
下面是我实现工具调用的核心代码,简化到能看懂的规模。这里用一个“查询订单状态”的工具做例子。
from pydantic import BaseModel, Field class QueryOrderInput(BaseModel): order_id: str = Field( description="订单号,必填,格式如 ORD-2024-0001" ) include_detail: bool = Field( default=False, description="是否返回明细行" ) def query_order(order_id: str, include_detail: bool = False) -> dict: # 真实实现会在这里查数据库或调第三方接口 return {"status": "shipped", "order_id": order_id} TOOL_REGISTRY = { "query_order": { "description": ( "当用户询问订单状态、物流进度时调用。" "必须确认订单号后再调用,缺单号先向用户追问。" ), "input_schema": QueryOrderInput.model_json_schema(), "handler": query_order, } }真正重要的其实是“输入校验”这步。模型输出的工具调用参数,绝不能直接传给 handler。我加了这样几层:先用 Pydantic 检查类型和必填项,再跑一层业务校验(比如订单号前缀必须匹配),都通过了才执行。这里有个细节:handler 的执行要包在超时和异常捕获里,返回给模型的结果必须带一个状态标记,比如{"ok": true, "data": ...}或{"ok": false, "error": ...}。模型看到 ok 字段才知道这次调用是否成功,否则它可能基于一个失败结果继续瞎编。
3.3 任务编排与重试机制
单次工具调用只是零件,真正的任务编排是把多个零件串起来。Moltbot 用了一个极简的“任务状态机”:待解析、待执行、等待确认、已完成、失败。每一步工具调用的结果都会更新状态,状态机的当前值就是下一次模型决策的上下文。
比如“处理退货申请”这个任务:模型先调用 extract_return_info 从邮件里提取退货信息;提取完进入校验环节,比对商品表确认这个商品存在;如果信息缺漏,状态回到待解析并等待补充;如果完整,进入等待确认节点,由人工确认后再调用 create_return 写入系统。这个流程中没有一步是“模型直接写系统”,模型每一步的输出都先落到状态机,再被校验,最后才触发写操作。这样即便某一步模型抽风,也不会直接产生脏数据。
重试机制我也踩了不少坑。工具执行失败后,直接把错误信息丢回给模型让它自己重试,经常会造成死循环,因为模型会不断换一个说法调用同一个工具。我的做法是:同一个工具在同一个任务里最多允许失败三次,超过三次就进入人工处理队列,不再让模型继续折腾。这条规则听起来简单,但能省掉大量无用 token 和用户投诉。
3.4 把 Bot 接到真实业务里
Moltbot 对外暴露的是一个 HTTP 接口,接收任务请求,返回任务 ID。调用方拿这个 ID 查询进度,进度里包含当前状态和一步操作需要展示给用户的信息。这样设计的好处是解耦——Bot 内部怎么循环调用模型、怎么调工具,调用方完全不关心,它只需要知道“任务建好了”以及“任务当前卡在哪”。
接真实业务时,我最建议先接一个低频、非关键、不需要写数据的场景跑两到四周。跑通了再逐步放开权限。Moltbot 在第一个真实业务里只做了“提取 + 展示”两件事,模型不写任何数据,人工把提取结果复制到正式系统。就这样跑了三周,积累了足够多的真实样本,我才敢把“自动写入”开关打开。慢就是快,这个道理在 AI Bot 落地那里尤其适用。
4. 常见问题与排查技巧实录
4.1 模型不按计划执行
最常遇到的诡异现象是:任务进行到一半,模型突然开始输出和当前流程无关的内容,比如在填订单状态的环节突然开始聊起天气,或者把下一个工具的参数提前编好。排查几次之后,我发现根因往往是上下文里塞了太多无关的早期消息,模型被带偏了。
应对方式有两个:一个是在注入给模型的 session 里,把历史消息提炼成“当前已完成步骤 + 当前待处理事项”,而不是原始聊天记录;另一个是给每一步增加强约束 prompt,比如“你现在只负责填写订单金额字段,其他字段不要动,如果信息不足直接回复 NOT_ENOUGH_INFO”。强约束能明显减少幻觉式发挥,但注意别把所有话都塞进一个 prompt,prompt 太长模型反而抓不住重点。
4.2 上下文被塞爆
早先版本里,一次长任务跑久了 token 很容易爆。排查后发现是工具返回结果太大——比如查订单把一个几十行的明细原样返回给模型,模型根本不需要看这么多。后来我给工具返回加了一层摘要:返回给模型的内容是精简后的状态摘要,完整明细留在独立存储里,模型需要时才专门调用 detail 工具去取。
这个“分层取数”的思路值得安利:永远只给模型当前步骤需要的最小信息集合。信息少反而是好事,模型决策依据越聚焦,出错越少。有没有遇到过信息不全导致模型瞎猜的情况?也有,但缺信息时模型会主动追问(在 prompt 里鼓励它追问),这个问题的代价远低于信息过载导致走偏的代价。
4.3 工具调用幻觉:模型编参数
模型偶尔会编造一个看起来合理但根本不存在的参数值。比如订单号明明是 ORD-2024-0012,它可能在前置步骤里提取错了,之后所有查询都基于这个错号。这个问题不能靠模型自查,必须在工具层做硬校验。我加了一个“关键字段一致性检查”:把本次任务里已确认的维度字段(订单号、用户 ID、日期范围)存进状态对象,每次工具调用前比对参数是否和历史值冲突。冲突就不执行,并回给模型一条错误提示让它重新确认。
这条规则是我在整个项目里最得意的一个设计。它本质上是在告诉模型:你可以自由推理,但关键事实不能被悄悄修改。有了这道防线之后,很多“看起来模型在胡说八道”的问题,其实在工具层就被拦住了,根本到不了用户眼前。
4.4 并发与幂等
当 Bot 开始服务多个任务时,并发问题就来了。最主要的坑是:同一个任务的重复提交,以及工具被并发调用造成的重复写入。解决重复提交靠幂等键,每个任务创建时生成唯一 request_id,写入时检查是否已存在。解决重复写入靠状态机迁移:只有“待执行”状态才能迁到“已执行”,迁移失败说明有人抢先一步。
并发下还有个容易忽略的点:模型调用接口本身也可能超时或返回异常。我这边统一做了一级重试和退避策略,重试时用同一个任务 ID,确保不会因为重试而产生两个并行任务。所有跟外部系统交互的工具,都要求实现“幂等语义”——哪怕实现不了,也要在外层做防重保护。
4.5 安全边界:别让 Bot 太“能干”
最后想聊一个容易被忽视的问题:当你把 Bot 做得很能干之后,反而要小心它太能干。它会调数据库、会发消息、会改配置,这些能力的组合就可能变成风险。比如模型被注入了一段恶意指令(通过外部数据间接注入),它可能会尝试调用权限之外的敏感工具。
我的策略是三层隔离:一是权限最小化,Bot 账号只有最低限度的读写权限;二是敏感操作必须人工确认,这是硬编码的流程,模型无权跳过;三是外部输入一律“数据化”而不是“指令化”——从邮件、网页拿到的内容只作为数据字段存在状态对象里,不混入系统 prompt。这一层安全设计写出来只有几句话,但它是 Moltbot 能真正放进生产环境的底气。
4.6 问题排查速查表
| 症状 | 根因 | 解决思路 |
|---|---|---|
| 模型答非所问 | 上下文混入无关历史 | Session 改为摘要式注入 |
| 工具参数编造 | 关键字段状态丢失 | 关键字段一致性校验 |
| 工具调用死循环 | 失败后无限重试 | 失败上限 + 人工队列 |
| 任务重复写入 | 缺少幂等保护 | request_id + 状态机迁移 |
| 上下文 token 暴涨 | 工具返回过度 | 分层取数 + 摘要返回 |
这张表是我后来做线上支持时最常翻的。很多新问题查到最后,根因都在这些老问题上。
5. 演进实录:从 v1 到 v3 的教训
5.1 v1:能聊,但一干活就碎
v1 就是我前面说的 Clawdbot 时代,核心逻辑是“请求 -> 返回 -> 展示”,几乎没有状态概念。上线第一个内部 demo 时,演示效果很好,因为提前准备的对话都在模型会答的范围里。但真一开放给同事用,立刻露馅:十句里有六句答非所问,更别提让它执行操作。那段时间我一度怀疑是大模型不适合做 Bot,后来才明白是架构不支持做 Bot。
v1 阶段最大的价值是验证了一件事:用户对“AI 助手”的真实期望不是陪聊,而是“能替我干活”。很多人在演示的时候只会问“帮我写一段文案”这种纯生成任务,一旦放到真实业务里,问的是“帮我把这个表格里的数据更新一下”——这两种需求在工程上完全不是一回事。
5.2 v2:加了工具,却把自己坑了
v2 开始引入工具调用,解决的问题是“模型能干事了”。但矫枉过正:我把几十个工具一股脑全塞给模型,结果模型经常在错误时机调用工具。比如用户只是问“你们的退货政策是什么”,模型却先去调 create_return 工具。这种错误在日志里看很搞笑,但真实用户遇到就很崩溃。
v2 的教训总结成一句:工具是给模型用的,也是给模型设限的。不是工具越多越好,而是每个任务上下文里出现的工具越精准越好。后来我按任务类型给工具做分组,每次只暴露相关工具,问题立减大半。另外 v2 还缺人工确认节点,有一次模型在测试环境里真的把一条测试数据给“删除”了,虽然无伤大雅,但给我提了个醒——下一步必须做人工闸门。
5.3 v3:稳定落地的纪律
v3 就是现在的 Moltbot。它不追求模型多聪明,而是把每一个环节都变成了可校验、可控、可回滚的工程模块。回顾 v3 的代码,真正决定稳定性的不是某一段魔法代码,而是一堆“纪律”:工具描述写清楚、参数校验做齐全、关键操作要确认、失败重试有上限、上下文只给最小必要信息。这些纪律单看都很朴素,组合在一起才让 Bot 变的可依赖。
Moltbot 要解决的新问题还有很多,比如多任务并行时的资源分配、更复杂的多轮确认流程、长期记忆的质量控制。但相比 v1 时期那种“模型很牛,Bot 啥也不是”的状态,现在至少每一步都是扎实的。
如果让我用一个词总结这段从 Clawdbot 到 Moltbot 的经历,我会选“克制”。不是“让模型多做点”就能把 Bot 做好,恰恰相反,是要想清楚哪些事不该让模型做、哪些地方必须设闸、哪些信息不该塞给它。这个感悟是在踩了几十次坑之后才真正内化的。
最后再分享一个小技巧:如果你也在做类似的 AI Bot,建议从一开始就给每次工具调用记结构化日志——工具名、参数、返回值、耗时、谁触发的。这些日志不是给监控看热闹的,而是后期排查“模型为什么犯错”的第一手材料。我靠这些日志定位了至少一半的诡异问题。想继续扩展的话,Moltbot 后面准备加上基于日志的回归测试——每次改了 prompt 或工具描述,就跑一遍历史任务样本,看输出有没有退化。这一步做完,Bot 的迭代速度会再上一个台阶。