Skip to content

对话接口

对话接口提供与 Snail AI 智能体进行流式对话的能力,采用 SSE(Server-Sent Events)方式实时推送回答内容,支持多轮对话。智能体绑定视觉 CHAT 模型时,也支持随消息携带图片附件进行图片识别。


智能体流式对话

POST /snail-ai/openapi/v1/agent/chat

通过 SSE 流式方式与指定智能体进行对话。支持思考过程展示、多轮上下文、MCP 工具调用、RAG 知识库检索等完整的 Agent 能力。

请求体

字段类型必填说明
agentIdnumber智能体 ID
openIdstring外部用户标识(第三方系统的用户 ID)
contentstring用户消息内容
conversationIdstring对话 ID,由调用方生成;同一话题复用以保持上下文
attachmentsobject[]本次消息携带的附件,目前支持图片
attachments[].typestring附件类型,图片填 IMAGE
attachments[].resourceIdnumber通过 /resource/upload 上传得到的资源 ID
disabledMcpServerIdsnumber[]本次对话禁用的 MCP 服务 ID 列表
disabledSkillIdsnumber[]本次对话禁用的技能 ID 列表

图片附件

图片对话需要先上传资源,再把返回的 id 放入 attachments[].resourceId。资源上传接口为:

text
POST /snail-ai/openapi/v1/resource/upload

上传请求体:

字段类型必填说明
openIdstring外部用户标识
originalNamestring原始文件名
fileSizenumber文件大小,单位字节
contentstring图片二进制内容的 base64 字符串
bizTypestring业务类型,可填 ATTACHMENT
bizIdnumber业务 ID

携带图片附件时,智能体绑定的 CHAT 模型必须在模型配置中开启“支持图片输入”(configJson.capabilities 包含 vision)。每次对话最多 3 张图片,支持 JPG、PNG、WEBP,单张不超过 10MB。

curl 示例

新建对话(生成新的 conversationId):

bash
curl -X POST 'http://localhost:8900/snail-ai/openapi/v1/agent/chat' \
  -H 'Content-Type: application/json' \
  -H 'Snail-Ai-App-Id: <your-app-id>' \
  -H 'Snail-Ai-Token: <your-app-token>' \
  -d '{
    "agentId": 1,
    "openId": "external-user-001",
    "conversationId": "conv-sales-q3",
    "content": "帮我分析一下上季度的销售数据"
  }' \
  --no-buffer

多轮对话(复用同一 conversationId):

bash
curl -X POST 'http://localhost:8900/snail-ai/openapi/v1/agent/chat' \
  -H 'Content-Type: application/json' \
  -H 'Snail-Ai-App-Id: <your-app-id>' \
  -H 'Snail-Ai-Token: <your-app-token>' \
  -d '{
    "agentId": 1,
    "openId": "external-user-001",
    "conversationId": "conv-sales-q3",
    "content": "能再详细说明一下华东区域的数据吗?"
  }' \
  --no-buffer

禁用特定 MCP/技能:

bash
curl -X POST 'http://localhost:8900/snail-ai/openapi/v1/agent/chat' \
  -H 'Content-Type: application/json' \
  -H 'Snail-Ai-App-Id: <your-app-id>' \
  -H 'Snail-Ai-Token: <your-app-token>' \
  -d '{
    "agentId": 1,
    "openId": "external-user-001",
    "conversationId": "conv-weather-001",
    "content": "查询今天的天气",
    "disabledMcpServerIds": [3],
    "disabledSkillIds": [2]
  }' \
  --no-buffer

图片对话:

bash
curl -X POST 'http://localhost:8900/snail-ai/openapi/v1/resource/upload' \
  -H 'Content-Type: application/json' \
  -H 'Snail-Ai-App-Id: <your-app-id>' \
  -H 'Snail-Ai-Token: <your-app-token>' \
  -d '{
    "openId": "external-user-001",
    "originalName": "receipt.png",
    "fileSize": 204800,
    "content": "<base64-image-content>",
    "bizType": "ATTACHMENT"
  }'

curl -X POST 'http://localhost:8900/snail-ai/openapi/v1/agent/chat' \
  -H 'Content-Type: application/json' \
  -H 'Snail-Ai-App-Id: <your-app-id>' \
  -H 'Snail-Ai-Token: <your-app-token>' \
  -d '{
    "agentId": 1,
    "openId": "external-user-001",
    "conversationId": "conv-image-001",
    "content": "这张图片里说了什么?",
    "attachments": [
      {"type": "IMAGE", "resourceId": 88}
    ]
  }' \
  --no-buffer

响应格式

响应为 NDJSON(Newline Delimited JSON)流,每行是一个独立的 JSON 对象,通过 type 字段区分事件类型。

流式输出示例:

json
{"type":"thinking","content":"用户需要分析销售数据,我需要先检索相关的知识库文档..."}
{"type":"thinking","content":"已找到上季度销售报告,开始生成分析结果..."}
{"type":"text","content":"根据"}
{"type":"text","content":"上季度的销售数据"}
{"type":"text","content":"分析如下:"}
{"type":"text","content":"\n\n## 整体概览\n\n"}
{"type":"text","content":"- 总销售额:1,250 万元,同比增长 15.3%\n"}
{"type":"text","content":"- 订单量:8,560 笔,环比增长 8.2%\n"}
{"type":"text","content":"- 客单价:1,460 元,基本持平\n\n"}
{"type":"text","content":"## 区域分布\n\n华东区域贡献了 42% 的销售额..."}

事件类型

type说明
thinking智能体的思考/推理过程,可选择性展示给用户
text正式回答内容,客户端需将多个 text 事件拼接后显示

客户端处理示例

JavaScript(浏览器/Node.js):

javascript
async function chatWithAgent(agentId, openId, content, conversationId) {
  const response = await fetch('http://localhost:8900/snail-ai/openapi/v1/agent/chat', {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json',
      'Snail-Ai-App-Id': 'your-app-id',
      'Snail-Ai-Token': 'your-app-token'
    },
    body: JSON.stringify({ agentId, openId, content, conversationId })
  });

  const reader = response.body.getReader();
  const decoder = new TextDecoder();
  let buffer = '';
  let fullText = '';

  while (true) {
    const { done, value } = await reader.read();
    if (done) break;

    buffer += decoder.decode(value, { stream: true });
    const lines = buffer.split('\n');
    buffer = lines.pop() || '';

    for (const line of lines) {
      if (!line.trim()) continue;
      try {
        const event = JSON.parse(line);
        if (event.type === 'text') {
          fullText += event.content;
          // 实时更新 UI 显示
          updateUI(fullText);
        } else if (event.type === 'thinking') {
          // 可选:展示思考过程
          showThinking(event.content);
        }
      } catch (e) {
        // 非 JSON 行,直接作为文本处理
        fullText += line;
      }
    }
  }

  return fullText;
}

Python:

python
import requests
import json

def chat_with_agent(agent_id, open_id, conversation_id, content):
    url = "http://localhost:8900/snail-ai/openapi/v1/agent/chat"
    headers = {
        "Content-Type": "application/json",
        "Snail-Ai-App-Id": "your-app-id",
        "Snail-Ai-Token": "your-app-token"
    }
    payload = {
        "agentId": agent_id,
        "openId": open_id,
        "conversationId": conversation_id,
        "content": content
    }

    response = requests.post(url, json=payload, headers=headers, stream=True)
    full_text = ""

    for line in response.iter_lines(decode_unicode=True):
        if not line or not line.strip():
            continue
        try:
            event = json.loads(line)
            if event["type"] == "text":
                full_text += event["content"]
                print(event["content"], end="", flush=True)
            elif event["type"] == "thinking":
                # 可选处理思考过程
                pass
        except json.JSONDecodeError:
            full_text += line

    print()  # 换行
    return full_text

openId 说明

openId 是外部系统中的用户标识,用于区分不同的外部用户。Snail AI 会根据 openId 维护独立的对话上下文和记忆。

场景openId 示例
飞书集成飞书用户 ID
钉钉集成钉钉用户 ID
企业微信企业微信用户 ID
自定义前端自定义用户标识
匿名用户会话级 UUID

conversationId 说明

  • 首次对话:由调用方生成新的 conversationId,例如按业务会话 ID、UUID 或雪花 ID 生成
  • 多轮对话:复用已有的 conversationId,智能体会基于历史上下文继续对话
  • 新话题:生成新的 conversationId,避免不同话题共享上下文

错误处理

智能体不存在:

json
{
  "code": 0,
  "msg": "智能体不存在或已被禁用",
  "data": null
}

参数缺失:

json
{
  "code": 0,
  "msg": "agentId、openId、conversationId 和 content 为必填参数",
  "data": null
}

流式过程中出错:

如果在流式输出过程中发生错误,连接会被中断。客户端应实现断线检测和重试机制。

Apache 2.0 Licensed