![[Bug]: `str()`/`.response` on async streaming chat response (astream_chat) returns empty string](https://www.chat-gpts.plus/wp-content/uploads/2026/07/22178-d5526984.jpg)
[Bug]: `str()`/`.response` on async streaming chat response (astream_chat) returns empty string
快速结论:该 Bug 发生在 LlamaIndex 异步流式聊天(astream_chat)场景下,当流式传输结束后调用 str(resp) 或 resp.response 会返回空字符串。优先排查你是否在异步流式响应完成后直接读取 response 属性,而非同步流式 stream_chat。
问题场景
用户在使用 LlamaIndex 的 SimpleChatEngine(或其他使用 StreamingAgentChatResponse 的引擎)调用 astream_chat 方法进行异步流式聊天时,流式传输过程正常,Token 可以正常输出并保存到内存,但通过 str(resp) 或 resp.response 获取最终文本却返回空字符串。同步版本的 stream_chat 功能正常。
报错原文
Output: ''
原因分析
已由 Issue 提交者和评论者确认,Bug 根因位于 StreamingAgentChatResponse 实现中:
- 问题 1:
__str__方法只从同步队列self.queue中提取数据,从未检查异步队列self.aqueue。异步流式完成后,累积的文本仍滞留在异步队列中。 - 问题 2:
awrite_response_to_history方法在异步流式完成后,虽然累积了final_text并写入内存,但从未将最终文本赋值给self.response或self.unformatted_response,导致response属性保持空字符串。
环境排查
- LlamaIndex 版本:0.14.23(Issue 中复现的版本)
- 确认你使用的是
astream_chat而非stream_chat - 确认你在读取
response之前已await resp.awrite_response_to_history_task
解决步骤
- 方案一(推荐,最简单安全):在
awrite_response_to_history方法末尾(设置self.is_done = True之后)添加赋值:self.unformatted_response = final_text self.response = final_text.strip() - 方案二(备选):修改
__str__方法,使其同时检查并排空self.aqueue(当self.queue为空且self.aqueue不为空时):def __str__(self) -> str: if self.is_done and not self.is_function: if not self.queue.empty(): while self.queue.queue: delta = self.queue.queue.popleft() self.unformatted_response += delta self.response = self.unformatted_response.strip() elif self.aqueue is not None and not self.aqueue.empty(): while not self.aqueue.empty(): delta = self.aqueue.get_nowait() self.unformatted_response += delta self.response = self.unformatted_response.strip() return self.response - 手动修复方式:如果你无法修改源码,可在调用
astream_chat后主动遍历异步流式生成器来消耗队列,然后手动设置resp.response:resp.response = "你的累积文本"。但这只是临时绕过。
注意:以上修复方案来自 Issue 讨论中的推测,尚未在官方版本中合并。可优先尝试方案一。
验证方法
在修复后,运行以下测试代码确认 str(resp) 返回空字符串变为正常的回复文本:
import asyncio
from llama_index.core.chat_engine.simple import SimpleChatEngine
from llama_index.core.llms.mock import MockLLM
async def main() -> None:
engine = SimpleChatEngine.from_defaults(llm=MockLLM(max_tokens=8))
resp = await engine.astream_chat("What is two plus two")
await resp.awrite_response_to_history_task
print(repr(str(resp))) # 修复前输出 '',修复后应输出正常文本
asyncio.run(main())



