# AI 写作助手后端接口与 Prompt 协议文档 ## 1. 文档目标 本文档用于指导 AI 写作助手第二阶段升级中的后端开发、接口设计、提示词设计和联调约束。 本轮后端目标不是重做 DeerFlow 的整体架构,而是在保留现有 Python + LangGraph + 线程体系的基础上,新增一套稳定的“选区改写型能力”,服务前端的 Tiptap 写作编辑器。 --- ## 2. 本轮后端职责 后端负责: - 接收当前线程信息 - 接收用户选区文本 - 接收改写动作 - 选取必要上下文 - 调用模型生成候选改写结果 - 返回纯净候选文本 后端本轮不负责: - 直接编辑 Tiptap JSON - 直接操作前端编辑器选区 - 直接替换前端文档内容 - 做复杂富文本 patch - 做 tracked changes --- ## 3. 设计原则 ### 3.1 纯文本协议优先 首版只让后端处理: - 选区文本 - 前后文文本 - 动作类型 - 风格参数 不让后端直接理解完整富文本 JSON。 ### 3.2 前端负责应用,后端负责生成 - 前端负责选区获取 - 前端负责候选结果展示 - 前端负责替换 / 插入 - 后端只负责“给出候选文本” ### 3.3 结果必须可直接落文档 后端输出必须尽量是可直接放回编辑器的正文,不应带解释性前缀,例如: - “当然可以,以下是润色版本:” - “我帮你改写如下:” - “下面是优化后的内容:” 这类内容必须禁止。 --- ## 4. 推荐接口设计 ## 4.1 主接口 推荐新增统一接口: ```text POST /api/writing/rewrite ``` 由 `action` 决定具体重写类型。 ## 4.2 为什么推荐统一接口 因为前端交互是一套统一浮层和统一预览面板,拆成多个接口会导致: - 前端判断分支增多 - 埋点与异常处理分散 - 后续新增动作不方便扩展 统一接口更适合本轮需求。 --- ## 5. 请求体定义 建议请求体如下: ```json { "threadId": "string", "documentId": "string", "selection": { "from": 120, "to": 260, "text": "待改写文本" }, "action": "polish", "tone": "professional", "surroundingContext": { "before": "选区前文", "after": "选区后文" } } ``` --- ## 6. 字段说明 ### 6.1 `threadId` 用途: - 关联当前 DeerFlow 线程 - 必要时取线程上下文或会话元数据 ### 6.2 `documentId` 用途: - 标识当前右侧文档 - 首版可选 - 如果当前系统还没有独立文档 ID,可先允许为空 ### 6.3 `selection.from` / `selection.to` 用途: - 帮助前后端联调排查 - 首版后端通常不需要真正使用偏移量 - 建议保留,便于日志定位 ### 6.4 `selection.text` 用途: - 这是本轮最核心输入 - 后端实际重写的主文本 ### 6.5 `action` 允许值: - `polish` - `expand` - `shorten` - `tone` ### 6.6 `tone` 仅当 `action = tone` 时使用。 建议允许值: - `professional` - `casual` - `readable` - `academic` - `expressive` ### 6.7 `surroundingContext.before` 用途: - 提供选区前文 - 帮助模型理解语气、主语、叙事连续性 建议: - 控制长度 - 不要塞太多无关上下文 ### 6.8 `surroundingContext.after` 用途: - 提供选区后文 - 帮助模型在扩写、改语气时与后续内容衔接 --- ## 7. 返回体定义 建议返回体如下: ```json { "output": "AI 改写后的候选文本", "originalSelection": { "from": 120, "to": 260, "text": "待改写文本" }, "metadata": { "action": "polish", "tone": null, "model": "your-model-name" } } ``` --- ## 8. 返回字段要求 ## 8.1 `output` 必须: - 只包含候选正文 - 尽量不夹带解释语 - 能直接被前端替换或插入 ## 8.2 `originalSelection` 作用: - 前端可以做校验 - 联调时方便确认是针对哪段文本返回的 ## 8.3 `metadata` 作用: - 便于埋点 - 便于日志记录 - 便于问题追踪 --- ## 9. 错误响应规范 建议统一错误结构: ```json { "error": { "code": "WRITING_REWRITE_FAILED", "message": "rewrite failed" } } ``` 建议错误码: - `WRITING_REWRITE_FAILED` - `WRITING_INVALID_ACTION` - `WRITING_INVALID_TONE` - `WRITING_EMPTY_SELECTION` - `WRITING_MODEL_UNAVAILABLE` - `WRITING_CONTEXT_TOO_LARGE` --- ## 10. 动作语义定义 ## 10.1 `polish` 目标: - 保持原意 - 改善表达 - 提升通顺度、自然度和可读性 不应: - 引入新事实 - 改写成完全不同内容 ## 10.2 `expand` 目标: - 保持主旨 - 扩充细节 - 增强画面感、解释性或完整度 不应: - 无限制发散 - 添加明显脱离主题的新内容 ## 10.3 `shorten` 目标: - 压缩篇幅 - 保留关键信息 - 减少重复表达 不应: - 丢失关键论点 - 压缩到语义残缺 ## 10.4 `tone` 目标: - 不改变原意 - 调整语言风格 不应: - 改写事实 - 改写逻辑结构到完全不同 --- ## 11. Prompt 设计原则 ## 11.1 通用系统约束 所有改写类 prompt 都应包含以下约束: - 直接输出最终可用正文 - 不输出标题,除非原文本身就是标题改写 - 不输出解释 - 不输出分析过程 - 不输出“以下是结果”之类前缀 - 保持与上下文语气一致 ## 11.2 上下文使用原则 前后文只用于理解,不要求模型重写前后文。 明确告诉模型: - 只改写选中文本 - 前后文仅用于参考衔接 ## 11.3 长度控制原则 - `polish`:长度与原文接近 - `expand`:长度可明显增加,但不要失控 - `shorten`:长度明显缩短,但要保留关键信息 - `tone`:长度尽量与原文接近 --- ## 12. Prompt 模板建议 ## 12.1 润色模板 ```text 你是一名中文写作编辑助手。 请在不改变原意的前提下,对“选中文本”进行润色,使表达更自然、更流畅、更清晰。 要求: 1. 保留原文事实和核心意思。 2. 不要添加原文没有的新事实。 3. 不要输出解释,不要输出前缀,不要输出分析过程。 4. 直接输出润色后的正文。 前文参考: {before} 选中文本: {selection} 后文参考: {after} ``` ## 12.2 扩写模板 ```text 你是一名中文写作编辑助手。 请在不偏离主题的前提下,对“选中文本”进行扩写,增加必要细节、画面感或补充说明,使内容更充实。 要求: 1. 保持原文主旨不变。 2. 增加内容时要自然,不要跑题。 3. 不要输出解释,不要输出前缀,不要输出分析过程。 4. 直接输出扩写后的正文。 前文参考: {before} 选中文本: {selection} 后文参考: {after} ``` ## 12.3 缩写模板 ```text 你是一名中文写作编辑助手。 请在保留关键信息和原意的前提下,对“选中文本”进行缩写,使其更精炼。 要求: 1. 不要丢掉核心信息。 2. 去掉重复、冗余和拖沓表达。 3. 不要输出解释,不要输出前缀,不要输出分析过程。 4. 直接输出缩写后的正文。 前文参考: {before} 选中文本: {selection} 后文参考: {after} ``` ## 12.4 改语气模板 ```text 你是一名中文写作编辑助手。 请在不改变原意和事实的前提下,把“选中文本”改写成更{tone_label}的表达方式。 要求: 1. 保持原文信息不变。 2. 只调整表达风格,不改变事实和逻辑。 3. 不要输出解释,不要输出前缀,不要输出分析过程。 4. 直接输出改写后的正文。 前文参考: {before} 选中文本: {selection} 后文参考: {after} ``` --- ## 13. Tone 映射建议 建议前端传标准值,后端映射中文标签: - `professional` -> 专业、正式 - `casual` -> 口语化、轻松自然 - `readable` -> 更易读、更清晰 - `academic` -> 学术、严谨 - `expressive` -> 更有文采、更有表现力 --- ## 14. 上下文截取策略 ## 14.1 推荐策略 前端传: - 选区前固定长度文本 - 选区后固定长度文本 例如: - 前文 200 到 500 字 - 后文 200 到 500 字 ### 原因 - 足够帮助模型理解文气和衔接 - 不会让请求太重 ## 14.2 不建议 - 把整篇长文全量塞进去 - 把整个线程消息都塞进改写接口 如果后端确实要参考线程上下文,也建议只取最近和写作相关的少量消息摘要。 --- ## 15. LangGraph 接入建议 ## 15.1 推荐接入方式 在现有 LangGraph / gateway 架构中新增一个写作改写专用入口。 建议二选一: ### 方案 A 新增专用 router: - `POST /api/writing/rewrite` 内部调用现有模型层 / agent 层。 ### 方案 B 新增专用 graph node 或 tool: - `rewrite_selection` 再由 router 调用该能力。 ## 15.2 更推荐方案 推荐: - 对外暴露统一 router - 内部走已有模型封装或 LangGraph 节点 这样前端接口更稳定,后续后端内部重构不会影响前端。 --- ## 16. 后端模块拆解 ## 16.1 模块 A:接口层 负责: - 请求校验 - 错误响应 - 参数标准化 需要完成: - 统一 rewrite API - action / tone 校验 - 空选区校验 ## 16.2 模块 B:上下文拼装层 负责: - 拼装 before / selection / after - 必要时提取线程相关信息 需要完成: - 上下文长度控制 - 清洗空白和异常字符 ## 16.3 模块 C:Prompt 层 负责: - 选择模板 - 填充 action 和 tone 需要完成: - 4 类动作模板 - tone 映射 ## 16.4 模块 D:模型调用层 负责: - 走现有模型配置体系 - 执行大模型请求 需要完成: - 统一调用入口 - 模型不可用错误处理 ## 16.5 模块 E:结果清洗层 负责: - 去掉解释性前缀 - 去掉多余包裹 - 标准化返回 需要完成: - 输出清洗 - metadata 填充 --- ## 17. 返回结果清洗建议 即使 prompt 已经约束,模型仍可能输出: - “以下是润色后的内容:” - “当然,这里是改写结果:” - “优化如下:” 建议后端加一层轻量清洗: - 去掉常见说明性前缀 - 去掉包裹性 markdown 代码块 - 去掉多余首尾空白 注意: - 清洗必须保守 - 不要误删正文 --- ## 18. 日志与观测建议 建议记录: - `threadId` - `documentId` - `action` - `tone` - `selection_length` - `before_length` - `after_length` - `model_name` - `latency_ms` - `success / fail` 不要直接把整段用户正文原文打到普通日志里,避免敏感信息风险。 --- ## 19. 后端测试清单 ## 19.1 单元测试 - action 校验 - tone 校验 - 空选区校验 - prompt 选择逻辑 - 输出清洗逻辑 ## 19.2 集成测试 - `polish` - `expand` - `shorten` - `tone-professional` - `tone-casual` - `tone-readable` - `tone-academic` - `tone-expressive` ## 19.3 边界测试 - 选区过短 - 选区过长 - 前后文为空 - 多段文本带换行 - 模型超时 - 模型不可用 --- ## 20. 联调约束 ## 20.1 前后端必须统一 - `action` 枚举值 - `tone` 枚举值 - 错误码 - 返回体字段名 ## 20.2 联调重点 - 多段落文本中换行保留是否正确 - AI 返回内容是否适合直接落文档 - 超时和失败时前端是否能优雅重试 ## 20.3 联调建议顺序 1. 先 mock 返回固定文本 2. 再接真实模型 3. 先验证单段落 4. 再验证多段落 5. 最后验证大段文本 --- ## 21. 优先级建议 ### P0 - 统一 rewrite API - 4 类动作支持 - 输出纯净正文 - 错误结构标准化 ### P1 - 输出清洗增强 - 埋点与日志 - 上下文截断策略优化 ### P2 - 更细粒度风格控制 - 结果质量二次校验 --- ## 22. 完成定义 后端满足以下条件即可视为本轮完成: - 前端能通过统一接口发起改写 - 4 类动作均可稳定返回候选文本 - 返回文本基本可直接用于替换或插入 - 多段落文本能稳定处理 - 错误结构规范统一 --- ## 23. 结论 本轮后端最重要的,不是做复杂文档结构编辑,而是把“选区改写”做成稳定、可预测、可直接接入前端编辑器的能力。 最稳妥的路线是: - 统一接口 - 统一动作枚举 - 统一 prompt 模板 - 统一错误结构 - 统一输出约束 只要这层做稳,前端的 Tiptap 写作编辑器就能很顺畅地完成豆包式“选中即改、预览后应用”的核心体验。