• 性质:对话沉淀为可复用 Q&A
  • 日期:2026-07-01
  • 项目上下文:md-render AI 助手 / AgentPanel 交互
  • 关键词:AI 助手、选择卡片、结构化输出、生成式 UI、agent 协议、用户确认

背景

AI 助手已经不只是聊天框,它会读文档、调用工具、创建稿件、整理工作区。随着能力变多,它经常需要把下一步交给用户确认,例如:

  • 先做当前稿,还是拆成一个系列?
  • 直接创建选题,还是先补充旧文参考?
  • 覆盖当前文档,还是另存为新稿?

这些选择如果只写在自然语言回复里,就会变成:

A. 先做当前稿
B. 做系列化

用户看得懂,但应用看不懂。用户还要手动回复「选 A」,AI 才能继续下一轮。这个过程在聊天里能凑合,在工作台里就显得笨拙。

问题

这个问题的核心不是「卡片样式不好看」,而是自然语言回复与应用交互之间缺少结构化协议

具体表现为三层错位:

  1. 表达层错位

    AI 把选项写成文本,前端只能按普通消息渲染,无法知道哪些句子是可点击选项。

  2. 动作层错位

    用户点击选项这件事,本质上是在给 agent 下一轮输入;如果没有结构化 prompt,点击后很难稳定恢复成「我选择 A:某方案」。

  3. 职责层错位

    如果把选择做成 tool,就会把「等待用户决策」误塞进「执行系统动作」里。tool 应该执行动作,选择卡片应该承接用户确认。

所以真正要解决的是:

如何让 AI 的「请你选择」既能被人读懂,又能被界面解析,并且点击后能自然回到 agent loop?

解决方案

通用做法是把回复拆成两部分:人读文本 + 机器读协议

人读文本负责解释「为什么要选」;机器读协议负责告诉前端「有哪些选项、点击后发什么 prompt」。

方案分层

  1. 模型输出协议

    当 AI 需要用户在 2-6 个方案里选择时,在回复末尾追加一个隐藏 JSON 协议,例如:

    <!-- agent-choice
    {"options":[{"label":"A","title":"先做当前稿","description":"零启动成本","prompt":"我选择 A:先做当前稿"}]}
    -->

    这样人看到的是正常回复,UI 看到的是可解析的结构化数据。

  2. 解析层

    用一个纯函数解析 assistant 文本,输出稳定结构:

    {
    displayText: '确认想做哪个?',
    choices: [
    { label: 'A', title: '先做当前稿', description: '零启动成本', prompt: '我选择 A:先做当前稿' }
    ]
    }

    解析层不要依赖 React、store 或 IPC,方便单独测试和复用。

  3. UI 渲染层

    AgentPanel 只负责把 choices 渲染成卡片。用户点击卡片后,不写新业务流程,而是复用原来的 runTurn,把 choice.prompt 当成下一轮用户输入发回 agent。

  4. 兜底解析

    为了兼容旧模型输出,可以额外识别常见 A/B/C 列表,把普通文本选项转成卡片。但这只能做兼容路径,主路径仍应是隐藏协议。

为什么不用 tool

选择卡片不是 agent 能力本身,而是用户确认交互

如果把它做成 tool,会把「让用户点选」误塞进模型工具调用层,反而让职责混乱:

  • tool 适合执行动作,比如读文档、写文档、创建稿件;
  • choice card 适合等待用户决策;
  • 用户点击后再进入下一轮 agent loop,才是动作真正继续执行的时机。

所以更合理的边界是:

agentEngine 约定输出协议
→ choiceCards.js 解析协议
→ AgentPanel 渲染卡片
→ 点击卡片后复用 runTurn

md-render 的落地

本次实现采用了这个最小闭环:

  • agentEngine.js:系统提示里新增选择协议要求;
  • choiceCards.js:解析隐藏 agent-choice JSON,也兜底识别 A/B/C 文本;
  • AgentPanel.jsx:assistant 气泡里渲染选择卡片,点击后自动发起下一轮;
  • styles.css:补选择卡片样式;
  • md-render-agent skill:记录这个交互约定,避免以后重复设计。

验证点

  • 隐藏协议会被剥离,不显示给用户;
  • 协议里的 options 会渲染成卡片;
  • 点击卡片会发送对应 prompt;
  • 普通 A/B/C 文本能兜底显示卡片;
  • 无选择的普通回复不会误触发;
  • 长标题和说明不会撑破气泡;
  • AI 正在运行时,卡片不可重复点击。

可复用判断

以后遇到类似交互,可以用这组判断:

现象 判断 处理
AI 让用户选 A/B/C 这是用户确认交互 做 choice card
AI 要读写文件 这是系统动作 做 tool
AI 只是给建议 这是普通回答 不需要协议
AI 选项要驱动下一步 需要结构化 prompt 卡片点击后复用 agent loop
旧回复已经是 A/B 文本 需要兼容 做兜底解析,不当主路径

一句话总结

AI 让用户选择时,不要只让模型输出 A/B 文本;要让模型输出「人读文本 + 机器读协议」,再由前端把协议渲染成可点击卡片。

另见

Query 草稿:Codex 整理本轮 md-render AI 助手交互改造;2026-07-01。