Files
AIRegulation-DocAnalysis/.env.example
T
wangweiandCopilot 49ee50c104 fix: harden MCP endpoint after code review
Critical: the MCP SDK auto-enables DNS-rebinding protection when its host
parameter is left at the 127.0.0.1 default, hard-coding a loopback-only Host
allow-list. Every remote client (the only deployment this feature targets) was
refused with HTTP 421 before auth or the tool ran. Now driven by a new
MCP_ALLOWED_HOSTS setting, with '*' as an explicit, logged opt-out.

Also bounds query/top_k to match AskRequest (top_k is amplified 4x downstream,
so an unbounded value was a resource-exhaustion vector), decodes the
Authorization header as latin-1 per the ASGI spec instead of raising a 500 on
malformed bytes, and returns WWW-Authenticate on 401 per RFC 7235.

Moves the psycopg2 import guard into backend/tests/conftest.py: duplicated
across four test modules, it only worked because of alphabetical collection
order, and any earlier-sorting package would have reintroduced a live
connection attempt against the production database.

Registers the mcp module in the authoritative backend architecture doc.

84 backend tests pass. Verified against a live server: allowed remote Host
returns a valid initialize result, unknown Host returns 421, missing token
returns 401 with WWW-Authenticate.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-07-29 17:11:54 +08:00

179 lines
6.4 KiB
Bash
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# .env.example - 环境变量配置示例
# AI+合规智能中枢
# ===== 应用基础配置 =====
APP_NAME=AI+合规智能中枢
APP_VERSION=0.1.0
DEBUG=false
# ===== Milvus向量数据库配置 =====
MILVUS_HOST=6.86.80.8
MILVUS_PORT=19530
MILVUS_COLLECTION=regulations_dense_1024_v2
MILVUS_DB_NAME=default
MILVUS_INDEX_TYPE=IVF_FLAT
MILVUS_NLIST=128
MILVUS_NPROBE=16
# ===== 嵌入模型配置 =====
EMBEDDING_MODEL=text-embedding-v3
EMBEDDING_DIM=1024
EMBEDDING_API_KEY=your_embedding_api_key_here
EMBEDDING_BASE_URL=http://6.86.80.4:30080/v1
EMBEDDING_TIMEOUT_SECONDS=120
# ===== MinIO对象存储配置 =====
MINIO_ENDPOINT=6.86.80.8:9000
MINIO_ACCESS_KEY=minioadmin
MINIO_SECRET_KEY=minioadmin123
MINIO_BUCKET=compliance-docs
MINIO_SECURE=false
# ===== Redis配置 =====
REDIS_HOST=6.86.80.8
REDIS_PORT=6379
REDIS_PASSWORD=
REDIS_DB=0
# ===== PostgreSQL配置 =====
POSTGRES_HOST=6.86.80.8
POSTGRES_PORT=5432
POSTGRES_USER=compliance
POSTGRES_PASSWORD=compliance123
POSTGRES_DB=compliance_db
# ===== 文档处理配置 =====
CHUNK_SIZE=512
CHUNK_OVERLAP=50
MAX_FILE_SIZE_MB=100
DOCUMENT_METADATA_PATH=backend/data/documents.json
PARSER_BACKEND=aliyun
CHUNK_BACKEND=aliyun
# 文档元数据存储后端:json(默认,无需数据库)或 postgres(启用 PG 持久化)
# ⚠ 以下功能需要 postgres(设为 json 时功能静默降级或报 500):
# - Direction B: 合规分析历史记录 (/compliance/history/*)
# - Direction B: DOCX 报告下载
# - Direction C: Finding Chat 消息持久化
DOCUMENT_REPOSITORY_BACKEND=json
# Set to true only when a Celery worker is running (./dev.sh start worker).
# Default false: document processing runs in FastAPI's threadpool (no external worker needed).
USE_CELERY_WORKER=false
# ===== 法规感知爬取配置 =====
PERCEPTION_CRAWL_TIMEOUT_SECONDS=120
PERCEPTION_MAX_EVENTS_PER_SOURCE=100
PERCEPTION_DIFF_SIMILARITY_THRESHOLD=0.85
# ===== 阿里云文档解析 =====
ALIBABA_ACCESS_KEY_ID=your_aliyun_access_key_id
ALIBABA_ACCESS_KEY_SECRET=your_aliyun_access_key_secret
ALIBABA_ENDPOINT=docmind-api.cn-hangzhou.aliyuncs.com
ALIYUN_PARSE_POLL_INTERVAL_SECONDS=5
ALIYUN_PARSE_TIMEOUT_SECONDS=900
ALIYUN_PARSE_LAYOUT_STEP_SIZE=50
ALIYUN_LLM_ENHANCEMENT=true
ALIYUN_ENHANCEMENT_MODE=VLM
DOCUMENT_PARSE_ARTIFACT_PREFIX=artifacts
PARSER_FAILURE_MODE=fail
# ===== API服务配置 =====
API_HOST=0.0.0.0
API_PORT=8000
# ===== LLM配置(必填)=====
# LLM提供商选择: qwen / deepseek / qwen_vl
LLM_PROVIDER=deepseek
LLM_MODEL=deepseek-v4-flash
LLM_MAX_TOKENS=4096
LLM_TEMPERATURE=0.7
# ===== 统一API代理配置 =====
# 使用new-api代理服务,支持多个LLM模型
# 获取API Key: 向管理员申请
QWEN_API_KEY=your_api_key_here
DEEPSEEK_API_KEY=your_api_key_here
QWEN_BASE_URL=http://6.86.80.4:30080/v1
DEEPSEEK_BASE_URL=http://6.86.80.4:30080/v1
# ===== 可用模型 =====
# Qwen系列: qwen3.5-plus, qwen3-plus, qwen-max, qwen-turbo, qwen-long
# Qwen VL系列: qwen3-vl-plus, qwen-vl-max
# DeepSeek系列: deepseek-v4-flash, deepseek-v3.2, deepseek-v3, deepseek-chat, deepseek-coder
QWEN_MODEL=qwen3.6-plus
QWEN_VL_MODEL=qwen3-vl-plus
DEEPSEEK_MODEL=deepseek-v4-flash
# ===== RAG配置 =====
RAG_TOP_K=10
RAG_RETRIEVAL_TOP_K=20
RAG_MAX_CONTEXT_TOKENS=4000
RAG_SUMMARY_MAX_TOKENS=1024
RAG_SKILLS_MAX_TOKENS=2048
# ── Reranker (Cross-Encoder) ──────────────────────────────────────────────────
# Set RERANKER_ENABLED=true and point to a TEI or Cohere-compatible rerank API.
# Recommended model: BAAI/bge-reranker-v2.5-gemma2-lightweight (lighter) or
# BAAI/bge-reranker-v2-m3 (heavier, higher quality).
# The endpoint must expose POST /rerank (TEI style) or POST /v1/rerank (Cohere style).
RERANKER_ENABLED=true
RERANKER_BASE_URL=http://6.86.80.4:30080/v1
RERANKER_MODEL=BAAI/bge-reranker-v2-m3
RERANKER_API_KEY=
RERANKER_TOP_K=5
# ===== 会话配置 =====
SESSION_MAX_SESSIONS=100
SESSION_TIMEOUT_MINUTES=30
# SESSION_BACKEND=redis 启用 Redis 持久化会话(需要 Redis 可用,推荐生产环境)
# SESSION_BACKEND=memory 使用内存会话(重启丢失,适合本地开发)
SESSION_BACKEND=memory
# ===== 认证配置 (Auth) =====
# 生产环境必须替换为强随机密钥:
# python -c "import secrets; print(secrets.token_hex(32))"
AUTH_SECRET_KEY=change-me-in-production-must-be-32-or-more-characters-long
AUTH_ALGORITHM=HS256
# Token 有效期(分钟),默认 8 小时
AUTH_TOKEN_EXPIRE_MINUTES=480
# 设为 false 可跳过认证(仅限本地开发调试,生产必须 true)
AUTH_ENABLED=true
# ===== HyDE 查询增强 =====
# HyDE (Hypothetical Document Embeddings): 在检索前让 LLM 生成一段"假设性回答",
# 用该段落的 embedding 代替原始查询 embedding 进行向量检索。
# 无需新模型,复用现有 LLM 和 Embedding 服务。降低此功能可减少每次查询的 LLM 调用次数。
HYDE_ENABLED=true
HYDE_MAX_TOKENS=200
# ?????? LLM;???????????????
HYDE_LLM_PROVIDER=qwen
HYDE_LLM_MODEL=qwen3.5-flash
# ===== Agentic RAG 配置 (P0-1) =====
# 以下参数控制 /api/v1/agent/agentic/stream 多步推理管线
# 意图分类: simple_qa / compare / multi_hop / ambiguous
# compare 和 multi_hop 触发查询分解,最多 AGENTIC_MAX_SUB_QUERIES 个子查询
AGENTIC_MAX_SUB_QUERIES=4
# 引文锚定 fast-path 阈值: avg_score > 此值 且 chunks >= 3 时跳过 LLM grounding check
# 降低此值可让更多查询触发 LLM 二次验证(更准确,但延迟+成本增加)
AGENTIC_GROUNDING_THRESHOLD=0.65
# 各步骤 LLM 最大 token 数(越小越快,越大越准)
AGENTIC_INTENT_MAX_TOKENS=200
AGENTIC_PLAN_MAX_TOKENS=400
AGENTIC_GROUNDING_MAX_TOKENS=250
# ===== CORS =====
# 逗号分隔的允许跨域来源列表,生产环境绝不能使用 *
CORS_ALLOW_ORIGINS=http://localhost:5173
# ===== MCP (Model Context Protocol) =====
# MCP 端点(/mcp/)的 Host 头白名单,逗号分隔。MCP SDK 默认开启 DNS rebinding
# 防护,任何不在此列表中的 Host 都会被直接返回 HTTP 421,请求根本到不了鉴权和
# 工具逻辑。因此**远程部署必须把真实访问地址写进来**,否则所有外部 MCP 客户端
# Claude Desktop / IDE 等)100% 连不上。
# 语法:`:*` 后缀表示匹配任意端口;填 `*` 表示彻底关闭该防护(不推荐)。
# 例如部署在 6.86.80.9:8000 时:
# MCP_ALLOWED_HOSTS=6.86.80.9:*,127.0.0.1:*,localhost:*
MCP_ALLOWED_HOSTS=127.0.0.1:*,localhost:*,[::1]:*