前端调用 Ollama 接口:非 stream 与 stream 两种方式详解
谢藏锋
Ollama 是一款用于本地部署和运行大语言模型的工具,支持在本地环境中加载、运行多种开源大模型,无需依赖云端服务,便于开发者进行本地化的 AI 应用开发与测试。Ollama 的文本生成接口分为两类,非 stream 与 stream,适用不同的应用场景。
非 stream 模式
非 stream 模式的调用方式与传统接口类似,发送请求后需等待模型生成完整结果后一次性返回。由于大模型生成文本,尤其是长文本时耗时较长,需为 axios 设置合理的超时时间,避免请求提前中断。
示例代码如下:
import axios from 'axios';
async function callOllamaNonStream(prompt) {
try {
const response = await axios.post('http://localhost:11434/api/generate', {
model: 'qwen3-0.6b',
prompt: prompt,
stream: false
}, {
timeout: 60000, // 超时时间设置为60秒,可根据实际情况调整
});
return response.data.response;
} catch (error) {
console.error('非流式调用出错:', error);
}
}
上述代码中,将 stream 参数设为 false,指定使用非流式返回。timeout 设为 60 秒,可根据模型的响应速度灵活调整。
stream 模式
stream 模式是当前大模型交互的主流方式,能够在模型生成内容的过程中,实时将结果返回至前端并展示,提升用户体验。该模式的配置相对复杂,需对 axios 进行特定设置。
axios 需添加两个关键配置:responseType: 'stream' 和 adapter: 'fetch'。流式响应需以流的方式处理数据,默认的 xhr 适配器在处理流数据时存在局限,可能无法正常工作,关于这个问题详见「#615 Axios 处理 AIGC 流式传输:从报错到解决方案的深度解析」。
具体处理流程如下:
- 使用 getReader () 方法获取响应流的读取器
- 创建 TextDecoder 用于处理二进制流数据
- 循环读取流数据,直至读取完成
- 将二进制数据解码为文本
- 按行分割文本(Ollama 流式接口通常以 JSON 行形式返回数据)
- 解析每行的 JSON 数据,提取 response 字段
示例代码:
import axios from 'axios';
async function callOllamaStream(prompt, onUpdate) {
try {
const response = await axios.post('http://localhost:11434/api/generate', {
model: 'qwen3-0.6b',
prompt: prompt,
stream: true
}, {
responseType: 'stream',
adapter: 'fetch'
});
const decoder = new TextDecoder();
const reader = response.data.getReader();
let fullResponse = '';
while (true) {
const { done, value } = await reader.read();
if (done) break;
// 解码二进制流
const chunk = decoder.decode(value, { stream: true });
// 按行分割并过滤空行
const lines = chunk.split('\n').filter(line => line.trim() !== '');
// 解析每行数据
for (const line of lines) {
try {
const parsed = JSON.parse(line);
if (parsed.response) {
fullResponse += parsed.response;
onUpdate(fullResponse); // 实时更新回调
}
} catch (error) {
console.error('解析JSON出错:', error, '原始数据:', line);
}
}
}
return fullResponse;
} catch (error) {
console.error('流式调用出错:', error);
}
}
调用时,传入 prompt 和更新回调函数即可:
callOllamaStream('请介绍一下前端框架', (currentResponse) => {
// 在此处更新DOM,展示实时生成的内容
document.getElementById('result').innerText = currentResponse;
});
需要注意的是,Ollama 流式返回的每行数据均为完整的 JSON 对象,使用 split ('\n') 分割是可靠的处理方式。解析过程中需添加 try-catch 语句,以应对可能出现的格式问题,避免整个流程中断。
两种模式适用场景不同:非 stream 模式适用于对实时性要求不高,需获取完整结果后再进行处理的场景;stream 模式适用于聊天界面、实时内容生成等需要即时反馈的场景。可根据实际需求选择合适的调用方式。