Completion 单次会话输出
Completion 主要用于 AI 单次内容生成的实现,帮助业务快速搭建自己的 AI 内容生成功能。支持 React、Vue2、Vue3 和微信小程序等多个技术栈。
设计理念
Completion SDK 基于 Headless UI 概念设计,专注于提供数据状态管理和业务逻辑处理,不包含任何预置的 UI 组件。
优点:
- 🎨 高度可定制化:完全自由地设计和实现 UI 界面
- 🔧 灵活性强:适配各种设计系统和 UI 框架
- 📦 轻量级:不包含 UI 代码,包体积更小
- 🔄 技术栈无关:可与任何 UI 库或组件库结合使用
- ⚡ 单次生成:专注于单次 AI 内容生成,无历史消息管理
注意事项:
- ⚠️ 需要自行实现 UI:开发者需要根据业务需求自行设计和实现生成界面
- 🛠️ 需要处理样式:输入框、按钮、内容展示等 UI 元素需要自行开发
- 📱 适配工作:不同平台的 UI 适配需要开发者自行处理
与 Chat 的区别:
- Chat:支持多轮对话,维护消息历史记录
- Completion:单次内容生成,无消息历史,专注于文本生成任务
架构图
下图展示了 Completion SDK 的三层架构关系:
架构说明
- UI 组件层:各种 UI 组件库和自定义组件,负责内容生成界面展示
- Completion SDK 层:🎯 核心抽象层,提供 Headless UI 的状态管理和业务逻辑,支持多端适配
- AI 模型层:各种大语言模型,提供 AI 内容生成能力
Completion SDK 的核心价值:
- 📦 解耦 UI 与逻辑:UI 层可以自由选择,SDK 专注于状态管理
- 🔄 统一多端接口:一套 API 适配多个技术栈和 AI 模型
- 🛠️ 简化开发复杂度:封装网络通信、状态管理等底层细节
- ⚡ 专注内容生成:优化单次生成场景,提供精确的状态控制
使用方法
jsx
import { useCompletion } from '@tencent/ssv-ai-sdk-react';
function CompletionComponent() {
const { content, status, error, extraInfo, generate, stop, setOptions } =
useCompletion({
api: {
completionEndpoint: {
url: 'https://api.example.com/completion',
requestInterceptor: (options) => ({
...options,
headers: {
...options.headers,
Authorization: 'Bearer your-token',
},
}),
},
},
mode: 'stream',
streamFormat: 'incremental',
});
const handleGenerate = async () => {
await generate({
prompt: '请写一篇关于人工智能的文章',
max_tokens: 1000,
});
};
return (
<div>
<button onClick={handleGenerate} disabled={status === 'loading'}>
{status === 'loading' ? '生成中...' : '开始生成'}
</button>
{status === 'loading' && <button onClick={stop}>停止生成</button>}
<div className="content-area">{content && <pre>{content}</pre>}</div>
{error && <div className="error">{error.message}</div>}
</div>
);
}
vue
<template>
<div>
<button @click="handleGenerate" :disabled="status === 'loading'">
{{ status === 'loading' ? '生成中...' : '开始生成' }}
</button>
<button v-if="status === 'loading'" @click="stop">停止生成</button>
<div class="content-area">
<pre v-if="content">{{ content }}</pre>
</div>
<div v-if="error" class="error">
{{ error.message }}
</div>
</div>
</template>
<script setup>
import { useCompletion } from '@tencent/ssv-ai-sdk-vue3';
const { content, status, error, extraInfo, generate, stop, setOptions } =
useCompletion({
api: {
completionEndpoint: {
url: 'https://api.example.com/completion',
requestInterceptor: (options) => ({
...options,
headers: {
...options.headers,
Authorization: 'Bearer your-token',
},
}),
},
},
mode: 'stream',
streamFormat: 'incremental',
});
const handleGenerate = async () => {
await generate({
prompt: '请写一篇关于人工智能的文章',
max_tokens: 1000,
});
};
</script>
vue
<template>
<div>
<button @click="handleGenerate" :disabled="completion.status === 'loading'">
{{ completion.status === 'loading' ? '生成中...' : '开始生成' }}
</button>
<button v-if="completion.status === 'loading'" @click="handleStop">
停止生成
</button>
<div class="content-area">
<pre v-if="completion.content">{{ completion.content }}</pre>
</div>
<div v-if="completion.error" class="error">
{{ completion.error.message }}
</div>
</div>
</template>
<script>
import { CompletionMixin } from '@tencent/ssv-ai-sdk-vue2';
export default {
mixins: [
CompletionMixin({
api: {
completionEndpoint: {
url: 'https://api.example.com/completion',
requestInterceptor: (options) => ({
...options,
headers: {
...options.headers,
Authorization: 'Bearer your-token',
},
}),
},
},
mode: 'stream',
streamFormat: 'incremental',
}),
],
methods: {
async handleGenerate() {
await this.ai.generate({
prompt: '请写一篇关于人工智能的文章',
max_tokens: 1000,
});
},
handleStop() {
this.ai.stop();
},
},
};
</script>
js
// pages/completion/completion.js
import { CompletionBehavior } from '@tencent/ssv-ai-sdk-miniprogram';
Component({
behaviors: [
CompletionBehavior({
api: {
completionEndpoint: {
url: 'https://api.example.com/completion',
requestInterceptor: (options) => ({
...options,
headers: {
...options.headers,
Authorization: 'Bearer your-token',
},
}),
},
},
mode: 'stream',
streamFormat: 'incremental',
}),
],
data: {
prompt: '',
},
methods: {
handleInput(e) {
this.setData({ prompt: e.detail.value });
},
async handleGenerate() {
await this.ai.generate({
prompt: this.data.prompt,
max_tokens: 1000,
});
},
handleStop() {
this.ai.stop();
},
},
});
配置 Config
api.completionEndpoint
定义 AI 内容生成接口,配置 url
、requestInterceptor
和 responseInterceptor
。
js
{
api: {
completionEndpoint: {
url: 'https://api.example.com/completion',
requestInterceptor: (options) => {
// 添加认证信息
return {
...options,
headers: {
...options.headers,
'Authorization': 'Bearer your-token',
'X-API-Version': 'v1'
}
};
},
responseInterceptor: (data) => {
// 处理响应数据格式转换
return {
content: data.text || data.content,
extraInfo: {
usage: data.usage,
model: data.model
}
};
}
}
}
}
api.completionEndpoint.requestInterceptor
请求拦截器,用于对发送给 AI 接口的请求进行拦截和修改。主要用于添加自定义请求头、身份验证信息或其他请求参数。
typescript
interface RequestInterceptor {
(options: RequestOptions): RequestOptions;
}
interface RequestOptions {
headers?: Record<string, any>;
data?: any;
[key: string]: any;
}
常见使用场景:
- 添加身份验证令牌
- 设置自定义请求头
- 添加 API 版本信息
- 修改请求参数格式
api.completionEndpoint.responseInterceptor
响应拦截器,用于处理 AI 接口返回的数据格式转换。
typescript
interface ResponseInterceptor {
(data: any): {
content?: string;
extraInfo?: Record<string, any>;
error?: any;
};
}
mode 模式
接口模式,可选 http
和 stream
。
stream
:流式数据,实时获取生成内容(推荐)http
:一次性返回完整内容
js
{
mode: 'stream'; // 或 'http'
}
streamFormat 流式格式
流式格式输出,可选 incremental
和 chunked
。影响内容 content
的输出方式。
incremental
:增量返回,每次返回的内容会累加到之前的内容chunked
:分块返回,每次返回完整的当前内容
js
{
streamFormat: 'incremental'; // 或 'chunked'
}
json JSON 模式
是否启用 JSON 模式输出,当设置为 true
时,会尝试解析返回的内容为 JSON 格式。
js
{
json: true; // 启用 JSON 模式
}
数据 State
content 生成内容
AI 生成的文本内容,实时更新:
jsx
function Component() {
const { content } = useCompletion({
// 配置...
});
return <div>{content}</div>;
}
vue
<template>
<div>{{ content }}</div>
</template>
<script setup>
const { content } = useCompletion({
// 配置...
});
</script>
vue
<template>
<div>{{ completion.content }}</div>
</template>
<script>
export default {
mixins: [
CompletionMixin({
// 配置...
}),
],
};
</script>
html
<!-- WXML 模板 -->
<view class="content">{{completion.content}}</view>
jsonContent JSON 内容
当启用 JSON 模式时,解析后的 JSON 对象:
jsx
const { jsonContent } = useCompletion({
json: true,
});
// jsonContent 将包含解析后的 JSON 对象
console.log(jsonContent);
extraInfo 额外信息
存储 AI 接口返回的额外信息,如使用统计、模型信息等:
typescript
interface ExtraInfo {
usage?: {
prompt_tokens: number;
completion_tokens: number;
total_tokens: number;
};
model?: string;
[key: string]: any;
}
jsx
function Component() {
const { extraInfo } = useCompletion({
// 配置...
});
return (
<div>
<p>使用的模型: {extraInfo.model}</p>
<p>Token 使用量: {extraInfo.usage?.total_tokens}</p>
</div>
);
}
vue
<template>
<div>
<p>使用的模型: {{ extraInfo.model }}</p>
<p>Token 使用量: {{ extraInfo.usage?.total_tokens }}</p>
</div>
</template>
vue
<template>
<div>
<p>使用的模型: {{ completion.extraInfo.model }}</p>
<p>
Token 使用量:
{{
completion.extraInfo.usage && completion.extraInfo.usage.total_tokens
}}
</p>
</div>
</template>
html
<!-- WXML 模板 -->
<view>
<text>使用的模型: {{completion.extraInfo.model}}</text>
<text>Token 使用量: {{completion.extraInfo.usage.total_tokens}}</text>
</view>
status 生成状态
表示当前生成任务的状态:
idle
:空闲状态,未开始生成loading
:生成中success
:生成成功完成failed
:生成失败stopped
:生成被停止
jsx
function Component() {
const { status, generate, stop } = useCompletion({});
return (
<div>
<button
onClick={() => generate({ prompt: 'Hello' })}
disabled={status === 'loading'}
>
{status === 'loading' ? '生成中...' : '开始生成'}
</button>
{status === 'loading' && <button onClick={stop}>停止</button>}
</div>
);
}
vue
<template>
<div>
<button
@click="generate({ prompt: 'Hello' })"
:disabled="status === 'loading'"
>
{{ status === 'loading' ? '生成中...' : '开始生成' }}
</button>
<button v-if="status === 'loading'" @click="stop">停止</button>
</div>
</template>
vue
<template>
<div>
<button @click="handleGenerate" :disabled="completion.status === 'loading'">
{{ completion.status === 'loading' ? '生成中...' : '开始生成' }}
</button>
<button v-if="completion.status === 'loading'" @click="handleStop">
停止
</button>
</div>
</template>
<script>
export default {
methods: {
async handleGenerate() {
await this.ai.generate({ prompt: 'Hello' });
},
handleStop() {
this.ai.stop();
},
},
};
</script>
html
<!-- WXML 模板 -->
<view>
<button
bindtap="handleGenerate"
disabled="{{completion.status === 'loading'}}"
>
{{completion.status === 'loading' ? '生成中...' : '开始生成'}}
</button>
<button wx:if="{{completion.status === 'loading'}}" bindtap="handleStop">
停止
</button>
</view>
<!-- JavaScript -->
<script>
Page({
async handleGenerate() {
await this.ai.generate({ prompt: 'Hello' });
},
handleStop() {
this.ai.stop();
},
});
</script>
error 错误信息
当生成过程中发生错误时,包含错误详情:
typescript
interface AIError {
message: string;
code?: string;
cause?: any;
}
jsx
function Component() {
const { error } = useCompletion({});
if (error) {
return <div className="error">错误: {error.message}</div>;
}
return null;
}
vue
<template>
<div v-if="error" class="error">错误: {{ error.message }}</div>
</template>
vue
<template>
<div v-if="completion.error" class="error">
错误: {{ completion.error.message }}
</div>
</template>
html
<!-- WXML 模板 -->
<view wx:if="{{completion.error}}" class="error">
错误: {{completion.error.message}}
</view>
方法 Methods
generate() 开始生成
启动 AI 内容生成:
typescript
interface CompletionParams {
prompt?: string;
max_tokens?: number;
temperature?: number;
[key: string]: any;
}
async function generate(params: CompletionParams): Promise<void>;
使用示例:
jsx
const { generate } = useCompletion({});
await generate({
prompt: '写一首关于春天的诗',
max_tokens: 500,
temperature: 0.7,
});
vue
const { generate } = useCompletion({}); await generate({ prompt:
'写一首关于春天的诗', max_tokens: 500, temperature: 0.7 });
vue
// 在组件方法中 async handleGenerate() { await this.ai.generate({ prompt:
'写一首关于春天的诗', max_tokens: 500, temperature: 0.7 }); }
js
// 在页面方法中
async handleGenerate() {
await this.ai.generate({
prompt: '写一首关于春天的诗',
max_tokens: 500,
temperature: 0.7
});
}
stop() 停止生成
停止当前正在进行的生成任务:
jsx
const { stop } = useCompletion({});
const handleStop = () => {
stop();
};
vue
const { stop } = useCompletion({}); const handleStop = () => { stop(); };
vue
handleStop() { this.ai.stop(); }
js
handleStop() {
this.ai.stop();
}
setOptions() 更新配置
动态更新 SDK 配置:
typescript
function setOptions(options: Partial<CompletionOptions>): void;
使用示例:
jsx
const { setOptions } = useCompletion({});
// 更新 API 端点
setOptions({
api: {
completionEndpoint: {
url: 'https://new-api.example.com/completion',
},
},
});
// 更新流式格式
setOptions({
streamFormat: 'chunked',
});
vue
const { setOptions } = useCompletion({}); setOptions({ mode: 'http', json: true
});
vue
this.ai.setOptions({ streamFormat: 'incremental' });
js
this.ai.setOptions({
mode: 'stream',
});
事件 Events
on() 监听事件
监听 SDK 内部事件:
typescript
function on(event: string, callback: (...args: any[]) => void): void;
可用事件
'content' 内容更新事件
当生成内容更新时触发:
js
ai.on('content', (content) => {
console.log('内容更新:', content);
});
'message' 原始消息事件
接收 AI 接口返回的原始数据:
js
ai.on('message', (rawData) => {
console.log('原始数据:', rawData);
});
'state_change' 状态变化事件
当 SDK 状态发生变化时触发:
js
ai.on('state_change', (state) => {
console.log('状态变化:', state);
});
使用示例:
jsx
const { ai } = useCompletion({});
useEffect(() => {
const handleContent = (content) => {
console.log('内容更新:', content);
};
ai.on('content', handleContent);
return () => {
ai.off('content', handleContent);
};
}, [ai]);
vue
const { ai } = useCompletion({}); onMounted(() => { const handleContent =
(content) => { console.log('内容更新:', content); }; ai.on('content',
handleContent); onUnmounted(() => { ai.off('content', handleContent); }); });
vue
mounted() { this.ai.on('content', this.handleContent); }, beforeDestroy() {
this.ai.off('content', this.handleContent); }, methods: { handleContent(content)
{ console.log('内容更新:', content); } }
js
onLoad() {
this.ai.on('content', this.handleContent);
},
onUnload() {
this.ai.off('content', this.handleContent);
},
handleContent(content) {
console.log('内容更新:', content);
}
最佳实践
1. 错误处理
jsx
const { generate, error, status } = useCompletion({});
const handleGenerate = async () => {
try {
await generate({ prompt: 'Hello' });
} catch (err) {
console.error('生成失败:', err);
// 处理错误
}
};
// 在 UI 中显示错误
if (error) {
return <div className="error">生成失败: {error.message}</div>;
}
2. 流式内容展示
jsx
const { content, status } = useCompletion({
mode: 'stream',
streamFormat: 'incremental',
});
return (
<div>
<pre className="content-area">{content}</pre>
{status === 'loading' && (
<div className="loading-indicator">正在生成...</div>
)}
</div>
);
3. JSON 模式使用
jsx
const { jsonContent, generate } = useCompletion({
json: true,
});
const handleGenerate = async () => {
await generate({
prompt: '请返回一个包含姓名和年龄的JSON对象',
});
};
// jsonContent 将包含解析后的对象
console.log(jsonContent); // { name: "张三", age: 25 }
4. 自定义请求处理
js
const completion = useCompletion({
api: {
completionEndpoint: {
url: '/api/completion',
requestInterceptor: (options) => ({
...options,
headers: {
...options.headers,
Authorization: `Bearer ${getToken()}`,
'X-User-ID': getCurrentUserId(),
},
}),
responseInterceptor: (data) => ({
content: data.result?.text || '',
extraInfo: {
usage: data.usage,
model: data.model_name,
},
}),
},
},
});