M5: implement RAGcore knowledge integration
KnowledgeProvider protocol with a deterministic TF-IDF-weighted extractive demo provider (never generative, always cites real excerpts) and a RAGcore HTTP adapter that degrades cleanly to unavailable. Knowledge nav + chat-style Q&A UI with source cards and honest grounded/insufficient/unavailable states. 57 backend tests passing, ruff clean. Fixed a real relevance bug (generic terms like "vehicle" crowding out distinctive matches) via IDF weighting, found by testing the actual S6 scenario. Verified end-to-end in the browser: grounded damage question cites both expected procedures; unrelated question honestly returns insufficient evidence with no fabrication.
This commit is contained in:
@@ -0,0 +1,56 @@
|
||||
from __future__ import annotations
|
||||
|
||||
from functools import lru_cache
|
||||
from typing import Literal, Protocol
|
||||
|
||||
from pydantic import BaseModel
|
||||
|
||||
from app.core.config import get_settings
|
||||
|
||||
EvidenceState = Literal["grounded", "insufficient", "unavailable"]
|
||||
|
||||
|
||||
class SourceCard(BaseModel):
|
||||
document_id: str
|
||||
title: str
|
||||
version: str
|
||||
section: str
|
||||
excerpt: str
|
||||
|
||||
|
||||
class GroundedAnswer(BaseModel):
|
||||
answer: str
|
||||
evidence_state: EvidenceState
|
||||
sources: list[SourceCard]
|
||||
provider: str
|
||||
correlation_id: str
|
||||
|
||||
|
||||
class KnowledgeHealth(BaseModel):
|
||||
provider: str
|
||||
available: bool
|
||||
detail: str
|
||||
tenant: str
|
||||
workspace: str
|
||||
collection: str
|
||||
document_count: int
|
||||
|
||||
|
||||
class KnowledgeProvider(Protocol):
|
||||
name: str
|
||||
|
||||
def health(self) -> KnowledgeHealth: ...
|
||||
|
||||
def ask(self, question: str, correlation_id: str) -> GroundedAnswer: ...
|
||||
|
||||
|
||||
@lru_cache
|
||||
def get_knowledge_provider() -> KnowledgeProvider:
|
||||
settings = get_settings()
|
||||
if settings.knowledge_provider == "ragcore":
|
||||
from app.services.knowledge.ragcore import RAGcoreKnowledgeProvider
|
||||
|
||||
return RAGcoreKnowledgeProvider()
|
||||
from app.services.knowledge.demo import DemoKnowledgeProvider
|
||||
|
||||
return DemoKnowledgeProvider()
|
||||
Reference in New Issue
Block a user