Completion → Stream 迁移指南
Completion 在 v2.0 中已不推荐使用。单次生成场景请迁移到 Stream 系列 API。
快速对比
| 对比项 | Completion | Stream |
|---|---|---|
| React / Vue3 | useCompletion | useStream |
| Vue2 | CompletionMixin | StreamMixin |
| 小程序 | CompletionBehavior | 当前未导出 StreamBehavior,建议按需使用 AgentBehavior |
| 触发方法 | generate(params) | generate(params) |
| 内容状态 | content | parts |
| 输出结构 | 字符串 | 时序 Part[] |
| 历史消息 | 无 | 无,每次 generate 重置 |
迁移步骤
1. 替换 import
ts
// 之前
import { useCompletion } from '@tencent/ssv-ai-sdk-react';
// 之后
import { useStream } from '@tencent/ssv-ai-sdk-react';
ts
// 之前
import { useCompletion } from '@tencent/ssv-ai-sdk-vue';
// 之后
import { useStream } from '@tencent/ssv-ai-sdk-vue';
ts
// 之前
import { CompletionMixin } from '@tencent/ssv-ai-sdk-vue2';
// 之后
import { StreamMixin } from '@tencent/ssv-ai-sdk-vue2';
2. 替换 endpoint
ts
// 之前
api: {
completionEndpoint: {
url: 'https://your-api.com/completion',
},
}
// 之后
api: {
streamEndpoint: {
url: 'https://your-api.com/stream',
},
}
3. 替换内容渲染
Completion 直接渲染 content,Stream 需要按 parts 顺序渲染:
tsx
// 之前
<div>{content}</div>
// 之后
{parts.map((part, index) => {
if (part.type === 'reasoning') return <div key={index}>{part.reason}</div>;
if (part.type === 'text') return <p key={index}>{part.text}</p>;
if (part.type === 'tool_call') return <ToolCard key={part.id} part={part} />;
return null;
})}
React 完整示例
tsx
import { useState } from 'react';
import { useStream } from '@tencent/ssv-ai-sdk-react';
import { AGUIPlugin } from '@tencent/ssv-ai-sdk-plugin-agui';
export function StreamGenerator() {
const [input, setInput] = useState('');
const { parts, status, generate, stop } = useStream({
api: {
streamEndpoint: {
url: 'https://your-api.com/stream',
},
},
mode: 'stream',
plugins: [new AGUIPlugin()],
});
const handleGenerate = async () => {
if (!input.trim() || status === 'loading') return;
await generate({ input });
setInput('');
};
return (
<div>
<textarea value={input} onChange={(e) => setInput(e.target.value)} />
{status === 'loading' ? <button onClick={stop}>停止</button> : <button onClick={handleGenerate}>生成</button>}
{parts.map((part, index) => {
if (part.type === 'reasoning') return <div key={index}>{part.reason}</div>;
if (part.type === 'text') return <p key={index}>{part.text}</p>;
return null;
})}
</div>
);
}
更多框架示例:
@ssv-lab