前后端交互
本章解释从“用户点击发送”到“收到 AI 回复并写回编辑器”的完整链路,并重点说明前端发送的 params 如何帮助模型更好完成任务。
端到端流程图
流程中的关键点:
- 构造并发送 params:收集上下文包 + 用户输入,交给消息引擎发起请求
- 流式解析与渲染:default 协议走
callbacks.onMessage;agui 协议走内置解析 - 结果写回编辑器:用户点击“替换/插入”等动作后执行写回
params 结构(后端真正应该用的输入)
params 字段如下(按重要性排序):
{
systemPrompt, // 已替换 {cursorMarker} 的系统提示词
prompt, // 用户输入的内容,即用户的要求
skill, // 用户所选的技能名称:'write' | 'image' | 'code' | 'mermaid' | 'search'
from, // 当前对话的来源:'assistant' | 'chat'
reasoning, // 是否深度思考(boolean)
model, // 当前模型对象(value/label/endpoint/protocol/...)
messages, // 当前会话的所有消息(数组)
locale, // 'zh-CN' | 'en-US'
selectionText, // 用户选区纯文本(可能为空)
selectionNodes, // 选区节点级 Markdown(可能为空;可能含选区标记)
document, // 全文 Markdown(含光标/选区标记)
cursorMarker, // 当前光标位置标记(默认 '⦙')
chatID, // 当前会话 id(会话 id 相同可认为是连续对话)
documentID, // 文档 id(业务可用于检索/存档)
userID, // 用户 id(业务可用于配额/审计)
attachments, // 可选:聊天附件数组(仅 chat 且启用 files.enabled)
}其中与“编辑任务完成质量”最相关的是:
systemPromptskillselectionNodes/documentcursorMarker(已内嵌在 systemPrompt 与 document / selectionNodes 中)
后端如何使用 params(建议的 Prompt 组装策略)
把 systemPrompt 作为 system role
强建议把 systemPrompt 放进模型的 system 消息(或最上层指令),不要混进 user prompt。
- systemPrompt 里包含“输出必须可直接插入 / 替换”“不得破坏 Markdown”等硬约束
- 能明显降低模型输出废话、破坏结构、越界修改的概率
根据 skill 做路由与额外约束
skill 的作用不止是 UI 展示,它应驱动后端策略:
write:允许生成 / 改写 Markdown;输出应尽量是“可直接替换 / 插入”的内容code:输出应是代码块 Markdown(避免解释性文字)mermaid:输出 Mermaid 代码块image:返回图片 Markdownsearch:返回总结/解释,但不要改写文档结构(除非业务定义允许)
推荐做法:为不同 skill 定义不同的后端模板(或不同的 Agent 工具链)。
优先用 selectionNodes,而不是 selectionText
选区场景下:
selectionText会丢结构(列表/表格/代码块)selectionNodes是节点级 Markdown,结构更稳,并可能包含选区起止 cursorMarker,可包含多个节点
后端策略建议:
- 如果
selectionNodes非空:把它作为“允许编辑的唯一范围”(严格约束) - 如果选区为空但
document含 cursorMarker:把 cursorMarker 附近上下文作为“局部可编辑区域” - 如果两者都为空:提示用户先选中内容或确认插入点(或在后端做降级策略)
正确理解 cursorMarker(让模型“知道要改哪”)
ai.cursorMarker(默认 ⦙)会出现在:
document:光标处为 1 个 cursorMarker;选区时为 2 个 cursorMarker(起止)selectionNodes:可能含起止 cursorMarker;若无法插入 cursorMarker,则可能包裹在首尾systemPrompt:规则说明中引用该 cursorMarker
后端应该把 cursorMarker 当作“结构化指令”,而不是普通字符:
- 选区:只允许改两 cursorMarker 之间的内容
- 光标:在 cursorMarker 处插入内容;不要改 cursorMarker 以外内容
根据 from 区分交互语义
assistant:偏“编辑型输出”,可以更激进地要求输出可写回文档chat:偏“对话型输出”,允许更多解释/澄清(但仍建议保持简洁)
推荐后端做两套提示词策略:
- assistant:严格输出、少解释、可插入
- chat:更自然、允许多轮、可询问用户缺失信息
根据 attachments 建议的使用方式
附件只在满足条件时出现:
from === 'chat'ai.chat.files.enabled === true- 用户已上传且上传完成(文件状态不是 progress)
attachments 来自 onFileUpload 返回信息。
后端常见策略:
- 图片:走 OCR / 视觉模型,提取要点后参与回答
- 文档 / PDF:做切分、向量化检索(RAG),再把相关片段加入上下文
- 表格:解析为结构化数据后再让模型回答
推荐的后端接口形态
SSE + 自定义协议(default)
- 控制输出 JSON 结构
- 前端用
ai.callbacks.onMessage做映射
最低要求:每个 SSE 事件输出一行 JSON(不要直接输出带换行的 Markdown),可以参考:Umo Editor Server 的 AI SSE 示例接口。
SSE + AG-UI(agui)
- 控制输出 AG-UI 事件类型
- 前端自动解析显示(适合 agent 工具调用)
如果准备做“工具调用 / 多步骤任务 / 进度状态”,建议优先 AG-UI,可以参考:Umo Editor Server 的 AI SSE 示例接口。