V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
pengdw
V2EX  ›  问与答

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

  •  
  •   pengdw · 5 小时 9 分钟前 · 109 次点击

    最近我们给「 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 流水线,本质上就是把「提示词工程」升级成「系统工程」

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

    目前尚无回复
    关于   ·   帮助文档   ·   自助推广系统   ·   博客   ·   API   ·   FAQ   ·   Solana   ·   984 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 21ms · UTC 18:18 · PVG 02:18 · LAX 10:18 · JFK 13:18
    ♥ Do have faith in what you're doing.