使用说明
基于LangChain的混合RAG服务器(MCP)
FastAPI RAG服务器,集成了基于文档的QA、命令生成和数据库集成。
包括Parent-Document Retriever、FlashRank Re-Ranking、DB+文档混合响应、intent自动分支、模型上下文协议(MCP)支持。
文档状态:在所有Python文件中添加韩语文档和详细注释(公开产品组合)
主要功能
- 加载多格式文档 →收听→矢量加载(
ingest_langchain.py)- PDF(自动区分文本PDF/扫描PDF)
- 文本文件(TXT,MD)
- Word文档(DOCX)
- HTML文件
- PDF自动处理:
- 文本PDF:PyMuPDF直接提取文本
- 扫描PDF:Tesseract OCR图像文本识别(支持韩语/英语)
- DB+文档混合QA (
/ask):- LLM选择并验证后运行MySQL白名单查询
- 将数据库结果和文档搜索上下文合并
hybrid_answer用回答
- Parent-Document Retriever:child是搜索/排名,parent是LLM上下文(Chroma+SQLite)
- 第二步搜索:矢量搜索→FlashRank Re-Ranking
- Guardrail&Confidence:top score切,good hit个数,可信度分数/级返回
- Intent分类(
/ask:自动路由到explain/command - 命令生成JSON+解析+白名单验证(
/command) - 包含来源/score/预览的RAG响应(
/chat)
技术堆栈
- Python 3、FastAPI、Uvicorn
- LangChain(OpenAI、Chroma、文本拆分器、社区)
- 父文档检索器패턴 (Chroma子节点+SQLite父节点)
- FlashRank重新排名
- 皮丹提克
- PyMuPDF(PDF文本提取)
- Tesseract OCR(扫描PDF图像识别)
- Mysql+mysql-connector-python(数据库排名/分数查询)
文件夹结构
.
├── api/ # FastAPI 서버 관련 파일
│ └── rag_server.py # FastAPI 엔트리포인트 (/chat, /command, /ask)
├── chains/ # LLM 체인 구현 (RAG/SQL/DB/하이브리드)
│ ├── __init__.py
│ ├── rag_chain.py
│ ├── sql_query_chain.py
│ ├── db_query_chain.py
│ ├── db_summary_chain.py
│ ├── hybrid_chain.py
│ ├── hybrid_onecall_chain.py
│ └── command_chain.py
├── commands/ # 명령 화이트리스트
│ ├── __init__.py
│ └── registry.py # 허용 명령 목록 및 파라미터 정의
├── docs/ # 원본 문서 저장 폴더
├── ingest/ # 문서 수집 및 벡터DB 구축
│ ├── __init__.py
│ ├── ingest_langchain.py # 문서 적재 스크립트
│ ├── docstore_sqlite.py # SQLite 기반 Parent 문서 저장소
│ └── debug_chroma_scan.py # ChromaDB 디버깅 스크립트
├── loaders/ # 문서 로더 (다중 포맷 지원)
│ ├── auto_loader.py # 자동 문서 로더 (PDF 자동 구분)
│ ├── pdf_detector.py # PDF 종류 판별기 (텍스트/스캔)
│ ├── pdf_text_loader.py # 텍스트 PDF 로더
│ ├── pdf_scan_loader.py # 스캔 PDF 로더 (OCR)
│ └── rules.py # 파일 확장자별 로더 규칙
├── ocr/ # OCR 엔진
│ ├── __init__.py
│ ├── base.py # OCR 베이스 클래스
│ ├── tesseract_ocr.py # Tesseract OCR 구현
│ └── dummy_ocr.py # 더미 OCR (테스트용)
├── preprocess/ # 전처리 유틸리티
│ └── text_cleaner.py # 텍스트 정리
├── prompts/ # LLM 프롬프트 템플릿
│ ├── __init__.py
│ ├── command_prompt.py
│ ├── intent_prompt.py
│ ├── rag_prompt.py
│ ├── sql_query_prompt.py
│ ├── db_query_prompt.py
│ ├── db_summary_prompt.py
│ ├── hybrid_onecall_prompt.py
│ └── hybrid_prompt.py
├── reasoning/ # LLM 기반 추론 모듈
│ ├── __init__.py
│ ├── chains/ # LLM 체인들
│ ├── prompts/ # 프롬프트 템플릿
│ ├── schemas/ # Pydantic 스키마
│ └── services/ # 검색/파싱/검증 서비스
├── retrieval/ # 검색 및 벡터화
│ ├── retrieval.py # Parent-Child 검색 + FlashRank re-ranking
│ ├── vector_store.py # ChromaDB 벡터 저장소
│ └── rerank_flashrank.py # FlashRank 재정렬 엔진
├── schemas/ # Pydantic 스키마 정의
│ ├── __init__.py
│ ├── command.py
│ ├── intent.py
│ ├── rag_answer.py
│ ├── sql_query.py
│ ├── db_query.py
│ ├── db_summary.py
│ └── hybrid_answer.py
├── services/ # 비즈니스 로직 서비스
│ ├── __init__.py
│ ├── retrieval.py # Parent-Child 검색
│ ├── vector_store.py # 벡터 저장소 관리
│ ├── intent_classifier.py # 의도 분류
│ ├── command_parser.py # 명령 JSON 파싱
│ ├── command_validator.py # 명령 검증
│ ├── db_service.py # MySQL 연결 및 쿼리 실행
│ ├── db_router.py # DB 질문 판별
│ ├── db_schema_provider.py # DB 스키마 정보 제공
│ ├── db_query_parser.py # DB 쿼리 JSON 파싱
│ ├── db_query_validator.py # DB 쿼리 검증
│ ├── db_summary_parser.py # DB 요약 결과 파싱
│ ├── db_fallback_summary.py # DB 요약 폴백
│ ├── sql_query_parser.py # SQL 쿼리 파싱
│ ├── sql_validator.py # SQL SELECT 전용 검증
│ ├── hybrid_parser.py # 하이브리드 답변 파싱
│ └── confidence.py # 신뢰도 계산
├── test/ # 테스트 스크립트
│ ├── test_loaders.py # 로더 테스트
│ ├── test_retrieval.py # 검색 기능 테스트
│ └── test_db.py # DB 연결 테스트
├── config.py # 전역 설정 파일
├── query_test.py # 검색 단독 테스트
├── requirements.txt # 프로젝트 의존성
├── chroma_db/ # ChromaDB 벡터 저장소 (자동 생성)
└── README.md # 이 파일
主要文件说明
根目录
FastAPI服务器
api/rag_server.py:FastAPI服务器主文件/chat,/command,/ask提供端点- 运行二级搜索管道(矢量搜索+FlashRank Re-Ranking)
- Guardrail和Confidence计算
- 所有端点均包含详细的韩语文档
收集和测试文档
-
ingest/ingest_langchain.py:文档收集和矢量数据库构建脚本docs/读取文件夹中的文档并将其保存到ChromaDB- 保存为Parent-Child结构(搜索为child,LLM上下文为parent)
- 文档窃听和嵌入转换
- 包括详细的韩语文档
-
query_test.py:仅测试矢量搜索功能的脚本- 无需运行服务器即可查看搜索结果
- 包括韩语使用注释
-
config.py:项目全局设置文件- OpenAI API密钥、模型设置、Guardrail参数等
- 将敏感信息显示为占位符
- 添加详细的韩语说明
装载机/
auto_loader.py:自动文档加载程序- 自动检测文件夹中的所有文档,并选择适当的加载程序
- 对于PDF文件,自动区分文本PDF和扫描PDF进行处理
- 自动添加文档元数据(doc_id、source、kind、domain等)
pdf_detector.py:PDF类型辨识器- 通过检查是否存在文本层自动识别文本PDF/扫描PDF
pdf_text_loader.py:文本PDF加载程序- 使用PyMuPDF直接从文本层提取文本
- 将整合加载到每个文件一个Document
pdf_scan_loader.py:扫描PDF加载程序- 使用Tesseract OCR从图像中提取文本
- 韩语/英语多语言支持
- 将整合加载到每个文件一个Document
rules.py:按文件扩展名加载规则- 加载程序映射,如TXT、MD、PDF、DOCX、HTML等
ocr/
base.py:OCR基类- 定义OCR引擎的通用接口
tesseract_ocr.py:Tesseract OCR实施- 将PDF渲染为图像并执行OCR
- 多语言支持(韩语、英语等)
dummy_ocr.py:堆叠OCR(测试用)
预处理/
text_cleaner.py:文本清理实用程序- 统一改行文字、消除过多空白等
reasoning/包
reasoning/chains/ -LLM链实施
-
rag_chain.py:RAG链- 将矢量搜索的文档转换为上下文
- 使用LangChain链配置问题→搜索→答案生成管道
- 所有函数都包含韩语文档
-
sql_query_chain.py:SQL查询创建链- 自然语言→SQL查询转换
- 通过SELECT专用验证增强安全性
-
db_query_chain.py:DB查询选择链- LLM指南选择允许的数据库查询列表之一
-
db_summary_chain.py:DB摘要链- 用自然语言概括DB查询结果
-
hybrid_chain.py:二级混合链- 合并DB摘要+文档上下文以生成最终答案
-
hybrid_onecall_chain.py:单呼叫混合链- 一次处理DB rows+文档上下文
-
command_chain.py:命令创建链- 将自然语言命令转换为JSON格式
reasoning/prompts/ -LLM提示模板
-
intent_prompt.py:目的分类提示- 将用户输入分类为“command”或“explain”
-
rag_prompt.py:RAG响应提示- 创建基于搜索到的文档上下文的响应
-
sql_query_prompt.py:SQL生成提示- 自然语言→SQL转换提示
-
db_query_prompt.py:DB查询选择提示- 从允许的查询列表中选择
-
db_summary_prompt.py:DB摘要提示- 结果摘要提示
-
hybrid_onecall_prompt.py:混合单一呼叫提示- DB+文档集成提示
-
hybrid_prompt.py:混合二级提示- 用于回退的混合提示
-
command_prompt.py:命令生成提示- 生成JSON命令提示
reasoning/schemas/ -Pydantic模式
-
intent.py:目的分类结果模式IntentResult模型
-
rag_answer.py:RAG答案方案- 基于搜索的响应结构
-
sql_query.py:SQL查询模式- 生成的SQL查询结构
-
db_query.py:DB查询请求模式DBQueryRequest模型
-
db_summary.py:DB摘要结果方案DBSummaryResult模型
-
hybrid_answer.py:混合回答方案- DB+文档集成响应结构
-
command.py:命令模式CommandResponse,CommandAction模型
reasoning/services/ -业务逻辑服务
所有服务均遵循单一责任原则(SRP),包括详细的韩语文档:
搜索和排名
-
retrieval.py:父母子女검색 + FlashRank重新排名- 实施二级搜索管线
- OCR关键字偏斜
-
rerank_flashrank.py:FlashRank重新排序引擎- 根据搜索结果的语义相关性重新排序
目的分类和路由
-
intent_classifier.py:分类用户意图- 基于Rule+基于LLM的混合
- “command”或“explain”分类
-
db_router.py:识别DB问题- 识别用户问题是否与DB相关
命令处理
-
command_parser.py:命令解析JSON- LLM生成命令解析JSON
-
command_validator.py:验证命令白名单commands/registry.py基础验证
SQL查询处理
-
sql_query_parser.py:解析SQL查询- LLM生成SQL解析
-
sql_validator.py:仅验证SQL SELECT- 阻止DML(INSERT,UPDATE,DELETE)
数据库查询处理
-
db_service.py:运行SQL连接和查询- 基于白名单运行允许的查询
-
db_schema_provider.py:提供数据库模式信息- 要提供给LLM的数据库结构信息
-
db_query_parser.py:DB查询解析JSON- LLM生成的DB查询解析JSON
-
db_query_validator.py:验证DB查询- 验证允许的查询和参数
数据库摘要
-
db_summary_parser.py:解析数据库摘要结果- 解析LLM摘要结果
-
db_fallback_summary.py:数据库摘要回退- LLM失败时生成基于规则的摘要
混合答案
hybrid_parser.py:解析混合答案- 解析DB+文档集成响应
可靠性和guardrail
confidence.py:计算可靠性- 基于搜索分数+良好的文档数量计算可信度
- high/medial/low级别分类
测试文件(test/文件夹)
-
test/test_loaders.py:文档加载程序测试脚本- PDF类型判别测试
- 文本PDF提取示例输出
- 扫描PDF OCR样例输出
- AutoLoader完整摘要
- 包括韩语文档
-
test/test_retrieval.py:搜索功能测试脚本- 在ChromaDB中搜索Child文档
- 按doc_id排序
- 从SQLiteDocStore恢复Parent文档
- 详细的韩语函数说明
-
test/test_db.py:测试数据库连接和查询- 检查您的MySQL连接
- 运行示例查询
- 包括韩语文档
-
query_test.py(根):测试ParentDocumentRetriever行为- 测试交互式问答
安装&首选参数
1.安装软件包
pip install -r requirements.txt
2.安装Tesseract OCR(用于扫描PDF处理)
处理扫描PDF文件需要Tesseract OCR。
窗户:
- Tesseract OCR安装程序 下载和安装
- 默认安装路径:
C:\Program Files\Tesseract-OCR\tesseract.exe loaders/auto_loader.py哇ocr/tesseract_ocr.py在中检查/修改路径
Linux(Ubuntu/Debian):
sudo apt-get install tesseract-ocr
sudo apt-get install tesseract-ocr-kor # 한국어 지원
macOS:
brew install tesseract
brew install tesseract-lang # 다국어 지원
注意:
- 建议安装韩语语言包以支持韩语
- 安装后的语言代码:
"eng+kor"(英语+韩语)
环境变量(建议env)
OPENAI_API_KEY=your-api-key
EMBED_MODEL=text-embedding-3-small
CHAT_MODEL=gpt-4o-mini
CHROMA_DIR=./chroma_db
COLLECTION_NAME=my_rag_docs
TOP_K=4
DOCSTORE_PATH=./parent_docstore.sqlite
# 선택사항 - MySQL 설정 (DB 질문 사용 시)
MYSQL_HOST=localhost
MYSQL_PORT=3306
MYSQL_USER=your_user
MYSQL_PASSWORD=your_password
MYSQL_DATABASE=your_db
# 선택사항 - Tesseract OCR 설정 (스캔 PDF 처리)
TESSERACT_CMD=C:\\Program Files\\Tesseract-OCR\\tesseract.exe
OCR_LANGUAGE=eng+kor
安全建议:
- 敏感信息使用环境变量或保密服务
- Git上
.env禁止提交文件(.gitignore添加到)
数据装载(ingest)
将文档 docs/放入并运行:
python ingest/ingest_langchain.py
支持文件格式
- PDF:自动区分文本PDF和扫描PDF
- 文本PDF:PyMuPDF直接提取文本
- 扫描PDF:Tesseract OCR识别图像文本
- 文本文件:TXT,MD
- Word文档:DOCX
- HTML文件:HTML、HTM
处理方式
- 区块设置:默认800个字符,重叠100个字符(
config.py/ingest/ingest_langchain.py) - 存储方式:儿童→Chroma,父母→SQLite(
parent_docstore.sqlite) - PDF处理:每个文件合并一个Parent文档(无分页)
- 元数据:自动添加到每个文档
doc_id:每个文件的唯一IDsource:文件路径kind:文档类型(pdf_text、pdf_scan_ocr、txt、md等)domain:域标签page:页码(当年)
- 重新运行:更改源文档时重新运行
处理流
# ingest/ingest_langchain.py 실행
# 1. docs/ 폴더 스캔
# 2. PDF 자동 구분 (텍스트 vs 스캔)
# 3. 텍스트 추출 (PyMuPDF 또는 Tesseract OCR)
# 4. 파일별 Parent 문서 생성 및 SQLite 저장
# 5. Child 청크 생성 및 ChromaDB 벡터 저장
# 6. 진행 상황 콘솔 출력
运行服务器
1.装载文档(仅第一次)
python ingest/ingest_langchain.py
2.启动FastAPI服务器
uvicorn api.rag_server:app --reload --port 8000
或内置测试:
python -m uvicorn api.rag_server:app --reload --port 8000
3.API测试
在浏览器中查看交互式API文档:
http://localhost:8000/docs
API端点
/chat -基于RAG的Q&A
请求:
{
"question": "질문 내용"
}
回答:
{
"answer": "응답 텍스트",
"sources": [
{
"source": "문서 경로",
"score": 0.95,
"preview": "미리보기 텍스트..."
}
],
"guard": {
"reason": "ok",
"top_score": 0.85,
"good_hits": 3
},
"confidence": {
"level": "high",
"score": 0.92,
"details": {
"base": 0.85,
"bonus": 0.07
}
}
}
/command -命令JSON建议
请求:
{
"question": "어떤 작업을 하고 싶은지"
}
回复:
{
"speech": "요약 음성",
"actions": [
{
"action": "명령이름",
"params": {
"param1": "값1"
}
}
],
"confidence": 0.9,
"guard": {
"reason": "ok"
}
}
/ask -基于目的的集成界面
请求:
{
"question": "질문 또는 명령"
}
回答(如果是DB问题):
{
"type": "hybrid_answer",
"question": "...",
"speech": "...",
"db_summary": "DB 조회 결과 요약",
"doc_notes": "관련 문서 추가 설명",
"answer": "최종 통합 답변",
"query": "GetTopScores",
"params": { "limit": 10 },
"rows": [ ... ],
"sources": [ ... ],
"guard": { "reason": "ok" }
}
回答(如果是一般问题):
{
"type": "rag_answer",
"answer": "...",
"sources": [ ... ],
"guard": { "reason": "ok" },
"confidence": { "level": "high", "score": 0.9 }
}
呼叫示例
# RAG 질문
curl -X POST http://localhost:8000/chat \
-H "Content-Type: application/json" \
-d '{"question": "RAG 파이프라인 설명"}'
# 명령 요청
curl -X POST http://localhost:8000/command \
-H "Content-Type: application/json" \
-d '{"question": "화면 밝기 올려줘"}'
# 통합 인터페이스 (의도 자동 판별)
curl -X POST http://localhost:8000/ask \
-H "Content-Type: application/json" \
-d '{"question": "지난주 상위 점수는?"}'
动作流
1.收集文档(Ingest)
docs/在文件夹中自动浏览文档- PDF文件:文本PDF/扫描自动识别PDF
- 文本PDF:PyMuPDF提取文本
- 扫描PDF:Tesseract OCR识别图像文本
- 在每个文件中
doc_id赋予(每个文件的唯一ID) - 每个文件创建一个Parent文档(合并所有页面)
- 将Parent文档拆分为Child区块(800个字符,100个重叠字符)
- Parent存储SQLite,Child存储在ChromaDB中作为矢量
2.请求搜索(文档)
- 搜索Child文档similarity(initial_k=20)
- OCR关键字查询时优先搜索OCR文档(关键字偏置)
- 使用FlashRank Re-ranking重新排列结果
- Parent文档还原和重复数据删除
- 按Parent计算最小distance score
- Guardrail和可靠性计算
3. /chat 端点
- Parent上下文格式(每个文档900个字符,共3500个字符)
_trim_context最多限制12000个字符- 生成LLM响应+返回来源信息
4. /command 端点
- 使用相同上下文
- LLM生成JSON格式命令
- 解析JSON并验证白名单
- 信任度低则屏蔽
5. /ask 端点(DB+文档混合)
- 如果问题与DB有关:
- LLM选择允许查询列表(DB白名单)之一生成JSON
- 在服务器上验证后运行MySQL(最多使用50条rows)
- 与文档搜索上下文合并
hybrid_answer用回答 - 失败时:默认查询
GetTopScores+基于规则的摘要回退
- 如果与DB无关:
- intent分类(
command/explain)后/command或/chat运行逻辑
- intent分类(
主要设置点
ingest_langchain.py:父母/子女分开(build_parent_retriever),COLLECTION_NAMEconfig.py:CHUNK_SIZE=800,CHUNK_OVERLAP=100,TOP_K,TOP_SCORE_MAX,MIN_GOOD_HITS,GOOD_HIT_SCORE_MAX,CONF_SCORE_MIN/MAX,DOCSTORE_PATHrag_server.py:INITIAL_K=20,_trim_context最多12000个字符services/retrieval.py:fetch_multiplier=3将rerank范围扩大到top_k,以缓解parent deducpe损失commands/registry.py:允许命令/定义必需的args
体系结构注释(Parent-Document Retriever)
- 搜索为child区块(Chroma),LLM上下文为parent(SQLite)
- 流:child搜索→FlashRank rerank→parent恢复/重复数据删除→每个parent的最小distance score→guard/considence→上下文剪切→LLM
操作/安全提示
- API密钥使用环境变量/保密服务
chroma_db/需要时可再生(ingest重新运行)- PDF文件处理:
- 文本PDF可以快速处理
- 扫描PDF的OCR处理可能需要很长时间(与文件大小和页数成正比)
- 建议使用高分辨率PDF以提高OCR准确度
- 发生问题时
docs/troubleshooting.txt参考
主要功能
PDF自动分隔
- 自动确定是否存在文本层
- 文本PDF:快速直接提取
- 扫描PDF:OCR识别图像文本
优化OCR关键字搜索
- 在搜索运单编号、跟踪码等关键词时,首先搜索OCR文档
- 通过关键字偏置提高搜索准确度
Parent-Child结构
- 搜索是小Child区块,提高了准确度
- LLM上下文作为整个Parent文档提供,以保留上下文
