You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何结合asyncio实现LangChain RetrievalQA的并行处理?

解决LangChain RetrievalQA异步并行处理问题

问题原因

你当前的代码无法运行,核心原因是RetrievalQA默认的调用方法是同步阻塞的,不能直接用await发起异步调用。要实现多查询并行,需要改用LangChain的异步组件,或者将同步调用包装为异步执行。

可行方案1:使用LangChain原生异步组件

LangChain提供了异步版本的LLM和链方法,能原生支持异步操作,性能更优(要求LangChain版本≥0.1.0)。

代码示例

import langchain
from langchain.chat_models import AsyncChatOpenAI  # 改用异步LLM
from langchain.chains import RetrievalQA
from langchain.vectorstores import FAISS
from langchain.schema.vectorstore import VectorStoreRetriever
import asyncio
import nest_asyncio

# 初始化向量检索器
retriever = VectorStoreRetriever(vectorstore=FAISS(...))

# 使用异步版本的ChatOpenAI
chat = AsyncChatOpenAI(model="gpt-3.5-turbo-16k", temperature=0.7)

# 初始化RetrievalQA链
qa_chain = RetrievalQA.from_llm(
    chat,
    retriever=retriever,
    return_source_documents=True
)

queries = ['query1', 'query2', 'query3']
data_to_append = []

async def process_query(query):
    vectordbkwargs = {"search_distance": 0.9}
    # 使用链的异步调用方法ainvoke
    result = await qa_chain.ainvoke({"query": query, "vectordbkwargs": vectordbkwargs})
    data_to_append.append({
        "Query": query,
        "Source_Documents": result["source_documents"],
        "Generated_Text": result["result"]
    })

async def main():
    tasks = [process_query(q) for q in queries]
    await asyncio.gather(*tasks)

if __name__ == "__main__":
    nest_asyncio.apply()
    asyncio.run(main())

可行方案2:将同步调用包装为异步执行

如果使用的LangChain版本不支持异步组件,可通过asyncio.to_thread将同步调用包装到线程池中,实现并行处理。

代码示例

import langchain
from langchain.chat_models import ChatOpenAI
from langchain.chains import RetrievalQA
from langchain.vectorstores import FAISS
from langchain.schema.vectorstore import VectorStoreRetriever
import asyncio
import nest_asyncio

retriever = VectorStoreRetriever(vectorstore=FAISS(...))
chat = ChatOpenAI(model="gpt-3.5-turbo-16k", temperature=0.7)

qa_chain = RetrievalQA.from_llm(
    chat,
    retriever=retriever,
    return_source_documents=True
)

queries = ['query1', 'query2', 'query3']
data_to_append = []

async def process_query(query):
    vectordbkwargs = {"search_distance": 0.9}
    # 用to_thread将同步调用包装为异步
    result = await asyncio.to_thread(
        qa_chain,
        {"query": query, "vectordbkwargs": vectordbkwargs}
    )
    data_to_append.append({
        "Query": query,
        "Source_Documents": result["source_documents"],
        "Generated_Text": result["result"]
    })

async def main():
    tasks = [process_query(q) for q in queries]
    await asyncio.gather(*tasks)

if __name__ == "__main__":
    nest_asyncio.apply()
    asyncio.run(main())

注意事项

  • 方案1是原生异步实现,无线程切换开销,推荐优先使用。
  • 方案2本质是多线程并行,适合IO密集型场景(如OpenAI API调用、向量检索),能有效提升处理效率。
  • 若向量库检索本身是同步阻塞的,两种方案都能并行处理检索操作。

内容的提问来源于stack exchange,提问作者Abhishek R

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.07 20:03:26