如何改造处理LLM函数调用的Future返回函数以支持流式响应?
改造VertexAI对话函数以支持流式输出并保留函数调用逻辑
以下是满足需求的实现方案:先同步完成所有函数调用流程,再将LLM的最终响应以原生流式方式返回,而非简单包装Future为Stream。
Stream<String> generateResponseStream(String query) async* { final chat = model.startChat(); GenerateContentResponse response = await chat.sendMessage(Content.text(query)); // 同步处理多轮函数调用(此阶段必须等待函数执行完毕,无法流式) while (response.functionCalls.isNotEmpty) { final List<Map<String, DataRow>> functionCallResults = []; for (final functionCall in response.functionCalls) { final functionIdentifier = functionCall.name; final parameters = functionCall.args; final result = await executeFunction(functionIdentifier, parameters); functionCallResults.add({ functionIdentifier: result, }); } // 发送函数执行结果,继续对话(同步获取响应以判断是否还有后续函数调用) response = await chat.sendMessage( functionCallResults.length == 1 ? Content.functionResponse( functionCallResults.single.entries.single.key, functionCallResults.single.entries.single.value, ) : Content.functionResponses([ for (final entry in functionCallResults) FunctionResponse( entry.entries.single.key, entry.entries.single.value, ), ]), ); } // 所有函数调用处理完成,流式获取最终响应 // 对话历史已保存,发送空文本触发LLM生成最终回答(若API不允许空文本,可改为发送提示语如"请给出最终回答") final stream = chat.sendMessageStream(Content.text('')); await for (final chunk in stream) { if (chunk.text != null && chunk.text!.isNotEmpty) { yield chunk.text!; } } // 流式响应为空时返回默认提示 yield 'Sorry, I am not able to respond to your query at the moment.'; }
关键逻辑说明:
- 函数调用处理:保留原代码的同步循环逻辑,因为函数调用必须拿到执行结果才能推进对话,此阶段无法实现流式输出。
- 流式响应触发:当确认无后续函数调用后,利用VertexAI提供的
sendMessageStream方法,基于已有的对话历史触发LLM生成流式响应。 - 流式片段处理:通过
await for遍历流式返回的每个响应片段,将非空的文本内容逐个输出。
内容的提问来源于stack exchange,提问作者Ahmed
相关产品推荐
相关产品推荐

