跳到主内容

创建对话补全 · Create Chat Completion

向指定角色发送一条消息并以流式(SSE)方式获取 AI 回复。这是与角色对话的核心接口。

接口地址

POST https://api.xiangcao.ai/create-chat-completion

该接口为流式(SSE)长连接,单次超时 300s,已开启 CORS。

鉴权

在请求头中携带你的 API Key:

Authorization: Bearer <YOUR_API_KEY>

缺少或无效的 Token 会返回 401。接口对每个用户有调用频率限制(rate limit)。

请求体(JSON)

所有字段均为可选:传 archiveId 续聊、传 characterId 开新对话,二者至少其一。其余字段不传时,网关会用账号的模型设置(model settings)填充默认值,因此最简调用只需 characterId + message

常用字段

字段类型说明
archiveIdstring对话存档 ID。续聊已有对话时传入;不传则根据 characterId 自动新建或复用存档。
characterIdstring角色 ID。未提供 archiveId 时必填,用于创建新存档。
messagestring用户消息内容。regenerate 模式下可省略。支持 正文\n{指令} 的内嵌指令格式。
regenerateboolean是否重新生成上一条 AI 回复。为 true 时通常无需再传 message
modelstring覆盖账号默认模型。不传则使用账号模型设置中的模型。
maxTokensnumber本次回复的最大输出 token 数。
maxContextnumber上下文窗口最大 token 数。
reasoningEffortenum推理强度,取值见下方类型定义。
contentFormatenum内容格式:roleplay / script / novel
inputGuardenum输入审查模式:rules(默认)/ model / off

archiveIdcharacterId 至少提供一个:传 archiveId 续聊,传 characterId 开新对话。

完整类型定义(TypeScript)

interface CreateChatCompletionRequest {
  /** 对话存档 ID;不传则按 characterId 自动新建/复用 */
  archiveId?: string;
  /** 角色 ID;未提供 archiveId 时必填 */
  characterId?: string;
  /** 用户消息;regenerate 模式下可省略。支持 "content\n{instruction}" 内嵌指令 */
  message?: string;
  /** 重新生成上一条 AI 回复 */
  regenerate?: boolean;

  /** 覆盖账号默认模型 */
  model?: string;
  /** 纯标识符,仅写入消息 metadata.modelDisplayName,不参与上游请求构建 */
  modelDisplayName?: string;

  /** 覆盖存档中的用户名 */
  userName?: string;
  /** 用户角色描述,用于 {{persona}} 宏 */
  userPersona?: string;

  /** 上下文窗口最大 token 数 */
  maxContext?: number;
  /** 本次回复的最大输出 token 数 */
  maxTokens?: number;
  /** 角色卡内容占用的 token 上限,超出按比例截断 */
  maxCharacterTokens?: number;

  /** 推理强度(覆盖存档/prompt 模板设置) */
  reasoningEffort?: ReasoningEffort;
  /** 内容解析模式,写入消息的 content_format 字段 */
  contentFormat?: ContentFormat;
  /** 输入审查模式,默认 "rules" */
  inputGuard?: InputGuardMode;

  /** prompt 模板局部变量,可用 {{getvar::变量名}} 引用 */
  variables?: ChatVariables;
}

type ReasoningEffort = "none" | "minimal" | "low" | "medium" | "high" | "xhigh";

type ContentFormat = "roleplay" | "script" | "novel";

type InputGuardMode = "rules" | "model" | "off";

interface ChatVariables {
  /** 输出语言 */
  language?: "English" | "繁體中文" | "简体中文";
  /** 字数提示,对应模板里的 {{getvar::word_count}} */
  word_count?: string;
  model_name?: string;
}

promptIdcreditsCostenableKnowledgeenableStatusBlockContext 等字段由网关内部根据账号设置填充,调用方无需传入。

响应:SSE 事件流

响应类型为 text/event-stream。每个事件以 data: {json}\n\n 形式推送,通过 JSON 中的 type 字段区分类型:

type含义
archive_created新建(或复用)存档时返回,携带 archiveIdreused
user_message用户消息已保存到存档,携带 message
message_stream生成过程中的中间状态,每次发送当前完整的 contentItems(非增量),前端直接替换即可。
assistant_completeAI 回复生成完成并落库,message 含 tokens、耗时等 metadata。
message_deletedregenerate 模式下,被删除的旧回复消息 ID。
knowledge_updated(可选)开启 Knowledge 时,记忆更新完成。
status_bar_generating(可选)开启状态栏自动生成时,AI 回复完成后开始生成状态栏,前端可进入加载态。
status_bar_updated(可选)状态栏生成完成,携带 messageIdstatusItems;未产出内容时不发送。
chat_complete本次对话流程结束,前端可据此释放加载状态。
aborted请求被中断。
error生成过程中出错,携带 error 与可选 statusCode

注意:message_stream 每次推送的是「当前完整的 contentItems」而非增量,前端直接替换即可。

事件类型定义(TypeScript)

type SSEChunk =
  | ArchiveCreatedChunk
  | UserMessageChunk
  | MessageStreamChunk
  | AssistantCompleteChunk
  | MessageDeletedChunk
  | KnowledgeUpdatedChunk
  | StatusBarGeneratingChunk
  | StatusBarUpdatedChunk
  | ChatCompleteChunk
  | AbortedChunk
  | ErrorChunk;

interface ArchiveCreatedChunk {
  type: "archive_created";
  archiveId: string;
  /** true=复用了该角色最近一次存档(可能有未加载的历史);false/缺省=新建空存档 */
  reused?: boolean;
}

interface UserMessageChunk {
  type: "user_message";
  message: ArchiveMessage; // 已保存的用户消息
}

interface MessageStreamChunk {
  type: "message_stream";
  message: ArchiveMessage; // 生成中的当前完整状态(contentItems 全量,非增量)
}

interface AssistantCompleteChunk {
  type: "assistant_complete";
  message: ArchiveMessage; // 已落库的完整 AI 回复,含 metadata
}

interface MessageDeletedChunk {
  type: "message_deleted";
  messageId: string; // regenerate 模式下被删除的旧回复 ID
}

interface KnowledgeUpdatedChunk {
  type: "knowledge_updated"; // 记忆更新完成(开启 Knowledge 时)
}

interface StatusBarGeneratingChunk {
  type: "status_bar_generating"; // 开始生成状态栏(前端进入加载态)
}

interface StatusBarUpdatedChunk {
  type: "status_bar_updated";
  /** 关联的 AI 回复消息 ID */
  messageId: string;
  /** 状态栏渲染指令(Server-Driven UI),前端直接渲染 */
  statusItems: StatusItem[];
}

interface ChatCompleteChunk {
  type: "chat_complete"; // 本次流程结束
}

interface AbortedChunk {
  type: "aborted"; // 请求被中断
}

interface ErrorChunk {
  type: "error";
  error: string;
  statusCode?: number;
}

/** status_bar_updated.statusItems 的元素类型(Server-Driven UI,前端按 type 渲染) */
type StatusItem =
  | { type: "header"; title: string }
  | { type: "range"; key: string; value: string; percent: number; trend?: "up" | "down" }
  | { type: "counter"; key: string; value: string; current: number; total: number; trend?: "up" | "down" }
  | { type: "tags"; key: string; tags: string[] }
  | { type: "text"; key: string; value: string; trend?: "up" | "down" }
  | { type: "plain"; text: string };

消息对象 ArchiveMessage

user_message / message_stream / assistant_complete 事件里的 message 字段结构如下:

interface ArchiveMessage {
  /** 消息 ID(API 返回时包含) */
  id?: string;
  /** 角色 */
  role: "user" | "assistant" | "system";
  /** 原始文本;目前下发为空字符串(兼容保留),请改用 contentItems */
  content: string;
  /** 内容解析模式 */
  contentFormat?: ContentFormat;
  /** 服务端解析后的渲染指令(Server-Driven UI),消息正文以此为准 */
  contentItems?: ContentItem[];
  /** 角色状态栏内容 */
  statusBlock?: string[];
  /** 状态栏渲染指令 */
  statusItems?: StatusItem[];
  /** 快捷选项 - 点击后作为 user 消息发送 */
  presetOptions?: string[];
  /** Tool calls(仅 assistant 消息) */
  toolCalls?: ToolCallInfo[];
  /** 模型、tokens 等元数据 */
  metadata?: MessageMetadata;
  /** 关联生成的图片 URL */
  imageUrl?: string;
  /** 创建时间(毫秒时间戳) */
  createdAt?: number;
  /** 软删除标记 */
  deleted?: boolean;
  deletedAt?: number;
}

interface MessageMetadata {
  /** 上游实际使用的模型 ID(用于计费) */
  model?: string;
  /** 调用方传入的展示用标识符 */
  modelDisplayName?: string;
  promptTokens?: number;
  completionTokens?: number;
  /** 推理 tokens(部分模型如 DeepSeek-R1、o1 返回) */
  reasoningTokens?: number;
  /** 缓存命中 tokens(Prompt Caching) */
  cachedTokens?: number;
  totalTokens?: number;
  /** 生成耗时(毫秒) */
  latencyMs?: number;
  /** 停止原因:stop / length / tool_calls / content_filter */
  finishReason?: string;
  /** 思维链内容(部分模型返回) */
  reasoningContent?: string;
  /** 本条消息扣除的积分数 */
  creditsCost?: number;
  /** 发送失败标记(余额不足等,消息已存但未被 AI 处理) */
  sendFailed?: boolean;
  [key: string]: unknown;
}

interface ToolCallInfo {
  id: string;
  type: "function" | "custom";
  function?: { name: string; arguments: string };
}

内容格式与解析(contentFormat / contentItems

消息正文统一通过 contentItems 下发:服务端按 contentFormat 把内容解析成渲染指令数组(Server-Driven UI),前端按 type 直接渲染,无需自己解析标记。

⚠️ content 字段目前下发为空字符串(仅作兼容保留),请统一使用 contentItems 渲染,不要依赖 content

contentFormat 决定解析方式:

取值数据格式
roleplay角色扮演:用符号对标记对话 / 独白 / 音效 / 环境,叙事与对话交织,多用于双人互动。
novel小说式:标记方式与 roleplay 一致,定位偏连续叙事 / 散文段落,前端可用不同排版样式。
script剧本式:用 @SCENE / @ROLE 角色名 / @VOICEOVER / @SFX / @INFO 等块标记。

解析结果类型(TypeScript)

/** contentItems 的元素:服务端解析后的渲染指令,前端按 type 渲染 */
type ContentItem =
  | { type: "paragraph"; segments: ContentSegment[] }
  | { type: "scene"; title: string }
  | { type: "intext"; intextType: string; lines: string[] }
  | { type: "character"; name: string; segments: ContentSegment[] }
  | { type: "voiceover"; content: string }
  | { type: "sfx"; content: string }
  | { type: "info"; infoType: string; source?: string; content: string };

/** 段落 / 角色台词内的细分片段(对话、独白、音效、环境等) */
type ContentSegment =
  | { type: "text"; content: string }
  | { type: "dialogue"; content: string; open: string; close: string }
  | { type: "monologue"; content: string; open: string; close: string }
  | { type: "sound"; content: string; open: string; close: string }
  | { type: "environment"; content: string; open: string; close: string };

示例

请求:

curl -N -X POST "https://api.xiangcao.ai/create-chat-completion" \
  -H "Authorization: Bearer <YOUR_API_KEY>" \
  -H "Content-Type: application/json" \
  -d '{
    "characterId": "abc123",
    "message": "你好,今天过得怎么样?"
  }'

响应(节选):

data: {"type":"archive_created","archiveId":"arc_001","reused":false}

data: {"type":"user_message","message":{"id":"msg_u1","role":"user","content":"","contentItems":[{"type":"paragraph","segments":[{"type":"text","content":"你好,今天过得怎么样?"}]}]}}

data: {"type":"message_stream","message":{"role":"assistant","content":"","contentItems":[{"type":"paragraph","segments":[{"type":"text","content":"我"}]}]}}

data: {"type":"message_stream","message":{"role":"assistant","content":"","contentItems":[{"type":"paragraph","segments":[{"type":"text","content":"我很好"}]}]}}

data: {"type":"assistant_complete","message":{"id":"msg_a1","role":"assistant","content":"","contentItems":[{"type":"paragraph","segments":[{"type":"text","content":"我很好,谢谢你的关心~"}]}],"metadata":{"model":"...","completionTokens":42,"latencyMs":1830,"finishReason":"stop"}}}

data: {"type":"status_bar_generating"}

data: {"type":"status_bar_updated","messageId":"msg_a1","statusItems":[{"type":"range","key":"好感度","value":"72/100","percent":72,"trend":"up"}]}

data: {"type":"chat_complete"}

错误处理

若在流开始前出错,会返回相应 HTTP 状态码及 JSON:{ "success": false, "error": "..." }。若已进入流式阶段,错误会以 error 事件下发。

状态码说明
400请求参数无效,例如消息超长或 model 非法。
401未携带有效的 Bearer Token,或账号被封禁。
402积分不足,无法完成本次生成。
403当前模型需要更高的 VIP 等级。
500服务端内部错误。