FastAPI + Milvus (Standalone 默认 / Lite 可选) + DeepSeek API + ReAct Agent + Multi-Channel RAG
The Python AI service owns the read/intelligence path — document parsing, chunking, embedding, vector search, RAG retrieval, agent reasoning, and LLM interaction.
app/
├── api/ # FastAPI route modules (chat, knowledge, health)
├── core/
│ ├── agent/ # Agent system (ReAct, multi-agent, workflow runtime)
│ ├── chunker/ # Semantic text chunking + quality assessment
│ ├── embedding/ # Embedding services (Ollama, DeepSeek placeholder, test fallback)
│ ├── llm/ # LLM interfaces (DeepSeek, Ollama, mock)
│ ├── parser/ # Document parsers (PDF, DOCX, Markdown, TXT)
│ ├── rag/ # RAG engine (~23 modules)
│ ├── tools/ # Tool system (search, calculator, time)
│ ├── vectorstore/ # Milvus (Standalone 默认 / Lite 可选) + BM25 keyword index
│ └── exceptions.py
├── models/ # Pydantic models
└── utils/ # Configuration, validators
Agent V1 契约(只读研究型 Agent 的能力边界与输入/输出 JSON 契约)见 agent-v1-scope.md。
- Intent Classification → 2. Query Rewriting → 3. Query Routing → 4. Multi-Channel Retrieval (Vector + BM25 + GraphRAG) → 5. RRF Fusion → 6. Optional Reranking → 7. Postprocessing → 8. Context Compression → 9. ReAct Agent Loop → 10. Self-Reflection → 11. Source Citation
All advanced features are gated via environment variables (see .env.example):
| Flag | Default | Description |
|---|---|---|
RAG_HYBRID_ENABLED |
true |
Vector + BM25 hybrid retrieval with RRF |
RAG_GRAPH_ENABLED |
false |
Scoped GraphRAG channel (P7) |
RAG_RERANKER_MODE |
disabled |
Second-stage reranking (P6) |
RAG_MULTIMODAL_ENABLED |
false |
OCR/image evidence (P8) |
RAG_AGENT_WORKFLOW_ENABLED |
true |
Bounded single-agent workflow (P9) — 当前 .env 已启用 |
RAG_MULTI_AGENT_ENABLED |
false |
Multi-agent collaboration (P10) |
cd python-ai
# Create virtual environment
python -m venv .venv
# Activate (Windows PowerShell)
.\.venv\Scripts\Activate.ps1
# Activate (macOS/Linux)
source .venv/bin/activate
# Install dependencies
pip install -r requirements.txt
# Optional: install test deps
pip install -r requirements-dev.txtrequirements.txt 是 pip-compile --generate-hashes 的哈希锁:不要手工往尾部追加不带
--hash= 的条目(任一条目带哈希时 pip 自动开启 --require-hashes,其余裸 pin 会被整体
拒绝),也不要在 Windows-only 的传递依赖(pywin32、win32-setctime)上漏掉
sys_platform == "win32" marker;反向同罪——只在非 Windows 上需要的依赖(uvicorn[standard]
的 uvloop)在 Windows 宿主上编译时会被 pip-compile 按 marker 为假直接跳过,锁里没有它,
Linux 侧就会死于"extra 自带的 >= 规格不是 =="。requirements-dev.txt 由同一份 .in
编译,两类问题都是两份锁一起坏,而 CI 的 python job 装的是 dev 锁。三条口径由
scripts/static-checks.py --requirements-markers 纯文本核对,细节见
PRODUCTION_OPS §12;arq 与 opentelemetry 两条由
deploy/Dockerfile.python 显式钉版安装,不在锁里。
# From python-ai/ directory with venv activated
python -m app.main
# Or with explicit PYTHONPATH
PYTHONPATH=. python -m app.mainHealth check: curl http://localhost:9000/health → {"status":"healthy"}
pytest -q tests # All tests (1381 functions)
pytest -q tests/test_adaptive_retrieval.py # Specific module| Pattern | Where | Purpose |
|---|---|---|
| Strategy | Intent classifier, self-reflector, query router | Swappable LLM/Rule/Hybrid implementations |
| Factory | QueryRouterFactory, IntentClassifierFactory | Configuration-driven creation |
| Singleton | Retriever, config, trace store, graph store | Global instances |
| Provider fallback | LLM (DeepSeek → Ollama → optional mock) | Real provider first; mock only with LLM_ALLOW_MOCK=true |
| Embedding strategy | Ollama → fail closed; random only with EMBEDDING_ALLOW_FALLBACK=true |
Avoid silent fake vectors in production |
DEEPSEEK_API_KEYis used for chat LLM calls.- DeepSeek does not currently provide the embedding API expected by this project; the DeepSeek embedding client raises an error unless test fallback is explicitly enabled.
- For document indexing outside tests, run a real embedding provider such as Ollama and configure
OLLAMA_BASE_URLplusOLLAMA_EMBEDDING_MODEL(note: the.env.examplevariable isOLLAMA_EMBEDDING_MODEL, not the deprecatedOLLAMA_MODEL). LLM_ALLOW_MOCK=trueandEMBEDDING_ALLOW_FALLBACK=trueare development/test switches. Keep both disabled in production.
Python AI returns text/event-stream for streaming chat:
data: {"content": "token text..."}
data: {"sources": [...]}
data: [DONE]
Java backend reads this stream and forwards chunks to the frontend via SseEmitter.
| 模块 | 功能 | 测试数 |
|---|---|---|
| IntentClassifier | 意图识别 | - |
| QueryDecomposer | 查询分解 | 35 |
| ContextCompressor | 上下文压缩 | 43 |
| SelfReflector | 自我反思 | 36 |
| QueryRouter | 智能检索路由 | 42 |
| MultiTurnStrategy | 多轮检索策略 | 45 |
| Utils | 公共工具 | 36 |
| 功能 | 状态 | 默认 | 依赖 |
|---|---|---|---|
| Hybrid Retrieval (Vector + BM25) | ✅ Stable | 开启 | 无额外依赖 |
| Reranker (第二-stage) | 🧪 Beta | 关闭 | RAG_RERANKER_MODE=lexical/cross_encoder |
| Multimodal / OCR | 🔬 Experimental | 关闭 | Tesseract + requirements-multimodal.txt |
| Single-Agent Workflow | 🧪 Beta | 关闭 | RAG_AGENT_WORKFLOW_ENABLED=true |
| Multi-Agent Collaboration | 🔬 Experimental | 关闭 | 依赖 P9 + 明确选中的知识库 |
详见 python-ai/.env.example 和本文件 Feature Flags 一节。