727 lines
12 KiB
Markdown
727 lines
12 KiB
Markdown
# 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 写作编辑器就能很顺畅地完成豆包式“选中即改、预览后应用”的核心体验。
|