上周的订单扫描有个问题:只要有一条记录格式不对,整个租户的所有订单都读不出来。好的坏的,一起被挡住了。
这轮的改动,正好从这里开始。101天,系统开始明白一件事:单个错误不应该让整个任务失效。
一、一条坏记录,不再拖垮全部订单
之前订单库中只要有一条记录不符合契约,整个扫描任务就会失败,导致同一租户的其他正常订单也无法被读取。这是一个典型的“全有或全无”设计——为了保护数据质量,代价是牺牲了可用性。
这轮改成了“按记录隔离”:发现不合规记录后,将其放入专门的不合规清单,同时继续扫描其他文件和记录。返回结果中增加了合规订单数量、不合规数量、总记录数等信息,统计真实完整。
只有在“没有任何合规记录、但存在不合规记录”时,才将整个任务判定为契约级失败。写入侧仍然保持严格校验,不合规数据不能上传或补丁写入。
系统不再因为一条坏记录,就拒绝服务其他正常的请求。
二、知识库名称不存在时,告诉你“那看看这些”
过去,模型使用一个已经被删除的知识库名称时,系统通常只返回“知识库不存在”。模型不知道有哪些是存在的,只能继续用同一个名称反复尝试,最终耗尽轮次。
这轮改了:错误结果会携带当前可用的知识库清单、清单总数以及结构化的下一步操作建议。
只有一个可用知识库时,直接提示其名称;有多个候选时,只提供候选,不擅自替模型选择;当前没有任何可用知识库时,明确要求停止尝试,而不是继续猜名称。对知识库文件读取、修改、导入和订单列表等多个入口都统一了这种返回格式。
同时增加了重复失败保护:当同一个工具、同一组参数、同一种结构化失败原因连续出现时,会提示更换参数或终止操作,避免无效重试。这个保护只依赖结构化错误码,不依赖错误文案——文案变了,保护依然有效。
错误信息不只是告诉你“错了”,还告诉你“下一步该怎么做”。
三、工具被过滤了,日志会记下来,不会静默消失
之前搜索结果中,用户明确点名的工具可能因为通用关键词命中数量较多,被其他无关工具挤到后面,模型看到前几项后可能误以为该工具不存在。
这轮改了匹配优先级:只要查询中出现完整工具名,就会给予最高优先级,让被点名的工具直接排在前面。工具列表被截断时,会保留明确的截断标记。工具因为组织权限或可见性被过滤时,日志会记录工具名称、来源、所属组织和过滤原因,不再静默跳过。
运行时目录里有什么、为什么没有,现在都能查到了。
四、证据账本:写满时不崩溃,只停止收录
证据账本是用来记录“系统完成某件事的证据”的。但当证据太多时——条数超过上限或字节数超过上限——之前会直接抛异常,而且是在模型调用开始前发生,每一轮都可能失败,用户只能看到“请重试”,但重试仍然会在相同位置失败。
这轮改了:超限后不再抛异常,而是停止收录超出的证据,并写入饱和标记和归因日志。系统会区分是条数达到上限还是字节容量达到上限——两者对应的解决办法不同。
保留策略采用“保留前面已有的证据、丢弃最新证据”,这样多轮重复扫描时结果稳定,不会因为反复淘汰和重新加入导致证据集合来回变化。容量也提高了,能满足一次任务需要收集几十条工具证据的场景。
饱和标记使用与证据收据相同的签名和编码机制,并随可信上下文传递给后续流程。Hook能区分“候选没有取证”和“证据账本已经饱和但部分证据未被收录”——不过饱和标记本身不参与授权判断,不能绕过证据门禁。
证据太多不会让系统崩溃,只会让收集器停止工作,并告诉你原因。
五、技能正文写入:超限就整体回滚
技能正文写入入口补齐了大小限制,避免过大的正文绕过部分入口限制直接进入系统。
更关键的是原子性保证:如果最终校验失败,之前已经写入的内容会整体回滚,不会留下半截正文或部分更新状态——用户不会看到“技能保存了一半”这种状态,要么完整成功,要么原样退回。
技能写入不会留下一半的内容,要么完整进来,要么完整退回去。
101天,系统不再因为一条坏记录而拖垮全部,不再因为知识库名称写错就无限重试,不再因为工具被过滤就静默消失,不再因为证据太多就抛异常,不再因为技能写入失败就留下半截内容。
在101天,系统终于学会了隔离错误,而不是扩散错误。
这,是第101天。
《从0到1:企业级AI项目迭代日记》记录一个企业级 AI 项目从创意、架构到落地的真实过程。不讲神话,只记录进化。
如果你也在做企业 AI 落地,欢迎留言来聊。或者,把这篇转发给一个正在踩同样坑的朋友。