FastAPI部署Llama-index聊天机器人报‘Event loop is already running’错误
解决FastAPI部署Llama-index聊天机器人的“Event loop is already running”错误
核心原因
Llama-index的同步chat方法内部可能会启动新的事件循环,而FastAPI本身已在运行异步事件循环(默认使用uvloop),两者冲突导致报错。Jupyter中用nest_asyncio能解决是因为它修改了标准库事件循环的行为,但该方案不兼容uvloop,因此在FastAPI中无效。
解决方案
方案1:使用Llama-index的异步聊天接口
BaseChatEngine提供了异步版本的achat方法,直接替换同步的chat调用即可:
@app.post("/api/chat/{question}", dependencies=[Depends(sessionValidator)]) async def chat(question: str = Path(...), my_chatbot=Depends(chatbotProvider)): try: logger.info(f"Getting LLM response..") # 替换为异步achat方法 ans = await my_chatbot.chatbot.achat(question) logger.info(f"SUCCESS! Chatbot responded: {ans.response}") return ans.response except Exception as e: logger.error(f"FAILED! Got no response from chatbot! Err {e}") raise HTTPException(status_code=500, detail="Chatbot gave no response!")
方案2:正确使用asyncio.to_thread运行同步方法
之前的asyncio.to_thread调用存在参数传递错误,需传递函数对象和参数,而非直接执行函数:
import asyncio @app.post("/api/chat/{question}", dependencies=[Depends(sessionValidator)]) async def chat(question: str = Path(...), my_chatbot=Depends(chatbotProvider)): try: logger.info(f"Getting LLM response..") # 正确传递函数对象和参数 ans = await asyncio.to_thread(my_chatbot.chatbot.chat, question) logger.info(f"SUCCESS! Chatbot responded: {ans.response}") return ans.response except Exception as e: logger.error(f"FAILED! Got no response from chatbot! Err {e}") raise HTTPException(status_code=500, detail="Chatbot gave no response!")
方案3:确保LLM使用异步实例
如果使用Ollama的LLM,改用异步版本的AsyncOllama,避免同步LLM内部触发事件循环冲突:
# 在MyChatAssistant的初始化代码中修改LLM实例 from llama_index.llms.ollama import AsyncOllama llm = AsyncOllama(model="llama3") # 后续创建索引和聊天引擎时使用该异步LLM
之前尝试失败的原因
- 直接
await chat(question):chat是同步方法,不支持await语法,会触发错误。 run_in_executor:聊天引擎内部若依赖异步操作,放到线程池仍可能触发事件循环冲突,适配性不如asyncio.to_thread。- 错误的
asyncio.to_thread调用:之前直接传入chat(question)相当于先执行了同步方法,再把结果传给to_thread,完全未起到异步隔离作用。 run_until_complete/create_task:在已运行的事件循环中调用run_until_complete本身就会触发“Event loop is already running”错误。
内容的提问来源于stack exchange,提问作者Sun Bee
相关产品推荐
相关产品推荐

