后端 Agent HTTP/SSE API 参考(完全自定义方案)

面向不用 Flutter SDK、自建 UI 的集成方(Web / React Native / 原生 / 后端代理)。直连 ai-boss 后端的 HTTP + SSE 接口,自己渲染对话与业务卡片。

用 Flutter?直接用《Agent SDK 对接说明》更快(它封装了这里的全部)。


0. 概览

你的 UI ──HTTP/SSE──▶ ai-boss 后端 ──连接器──▶ NearBoss / 业务网关
        (本文档)                    (上游 BFF,见下)
  • 本文档 = 你和 ai-boss 后端 的契约(/api/v1/agent/*)。
  • 上游 BFFdocs/外部 api/2026-06-10-aigent-AI对接说明.md,minipos-aigent)是 ai-boss 后端再往下调的 NearBoss 接口——你直接对接它。两者别混。

支持两个专家:营销专家 promo-designer、数据专家 data-analyst。一个 SSE 入口承载对话 + 流式文本 + 结构化卡片;营销活动的确认 / 生命周期走独立的同步端点。


1. 通用约定

1.1 Base URL

所有路径以 ai-boss 后端根地址为前缀,统一 /api/v1。例:https://api.example.com/api/v1/agent/chat

1.2 认证头(每个请求都带)

必填说明
X-Merchant-Id商家 ID(租户隔离)。缺 → 401。
X-Store-Id门店 ID(scope;部分工具需要)
X-User-Id用户 ID(审计)
X-Roleboss / store_manager / staff / ops / admin(默认 boss
X-Plan套餐(默认 basic
Accept-Languagezh / en / ar(影响返回文案语言)
X-Trace-Id链路追踪 ID;不传则后端自动生成并回显
Content-Typeapplication/json

自定义鉴权(JWT 等)按你的网关约定附加 Authorization,但租户隔离仍需 X-Merchant-Id

1.3 SSE 帧格式

对话端点返回 Content-Type: text/event-stream,每个事件一帧:

event: <事件名>
data: <一行 JSON>

(事件名 + JSON 数据 + 空行分隔。)以 final(或 plan_final)事件标记流结束,随后连接关闭。

1.4 trace_id

每个请求生成唯一 trace_id,回显在响应头 X-Trace-Id、SSE final 事件、后端日志——排障时提供它即可全链路定位。

1.5 统一错误格式(非 SSE 端点)

HTTP <status>
{
  "error_code": "AUTH_INVALID",
  "message": "人类可读说明",
  "kind": "auth|authz|quota|validation|biz|system",
  "trace_id": "…"
}

2. 对话主端点(SSE)

POST /api/v1/agent/chat
Content-Type: application/json
Accept: text/event-stream

2.1 请求体

字段类型必填说明
messagestring用户问题 / 指令
agent_idstring指定专家(promo-designer / data-analyst…)。省略 → 路由器按意图自动分流
conversation_idstring续聊会话 ID;省略则自动新建并在首帧回传
entrystring场景入口 ID(优先级高于 agent_id)
contextobject上下文;营销编辑续聊时带 {"draft": {…前轮活动草稿}} 防覆盖
choose_expertbool「换个专家」:返回候选专家列表让用户选,不自动重路由
exclude_agentsstring[]重路由时避开的专家
plan_run_idstring多步规划续跑 ID
resumeobject审批 / 补答续跑参数

2.2 响应

HTTP 200 + SSE 流。首帧总是 conversation(携 conversation_id),随后按对话进展推送 token / 卡片 / 控制事件,以 final 收尾。


3. SSE 事件类型与 payload

事件何时data 关键字段UI 该做什么
conversation首帧{conversation_id}存下,用于续聊
step阶段 / 工具调用{phase, agent, agent_name, tool?, ok?}可选:展示「正在查询…」
tokenLLM 逐字{text}追加到当前助手气泡
action_card结构化输出见 §3.1渲染业务卡片
final流尾(必发){answer, cost_usd?, trace_id}收尾;流结束
clarify路由低置信 / 缺信息{message, candidates[], kind}渲染候选 chip 让用户选
routed / reroute自动 / 决策转接{agent, reason} / {from_agent, reason}可选:提示「已转接到 X」
approval_required需人工审批{step_id, message, options[]}弹确认;用户选择后带 resume 重发
ask_user需补充信息{step_id, message, input_type?}收集输入后带 resume 重发
plan_created / plan_progress / plan_final多步规划计划 DAG / 进度 / 汇总可选:渲染步骤树
memory / memory_used / memory_write记忆读写已读 / 已用 / 已存的偏好项可选:透明展示「已结合历史偏好」
error出错{error_code, message, trace_id}渲染错误气泡,不击穿

还有一组 react_* 事件属实验中的 ReAct 路径,当前默认不开启,集成时可忽略。

3.1 action_card 结构

{
  "id": "card_1",
  "title": "活动建议",
  "body": "建议做一场招牌秒杀…",
  "category": "marketing",
  "indicators": [ {"key": "net_income", "value": 12345.6} ],
  "chart": {
    "type": "line",
    "title": "近7天净收入趋势",
    "unit": "AED",
    "data": [ {"x": "06-09", "y": 1820.5}, … ]
  },
  "form": { "kind": "nb_campaign", "...": "可编辑草稿字段" },
  "buttons": [ {"id":"confirm","label":"确认发布","action":"...","params":{}} ]
}
  • 数据卡(数据专家):indicators + 可选 chart。数字全部来自接口,零推算(后端不自算)。指标域:净收入 / 成功交易 / 退款。
  • 营销卡(营销专家):form.kind 决定卡型——nb_type_picker(选活动类型)/ nb_campaign(可编辑草稿)/ nb_campaign_list(活动列表)/ nb_campaign_detail(详情 + 生命周期按钮)。buttons / availableActions 驱动操作。

3.2 完整示例流

event: conversation
data: {"conversation_id":"conv_abc"}

event: step
data: {"phase":"start","agent":"promo-designer","agent_name":"营销专家"}

event: token
data: {"text":"根据你的数据,"}

event: action_card
data: {"id":"k1","title":"活动建议","form":{"kind":"nb_campaign"},"buttons":[…]}

event: final
data: {"answer":"根据你的数据,建议做一场招牌秒杀…","cost_usd":0.012,"trace_id":"t_xyz"}

4. 营销确认 / 管理端点(同步,非 SSE)

营销活动遵循 preview→commit 两段式:对话里产出草稿卡(preview),用户确认后调以下端点落地。

4.1 确认发布 / 存草稿

POST /api/v1/agent/nearboss/commit

两种 body:

// A. token 直提(未编辑,卡片按钮已带 preview_token)
{ "surface": "campaign", "preview_token": "…", "action": "PUBLISH", "confirmed": true }

// B. 编辑后提交(改了草稿字段)→ 后端 re-preview→commit
{ "surface": "campaign", "action": "PUBLISH",   // PUBLISH | DRAFT
  "params": { "activityType": "FLASH_SALE", "activityName": "周末秒杀", "...": "…" } }

surface 取值:campaign(活动)/ member_tag(会员标签)/ member_delete(删会员)/ report_export(报表导出)。

成功 200

{ "id": "act_1", "status": "PUBLISHED", "activityName": "周末秒杀" }

业务错误(4xx,error_code + message):参见 §6。

4.2 活动生命周期动作

POST /api/v1/agent/nearboss/campaign/action
{ "op": "PAUSE", "id": "act_1", "confirmed": false }
  • opPAUSE / RESUME / TERMINATETERMINATE 不可逆,首次返回 AIGENT_CONFIRM_REQUIRED,带 confirmed: true 重发。
  • 成功 200:整形后的详情卡(status / statusLabel / availableActions / metrics)——可直接刷新你的详情卡 UI。

哪些动作可用由返回的 availableActions 决定(按状态 DRAFT / PENDING / ACTIVE / PAUSED / ENDED),别在 UI 写死。


5. 历史会话端点

方法路径用途
GET/api/v1/conversations?limit=&offset=会话列表(按最近活跃)
GET/api/v1/conversations/{id}/messages?limit=&before_seq=会话消息(游标翻页,含历史 action_card
POST/api/v1/conversations/{id}/archive归档会话

6. 错误码表

error_codeHTTPkind含义 / 处理
AUTH_INVALID401authX-Merchant-Id
AUTHZ_DENIED403authz角色无权限
QUOTA_EXCEEDED429quota配额用尽(可能降级运行)
VALIDATION400validation入参 / 字段校验失败
TOOL_FAILED502biz下游工具 / API 调用失败
LLM_UNAVAILABLE503systemLLM 不可用(SSE 内以 error 事件透出)
BIZ_UNAVAILABLE503biz业务系统不可用
SYS_INTERNAL500system内部错误
AIGENT_CONFIRM_REQUIRED4xxvalidation危险操作需二次确认(带 confirmed:true 重发)
AIGENT_PREVIEW_EXPIRED / TOKEN_EXPIRED409validation预览失效,重走一次 preview
AIGENT_INVALID_ACTIVITY_TYPE400validation活动类型非法
MKT_*400biz上游活动校验(如「全单折扣须 10–99」),message 可直接转述商家

7. 专家与活动类型常量

agentIdpromo-designer(营销专家)· data-analyst(数据专家)。省略 agent_id 走统一入口自动分流。

4 类营销活动(枚举名与直觉相反,以此为准):

枚举含义关键参数
FLASH_SALE秒杀选品 + 秒杀价
DIRECT_AMOUNT_OFF订单直减directAmount 1–999 + 门槛 minOrderAmount
ORDER_DISCOUNT全单折扣discountValue 10–99(实付 X%,9 折=90)
FIRST_ORDER_DISCOUNT首单优惠discountType + discountValue + 门槛

8. cURL 速查

对话(SSE)

curl -N -X POST https://api.example.com/api/v1/agent/chat \
  -H 'X-Merchant-Id: M123' -H 'X-Store-Id: B1' -H 'X-Role: boss' \
  -H 'Accept-Language: zh' -H 'Content-Type: application/json' \
  -d '{"message":"做个全单9折活动","agent_id":"promo-designer"}'

确认发布

curl -X POST https://api.example.com/api/v1/agent/nearboss/commit \
  -H 'X-Merchant-Id: M123' -H 'Content-Type: application/json' \
  -d '{"surface":"campaign","action":"PUBLISH","params":{"activityType":"ORDER_DISCOUNT","discountValue":90}}'

终止活动(二次确认)

curl -X POST https://api.example.com/api/v1/agent/nearboss/campaign/action \
  -H 'X-Merchant-Id: M123' -H 'Content-Type: application/json' \
  -d '{"op":"TERMINATE","id":"act_1","confirmed":true}'

9. 自建 UI 最小实现提示

浏览器端用 fetch + ReadableStream 读 SSE(EventSource 不支持 POST + 自定义头,故用 fetch 手动解帧):

const resp = await fetch(`${BASE}/api/v1/agent/chat`, {
  method: 'POST',
  headers: { 'X-Merchant-Id': 'M123', 'X-Role': 'boss', 'Content-Type': 'application/json' },
  body: JSON.stringify({ message: '本月净收入多少', agent_id: 'data-analyst' }),
});
const reader = resp.body.getReader();
const dec = new TextDecoder();
let buf = '';
for (;;) {
  const { value, done } = await reader.read();
  if (done) break;
  buf += dec.decode(value, { stream: true });
  const frames = buf.split('\n\n'); buf = frames.pop();      // 留半帧
  for (const f of frames) {
    const ev = f.match(/^event: (.+)$/m)?.[1];
    const data = JSON.parse(f.match(/^data: (.+)$/m)?.[1] || '{}');
    if (ev === 'token') appendText(data.text);
    else if (ev === 'action_card') renderCard(data);
    else if (ev === 'final') finish(data.answer);
  }
}

确认 / 动作端点是普通 POST,按 §4 发 JSON 即可。


文档基于后端真实代码整理(2026-06-15)。SDK 集成见《Agent SDK 对接说明》。问题反馈联系 ai-boss 团队。