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

FastAPI端点与独立脚本运行ChromaDB+LangChain检索系统的输出差异

问题分析

你遇到的核心问题是:RAG系统在独立脚本中能正确检索并返回基于文档的结果,但集成到FastAPI后,LLM返回的是通用常识内容,未使用检索到的上下文。这说明检索环节未正常工作——FastAPI环境下的向量数据库没有加载到正确的文档,或者retriever没有返回相关片段,导致LLM只能生成无上下文的通用回答。

可能的原因

  1. 向量数据库加载异常

    • FastAPI运行时的工作目录与独立脚本不同,尽管你用了绝对路径,但可能存在权限问题(比如macOS的隐私权限限制FastAPI进程访问Desktop目录),导致无法加载Chroma持久化的向量数据。
    • 导入utils.processing时,向量库初始化代码重复执行,可能加载了空的或错误的向量库。
  2. 异步/同步执行冲突
    FastAPI的端点是异步函数,而LangChain的RetrievalQA.run()是同步方法,直接在异步上下文调用可能引发隐性问题(比如线程安全导致的检索失败),但未抛出异常,仅表现为无上下文返回。

  3. 环境变量与初始化时机问题

    • 虽然processing.py中硬编码了OPENAI_API_KEY,但FastAPI运行时的环境可能未正确继承该变量,不过从返回结果看LLM能正常调用,这个可能性较低,但仍需确认。
解决方案

步骤1:排查向量库加载状态

在processing.py中添加日志,确认向量库加载的文档数量:

# 在vectordb初始化后添加
print(f"Chroma加载文档数:{len(vectordb.get()['documents'])}")

分别运行独立脚本和FastAPI,对比打印的文档数:

  • 如果FastAPI环境下文档数为0,说明未加载到正确的向量库,需检查路径权限:
    • 确保FastAPI运行的终端有访问/Users/rodrigoburberg/Desktop/RAG_MPEP/RAG_MPEP/assets目录的权限(macOS可在「系统设置-隐私与安全性-文件与文件夹」中添加终端权限)。
    • 尝试将Chroma持久化目录改为项目内的相对路径(比如./assets),避免绝对路径带来的权限或环境差异问题。

步骤2:修复异步/同步冲突

将FastAPI端点改为同步函数,或用asyncio.to_thread包装同步调用:

方案A:改为同步端点

@app.post("/query")
def query_endpoint(query: Input):
    try:
        response = process_query(query.human_input)
        return Output(output=response)
    except Exception as e:
        raise HTTPException(status_code=500, detail=f"处理失败:{str(e)}")

方案B:用asyncio包装同步调用

import asyncio

@app.post("/query")
async def query_endpoint(query: Input):
    try:
        # 将同步任务放到线程池执行
        response = await asyncio.to_thread(process_query, query.human_input)
        return Output(output=response)
    except Exception as e:
        raise HTTPException(status_code=500, detail=f"处理失败:{str(e)}")

步骤3:确保初始化代码仅执行一次

避免每次导入processing.py都重复初始化向量库和QA链,用单例模式或缓存优化:

# processing.py中修改初始化逻辑
from functools import lru_cache
from langchain.embeddings.openai import OpenAIEmbeddings
from langchain.vectorstores import Chroma
from langchain.chat_models import ChatOpenAI
from langchain.chains import RetrievalQA
import os

@lru_cache(maxsize=None)
def get_qa_chain():
    # 建议用.env文件管理API密钥,避免硬编码
    os.environ["OPENAI_API_KEY"] = "你的API密钥"
    embeddings = OpenAIEmbeddings()
    vectordb = Chroma(persist_directory="/Users/rodrigoburberg/Desktop/RAG_MPEP/RAG_MPEP/assets", embedding_function=embeddings)
    llm = ChatOpenAI(temperature=0)
    doc_retriever = vectordb.as_retriever()
    return RetrievalQA.from_chain_type(llm=llm, chain_type="stuff", retriever=doc_retriever)

def query_document(user_query):
    mpep100_qa = get_qa_chain()
    result = mpep100_qa.run(user_query)
    return result

步骤4:验证检索结果

临时修改query_document函数,打印检索到的文档片段,确认是否获取到相关上下文:

def query_document(user_query):
    mpep100_qa = get_qa_chain()
    # 打印检索到的文档
    docs = mpep100_qa.retriever.get_relevant_documents(user_query)
    print(f"检索到的文档:{[doc.page_content[:200] for doc in docs]}")
    result = mpep100_qa.run(user_query)
    return result

如果打印的文档为空或无关,说明向量库本身或检索配置有问题,需重新生成向量库;如果有相关文档,问题则出在QA链的调用环节。

内容的提问来源于stack exchange,提问作者Rodrigo Burberg

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.11 01:32:23