{"openapi":"3.1.0","info":{"title":"招标代理 RAG API","description":"招标代理 RAG 系统 — 法规检索 + 合规审查 + 避坑提示","version":"0.1.0"},"paths":{"/api/auth/login":{"post":{"tags":["Auth"],"summary":"Login","operationId":"login_api_auth_login_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LoginRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/auth/me":{"get":{"tags":["Auth"],"summary":"Me","operationId":"me_api_auth_me_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/api/rag/health":{"get":{"tags":["System"],"summary":"Health","description":"全链路健康检查","operationId":"health_api_rag_health_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/api/rag/scenario-a/review":{"post":{"tags":["Scenarios"],"summary":"Scenario A Review","description":"场景 A：上传文档 → 标注不合规条款","operationId":"scenario_a_review_api_rag_scenario_a_review_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TextRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RAGResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/rag/scenario-b/search":{"post":{"tags":["Scenarios"],"summary":"Scenario B Search","description":"场景 B：关键词 → 列出禁止性/限制性规定","operationId":"scenario_b_search_api_rag_scenario_b_search_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/KeywordRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RAGResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/rag/scenario-c/check":{"post":{"tags":["Scenarios"],"summary":"Scenario C Check","description":"场景 C：草稿 → 逐条法规比对","operationId":"scenario_c_check_api_rag_scenario_c_check_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TextRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RAGResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/rag/scenario-d/ask":{"post":{"tags":["Scenarios"],"summary":"Scenario D Ask","description":"场景 D：自由问答（避坑模式）\n\n默认走 D″（agentic）。要退回单轮旧路，传 `mode=\"fast\"`，或只传 `fast=true`；\n显式给了 mode 时以 mode 为准（`fast=true, mode=\"agentic\"` → agentic）。","operationId":"scenario_d_ask_api_rag_scenario_d_ask_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/KeywordRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RAGResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/rag/review-file":{"post":{"tags":["Review"],"summary":"Review File","description":"上传文件 → 双栏审查对比 → 新窗口显示\n\n支持格式: .txt / .docx / .pdf\n输出: 带颜色标注的 HTML（红色=违规, 黄色=需关注, 绿色=合规, 蓝色=法规引用）","operationId":"review_file_api_rag_review_file_post","parameters":[{"name":"kb_name","in":"query","required":false,"schema":{"type":"string","description":"知识库（legacy，由 org_types 替代）","default":"regs_govproc","title":"Kb Name"},"description":"知识库（legacy，由 org_types 替代）"},{"name":"org_types","in":"query","required":false,"schema":{"type":"array","items":{"type":"string"},"description":"适用单位类型","default":["govproc","bidding","cross"],"title":"Org Types"},"description":"适用单位类型"},{"name":"fast","in":"query","required":false,"schema":{"type":"boolean","default":false,"title":"Fast"}},{"name":"unit","in":"query","required":false,"schema":{"type":"string","description":"单位名称（如 天津市总医院）","default":"","title":"Unit"},"description":"单位名称（如 天津市总医院）"},{"name":"model","in":"query","required":false,"schema":{"type":"string","description":"Qwen35B-q4 或 Qwen9B","default":"Qwen35B-q4","title":"Model"},"description":"Qwen35B-q4 或 Qwen9B"}],"requestBody":{"content":{"multipart/form-data":{"schema":{"$ref":"#/components/schemas/Body_review_file_api_rag_review_file_post"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/rag/ingest":{"post":{"tags":["Ingestion"],"summary":"Ingest Text","description":"摄入法规文本","operationId":"ingest_text_api_rag_ingest_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/IngestRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/IngestResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/rag/units":{"get":{"tags":["Management"],"summary":"List Units","description":"列出 org_policies 下所有单位","operationId":"list_units_api_rag_units_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/api/rag/knowledge-bases":{"get":{"tags":["Management"],"summary":"List Knowledge Bases","description":"列出所有知识库及统计","operationId":"list_knowledge_bases_api_rag_knowledge_bases_get","parameters":[{"name":"format","in":"query","required":false,"schema":{"type":"string","description":"html 或 json","default":"html","title":"Format"},"description":"html 或 json"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/rag/knowledge-base/{kb_name}":{"delete":{"tags":["Management"],"summary":"Delete Knowledge Base","description":"删除知识库（含双集合）","operationId":"delete_knowledge_base_api_rag_knowledge_base__kb_name__delete","parameters":[{"name":"kb_name","in":"path","required":true,"schema":{"type":"string","title":"Kb Name"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/rag/units/ingest":{"post":{"tags":["Management"],"summary":"Ingest Unit","description":"摄入指定单位的内控制度","operationId":"ingest_unit_api_rag_units_ingest_post","parameters":[{"name":"unit_name","in":"query","required":true,"schema":{"type":"string","title":"Unit Name"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/rag/knowledge-base/{kb_name}/clear":{"delete":{"tags":["Management"],"summary":"Clear Knowledge Base","description":"清空知识库数据（保留集合结构）","operationId":"clear_knowledge_base_api_rag_knowledge_base__kb_name__clear_delete","parameters":[{"name":"kb_name","in":"path","required":true,"schema":{"type":"string","title":"Kb Name"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/rag/upload-ingest":{"post":{"tags":["Management"],"summary":"Upload Ingest","description":"上传单个法规文件（.txt/.md/.docx/.pdf）并立即摄入到指定子库","operationId":"upload_ingest_api_rag_upload_ingest_post","parameters":[{"name":"kb_name","in":"query","required":false,"schema":{"type":"string","default":"regs_govproc","title":"Kb Name"}}],"requestBody":{"required":true,"content":{"multipart/form-data":{"schema":{"$ref":"#/components/schemas/Body_upload_ingest_api_rag_upload_ingest_post"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/rag/source-files":{"get":{"tags":["Management"],"summary":"List Source Files","description":"列出法规源目录下所有文件及其分类","operationId":"list_source_files_api_rag_source_files_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/api/rag/source-files/{filename}":{"delete":{"tags":["Management"],"summary":"Delete Source File","description":"删除源文件：从磁盘移除 + 清理分类JSON + 清除各子库中的向量数据","operationId":"delete_source_file_api_rag_source_files__filename__delete","parameters":[{"name":"filename","in":"path","required":true,"schema":{"type":"string","title":"Filename"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/rag/reingest":{"post":{"tags":["Management"],"summary":"Reingest","description":"触发重新摄入 — 从 knowledge_bases/ 目录读取最新文件\n\n增量模式（full=false）：仅摄入有变更的文件，基于内容哈希检测。\n全量模式（full=true）：清空后全量重建。","operationId":"reingest_api_rag_reingest_post","parameters":[{"name":"kb_name","in":"query","required":false,"schema":{"type":"string","description":"知识库（空=全部）","default":"","title":"Kb Name"},"description":"知识库（空=全部）"},{"name":"full","in":"query","required":false,"schema":{"type":"boolean","description":"true=全量清空重建, false=增量","default":false,"title":"Full"},"description":"true=全量清空重建, false=增量"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/rag/wiki-upload":{"post":{"tags":["Management"],"summary":"Wiki Upload","description":"把一条知识条目（.md / .txt）写入该 wiki 库的源目录。\n\n知识条目层是**文件驱动**的治理面：内核在语料快照构建时直接读源目录的\nmarkdown 建图（见 toolkit.CorpusSnapshot._load_wiki），**不落 Chroma**。\n故这里只做「校验 kind → 落盘」，与法条/判例的 ingest 是两条独立路径；\n新条目即时进入治理体检（wiki-lint 现读磁盘），检索面在服务重启后纳入。","operationId":"wiki_upload_api_rag_wiki_upload_post","parameters":[{"name":"kb_name","in":"query","required":true,"schema":{"type":"string","description":"目标知识条目库（kind: wiki）","title":"Kb Name"},"description":"目标知识条目库（kind: wiki）"}],"requestBody":{"required":true,"content":{"multipart/form-data":{"schema":{"$ref":"#/components/schemas/Body_wiki_upload_api_rag_wiki_upload_post"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/rag/wiki-lint":{"get":{"tags":["Management"],"summary":"Wiki Lint","description":"知识条目层**治理体检**（确定性 Lint，不参与检索）。\n\n对本包声明的每个 `kind: wiki` KB 扫其 markdown 目录，返回\n断链 / 孤立条目 / 疑似重复 / 连通域 / 标签 五类发现。\n本包未声明任何 `kind: wiki` 的 KB ⇒ 返回空的 `kbs`。","operationId":"wiki_lint_api_rag_wiki_lint_get","parameters":[{"name":"dup_threshold","in":"query","required":false,"schema":{"type":"number","maximum":1.0,"minimum":0.0,"description":"疑似重复的 suggest_links 阈值","default":0.5,"title":"Dup Threshold"},"description":"疑似重复的 suggest_links 阈值"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/rag/tools":{"get":{"tags":["Tools"],"summary":"List Tools","description":"工具层**契约** —— 轮子对外暴露的 5 个只读工具声明（干净语义 + 稳定 schema）。\n\n按「agent 工具」标准（2026-10-04 战略定案）：供编排器/外部系统发现本轮的\n能力面。description 随领域包变（内核级行为模板 + 插值该包集合显示名），\n参数只含 schema 形状、不含行业词；一律 read_only（写权限封顶「先审后写」）。\n\n声明不变；只读工具台 UI（`GET /tools`）新增**只读专用**调用端点\n`POST /api/rag/tools/call`，供人试调上述工具 —— 它复用 `WheelTools.call`\n的写拒绝即封顶，仍**无写传输层**；真正的写路径执行仍走轮子内部的 ReAct\n循环（agent.py），只到「先审后写」。","operationId":"list_tools_api_rag_tools_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/api/rag/tools/call":{"post":{"tags":["Tools"],"summary":"Tools Call","description":"试调**只读**工具（只读工具台用）—— 转发到 `WheelTools.call` 的唯一执行口。\n\n只读边界由 `WheelTools.call` 钉死：未知工具 / 写类名（含 ingest/upload/\ndelete 词根）/ 缺必填参数一律 `ValueError` → 400。本端点**只**把只读结果\n投影回 HTTP，不新增任何写能力。","operationId":"tools_call_api_rag_tools_call_post","requestBody":{"content":{"application/json":{"schema":{"additionalProperties":true,"type":"object","title":"Payload"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/rag/check-updates":{"post":{"tags":["Management"],"summary":"Check Updates","description":"检查源文件变更（不执行摄入）","operationId":"check_updates_api_rag_check_updates_post","parameters":[{"name":"kb_name","in":"query","required":false,"schema":{"type":"string","description":"知识库（空=全部）","default":"","title":"Kb Name"},"description":"知识库（空=全部）"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/models":{"get":{"tags":["OpenAI Compatible"],"summary":"List Models","description":"列出可用的 RAG 增强模型（OpenAI 兼容格式）","operationId":"list_models_v1_models_get","parameters":[{"name":"format","in":"query","required":false,"schema":{"type":"string","description":"html 或 json","default":"json","title":"Format"},"description":"html 或 json"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/chat/completions":{"post":{"tags":["OpenAI Compatible"],"summary":"Chat Completions","description":"OpenAI 兼容 Chat Completions — 自动 RAG 增强\n\n默认是**单轮**：检索一次 top-k，把结果注入系统提示后生成。\n需要模型自主检索时，显式用 `rag-agent:<kb>` 模型名或 body `mode=\"agentic\"`\n—— 走与 `/api/rag/scenario-d/ask` 相同的 ReAct 工具循环。\n\n用法（curl）:\n  curl -X POST http://127.0.0.1:8000/v1/chat/completions \\\n    -H \"Content-Type: application/json\" \\\n    -d '{\"model\":\"rag:all\",\"messages\":[{\"role\":\"user\",\"content\":\"采购多少金额要招标？\"}]}'\n\n自主检索:\n  {\"model\":\"rag-agent:all\",\"messages\":[...]}   或\n  {\"model\":\"rag:all\",\"mode\":\"agentic\",\"messages\":[...]}\n\nOpen WebUI 配置:\n  Provider: OpenAI\n  API Base: http://127.0.0.1:8000/v1\n  API Key: 登录后获取的 token（/api/auth/login 返回）\n  模型: rag:all, rag-agent:all, rag:<子库名> 等（实际列表见 /v1/models）","operationId":"chat_completions_v1_chat_completions_post","requestBody":{"content":{"application/json":{"schema":{"additionalProperties":true,"type":"object","title":"Request"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}}},"components":{"schemas":{"Body_review_file_api_rag_review_file_post":{"properties":{"file":{"type":"string","contentMediaType":"application/octet-stream","title":"File"}},"type":"object","title":"Body_review_file_api_rag_review_file_post"},"Body_upload_ingest_api_rag_upload_ingest_post":{"properties":{"file":{"type":"string","contentMediaType":"application/octet-stream","title":"File"}},"type":"object","required":["file"],"title":"Body_upload_ingest_api_rag_upload_ingest_post"},"Body_wiki_upload_api_rag_wiki_upload_post":{"properties":{"file":{"type":"string","contentMediaType":"application/octet-stream","title":"File"}},"type":"object","required":["file"],"title":"Body_wiki_upload_api_rag_wiki_upload_post"},"HTTPValidationError":{"properties":{"detail":{"items":{"$ref":"#/components/schemas/ValidationError"},"type":"array","title":"Detail"}},"type":"object","title":"HTTPValidationError"},"IngestRequest":{"properties":{"text":{"type":"string","minLength":1,"title":"Text","description":"法规文本"},"kb_name":{"type":"string","title":"Kb Name","description":"目标知识库","default":"regs_govproc"},"source_tag":{"type":"string","title":"Source Tag","description":"来源标记","default":""}},"type":"object","required":["text"],"title":"IngestRequest"},"IngestResponse":{"properties":{"kb":{"type":"string","title":"Kb","default":""},"chunks":{"type":"integer","title":"Chunks","default":0},"rules":{"type":"integer","title":"Rules","default":0},"semantic_count":{"type":"integer","title":"Semantic Count","default":0},"rules_count":{"type":"integer","title":"Rules Count","default":0},"elapsed":{"type":"number","title":"Elapsed","default":0.0}},"type":"object","title":"IngestResponse"},"KeywordRequest":{"properties":{"keyword":{"type":"string","minLength":1,"title":"Keyword","description":"查询关键词"},"kb_name":{"type":"string","title":"Kb Name","description":"知识库标识","default":"regs_govproc"},"fast":{"type":"boolean","title":"Fast","description":"快速模式（单轮，256 tokens）；未显式指定 mode 时生效","default":false},"model":{"type":"string","title":"Model","description":"LLM 模型: Qwen35B-q4 / Qwen9B","default":"Qwen35B-q4"},"mode":{"type":"string","title":"Mode","description":"检索模式: agentic (D″，模型自决检索) / fast (单轮 top-k)；留空时 fast=true → fast，否则 agentic","default":""},"debug":{"type":"boolean","title":"Debug","description":"返回 agentic 轨迹（轮数/工具调用/墙钟/错误）","default":false}},"type":"object","required":["keyword"],"title":"KeywordRequest"},"LoginRequest":{"properties":{"username":{"type":"string","minLength":1,"title":"Username","description":"用户名"},"password":{"type":"string","minLength":1,"title":"Password","description":"密码"}},"type":"object","required":["username","password"],"title":"LoginRequest"},"RAGResponse":{"properties":{"answer":{"type":"string","title":"Answer","default":""},"scenario":{"type":"string","title":"Scenario","default":""},"kb_name":{"type":"string","title":"Kb Name","default":""},"chunks_used":{"type":"integer","title":"Chunks Used","default":0},"elapsed":{"type":"number","title":"Elapsed","default":0.0},"tokens":{"additionalProperties":true,"type":"object","title":"Tokens"},"chunks":{"items":{},"type":"array","title":"Chunks"},"cases_found":{"type":"integer","title":"Cases Found","default":0},"cases":{"items":{},"type":"array","title":"Cases"},"mode":{"type":"string","title":"Mode","default":""},"sources":{"items":{},"type":"array","title":"Sources"},"errors":{"items":{},"type":"array","title":"Errors"},"evidence_missing":{"type":"boolean","title":"Evidence Missing","default":false},"grounding":{"additionalProperties":true,"type":"object","title":"Grounding"},"trace":{"additionalProperties":true,"type":"object","title":"Trace"}},"type":"object","title":"RAGResponse"},"TextRequest":{"properties":{"text":{"type":"string","minLength":1,"title":"Text","description":"文本内容"},"kb_name":{"type":"string","title":"Kb Name","description":"知识库标识","default":"regs_govproc"},"fast":{"type":"boolean","title":"Fast","description":"快速模式 (256 tokens)","default":false},"model":{"type":"string","title":"Model","description":"LLM 模型: Qwen35B-q4 / Qwen9B","default":"Qwen35B-q4"}},"type":"object","required":["text"],"title":"TextRequest"},"ValidationError":{"properties":{"loc":{"items":{"anyOf":[{"type":"string"},{"type":"integer"}]},"type":"array","title":"Location"},"msg":{"type":"string","title":"Message"},"type":{"type":"string","title":"Error Type"},"input":{"title":"Input"},"ctx":{"type":"object","title":"Context"}},"type":"object","required":["loc","msg","type"],"title":"ValidationError"}}}}