实现一个 HTTP 接口,
就拥有一个 完整产品
SlashX 把"前端 / 鉴权 / 后台 / 计费"打包成一个开放协议。你只需按 slashx.request.v1 / slashx.response.v1 接入,即可获得多端聊天前端、多租户后台和积分计费基础设施。
PROTOCOL · 协议详解
slashx.request.v1 / slashx.response.v1
两套契约,覆盖所有 AI 应用场景
SlashX 与你的服务之间通过两个方向的数据契约通信。SlashX 把用户的聊天请求打包成标准 JSON 发给你,你处理完成后按标准 JSON 返回。两个契约覆盖文本、图片、视频、文件、卡片、动作、 思考链、流式输出、异步轮询等所有场景。
请求契约
slashx.request.v1 · SlashX → 你的服务| 字段 | 必填 | 字段说明(小白友好版) |
|---|---|---|
schemaVersion | 必 | 协议版本号。写死 "slashx.request.v1"。它告诉 SlashX 你期望处理哪种格式的请求。未来协议升级时靠它兼容,非常重要——如果不填或填错 SlashX 会直接拒绝。 |
event | 可 | 事件类型。默认值是 user_message(用户发消息)。可以不写。其他取值:action_click=用户点了按钮,conversation_open=用户刚打开对话框(可发欢迎语),cancel=用户点了取消,retract=用户撤回了一条消息,idle=长时间没活动。 |
runId | 必 | 本次请求的唯一身份证。格式是 UUID,比如 550e8400-...。即使同一个用户发了同样的话两次,两次 runId 也不同。你可以用它做幂等去重——同一个 runId 被重放时不重复处理。 |
traceId | 必 | 全链路追踪 ID。一整个会话内的所有请求共享同一个 traceId。你把它打在日志里,出问题时直接从日志系统搜它就能看到完整调用链。格式也是 UUID。 |
conversationId | 必 | 会话 ID。用户打开一个对话窗口后,从第一轮到最后一轮 conversationId 始终不变。你可以根据它恢复上下文、实现多轮记忆。格式也是 UUID。 |
userId | 必 | 当前正在聊天的用户 ID。SlashX 保证它是经过登录鉴权的真实用户。你可以用它做用户画像、个性化回复、历史记录查询。 |
agent | 必 | 当前智能体的完整信息。agent.id=智能体唯一 ID、agent.name=名称。agent.config 是可选的,里面有 systemPrompt(后台配置的系统提示词,你应遵守它)、model(绑定的模型名)、temperature(0~2,0=严谨 2=发散)、tags(标签数组,可用来路由到不同策略)。 |
client | 必 | 用户客户端的信息,帮你做自适应。client.platform=设备类型(h5/ios/android/pc-web/miniprogram/pc-app,必填);client.capabilities=客户端支持的能力(image/video/audio/card/action/stream/markdown),决定了你能返回什么类型的内容,默认空数组;client.viewport=屏幕宽高(px,可选);client.locale=语言偏好,默认 zh-CN;client.timezone=时区(可选)。 |
input | 必 | 用户本次发送的全部内容——这是你处理请求的核心数据。input.text=文本内容(默认空字符串,所以可以不填)。其余全是可选的:input.images=图片数组、input.audio=音频、input.videos=视频、input.attachments=附件(PDF/Word/Excel 等,含 attachmentType)、input.quotes=用户引用了哪条历史消息、input.actionClick=当 event=action_click 时包含被点按钮的信息。 |
history | 可 | 最近 N 轮对话历史(默认空数组)。每项有 role(user/assistant/system/tool)和 content.text。你不需要自己存上下文,SlashX 自动帮你注入。注意历史里不传多媒体文件以保持请求体精简。 |
extensions | 可 | 业务自定义扩展字段(默认空对象)。SlashX 不校验、只管透传。你可以往里放任意 key=value,比如 referral 来源、A/B 实验分组、自定义路由参数。 |
POST /your-endpoint
Content-Type: application/json
X-Slashx-Signature: <HMAC-SHA256>
{
"schemaVersion": "slashx.request.v1",
"event": "user_message",
"runId": "550e8400-e29b-41d4-a716-446655440000",
"traceId": "ab12cd34-ef56-7890-abcd-ef1234567890",
"conversationId": "cv_88f3aa-bb11-4c9d-8e2e-1a2b3c4d5e6f",
"userId": "u_8821",
"agent": {
"id": "ag_writer",
"name": "AI 写作助手",
"config": {
"systemPrompt": "你是一位专业的技术文案…",
"model": "gpt-4o",
"temperature": 0.7,
"tags": ["copywriting", "tech-doc"]
}
},
"client": {
"platform": "pc-web",
"capabilities": ["image","video","audio","stream","markdown","card","action"],
"viewport": { "width": 1440, "height": 900 },
"locale": "zh-CN",
"timezone": "Asia/Shanghai"
},
"input": {
"text": "帮我总结文档要点,生成技术白皮书",
"images": [
{ "url": "https://cdn.example.com/screenshot.png",
"mimeType": "image/png",
"fileName": "产品截图.png" }
],
"audio": [
{ "url": "https://cdn.example.com/meeting.mp3",
"mimeType": "audio/mpeg",
"fileName": "会议纪要.mp3" }
],
"videos": [
{ "url": "https://cdn.example.com/demo.mp4",
"mimeType": "video/mp4",
"fileName": "操作演示.mp4" }
],
"attachments": [
{ "url": "https://cdn.example.com/requirement.docx",
"mimeType": "application/vnd.openxmlformats-officedocument.wordprocessingml.document",
"fileName": "需求文档-v3.docx",
"attachmentType": "document" }
],
"quotes": [
{ "kind": "quote",
"text": "上次你提到产品定位的三点是什么?",
"messageId": "msg_prev_01",
"excerpt": "产品定位:开发者优先…" }
]
},
"history": [
{ "role": "user", "content": { "text": "产品刚上线,需要市场文档" } },
{ "role": "assistant", "content": { "text": "好的,请提供产品功能和用户画像" } },
{ "role": "user", "content": { "text": "AI 辅助编程工具,用户是独立开发者" } }
],
"extensions": {
"custom_key": "custom_value",
"referrer_campaign": "q4_developer_content"
}
}响应契约
slashx.response.v1 · 你的服务 → SlashX| 字段 | 必填 | 字段说明(小白友好版) |
|---|---|---|
schemaVersion | 必 | 协议版本号。写死 "slashx.response.v1"。这是整个响应中唯一一个必须显式填写的外层字段(Zod 里没有默认值)。SlashX 靠它判断你返回的是哪个版本的 JSON。 |
runStatus | 可 | 本次处理的整体状态。默认 success,所以不填也行。5 种取值:pending=排队中、running=执行中(用于异步中间态)、success=成功(最常用)、error=出错(此时应填 error 字段说明原因)、cancelled=用户取消了。 |
messages | 可 | 返回给用户的消息列表——这是你最核心的产出。默认空数组,不填也行。每一条都会在聊天 UI 上渲染为一个独立气泡。5 种角色(role):assistant=正文回复、thinking=思考过程(前端可折叠)、tool=工具调用结果、system=系统级提示、error=错误气泡。一条响应里可以返回多条,比如先 thinking 后 assistant,实现完整链路。 |
messages[].id | 必 | 本条消息的唯一 ID,你必须生成(Zod 要求 min(1) 不能为空)。前端用它当渲染 key、定位增量更新、关联用户反馈。建议格式:msg_xxx。 |
messages[].content | 必 | 本条消息要展示的全部内容,必须填一个对象(至少含 text,其默认空字符串)。content.text=正文,支持 Markdown。其他全是可选的:images/videos/audio=多媒体数组(每项含 url+mimeType+fileName),attachments=文件附件(PDF/ZIP 等含 attachmentType),citations=引用来源(title+url+snippet 摘要),cards=结构化卡片(商品/订单/行程等含 title/imageUrl/fields/actions),actions=可点击按钮(发送消息/打开链接/复制/点赞/自定义)。 |
messages[].delta | 可 | 是否增量更新。默认 false,所以一般不用写。正常一次返回用默认值就行。流式 SSE 输出时设为 true,表示这帧是追加内容而不是替换。最后一条消息设 done=true 表示结束。 |
messages[].status | 可 | 本条消息自己的执行状态,默认 success。5 种取值看右边 runStatus 的说明。注意:即使整体 runStatus=success,某一条消息也可以是 status=error(比如工具调用失败但回复成功了)。 |
usage | 可 | 用量统计(可选但强烈建议返回,用于成本核算和用户展示)。所有子字段都可选:promptTokens=输入 token、completionTokens=输出 token、totalTokens=总计、costUsd=费用(美元)、modelUsed=模型名、latencyMs=耗时(毫秒)。 |
error | 可 | 错误信息,只在 runStatus=error 时使用。error.code=错误码(如 RATE_LIMITED)、error.message=描述文字、error.userVisible=是否展示给用户看(默认 true,建议友好措辞)、error.retryable=是否可以重试(默认 false)。 |
nextPoll | 可 | 异步任务专属。处理耗时较长时(比如 PDF 生成),先返回 runStatus=pending,同时填 nextPoll.afterMs=多少毫秒后客户端再问一次。客户端会自动按这个间隔轮询,直到你返回 success 或 error。 |
conversationUpdate | 可 | 更新会话元信息。可修改 title(聊天窗口标题)和 modeTag(会话标签),让用户在对话列表里一眼识别。所有子字段均可选。 |
HTTP 200
Content-Type: application/json
{
"schemaVersion": "slashx.response.v1",
"runStatus": "success",
"messages": [
// ① 思考过程(前端可折叠)
{
"id": "msg-thinking-001",
"role": "thinking",
"status": "success",
"delta": false,
"done": true,
"content": {
"text": "用户问了平台功能,我要检索资料并组织结构化回答…"
},
"meta": {
"thinkingDurationMs": 2340
}
},
// ② 工具调用
{
"id": "msg-tool-001",
"role": "tool",
"status": "success",
"delta": false,
"done": true,
"content": {
"text": "search_knowledge_base() → 找到 3 篇相关文档"
},
"meta": {
"toolName": "search_knowledge_base"
}
},
// ③ 正文回复(Markdown + 多媒体 + 卡片 + 按钮)
{
"id": "msg-assistant-001",
"role": "assistant",
"status": "success",
"delta": false,
"done": true,
"content": {
"text": "SlashX 是一个面向 AI 应用开发者的商业化基础设施…",
"images": [
{ "url": "https://images.unsplash.com/photo-1677442136019-21780ecad995?w=800",
"mimeType": "image/jpeg",
"fileName": "ai-platform-architecture.jpg" }
],
"videos": [
{ "url": "https://www.w3schools.com/html/mov_bbb.mp4",
"mimeType": "video/mp4",
"fileName": "产品演示.mp4" }
],
"attachments": [
{ "url": "https://www.w3.org/WAI/ER/tests/xhtml/testfiles/resources/pdf/dummy.pdf",
"mimeType": "application/pdf",
"fileName": "技术白皮书-v2.pdf",
"attachmentType": "document" }
],
"citations": [
{ "index": 1,
"title": "SlashX 官方文档",
"url": "https://docs.slashx.ai/providers/quickstart",
"snippet": "SlashX 支持三种服务商…" }
],
"cards": [
{ "type": "product",
"title": "SlashX Pro 订阅",
"subtitle": "适合中小团队",
"imageUrl": "https://images.unsplash.com/photo-1551434678-e076c223a692?w=400",
"fields": [
{ "label": "价格", "value": "¥299/月" },
{ "label": "智能体", "value": "不限" }
],
"actions": [
{ "label": "了解详情", "kind": "open_url",
"value": "https://slashx.ai/pricing" }
] }
],
"actions": [
{ "label": "👍 有帮助", "kind": "feedback", "value": "thumb_up" },
{ "label": "📋 复制摘要", "kind": "copy", "value": "SlashX 是…" },
{ "label": "📖 查看文档", "kind": "open_url", "value": "https://docs.slashx.ai" }
]
}
}
],
"usage": {
"promptTokens": 1024,
"completionTokens": 2048,
"totalTokens": 3072,
"costUsd": 0.0156,
"modelUsed": "openclaw/default",
"latencyMs": 4523
}
}SCENARIOS · 协议场景覆盖
一份协议 = 无限场景。以下是典型示例,展示两个契约如何应对不同需求。
用户发文字 → 服务返回纯文本。你只需读取 input.text,处理后写回 messages[assistant].content.text。返回的 text 支持标准 Markdown 语法(标题、列表、链接、代码块、引用),SlashX 前端自动渲染。
{
"event": "user_message",
"input": { "text": "你好" }
}{
"messages": [{
"id": "m1",
"role": "assistant",
"content": { "text": "你好!有什么可以帮你?" }
}]
}在回复正文之前,你可以先返回 thinking 角色来展示 AI 的思考,再返回 tool 角色来展示工具调用结果(如搜索了哪些数据源、调用了哪个函数)。前端把 thinking 渲染为可折叠的气泡,tool 渲染为带工具名标签的气泡。最后 assistant 总结。三条消息构成一个完整的「思考 → 工具 → 回答」链路。
{
"event": "user_message",
"input": { "text": "帮我查今日股市" }
}{
"messages": [
{ "id": "t1",
"role": "thinking",
"content": { "text": "正在调用行情 API…" },
"meta": { "thinkingDurationMs": 800 } },
{ "id": "t2",
"role": "tool",
"content": { "text": "fetch_stock() → 上证综指 +2.3%" },
"meta": { "toolName": "fetch_stock" } },
{ "id": "m1",
"role": "assistant",
"content": { "text": "今日上证综指上涨 **2.3%**,报收 3,450 点。" } }
]
}用户不止能发文字。input 里可以带 images(图片数组)、audio(音频)、videos(视频)、attachments(附件如 PDF/Word/Excel)。你的服务读取后,可以在返回的 content 中追加 images / videos / attachments 作为配图或生成的文件。每个媒体项必须含 url + mimeType + fileName,前端自动渲染缩略图或播放器。
{
"event": "user_message",
"input": {
"text": "这张图里有什么?",
"images": [{ "url": "https://…/photo.jpg", "mimeType": "image/jpeg" }],
"attachments": [{ "url": "https://…/notes.pdf", "mimeType": "application/pdf", "fileName": "听课笔记.pdf", "attachmentType": "document" }]
}
}{
"messages": [{
"id": "m1",
"role": "assistant",
"content": {
"text": "图中是一只金毛犬趴在草地上。笔记中提到了三个要点…",
"images": [{ "url": "https://…/result.png", "mimeType": "image/png", "fileName": "分析结果.png" }]
}
}]
}当你的 AI 生成长文本时,用户不想等几秒。把 Content-Type 设为 text/event-stream,逐帧推送。每帧 delta=true 表示增量,done=false 表示还有后续。前端自动累积拼接所有帧的 text,并在最后 done=true 时完成。每帧之间用空行(\\n\\n)分隔。
{
"event": "user_message",
"input": { "text": "写一篇 500 字的文章" }
}// Content-Type: text/event-stream
event: message
data: {"messages":[{"id":"m1","role":"assistant","delta":true,
"content":{"text":"今天"},"done":false}]}
event: message
data: {"messages":[{"id":"m1","role":"assistant","delta":true,
"content":{"text":"天气"},"done":false}]}
event: message
data: {"messages":[{"id":"m1","role":"assistant","delta":true,
"content":{"text":""},"done":true}]}有些任务耗时很长(PDF 生成、视频转码)。先返回 runStatus=pending,给 nextPoll.afterMs 告诉客户端过多少毫秒再问。SlashX 前端收到 pending 后自动按间隔轮询,直到你返回 success(带结果)或 error。轮询期间 messages 里放一个 system 角色气泡提示用户。
{
"event": "user_message",
"input": { "text": "生成一份财务月报 PDF" }
}// 首次应答(任务排队中)
{
"runStatus": "pending",
"messages": [
{ "role": "system", "content": { "text": "报告生成中,请稍候…" } }
],
"nextPoll": { "afterMs": 3000 }
}
// 轮询成功(任务完成)
{
"runStatus": "success",
"messages": [
{ "role": "assistant",
"content": {
"text": "财务月报已生成,请查收。",
"attachments": [
{ "url": "https://…/report.pdf",
"mimeType": "application/pdf",
"fileName": "2026Q2-财务月报.pdf" }
]
}
}
]
}纯文字有时不够直观。content 中可附加 cards 数组,每张卡片含 type / title / subtitle / imageUrl / fields(label-value 键值对)/ actions(可点击按钮)。同时 content.actions 可放全局按钮,支持 send_message(点击发送)、open_url(链接)、copy(复制)、feedback(点赞)。卡片适合电商商品展示、订单详情、行程推荐等场景。
{
"event": "user_message",
"input": { "text": "推荐上海三日游" }
}{
"messages": [{
"id": "m1",
"role": "assistant",
"content": {
"text": "为您推荐以下行程方案:",
"cards": [{
"type": "itinerary",
"title": "上海三日游 · 方案 A",
"subtitle": "经典路线,适合首次来沪",
"fields": [
{ "label": "Day 1", "value": "外滩 → 南京路 → 豫园" },
{ "label": "Day 2", "value": "迪士尼乐园全天" },
{ "label": "Day 3", "value": "田子坊 → 新天地 → 回程" },
{ "label": "预算", "value": "¥3,500 / 人" }
],
"actions": [
{ "label": "预订行程", "kind": "open_url",
"value": "https://booking.com/…" },
{ "label": "换个方案", "kind": "send_message",
"value": "推荐另一个上海三日游方案" }
]
}],
"actions": [
{ "label": "📋 复制行程", "kind": "copy",
"value": "Day1 外滩→南京路→豫园…" }
]
}
}]
}RESOURCES · 开发资源
