GoForum🌐 V2EX

从「能用」到「可治理」: AI 随手记做了一次「不动皮只动骨」的升级

pengdw · 2026-02-12 21:12 · 0 次点赞 · 0 条回复

最近我们给「 AI 随手记」做了一次大改造。
用户看到的还是老样子——写随手记、点生成、拿到一篇日记。但里面已经从一个「大杂烩流程」,变成了一条可组合、可追踪、可回放、还能做质量把关的「技能流水线」。

这篇文章用大白话讲讲:我们为什么要改、改了什么、踩了哪些坑,以及这件事对我们(和对想做类似产品的人)意味着什么。


一、为什么要动刀?——「能跑」和「能管」是两回事

以前的实现也能跑,但有几件事让我们越来越头疼:

  • 逻辑缠在一起
    生成一篇日记时,清洗、检索、写作、存库、向量化全挤在一坨,改一处怕动全身。

  • 出了问题不好查
    用户说「这次写得怪」,我们只能翻日志猜,很难精确还原「到底是哪一步、输入输出长什么样」。

  • 想小步试新东西很难
    比如只想换一段提示词或某一步策略,几乎要动整条链路,没法单独试。

  • 质量会飘
    不同模型(尤其像 Qwen 这类)有时会「脑补」事实,规则不好统一管。

所以我们这次的目标很明确:
把「写日记」从一个大函数,拆成一条「有标准接口的技能流水线」。
这样每一步都可以单独升级、单独排查、单独做灰度。


二、我们具体做了什么?(一句话版)

我们把系统重构成了四块:

  • SkillRegistry:技能注册表,知道有哪些技能、怎么找。
  • SkillExecutor:执行器,按标准接口跑每一个技能。
  • SkillOrchestrator:编排器,决定先跑谁、后跑谁、怎么串起来。
  • Trace:每次运行都留痕,谁在什么时候、吃了什么、吐出了什么、花了多久、有没有报错。

然后把「生成日记」这条主流程,拆成了 5 个技能

  1. note-normalize (清洗)
    把随手记整理成统一的结构化块,去噪音,准备好给后面用。

  2. memory-retrieve (记忆检索)
    用本地记忆做召回,给生成阶段补一点上下文;可以降级为空,不阻塞主流程。

  3. diary-compose (生成)
    按规则生成正文。

  4. diary-critic (审校门控)
    检查有没有「硬伤」:比如图片标记幻觉、背景信息泄露、拼接感太重等。
    不只是打分,还能拦:不合格就不落库,避免脏数据。

  5. persist (落库)
    通过审校的才存进去;不通过就阻断,并返回可解释的原因。

用户依然只点「生成日记」,但内部已经是一条清晰的流水线:清洗 → 检索 → 生成 → 审校 → 落库。


三、最关键的四种能力:可追踪、可回放、可灰度、可门控

这次重构,我们最在意的是四件事。它们不炫,但决定了能不能长期迭代、少背锅。

1 ) Trace:可追踪

每次运行都有一个 run_id,会记录:
每个技能吃了什么(输入摘要)、吐出了什么(输出摘要)、耗时多少、有没有报错。

以前:用户说「这次写得怪」→ 我们猜。
现在:按 run_id 一查,就能看到是哪一个技能、在什么输入下、产出了什么,相当于可回放的一盘录像

2 ) Replay:可回放

我们加了一套「固定样本」的复测数据。
改一个技能或一段提示词,可以用同一批样本反复跑,看有没有「修一个坏三个」。

这对稳定迭代特别重要:先能复现,再谈优化。

3 ) Rollout:可灰度

支持「按技能切版本」。
比如只把「 diary-compose 」换成新版本,其他技能不动,整条链路不用大动。
这样我们可以小步试新策略、新 prompt ,出问题也能快速回滚。

4 ) Gate:可门控

diary-critic 不只是打分数,而是有「拦」的能力。
高风险内容(幻觉、泄露、拼接味太重)可以不落库,并给用户一个可解释的原因,而不是悄悄存错。


四、踩过的坑

坑 1:Xcode 资源重名冲突

多个技能里都有 SKILL.mdinput.jsonoutput.json,Xcode 拷贝资源时会扁平化,结果出现「重复输出」之类的问题。

解决:改成全局唯一文件名(例如 SKILL-note-normalize.mdnote-normalize-input.json),并在 registry 里用 SKILL*.md 这种方式扫描,避免重名。

坑 2:第二次生成时崩溃( SwiftData detached backing data )

第一次生成后,我们在异步任务里还在读旧的 DiaryElement;第二次生成时先把旧元素删了,就触发了 fault 崩溃。

解决:去掉在后台乱跑的并发 Task ,把向量生成和保存放回同一条 async 执行流里,保证对象生命周期一致,不再「用已删掉的东西」。

坑 3:日记「像在拼接 notes 」

提示词太保守时,模型会变成「安全复述器」:一条条复述随手记,不像日记,像清单。

解决

  • 在 prompt 里允许「合并同主题、时间线重排、口语转书面、压缩重复」;
  • 在 Critic 里加「拼接味检测」(例如重合度阈值);
  • 命中后自动重写一轮,但不放宽事实约束,避免编造。

五、最难的一关:既不虚构,又要像日记

「禁止虚构」和「读起来像日记」经常打架:
管太严 → 像清单;放太松 → 容易编造。

我们的做法是三层:

  1. 硬约束守底线
    不新增输入里没有的关键事实。这是红线。

  2. 结构规则保可读
    强制段落规划、主题合并,让文本有节奏、有重点,而不是流水账。

  3. 审校规则兜质量
    用 Critic 检测「拼接味」,必要时自动重写一次,仍然不放宽事实约束。

结果就是:既不把 notes 原样粘贴,也不靠「脑补」润色。


六、用户能感受到的变化

表面上看,还是「写随手记 → 一键生成日记」。但你会慢慢感觉到:

  • 首行格式更稳定
    例如:2026-2-6 上海,多云,2.8°C,不会乱变。

  • 文本更像日记
    不再是「一行行原始随手记的复制」,而是有合并、有节奏、口语转书面。

  • 出错更可解释
    我们内部能通过 trace 看到是哪个技能、在什么环节出了问题,修起来更有针对性;未来也可以把「可解释」适度开放给用户(比如「因内容未通过审校,未保存」)。


七、一点结论:AI 应用拼到后面,拼的是「能不能治理」

单次回答好不好,很重要;但产品要长期活下来,更关键的是:

  • 能不能治理:流程清晰、每一步可观测、可调参。
  • 能不能复盘:出问题能回放、能定位,而不是靠猜。
  • 能不能小步快跑:改一点、测一点、灰度一点,而不是一改就炸。

这次把「生成日记」做成 Skills 流水线,本质上就是把「提示词工程」升级成「系统工程」

如果你也在做类似的产品(日记、总结、写作助手等),我们会建议优先补三件事:
可追踪、可回放、可门控。
它们看起来不炫,但会直接决定你能不能长期迭代、少背锅、少踩坑。

0 条回复
添加回复
你还需要 登录 后发表回复

登录后可发帖和回复

登录 注册
主题信息
作者: pengdw
发布: 2026-02-12
点赞: 0
回复: 0