feat: 重构知识库系统,移除Hermes集成,增强RAG和同步功能

主要变更:
- 移除Hermes智能体及相关回调服务
- 新增知识库RAG、同步、调度、规范化和索引任务服务
- 重构orchestrator服务,增强运行时聊天功能
- 更新前端聊天、政策制度、设置等页面样式和逻辑
- 更新expense_claims和document_intelligence服务
- 删除llm_wiki相关服务和测试文件
- 更新docker-compose配置和启动脚本
This commit is contained in:
caoxiaozhu
2026-05-17 08:38:41 +00:00
parent 212c935308
commit 68f663f2f4
308 changed files with 83729 additions and 13588 deletions

View File

@@ -1,13 +1,10 @@
from __future__ import annotations
import json
from sqlalchemy import create_engine
from sqlalchemy.orm import sessionmaker
from sqlalchemy.pool import StaticPool
from app.services.document_intelligence import DocumentIntelligenceService, build_document_insight
from app.services.runtime_chat import RuntimeChatService
def test_build_document_insight_prefers_transport_for_didi_text_with_hotel_noise() -> None:
@@ -23,28 +20,7 @@ def test_build_document_insight_prefers_transport_for_didi_text_with_hotel_noise
assert any(field.label == "金额" and field.value == "48元" for field in insight.fields)
def test_document_intelligence_service_uses_vlm_result_when_preview_available(monkeypatch) -> None:
calls: list[tuple[str, ...]] = []
def fake_complete(self, messages, *, slot_priority=("main", "backup"), max_tokens=500, temperature=0.2):
calls.append(slot_priority)
if slot_priority == ("vlm",):
assert isinstance(messages[1]["content"], list)
return json.dumps(
{
"document_type": "taxi_receipt",
"scene_code": "transport",
"scene_label": "交通票据",
"expense_type": "transport",
"confidence": 0.91,
"evidence": ["图片主体为滴滴行程单OCR 中出现订单号、上车、下车等字段"],
},
ensure_ascii=False,
)
return None
monkeypatch.setattr(RuntimeChatService, "complete", fake_complete)
def test_document_intelligence_service_uses_rule_result_when_preview_available() -> None:
engine = create_engine(
"sqlite+pysqlite:///:memory:",
connect_args={"check_same_thread": False},
@@ -62,8 +38,7 @@ def test_document_intelligence_service_uses_vlm_result_when_preview_available(mo
session.close()
assert insight.document_type == "taxi_receipt"
assert insight.classification_source == "llm_vision"
assert calls[0] == ("vlm",)
assert insight.classification_source == "rule"
def test_document_intelligence_extracts_larger_decimal_amount_from_multiple_candidates() -> None:
@@ -76,28 +51,7 @@ def test_document_intelligence_extracts_larger_decimal_amount_from_multiple_cand
assert any(field.label == "金额" and field.value == "13.4元" for field in insight.fields)
def test_document_intelligence_service_uses_vlm_fields_to_correct_amount(monkeypatch) -> None:
def fake_complete(self, messages, *, slot_priority=("main", "backup"), max_tokens=500, temperature=0.2):
if slot_priority == ("vlm",):
return json.dumps(
{
"document_type": "taxi_receipt",
"scene_code": "transport",
"scene_label": "交通票据",
"expense_type": "transport",
"confidence": 0.89,
"evidence": ["图片主体为滴滴行程单,金额区域显示 13.4 元"],
"fields": [
{"key": "amount", "label": "金额", "value": "13.4"},
{"key": "merchant_name", "label": "商户", "value": "滴滴出行"},
],
},
ensure_ascii=False,
)
return None
monkeypatch.setattr(RuntimeChatService, "complete", fake_complete)
def test_document_intelligence_service_keeps_rule_fields_without_model_correction() -> None:
engine = create_engine(
"sqlite+pysqlite:///:memory:",
connect_args={"check_same_thread": False},
@@ -114,5 +68,5 @@ def test_document_intelligence_service_uses_vlm_fields_to_correct_amount(monkeyp
finally:
session.close()
assert any(field.label == "金额" and field.value == "13.4" for field in insight.fields)
assert any("大模型复核结果修正" in warning for warning in insight.warnings)
assert any(field.label == "金额" and field.value == "1元" for field in insight.fields)
assert insight.warnings == ()