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, generate, stop } = useCompletion({
api: {
completionEndpoint: {
url: 'your-completion-endpoint',
},
},
});
const handleGenerate = async () => {
await generate({
prompt: '请写一篇关于人工智能的文章',
});
};
return (
<div>
<button onClick={handleGenerate} disabled={status === 'loading'}>
开始生成
</button>
{status === 'loading' && <button onClick={stop}>停止生成</button>}
<div className="content">{content}</div>
</div>
);
}
vue
<template>
<div>
<button @click="handleGenerate" :disabled="status === 'loading'">
开始生成
</button>
<button v-if="status === 'loading'" @click="stop">停止生成</button>
<div class="content">{{ content }}</div>
</div>
</template>
<script setup>
import { useCompletion } from '@tencent/ssv-ai-sdk-vue3';
const { content, status, generate, stop } = useCompletion({
api: {
completionEndpoint: {
url: 'your-completion-endpoint',
},
},
});
const handleGenerate = async () => {
await generate({
prompt: '请写一篇关于人工智能的文章',
});
};
</script>
vue
<template>
<div>
<button @click="handleGenerate" :disabled="completion.status === 'loading'">
开始生成
</button>
<button v-if="completion.status === 'loading'" @click="handleStop">
停止生成
</button>
<div class="content">{{ completion.content }}</div>
</div>
</template>
<script>
import { CompletionMixin } from '@tencent/ssv-ai-sdk-vue2';
export default {
mixins: [
CompletionMixin({
api: {
completionEndpoint: {
url: 'your-completion-endpoint',
},
},
}),
],
methods: {
async handleGenerate() {
await this.ai.generate({
prompt: '请写一篇关于人工智能的文章',
});
},
handleStop() {
this.ai.stop();
},
},
};
</script>
js
// pages/completion/completion.js
import { CompletionBehavior } from '@tencent/ssv-ai-sdk-miniprogram';
Component({
behaviors: [
CompletionBehavior({
api: {
completionEndpoint: {
url: 'your-completion-endpoint',
},
},
}),
],
methods: {
async handleGenerate() {
await this.ai.generate({
prompt: '请写一篇关于人工智能的文章',
});
},
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,流式返回为内容叠加,每次后端返回的 content 都为最新的内容,需要在 SDK 内部进行拼接后输出。chunked,流式返回为完整内容,需要 SDK 内部做覆盖。
js
{
// 忽略其他配置...
streamFormat: 'incremental';
}
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
function Component() {
const { jsonContent } = useCompletion({
json: true,
});
// jsonContent 将包含解析后的 JSON 对象
return <div>{jsonContent && JSON.stringify(jsonContent)}</div>;
}
vue
<template>
<div>{{ jsonContent }}</div>
</template>
<script setup>
const { jsonContent } = useCompletion({
json: true,
});
</script>
vue
<template>
<div>{{ completion.jsonContent }}</div>
</template>
<script>
export default {
mixins: [
CompletionMixin({
json: true,
}),
],
};
</script>
html
<!-- WXML 模板 -->
<view class="json-content">{{completion.jsonContent}}</view>
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,
});
js
const { generate } = useCompletion({});
await generate({
prompt: '写一首关于春天的诗',
});
js
// 在组件方法中
async handleGenerate() {
await this.ai.generate({
prompt: '写一首关于春天的诗',
});
}
js
// 在页面方法中
async handleGenerate() {
await this.ai.generate({
prompt: '写一首关于春天的诗',
});
}
stop() 停止生成
停止当前正在进行的生成任务:
jsx
const { stop } = useCompletion({});
const handleStop = () => {
stop();
};
js
const { stop } = useCompletion({});
const handleStop = () => {
stop();
};
js
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',
});
js
const { setOptions } = useCompletion({});
setOptions({
mode: 'http',
json: true,
});
js
this.ai.setOptions({
streamFormat: 'incremental',
});
js
this.ai.setOptions({
mode: 'stream',
});
事件 Events
on/off 事件监听和卸载
事件监听和卸载函数。
js
const { on, off } = useCompletion({});
// 在 useEffect 中监听
useEffect(() => {
const handleError = (error) => {
console.error('发生错误:', error);
};
on('error', handleError);
return () => {
off('error', handleError);
};
}, []);
js
import { onMounted, onBeforeUnmount } from 'vue';
const { on, off } = useCompletion({});
// 在组件挂载时设置监听
onMounted(() => {
on('content', handleContent);
});
// 在组件卸载前取消监听
onBeforeUnmount(() => {
off('content', handleContent);
});
// 事件处理函数
function handleContent(content) {
console.log('内容更新:', content);
}
js
export default {
// 在组件创建时设置监听
created() {
this.ai.on('content', this.handleContent);
},
// 在组件销毁前取消监听
beforeDestroy() {
this.ai.off('content', this.handleContent);
},
methods: {
handleContent(content) {
console.log('内容更新:', content);
},
},
};
js
Component({
// 其他配置...
attached() {
// 监听内容更新事件
this.ai.on('content', this.handleContent);
},
detached() {
// 取消监听
this.ai.off('content', this.handleContent);
},
methods: {
handleContent(content) {
console.log('内容更新:', content);
},
},
});
message 消息
监听原始消息数据,每次接收到流式消息时触发。
js
const { on } = useCompletion({});
on('message', (data) => {
console.log('收到原始消息:', data);
});
js
const { on } = useCompletion({});
on('message', (data) => {
console.log('收到原始消息:', data);
});
js
this.ai.on('message', (data) => {
console.log('收到原始消息:', data);
});
js
this.ai.on('message', (data) => {
console.log('收到原始消息:', data);
});
content 内容更新
当生成内容更新时触发。
js
const { on } = useCompletion({});
on('content', (content) => {
console.log('内容更新:', content);
});
js
const { on } = useCompletion({});
on('content', (content) => {
console.log('内容更新:', content);
});
js
this.ai.on('content', (content) => {
console.log('内容更新:', content);
});
js
this.ai.on('content', (content) => {
console.log('内容更新:', content);
});
state_change 状态变化
状态变化事件,当任何状态发生变化时触发,包括内容、状态、错误等。
js
const { on } = useCompletion({});
on('state_change', (state) => {
console.log('状态变化:', state);
// state 包含: content, jsonContent, error, status, extraInfo
});
js
const { on } = useCompletion({});
on('state_change', (state) => {
console.log('状态变化:', state);
});
js
this.ai.on('state_change', (state) => {
console.log('状态变化:', state);
});
js
this.ai.on('state_change', (state) => {
console.log('状态变化:', state);
});
@ssv-lab