用 FastAPI 和大模型搭一个 RAG 知识库
这套流程的目标很明确:把文档喂进去,切块、向量化、入库,再在用户提问时把相关片段捞出来交给大模型生成回答。听起来顺手,真正落地时反而是细节多,尤其是文档规整和检索召回这两段,做不好后面都会变味。
系统里主要用到 FastAPI、tortoise-orm 和异步模型调用,LLM 侧先接 OpenAI、AzureOpenAI、Moonshot,后面要扩展别的模型也不难。整体代码是围绕一个 LLMEngine 包起来的,调用层尽量保持一致,这样上层流程不用跟着不同厂商的 SDK 反复改。
文档规整
当前先支持 .docx,pdf 还没补上。这个选择算务实:先把最常见的结构化文档跑通,后面再补复杂格式,不然一开始就被解析兼容性拖住,整个链路很难看出问题在哪。
文档处理模块的职责是把非结构化文本拆成适合模型处理的片段,同时把图片资源路径一起处理好。
# /ExileChat/test/test_ai/test_document_chunk.py
from utils.ai.document_chunk import DocumentChunk
if __name__ == "__main__":
# 文档的路径或静态资源服务器的地址
file_path = "./data/测试文档.docx"
# 文档中图片存放的路径或图片服务器的地址,image_base_path 与 image_base_url 使用其一即可
image_base_path = "./data/images"
image_base_url = "https://example.com/images"
dc = DocumentChunk(image_base_path=image_base_path, is_debug=True)
content = dc.process_file(file_path)
print(f"Extracted content length: {len(content)}")
大模型调用
调用大模型前,api_key 和对应文档都得准备好。这里支持 OpenAI、AzureOpenAI、Moonshot,底层做成一个客户端工厂,外层只关心模型名和配置。
模型客户端封装
# /ExileChat/utils/ai/llm_engine.py
class ModelClient:
"""Models Client"""
api_key: str = None
kwargs: dict = {}
@classmethod
def open_ai():
():
():
:
():
.model_name = model_name
.api_key = api_key
.is_debug = is_debug
.args = args
.kwargs = kwargs
ModelClient.api_key = api_key
ModelClient.kwargs = kwargs
.client_dict = {
: ModelClient.open_ai,
: ModelClient.azure_open_ai,
: ModelClient.moonshot,
}
.client = .client_dict.get(model_name)()


