Agent SDK AI 智能对话组件 金融资讯平台嵌入式聊天 iTick SDK & 开发工具 iTick 官方 Agent SDK,为金融资讯平台提供即插即用的 AI 对话能力,支持 ShadowDOM 样式隔离、虚拟滚动、Markdown 渲染、流式 SSE 输出、React/Vue 3 多框架封装。
Agent SDK 文档
iTick AI Chat SDK — 为金融资讯平台提供即插即用的 AI 对话能力。
核心特性
- ShadowDOM 样式隔离 — 组件样式完全隔离,不受宿主页面 CSS 影响
- 虚拟滚动 — 支持万级消息量的高性能渲染
- Markdown 渲染 — 内置 GFM 格式渲染,支持表格、代码高亮、流式输出
- 多语言 — 内置简体中文、繁体中文、英文
- 主题切换 — 支持亮色/暗色/跟随系统三种模式
- 双模式 — 极速模式(fast)与智能分析模式(think),支持运行时切换
- 流式 SSE — 基于 Server-Sent Events 的实时流式输出,支持取消
- 消息分段 — 支持 think 与 content 交替流式输出,每个 think 模块独立状态
- 框架无关 — 核心纯 TypeScript,同时提供 React / Vue 3 封装
安装
# 核心包(必需)
npm install @itick/chat-core
# React 封装(可选)
npm install @itick/chat-react
# Vue 3 封装(可选)
npm install @itick/chat-vue
也可以通过 <script> 标签直接引入 UMD 包:
<script src="https://unpkg.com/@itick/chat-core/dist/chat-core.umd.js"></script>
<script>
const sdk = new ChatSDK.ChatSDK({ /* ... */ });
</script>
快速接入
原生 JavaScript
import { ChatSDK } from '@itick/chat-core';
const sdk = new ChatSDK({
apiUrl: 'https://agent.itick.org/agent/stream/v1',
token: 'your-api-token',
container: document.getElementById('chat-container'),
width: '100%',
height: '600px',
});
// 监听事件
sdk.on('message:receive', ({ message }) => {
console.log('收到消息:', message.content);
});
sdk.on('error', ({ error }) => {
console.error('请求出错:', error);
});
// 挂载到页面
sdk.mount();
React
import { ChatWidget, type ChatWidgetRef } from '@itick/chat-react';
import { useRef } from 'react';
function App() {
const chatRef = useRef<ChatWidgetRef>(null);
return (
<ChatWidget
ref={chatRef}
apiUrl="https://agent.itick.org/agent/stream/v1"
token="your-api-token"
width="100%"
height="600px"
locale="zh-CN"
onMessageReceive={({ message }) => console.log(message)}
/>
);
}
Vue 3
<template>
<ChatWidget
ref="chatRef"
:apiUrl="apiUrl"
:token="token"
width="100%"
height="600px"
locale="zh-CN"
@messageReceive="onReceive"
/>
</template>
<script setup>
import { ref } from 'vue';
import { ChatWidget } from '@itick/chat-vue';
const chatRef = ref();
const apiUrl = 'https://agent.itick.org/agent/stream/v1';
const token = 'your-api-token';
function onReceive({ message }) {
console.log(message);
}
</script>
核心配置
| 字段 | 类型 | 必填 | 默认值 | 描述 |
|---|---|---|---|---|
apiUrl | string | 是 | - | 流式接口地址 |
token | string | 是 | - | 认证 token,通过 HTTP Header token 字段传递 |
container | HTMLElement | 是 | - | 宿主 DOM 节点 |
width | number | string | 否 | 自适应容器 | 宽度,支持数字(px)或字符串 |
height | number | string | 否 | 自适应容器 | 高度 |
themeColor | string | 否 | "#4F46E5" | 主题色 |
theme | 'light' | 'dark' | 'auto' | 否 | "light" | 主题模式 |
customCSS | string | 否 | - | 注入自定义 CSS |
locale | 'zh-CN' | 'zh-TW' | 'en-US' | 否 | - | 界面语言 |
placeholder | string | 否 | 由 i18n 决定 | 输入框占位文本 |
mode | 'fast' | 'think' | 否 | "think" | 聊天模式 |
actions | ActionsConfig | 否 | 全部显示 | 操作按钮显隐配置 |
disclaimer | string | 否 | 由 i18n 决定 | 免责声明文本 |
welcomeTitle | string | 否 | 由 i18n 决定 | 空状态欢迎标题 |
welcomeDescription | string | 否 | 由 i18n 决定 | 空状态欢迎描述 |
presetQuestions | string[] | 否 | 6 个金融问题 | 空状态预设问题 |
onQuestionClick | (q: string) => void | 否 | - | 预设问题点击回调(SDK 已自动发送消息) |
onError | (error: Error) => void | 否 | - | 错误回调 |
renderHistoryMessage | (msg: ChatMessage) => HTMLElement | string | 否 | - | 历史消息自定义渲染 |
renderActions | (msg: ChatMessage, callbacks: ActionCallbacks) => HTMLElement | undefined | 否 | - | 自定义操作按钮(追加到默认按钮后) |
ActionsConfig
| 字段 | 类型 | 默认值 | 描述 |
|---|---|---|---|
showCopy | boolean | true | 显示复制按钮 |
showRegenerate | boolean | true | 显示重新生成按钮 |
showLike | boolean | true | 显示点赞按钮 |
showShare | boolean | true | 显示分享按钮 |
API 文档
ChatSDK 实例方法
生命周期
| 方法 | 描述 |
|---|---|
mount() | 挂载到容器,创建 ShadowDOM 并渲染 UI。已销毁时抛错 |
unmount() | 移除 ShadowDOM,取消流式请求,保留实例和消息数据 |
destroy() | 彻底销毁实例,清空所有资源和事件监听 |
消息管理
| 方法 | 描述 |
|---|---|
sendMessage(content: string): Promise<void> | 发送消息,自动创建用户和 AI 消息,发起流式请求 |
clearMessages() | 清空所有消息 |
getMessages(): ChatMessage[] | 获取消息列表副本 |
setHistoryMessages(messages: ChatMessage[]) | 设置历史消息列表 |
配置管理
| 方法 | 描述 |
|---|---|
updateConfig(partial: Partial<ChatConfig>) | 动态修改配置,触发 UI 更新 |
getConfig(): Readonly<ChatConfig> | 获取当前配置的只读副本 |
插件管理
| 方法 | 描述 |
|---|---|
registerPlugin(plugin: MessageRenderPlugin) | 注册消息渲染插件 |
unregisterPlugin(name: string) | 注销插件 |
状态属性
| 属性 | 类型 | 描述 |
|---|---|---|
isMounted | boolean | 是否已挂载 |
isDestroyed | boolean | 是否已销毁 |
事件系统
通过 sdk.on(event, handler) 注册事件监听,sdk.off(event, handler) 移除。
生命周期事件
| 事件 | 参数 | 触发时机 |
|---|---|---|
mount | 无 | mount() 完成后 |
unmount | 无 | unmount() 完成后 |
destroy | 无 | destroy() 完成后 |
消息事件
| 事件 | 参数 | 触发时机 |
|---|---|---|
message:send | { content: string } | 用户发送消息时 |
message:receive | { message: ChatMessage } | AI 消息流式完成后 |
message:streaming | { message: ChatMessage; chunk: string } | 每次收到 content chunk |
message:thinking | { message: ChatMessage; chunk: string } | 每次收到 think chunk |
message:done | { message: ChatMessage } | 流式输出完成(含主动取消) |
操作事件
| 事件 | 参数 | 触发时机 |
|---|---|---|
actions:copy | { messageId, content, message } | 点击复制按钮 |
actions:regenerate | { messageId, message } | 点击重新生成按钮 |
actions:like | { messageId, content, message } | 点击点赞按钮 |
actions:share | { messageId, content, message } | 点击分享按钮 |
其他事件
| 事件 | 参数 | 触发时机 |
|---|---|---|
error | { error: Error } | 流式请求出错时 |
config:change | { config: ChatConfig } | updateConfig() 调用后 |
使用示例
sdk.on('message:streaming', ({ chunk }) => {
console.log('收到流式片段:', chunk);
});
sdk.on('message:done', ({ message }) => {
console.log('消息完成:', message.content);
});
sdk.on('actions:copy', ({ content }) => {
console.log('用户复制了:', content);
});
消息结构
interface ChatMessage {
id: string; // 唯一标识
role: 'user' | 'assistant' | 'system';
segments: MessageSegment[]; // think 与 content 按流顺序混合排列
content: string; // 所有 content 段拼接(向后兼容)
timestamp: number; // 时间戳
status?: 'sending' | 'streaming' | 'done' | 'error';
metadata?: Record<string, unknown>;
}
interface MessageSegment {
type: 'think' | 'content';
content: string;
status: 'streaming' | 'done';
}
segments 数组按流式到达顺序存储 think 和 content 块。例如:
[think] → [content] → [think] → [content] → ...
每个 think 模块拥有独立的 streaming/done 状态,完成后自动折叠。
高级功能
主题切换
// 初始化时设置
const sdk = new ChatSDK({ theme: 'auto', /* ... */ });
// 运行时切换
sdk.updateConfig({ theme: 'dark' });
支持三种模式:light(亮色)、dark(暗色)、auto(跟随系统)。
国际化
const sdk = new ChatSDK({ locale: 'zh-CN', /* ... */ });
// 运行时切换
sdk.updateConfig({ locale: 'en-US' });
支持:zh-CN(简体中文)、zh-TW(繁体中文)、en-US(英文)。
自定义 CSS
const sdk = new ChatSDK({
customCSS: `
.chat-message-user .chat-message-bubble {
border-radius: 20px;
}
`,
/* ... */
});
CSS 通过 ShadowDOM 注入,不会影响宿主页面。可通过 CSS 变量覆盖主题色:
--chat-primary: #4F46E5;
--chat-primary-hover: #4338CA;
操作按钮定制
const sdk = new ChatSDK({
// 隐藏部分按钮
actions: {
showLike: false,
showShare: false,
},
// 添加自定义按钮
renderActions: (message, callbacks) => {
const btn = document.createElement('button');
btn.textContent = '收藏';
btn.addEventListener('click', () => {
callbacks.onCopy(message.content);
});
return btn;
},
/* ... */
});
模式切换
用户可在输入框左下角切换极速模式(fast)和智能分析模式(think)。think 模式下会展示 AI 的思考过程。
// 初始化设置
const sdk = new ChatSDK({ mode: 'fast', /* ... */ });
// 运行时切换
sdk.updateConfig({ mode: 'think' });
消息渲染插件
插件可以覆盖默认的 Markdown 渲染行为:
interface MessageRenderPlugin {
name: string;
match: (message: ChatMessage) => boolean;
render: (message: ChatMessage, shadowRoot: ShadowRoot) => HTMLElement;
update?: (element: HTMLElement, message: ChatMessage) => void;
}
sdk.registerPlugin({
name: 'code-highlight',
match: (msg) => msg.content.includes('```'),
render: (msg) => {
const el = document.createElement('div');
el.innerHTML = /* 自定义渲染逻辑 */;
return el;
},
update: (el, msg) => {
el.innerHTML = /* 流式更新逻辑 */;
},
});
// 注销插件
sdk.unregisterPlugin('code-highlight');
注意:注册插件会覆盖内置的 Markdown 渲染。插件按注册顺序从后往前匹配,后注册的优先级更高。
历史消息渲染
const sdk = new ChatSDK({
renderHistoryMessage: (message) => {
// 返回 HTML 字符串或 HTMLElement
return `<div class="custom-message">${message.content}</div>`;
},
/* ... */
});
预设问题
const sdk = new ChatSDK({
presetQuestions: [
'今日美股三大指数行情如何?',
'BTC/USDT 当前价格和24小时涨跌幅?',
],
onQuestionClick: (question) => {
console.log('用户点击了问题:', question);
// SDK 已自动发送消息,此处仅作为通知钩子
},
/* ... */
});
框架集成
React
Props
| 属性 | 类型 | 必填 | 默认值 |
|---|---|---|---|
apiUrl | string | 是 | - |
token | string | 是 | - |
width | number | string | 否 | "100%" |
height | number | string | 否 | "600px" |
themeColor | string | 否 | "#4F46E5" |
customCSS | string | 否 | - |
locale | 'zh-CN' | 'zh-TW' | 'en-US' | 否 | "zh-CN" |
placeholder | string | 否 | - |
renderHistoryMessage | (msg: ChatMessage) => HTMLElement | string | 否 | - |
onMessageSend | (payload: { content: string }) => void | 否 | - |
onMessageReceive | (payload: { message: ChatMessage }) => void | 否 | - |
onMessageStreaming | (payload: { message: ChatMessage; chunk: string }) => void | 否 | - |
onMessageDone | (payload: { message: ChatMessage }) => void | 否 | - |
onError | (payload: { error: Error }) => void | 否 | - |
onConfigChange | (payload: { config: ChatConfig }) => void | 否 | - |
Ref 方法 (ChatWidgetRef)
| 方法 | 签名 |
|---|---|
sendMessage | (content: string) => Promise<void> |
clearMessages | () => void |
getMessages | () => ChatMessage[] |
setHistoryMessages | (messages: ChatMessage[]) => void |
registerPlugin | (plugin: MessageRenderPlugin) => void |
unregisterPlugin | (name: string) => void |
updateConfig | (partial: Partial<ChatConfig>) => void |
getSDK | () => ChatSDK | null |
注意:
apiUrl、token、width、height的 prop 变化不会触发热更新,需要重新挂载组件。themeColor、customCSS、locale、placeholder支持热更新。
Vue 3
Props
与 React 相同(不含回调类 props)。
Events
| 事件 | 参数 |
|---|---|
messageSend | { content: string } |
messageReceive | { message: ChatMessage } |
messageStreaming | { message: ChatMessage; chunk: string } |
messageDone | { message: ChatMessage } |
error | { error: Error } |
configChange | { config: ChatConfig } |
Expose 方法
与 React ChatWidgetRef 完全一致,额外包含 getSDK()。
接口格式
请求格式
SDK 发送 POST 请求到 apiUrl:
Headers:
Content-Type: application/json
token: {your-token}
Accept: text/event-stream
Body:
{
"input": {
"messages": [
{ "type": "human", "content": "用户消息内容" }
]
},
"config": {
"configurable": {
"thread_id": "{uuid}",
"enable_thinking": true
}
}
}
thread_id在实例化时自动生成,用于服务端会话保持enable_thinking根据mode配置决定(think为true,fast为false)- 只发送
role === 'user'的消息
SSE 响应格式
服务端需返回 Content-Type: text/event-stream,每条数据格式:
data: {"type": "think", "content": "思考过程..."}
data: {"type": "content", "content": "回复内容..."}
data: [DONE]
type: "think"— 思考过程,SDK 将其渲染为可折叠的 think 模块type: "content"— 正式回复内容,SDK 渲染为 Markdown 气泡[DONE]— 流结束标记
同时兼容 OpenAI 格式(choices[0].delta.content)。
开发调试
# 安装依赖
npm install
# 构建所有包
npm run build
# 代码检查
npm run lint
常见问题
如何自定义样式?
通过 customCSS 配置注入自定义 CSS,或通过 themeColor 设置主题色。所有样式通过 ShadowDOM 隔离,CSS 变量名以 --chat- 为前缀。
如何处理错误?
通过 onError 配置或 error 事件监听:
const sdk = new ChatSDK({
onError: (error) => { /* 处理错误 */ },
/* ... */
});
sdk.on('error', ({ error }) => {
console.error(error);
});
如何取消流式请求?
用户点击发送按钮(流式输出中会变为停止按钮)即可取消。程序化取消可通过 sdk.unmount() 或 sdk.destroy()。
如何保留会话上下文?
thread_id 在实例化时生成,只要不调用 destroy() 重建实例,同一个实例的多次对话会共享 thread_id,服务端可据此保持会话上下文。
虚拟滚动是否影响消息渲染?
不影响。虚拟滚动仅优化 DOM 节点的创建和回收,消息内容通过 segments 和 content 字段完整保留,操作按钮和推荐问题在消息状态变为 done 时自动追加。