deepseek-harness/.agents/notes/implemented/feature/2026-08-17-web-system-prompt-opaque-body.zh.md
07akioni 61b65d3147 fix(web): show system prompts in chat
Render reconstructable system prompts at each request-series boundary, preserve series declarations through pre-step wrappers, and keep the presentation and replay snapshots aligned across clients.
2026-08-25 14:44:08 +08:00

2.4 KiB
Raw Blame History

Agent Note: System prompt expands into the opaque context body

Status: implemented

English | 中文

Problem

Chat 的 系统提示词 行和上下文注入共用 DisclosureRow 外壳,其展开内容区需要呈现请求的 system 字段。如果把该字段渲染成 Markdown——标题、强调、列表——读者看到的将是模型从未收到的排版文档。上下文注入已经用 141px 代码块滚动区和保留模型所见字节与换行的 <pre> 文本解决了同一件事,因此该行需要复用这一呈现,而不是再造一套。

Decision

SystemPromptRow 展开后挂载与不透明上下文注入相同的内容区。它复用 ContextInjectionRow.module.css 的 Figma 10:2482 的 141px 滚动区,并把持久 request/header 的 system 字符串作为一块文本交给 OpaqueBody,因此展开后看到的是带真实换行的模型可见文本,以及相同的 20_000 字符显示上限。该行默认折叠,仍然没有流式路径。它不增加生产者标签、form 标记或 source 字段列表:system 字段是 header 上的一段拼接字符串,不是带 source 的 user/message。

Alternatives considered

在卡片式内容区里渲染结算后的 Markdown。 外壳可以对齐,但 Markdown 会改写模型读到的内容。标题或加粗是另一份文档,不是请求里的字节。

把拼接后的 system 字符串拆成 snapshot 分段。 持久 header 只保存组装后的文本。客户端臆造分段边界会把日志未命名的正文归到某个子系统,恢复或外来 header 也无法重建这些分段。

直接走 ContextInjectionRow。 那一行面向带 source 的 user-role 消息:它标角色、显示生产者,并按 form 选内容区。system 字段是另一件持久事实,没有这些字段。

Consequences

两处展开现在共用同一套内容区外壳和同一套文本展示,因此之后改 141px 滚动区或不透明显示上限会同时作用到两边。代价是较长的系统提示词在 141px 而不是 360px 内滚动,提示词里的 Markdown 标记会以字符形式可见。

Testing

packages/client/ui-chat/tests/system-prompt-row.client.spec.tsx 会展开并折叠该行,并钉住不透明 [data-context-text] 字节,包括不得变成标题的 Markdown 标记。apps/web/tests/replay-round-trip.e2e.ts 仍会打开组装后的展开行,并从该内容区读出 persona 行。