| title | Workflow Chat API 能力说明(框架层) |
|---|---|
| status | active |
| owner | eanzhao |
单一事实源(Single Source of Truth):
/api/chat、/api/ws/chat相关能力说明以本文为准。
Host 侧入口文档:src/workflow/Aevatar.Workflow.Host.Api/README.md、src/workflow/Aevatar.Workflow.Host.Api/CHAT_API_CAPABILITIES.md。
本文档面向框架使用者,说明当前 POST /api/chat 与 GET /api/ws/chat 可以做什么,尤其是:
- 根据
prompt自动判断是否要生成 workflow - 在
human_approval节点等待人工确认 - 支持多轮“反馈 -> 重新生成 -> 再审批”
- 审批通过后自动执行(
auto)或只定稿不执行(auto_review)
| Endpoint | 协议 | 作用 |
|---|---|---|
POST /api/chat |
HTTP + SSE | 发起一次 run,并持续接收运行时 envelope 投影流 |
GET /api/ws/chat |
WebSocket | 与 /api/chat 同能力,使用 WS 封装 |
POST /api/workflows/resume |
HTTP JSON | 恢复 human_input/human_approval 挂起步骤 |
POST /api/workflows/signal |
HTTP JSON | 向等待信号的步骤发送 signal |
说明:/api/chat 与 /api/ws/chat 走同一套执行链路,差别只有传输协议。
口径补充:
- API 输入会先规范化为应用命令模型,再走 CQRS 标准命令骨架:
target resolve -> command context -> envelope -> dispatch port -> accepted receipt。 - Workflow capability 只提供 workflow 特有的目标解析、payload 映射与观察映射;命令生命周期契约属于 CQRS Core,而不是 workflow 私有协议。
- 命令最终会被包装成
EventEnvelope;目标 Actor 的获取/创建由IActorRuntime负责,envelope 投递由IActorDispatchPort完成。 - 这里的
EventEnvelope是 runtime message envelope,不等于 Event Sourcing 的领域事件记录。 - 命令主链路不额外经过 ingress queue/stream;stream 保留给 actor envelope 的投影、实时输出与读侧观察。
command.ack/accepted=true对外只应被解释为“系统接受了该次交互并返回追踪句柄”,不应被解释为领域事件已提交或 ReadModel 已可见。
{
"prompt": "用户输入,必填",
"workflow": "可选:已注册 workflow 名称(内建 + 文件加载)",
"agentId": "可选:复用已有 Workflow Actor",
"workflowYamls": ["可选:inline YAML bundle(数组)"]
}选择优先级:
workflowYamls(inline bundle,首项为入口 workflow)workflow(已注册 workflow 名称 lookup)- 当
workflow/workflowYamls都为空且未提供agentId时,外部 API 边界默认路由到auto - 当只提供
agentId且workflow/workflowYamls为空时,保持 workflow 未指定,复用 actor 已绑定 workflow
契约约束:
workflow只表示“按名称查找已注册 workflow”(内建 + 文件加载)。workflowYamls只表示“inline YAML bundle”,不承担名称查找语义。- 若同时传
workflow与workflowYamls,以workflowYamls为准。 direct/auto/auto_review可显式传入,按注册表解析,不要求存在同名文件。
框架内建了 direct、auto、auto_review 三个 workflow(内部能力)。
- 直接
llm_call输出答案。
典型链路:
classify:判断“直接回答”还是“输出 YAML”- 非 YAML:直接回答用户问题并结束本次 run(不进入 YAML 校验/审批)
- YAML:先经过
workflow_yaml_validate校验 - 校验失败:走
refine_yaml继续修正 - 校验成功:进入
human_approval - 人工拒绝:走
refine_yaml,再次审批(可多轮) - 人工通过:
dynamic_workflow执行定稿 YAML
结论:auto 支持“根据 prompt 自动写 workflow + 强制校验 + 人工审批 + 通过即执行”。
和 auto 相同地支持“自动生成 + 强制校验 + 多轮审批优化”,但审批通过后:
- 不自动执行,只输出最终 YAML(适合手动触发最终 run)。
当 run 到 human_input 或 human_approval,运行时 envelope 投影流会发出 HUMAN_INPUT_REQUEST,包含:
runIdstepIdpromptsuspensionTypemetadata
客户端拿到这些字段后,调用恢复接口:
POST /api/workflows/resume
{
"actorId": "Workflow:xxx",
"runId": "run-xxx",
"stepId": "show_for_approval",
"approved": false,
"userInput": "这里是优化建议",
"commandId": "建议传,便于串联同一轮交互"
}如果某些流程在等待外部信号,再调用:
POST /api/workflows/signal
{
"actorId": "Workflow:xxx",
"runId": "run-xxx",
"signalName": "continue",
"payload": "任意字符串",
"commandId": "建议传"
}实践建议:显式传递 actorId + runId (+ stepId),不要依赖服务端内存映射。
统一输出 WorkflowOutputFrame,核心事件类型包括:
RUN_STARTED/RUN_FINISHED/RUN_ERRORSTEP_STARTED/STEP_FINISHEDTEXT_MESSAGE_START/TEXT_MESSAGE_CONTENT/TEXT_MESSAGE_ENDHUMAN_INPUT_REQUESTTOOL_CALL_START/TOOL_CALL_ENDSTATE_SNAPSHOTCUSTOM
常见 CUSTOM 事件:
aevatar.run.context:回传actorId/workflowName/commandIdaevatar.step.request、aevatar.step.completedaevatar.llm.reasoning:LLM 思考过程增量aevatar.media.chunk:媒体分片,payload 为MediaContentEventaevatar.workflow.waiting_signal
连接 GET /api/ws/chat 后,发送:
{
"type": "chat.command",
"requestId": "client-req-1",
"payload": {
"inputParts": [
{ "type": "text", "text": "帮我分析这段录音和截图" },
{ "type": "audio", "uri": "https://example.com/call.wav", "mediaType": "audio/wav" },
{ "type": "image", "uri": "https://example.com/screenshot.png", "mediaType": "image/png" }
]
}
}服务端回包类型:
command.ack:返回commandId/actorId/workflowagui.event:逐帧业务事件(payload 即WorkflowOutputFrame)command.error:输入或启动阶段错误
command.ack 使用约束:
- 客户端应把
actorId + commandId视为后续观察句柄,其中commandId负责追踪,actorId负责定位。 command.ack是 CQRS dispatch pipeline 生成的 accepted receipt,只表示当前命令已经通过 runtime 成功 dispatch 到目标 actor 语义边界。- 最终结果仍以
agui.event流与/api/actors/*查询为准。
{ "prompt": "解释一下 event sourcing" }{ "prompt": "设计一个内容生产流水线,包含并行校对与质量门禁", "workflow": "auto" }{ "prompt": "设计一个多语言本地化流程,先不要执行", "workflow": "auto_review" }{
"prompt": "执行 inline 流程",
"workflowYamls": [
"name: root\nroles: ...\nsteps: ...",
"name: child_a\nroles: ...\nsteps: ...",
"name: child_b\nroles: ...\nsteps: ..."
]
}参考实现:
src/workflow/Aevatar.Workflow.Infrastructure/CapabilityApi/*src/workflow/Aevatar.Workflow.Application/Runs/*src/workflow/Aevatar.Workflow.Application/Workflows/WorkflowDefinitionCatalog.cs