refactor(chat): remove the post-answer suggestion chips and the table that fed them
Measured use of the three chips above the composer was negligible. They were also not what they appeared to be: the server looked up a fixed triplet by session theme and passed it as metadata that overrode anything the model produced, so the same ten hardcoded sets served every user regardless of question or chart. That is a plausible reason nobody pressed them. Both copies of the per-theme table are gone, reply metadata narrows to the session title, and the two parse entry points collapse into one now that they return the same shape. The write schema still tolerates a suggestions field so a client on the previous bundle does not lose its message mid-deploy, and stored answers containing the legacy hidden block are still stripped rather than shown raw. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
+17
-1
@@ -4012,7 +4012,23 @@
|
||||
2. 契约收敛(用户评审后决定,同一分支内完成):`onboarding.greeting` 从 Agent 契约里彻底移除——schema、fallback、prompt、客户端响应校验与 `OnboardingContent` 类型全部不再有这个字段,不再为无渲染点的内容付费。`suggestions` 从 `career`/`marriage`/`timing` 的固定三元组改成按 `consultationDomainIds` 顺序覆盖全部十个域,校验用 refine 钉住「长度与顺序都必须与 registry 一致」,于是首页十张卡全部是 Agent 写的,静态 `prompt` 退回纯兜底角色。fallback 直接由 `generalGuidedJyotishTopics` 派生,避免手写十条又与 registry 漂移。生成十条比三条显著更慢,预算随之上调:路由 `maxDuration` 30→60 秒、服务端生成超时 18→45 秒、客户端单次请求超时 25→50 秒。缓存版本 `ayanam-onboarding-v4`→`v5`,让所有存量 v4 payload 重新生成一次。
|
||||
- 验证:`onboarding-presentation.test.ts` 的 hero 断言改为同时检查 `page.tsx` 与 `globals.css` 中不再出现 `starter-hero-note`,避免只删元素留下死样式;`starter-questions.test.ts` 的边界声明断言从「文件里存在这句话」收紧为「这句话出现在主题区小标题且受 `personalChartAvailable` 分支控制」,防止下一次挪动文案时悄悄丢掉。契约部分新增 5 条回归:只覆盖三个域的旧形态响应必须整体拒绝并落到覆盖全域的兜底、主题顺序被交换必须拒绝(否则问题会挂到错误的主题标签下)、fallback 自身必须能通过 payload schema(registry 里的 prompt 一旦不再第一人称就会被这条抓住)、prompt 与 payload/client 源码中不得再出现 greeting 字段、路由必须把 registry 主题列表发给 Agent。客户端请求超时断言从 25 秒下限改到 45 秒下限,与服务端生成预算对齐。全量套件 1720/1729 通过,9 个失败全部是本机 Docker/PostgreSQL fixture(与 BUG-265、BUG-269 同一类环境失败);`tsc --noEmit` 清洁,ESLint 仅存量 4 条 warning,`next build` 成功。未做的验证:**没有在浏览器里看过改动后的首页**,也没有真实调用过新契约的生成——本机没有模型密钥,十条问题的实际生成耗时是否落在 45 秒预算内、十张卡的文案是否彼此重复、以及 hero 删掉第三行后的留白与边界声明在窄屏的折行,都要等 staging 发布后确认。若线上出现大量 `fallback`,第一嫌疑就是 45 秒预算仍然不够。
|
||||
- 防复发:删除一个 UI 元素前必须先确认它有没有在承载与自身样式无关的合规或真实性文案——`starter-hero-note` 表面是装饰性说明行,实际是 BUG-200 边界声明的唯一落点。删元素时同步删样式,并用测试同时钉住两个文件,否则死 CSS 会在下一次改版时被误当作现有设计复用。声明数量的文案(「三个起点」)不要写死在与数据源无关的地方,数量必须跟着 registry 走。Agent 契约里的字段数量变化必须同步三件事:缓存版本、生成超时预算、客户端请求超时;只改 schema 不改预算的结果是全量用户静默落到 fallback,而 fallback 看起来是「正常内容」,不会报错。契约收紧时要用 refine 校验「集合与顺序」而不是只校验单项,否则模型少写几项或错位映射都能通过。
|
||||
- 相关记录:BUG-269(本次推翻其 hero 说明行处置)、BUG-200(首页真实性边界声明的原始约束,本次迁移未削弱)
|
||||
- 相关记录:BUG-269(本次推翻其 hero 说明行处置)、BUG-200(首页真实性边界声明的原始约束,本次迁移未削弱)、BUG-271(同一轮评审的下一项删除)
|
||||
- 复发自:无
|
||||
- 修复版本:本地未提交候选
|
||||
|
||||
## BUG-271 | 回答后输入框上方的三条推荐问题实际使用率极低且从未由 Agent 生成,整条链路删除
|
||||
|
||||
- 状态:resolved(本地修复,待提交与发布)
|
||||
- 首次发现:2026-08-18
|
||||
- 最近更新:2026-08-18
|
||||
- 影响面:会话内 `composer-suggestions` 追问按钮、`/api/consult` 写入的 assistant 消息字段、`consultation-reply-metadata` 与 `agent-reply` 的解析契约、会话写入 schema、`composer-wrap` 相关样式与 DESIGN.md 的对应条目。
|
||||
- 用户现象:用户实际测试后反馈「Agent 回答后用户输入框上方的三个推荐问题」使用频率很少,要求删除,并要求 Agent 也不再生成这三个问题。
|
||||
- 触发条件:任何咨询会话收到 assistant 回复之后,输入框上方固定出现三条按钮。
|
||||
- 根因:这里有一个与用户预期不同的事实——**这三条问题从来不是 Agent 生成的**。`createConsultationReplyMetadata` 按会话主题从写死的十主题三元组里取一组,服务端总是把它塞进 `parseAgentReply` 的 metadata 参数,而 metadata 分支优先级高于模型输出(`metadata?.suggestions ?? …`),因此模型即便真的输出了 `AYANAM_SUGGESTIONS` 也会被覆盖;Prompt 本身还明确禁止模型产出隐藏元数据块。同一份三元组表被完整复制在 `agent-reply.ts` 与 `consultation-reply-metadata.ts` 两处。也就是说,界面上看起来「个性化」的追问入口,实际是按主题查表的十组固定文案,与用户的具体问题、星盘证据都无关——这正是使用率低的合理解释。附带发现:`chooseConversationSuggestion` 里针对「先完成生时校正」这一条的生时校正跳转分支在当前链路下不可达,因为服务端 metadata 恒定覆盖,三元组里从不含这条文案。
|
||||
- 修复:删除渲染点(`composer-suggestions` 块)、派生状态 `activeSuggestions`、点击处理 `chooseConversationSuggestion` 与常量 `rectifyBeforeConsultationSuggestion`、客户端 `readSuggestions` 与三处 `suggestions` 写入(send、本地预览、预览会话种子)。服务端 `consultationReplyMetadataSchema` 收缩为只有 `title` 且 `.strict()`,`createConsultationReplyMetadata` 不再需要 `theme` 入参,两份 `fallbackSuggestions` 表全部删除。`parseAgentReply` 与 `parseAgentReplyBody` 在失去 suggestions 后返回形状完全相同,合并为单一 `parseAgentReply(value, metadata?)`,生时校正改调这一个入口。`ChatMessage` 去掉 `suggestions` 字段;但会话写入 schema 的 `suggestions` **有意保留为可选**——该 schema 是 `.strict()` 的,发布瞬间仍在运行旧 bundle 的客户端会继续带上这个字段,拒绝整个写入等于丢掉用户那条消息,代价远大于留一个被忽略的字段。`stripAgentReplyMetadata` 同样保留剥离 `AYANAM_SUGGESTIONS` 注释的能力,因为删除前写入的历史回答里仍带着这个块,不剥离会把原始 HTML 注释显示给用户。CSS 删除 8 处 `.composer-suggestions` 规则(含混合选择器中的片段与两个媒体查询内的规则),Prompt 里「follow-up suggestions 由服务端生成」改为只提标题,DESIGN.md 对应条目改写为「回答不提供追问建议」并记录原因。
|
||||
- 验证:新增/改写回归共 6 条:会话内不得再出现 `composer-suggestions`/`activeSuggestions`/`chooseConversationSuggestion` 且 CSS 同步无残留、metadata schema 必须拒绝 `suggestions` 字段(防止 chips 从元数据侧回流)、两个库文件与 consult 路由中不得再出现主题三元组或 suggestions 写入、历史遗留的 `AYANAM_SUGGESTIONS` 块必须被剥离且不得复活成字段、输入框与正文之间不得再有会改变高度的兄弟节点(原 chip 行会在流式过程中撑高 composer)、生时校正入口在失去 chip 跳转后仍可从首页卡片进入。全量 1716/1721 通过,5 个失败全部是本机 Docker/PostgreSQL migration fixture;`tsc --noEmit` 清洁,ESLint 仅存量 4 条 warning,`next build` 成功。未做的验证:**没有在浏览器里确认删掉 chip 行后会话底部的留白与滚动锚点表现**,尤其是 BUG-263 里「跳到最新」按钮的定位曾依赖 chip 行带来的高度变化,需要发布后目视确认按钮位置仍然合理。
|
||||
- 防复发:不要把查表得到的固定文案摆在会让用户以为是个性化生成的位置——这类「假个性化」入口既消耗界面空间又必然低使用率,而且因为看起来正常,不会有人报 bug。同一份兜底数据不允许在两个模块各存一份副本,否则删除时必然漏掉一处。删除一个可选字段时要区分「输出契约」与「输入契约」:输出侧应当立刻停止产出,输入侧在旧客户端与历史数据仍可能带上它时必须继续宽容接收,否则发布窗口内会丢用户数据。当两个函数因为字段删除而返回形状相同时应当合并,但要意识到其中一个可能是某个历史 Bug(此处 BUG-179)刻意建立的隔离措施,合并前必须确认该措施防的问题已经在结构上不可能发生。
|
||||
- 相关记录:BUG-179(曾因通用解析器的三条建议兜底污染生时校正,本次删除使其隔离措施不再必要)、BUG-263(「跳到最新」按钮定位曾受 chip 行高度影响)、BUG-249(草稿隔离验证里包含推荐问题填入路径)、BUG-270(同一轮评审的上一项删除)
|
||||
- 复发自:无
|
||||
- 修复版本:`a12f5797`(staging)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user