Ollama API调用messages参数返回空,CURL正常求排查方案
Ollama API使用messages参数请求无响应问题排查
问题描述
我搭建了一个简单Web界面用于和Ollama API交互,在聊天窗口输出响应。使用prompt参数请求时(格式如下)能正常获取响应流:
{ "model": "llama3", "prompt": "Hello world" }
但使用messages参数格式请求时,返回内容为空,不过用CURL调用该接口却能正常工作。messages请求格式如下:
{ "model": "llama3", "messages": [ { "role": "user", "content": "why is the sky blue?" }, { "role": "assistant", "content": "due to rayleigh scattering." }, { "role": "user", "content": "how is that different than mie scattering?" } ] }
我的请求代码如下:
let url = "http://localhost:11434/api/generate"; const data = { "model": "llama3", "messages": [ { "role": "user", "content": "why is the sky blue?" }, { "role": "assistant", "content": "due to rayleigh scattering." }, { "role": "user", "content": "how is that different than mie scattering?" } ] }; console.log(data); const requestOptions = { method: "POST", headers: { 'Content-Type': 'application/json', }, body: JSON.stringify(data), }; fetch(url, requestOptions) .then(res => res.body) .then(rb => { const reader = rb.getReader(); return new ReadableStream({ start(controller) { function push() { reader.read().then(async ({done, value}) => { if (done) { chatbox.innerHTML += "</p>"; console.log("done", done); controller.close(); return; } await controller.enqueue(value); let json = JSON.parse(new TextDecoder().decode(value)); chatbox.innerHTML += json.response; push(); }); } push(); } }); }) .then(stream => new Response(stream, { headers: { "Content-Type": "text/html" } }).text() ) .then(result => { console.log("Result:" + result); });
问题原因
核心遗漏点:使用messages参数调用/api/generate接口时,必须显式添加stream: true参数。
Ollama API在使用prompt参数时默认开启流式响应,但使用messages参数时并非如此。如果不声明stream: true,接口会一次性返回完整响应,而你的代码是按流式分块读取的逻辑,就会出现读取到空内容的情况。CURL能正常工作是因为默认处理了完整响应,或者隐含了流式配置。
解决方案
在请求的data对象中添加stream: true属性,修改后的data如下:
const data = { "model": "llama3", "stream": true, // 新增该参数 "messages": [ { "role": "user", "content": "why is the sky blue?" }, { "role": "assistant", "content": "due to rayleigh scattering." }, { "role": "user", "content": "how is that different than mie scattering?" } ] };
另外,代码中await controller.enqueue(value);这一行可以去掉,因为controller.enqueue是同步操作,不需要异步等待。
内容的提问来源于stack exchange,提问作者Titus Tesche
相关产品推荐
相关产品推荐

