Skip to main content
新的程序接入请使用官方 XpertAI TypeScript SDK,安装包名为 @xpert-ai/xpert-sdk,可在 TypeScript / JavaScript 项目中使用。SDK 可用于服务端、脚本和后端工作流,不依赖 ChatKit。 如果你的开发环境使用 Python、Java、Go 等其他语言,可以参照 TypeScript SDK 的实现,结合下方的 HTTP 接口参考,编写对应语言的客户端或 SDK。保持鉴权、请求与响应结构、SSE 事件处理和重连逻辑一致即可;具体用法以最新官方文档和 TypeScript SDK 源码为准。
旧 AI/v1 OpenAPI 接入方式(例如 POST /api/ai/v1/chat)已废弃,不再维护,不保证可用。此提示只针对旧接口;下方 SDK 业务案例继续保留,并已改成官方 SDK 写法。

接入前准备

  1. 发布要调用的智能体,取得其 ID(xpertId),即查询智能体返回的 assistant_id 字段。
  2. 创建有权访问该智能体的 API Key,并保存在服务端环境变量中。
  3. 设置 XPERTAI_API_URL,例如 https://api.xpertai.cn/api/ai。私有部署请替换为自己的地址;不追加 /v1。
  4. 使用 Node.js 18 或更新版本,并安装 SDK:
API Key 创建入口: 创建 API Key

使用 SDK 发起对话

下面的示例创建线程并发起一次运行,等待结果返回。请先设置 XPERTAI_API_KEY 和 XPERTAI_XPERT_ID。
保存 thread.thread_id;后续对话复用同一个线程,通过 client.runs.wait() 或 client.runs.stream() 发送新的消息,不需要重新创建线程。 调用智能体时,创建线程应显式传入 assistantId,后续运行使用同一个智能体 ID。SDK 会将 assistantId 转换为 HTTP 请求字段 assistant_id。接口允许省略该字段,此时按当前请求身份创建未绑定智能体的线程;后续运行若使用不同的执行身份,可能在对话权限检查时返回 403。创建时绑定智能体可提前确定其作用域,但不会授予额外权限。

创建线程成功,但运行返回 403

201 Created 只表示线程创建成功,不代表具备后续运行权限。如果运行返回 You do not have access to this conversation:
  1. 确认 API Key 有权访问已发布的目标智能体。用 client.threads.create({ assistantId: xpertId }) 创建新线程,再把同一个 xpertId 传给运行方法。修改示例不会修复此前已创建的线程。
  2. 创建和运行线程时使用相同的凭据及调用者身份,不要复用其他用户或无关智能体的线程。
  3. 如果新建并绑定的线程仍返回 403,请管理员核查 API Key 的实际调用身份、对话所有者(createdById)、智能体绑定(xpertId)和部署版本。传入 assistantId 不会跳过所有权或作用域检查,不能解决所有 403。

实时接收输出

若需要实时进度,可把上例中的 runs.wait() 替换为以下代码,在相同的 main() 中消费事件流:
使用流式调用时,请检查运行结束状态、错误和中断事件,不能仅凭 HTTP 请求成功或连接结束判断任务成功。已有运行的重连使用 client.runs.joinStream(threadId, runId);它只订阅已有运行,不会启动新任务。 如果只需要逐段打印回答文本,可将上面的循环替换为以下代码。其他事件交给应用自己的生命周期处理逻辑;文本筛选本身不能判断运行是否成功。

查询智能体

下面的片段复用首个示例中的 client、xpertId、thread 和 input,可放在同一个 main() 中按需使用。它们对应原来的智能体、线程、运行和存储案例。

查询列表和读取单个智能体

client.assistants.search() 对应 POST /api/ai/assistants/search,返回当前调用者有权访问的已发布智能体数组。选中目标条目后,将它的 assistant_id 填入 XPERTAI_XPERT_ID,也就是示例中的 xpertId 或 XP。如需按智能体标识筛选,可在查询选项中传入 metadata: { slug: "your-xpert-slug" }。

创建和管理线程

指定线程 ID

此例指定创建时的 ID,不是预填充智能体状态。

查询线程列表、详情和当前状态

当前状态取自线程的检查点,可在首轮运行后读取。getHistory() 的支持情况见下方兼容性说明。

在同一线程继续对话

复用已有线程 ID,而不是为每条消息创建新线程。

后台运行与运行管理

创建后台运行

create() 返回运行记录,后台继续执行;wait() 发起一次新的运行并等待其结果。这两个示例是不同的调用方式,不应为同一条消息连续调用两次。

查询状态和运行列表

以下片段复用后台创建返回的 run.run_id。

取消正在运行的任务

需要取消上述运行时再执行:

断线后接续运行

保存创建返回的 thread_id 和 run_id。流式创建时也可从 runs.stream() 的 onRunCreated 回调保存运行 ID。已有运行发生断线后,用 joinStream() 接续订阅:
此调用订阅已有运行,不会重新启动任务。不要用新的 runs.create() 或 runs.wait() 代替重连,以免重复执行。

上传附件后发起对话

使用当前 SDK 的 contexts 子客户端上传文件,再把返回的文件句柄交给智能体:

Store 持久存储

Store 案例继续保留,用于跨运行保存和读取数据。命名空间的首段使用智能体 ID,以下示例在它下面建立一个子命名空间。

写入和读取

列出命名空间和搜索数据

searchItems() 的首个参数是命名空间数组;筛选和查询选项放在第二个参数中。语义搜索的 query 依赖相应的记忆模型配置,上例只列出该命名空间中的数据。

兼容性与暂未支持的调用

SDK 暴露某个方法,不代表目标部署已实现对应服务端能力。按当前平台源码,原示例中的以下调用不能作为可直接运行的案例: 这是具体调用的支持限制,不代表智能体查询、线程管理、运行和 Store 案例被废弃。私有部署请核对所用 SDK 与服务端版本。

常用 SDK 能力

SDK 更新和完整示例以 SDK 仓库 为准。

HTTP 接口参考

直接使用 HTTP 接入时,可在侧栏的 HTTP 接口参考 查看上方案例对应的请求方式、参数、响应、cURL 示例和调试面板。这些是当前 SDK 使用的接口,不依赖 ChatKit。使用服务端 API Key,通过 Authorization: Bearer <API_KEY> 或 x-api-key 鉴权。 先 创建线程,再 发起流式运行 或 创建后台运行。连接断开后,应 订阅已有运行,避免重复启动同一任务。 HTTP 字段名与 SDK 选项名可能不同,例如 assistant_id、thread_id 和 max_depth,请以对应接口页的请求结构为准。本参考覆盖指南中的案例;上方标为暂未支持的方法不作为可用接口展示。

技术支持

SDK 还在不断完善中。如有问题或建议,请添加微信 xpertai 进行技术交流。
以下仅保留旧 AI/v1 REST 接入示例,不再维护,不保证可用。SDK 案例在上方正文中继续提供。

直接使用 REST API 调用智能体

调用接口是 POST /api/ai/v1/chat,不是创建知识库的 /api/ai/v1/kb。 完整参数与响应。
以下请求结构对应当前服务端的 action 协议。私有部署请先确认服务版本支持此结构,并在自己的部署上完成首轮和续聊验收;旧版接口不能仅凭相同路径判断兼容。

调用前准备

  1. 发布要调用的数字专家,记录其 ID(xpertId),不要填写名称或内部 agentKey。
  2. 使用有权访问该专家的 API Key。Key 只保存在服务端环境变量中,不要放进浏览器代码。
  3. 设置 API 服务地址。XPERT_BASE_URL 是域名或部署前缀,不包含 /api/ai,例如 https://api.xpertai.cn;私有部署请替换为自己的地址。
认证头使用 Authorization: Bearer <API_KEY>,也可使用 x-api-key。 历史示例使用服务端 API Key。

首次发送消息

这里的 request.message.input 是输入对象,其中的 input 是用户文本,不是直接把消息字符串传给 request。 首次调用省略 request.conversationId;options.xpertId 指定已发布专家。 如专家要求额外输入变量,应按专家定义填写 request.state 或输入对象,不能只发送文本。 附件须先上传,再传文件句柄;不能直接传浏览器 File 对象。

解析 SSE 并继续对话

返回内容是 text/event-stream。以下是简化的示意帧,实际事件包含更多字段:
  • 保存 on_conversation_start 的 data.id,作为后续请求的 request.conversationId。
  • 文本增量的 type 是 message;data 可以是字符串,也可以是 { "type": "text", "text": "..." }。工具、组件等结构不能直接拼接成文本。
  • 生命周期事件的 type 是 event,事件名在 JSON 的 event 字段里,不能只监听 SSE 的原生 event: 行。
  • 忽略以 : 开始的心跳注释;v1 当前实现也可能把 : keep-alive 放在 SSE 的 data: 中,解析 JSON 前应跳过这种心跳。网络数据块不等于完整 SSE 帧,要处理跨块 UTF-8、多行 data: 和空行分隔。
  • 收到 on_conversation_end 后检查 data.status 和 data.error。错误也可能通过原生 event: error 或 on_error 返回;HTTP 2xx 本身不代表执行成功。
  • on_interrupt 表示需要确认或补充输入,不是正常回答结束。断流前没有结束事件时,也不能当成成功或盲目重发,避免重复执行工具操作。
续聊请求体示例(将占位符替换为首轮返回的会话 ID 和同一个专家 ID):
conversationId 与 LangGraph 的 thread_id 是不同字段,不要互换。 续聊会解析会话绑定的专家;若同时填写 xpertId,它必须与会话专家或其可访问发布版本一致。 项目对话还需要相应权限,request.projectId、options.projectId 与已有会话项目不能冲突。

可运行的 Node.js 示例

下载 agent-chat.mjs,使用 Node.js 22 或更新版本运行:
脚本读取上述三个环境变量,执行两轮请求,保存首轮会话 ID 后继续提问,并逐段打印文本。 它检查 HTTP 状态、SSE Content-Type、流内错误、结束状态和会话 ID;遇到中断或提前断流会以非零退出码结束。 默认每轮超时为 120 秒,可在调用 chat() 时传入 timeoutMs 调整。超时不证明服务器已停止执行。 此示例用于文本对话;需要工具确认或富内容展示的应用应扩展对应事件处理。

重试、中断恢复与运行中追加

这些操作沿用相同端点,通过 request.action 区分;具体字段见接口参考中的各请求类型。恢复时的 target 和 decision.payload 应来自实际中断事件及该工具的要求;不要编造执行 ID 或固定套用确认内容。 clientMessageId 不能视为服务端幂等保证。运行状态不允许该操作时,应处理服务端错误。

常见问题与验收

上线前用目标部署及实际调用身份验证:首轮能回复;第二轮复用同一会话并理解前文;无效 Key 被拒绝;模型/工具失败和断流不会误报成功。 对于带工具的专家,还应测试中断确认和对应工具行为。