# 一张卡,把回答排成文章 > dsh-rich-cards 只做一件事:把回答末尾的那段 JSON,变成你愿意读完的版式。 对话里的长回答本质上是一篇文档:结论、证据、数据、时间线全混在一段 markdown 里,读者得自己找重点。卡片做的是先把这段文字拆成有名字的部分,再决定每一部分怎么排。 ## 它解决的不是美观问题 排版是副产品。被固定下来的是结构:先给一句话结论,再给证据,最后才展开细节。模型为了填满这些格子,不得不先把话说清楚——版式反过来约束了写作。 | | | | --- | --- | | 块类型 | 12 | | 布局 | 2(`card` / `article`)| | 代码量 | 1,273 行(宿主 318 + 客户端 955)| | 运行时依赖 | 0 | ## 两条传送带 插件历史上走过两条把数据送到渲染器的路,现在只剩第二条。 - **工具通道(已下线)**:注册一个 `rich_card` 工具,参数本身就是 JSON。写坏一个引号,整个回合以 `MALFORMED_RESPONSE` 结束——回答没了。 - **围栏通道(现行)**:模型在回答末尾写一个 ` ```card ` 代码块,正文是 JSON。渲染失败只留下一段源码,回答照常成立。 选后者不是因为它更优雅,是因为失败代价小一个数量级。 ## 一次回答的旅程 1. 宿主端往系统提示里加一段写作约定(`order: 34`),**不注册任何工具**。 2. 模型在回答末尾写一个 `card` 围栏块,正文是 JSON。 3. 浏览器端用 `MutationObserver` 扫到这段代码块,`parseFence` 解析成功,就在原位挂一张卡片。 4. 解析失败就原样留着,读者看到的是源码,不是坏掉的页面。 拆代码块的壳有讲究。渲染器的结构大致是: ```html
…