feat: implement RAG Service MVP with PARSER + Memory integration
RAG Service Implementation: - Create rag-service/ with full structure (config, document_store, embedding, pipelines) - Document Store: PostgreSQL + pgvector via Haystack - Embedding: BAAI/bge-m3 (multilingual, 1024 dim) - Ingest Pipeline: Convert ParsedDocument to Haystack Documents, embed, index - Query Pipeline: Retrieve documents, generate answers via DAGI Router - FastAPI endpoints: /ingest, /query, /health Tests: - Unit tests for ingest and query pipelines - E2E test with example parsed JSON - Test fixtures with real PARSER output example Router Integration: - Add mode='rag_query' routing rule in router-config.yml - Priority 7, uses local_qwen3_8b for RAG queries Docker: - Add rag-service to docker-compose.yml - Configure dependencies (router, city-db) - Add model cache volume Documentation: - Complete README with API examples - Integration guides for PARSER and Router
This commit is contained in:
47
services/rag-service/app/models.py
Normal file
47
services/rag-service/app/models.py
Normal file
@@ -0,0 +1,47 @@
|
||||
"""
|
||||
Pydantic models for RAG Service API
|
||||
"""
|
||||
|
||||
from typing import Optional, List, Dict, Any
|
||||
from pydantic import BaseModel, Field
|
||||
|
||||
|
||||
class IngestRequest(BaseModel):
|
||||
"""Request for document ingestion"""
|
||||
dao_id: str = Field(..., description="DAO identifier")
|
||||
doc_id: str = Field(..., description="Document identifier")
|
||||
parsed_json: Dict[str, Any] = Field(..., description="ParsedDocument JSON from PARSER service")
|
||||
user_id: Optional[str] = Field(None, description="User identifier")
|
||||
|
||||
|
||||
class IngestResponse(BaseModel):
|
||||
"""Response from document ingestion"""
|
||||
status: str = Field(..., description="Status: success or error")
|
||||
doc_count: int = Field(..., description="Number of documents ingested")
|
||||
dao_id: str = Field(..., description="DAO identifier")
|
||||
doc_id: str = Field(..., description="Document identifier")
|
||||
message: Optional[str] = Field(None, description="Error message if status=error")
|
||||
|
||||
|
||||
class QueryRequest(BaseModel):
|
||||
"""Request for RAG query"""
|
||||
dao_id: str = Field(..., description="DAO identifier")
|
||||
question: str = Field(..., description="User question")
|
||||
top_k: Optional[int] = Field(None, description="Number of documents to retrieve")
|
||||
user_id: Optional[str] = Field(None, description="User identifier")
|
||||
|
||||
|
||||
class Citation(BaseModel):
|
||||
"""Citation from retrieved document"""
|
||||
doc_id: str = Field(..., description="Document identifier")
|
||||
page: int = Field(..., description="Page number")
|
||||
section: Optional[str] = Field(None, description="Section name")
|
||||
excerpt: str = Field(..., description="Document excerpt")
|
||||
|
||||
|
||||
class QueryResponse(BaseModel):
|
||||
"""Response from RAG query"""
|
||||
answer: str = Field(..., description="Generated answer")
|
||||
citations: List[Citation] = Field(..., description="List of citations")
|
||||
documents: List[Dict[str, Any]] = Field(..., description="Retrieved documents (for debugging)")
|
||||
|
||||
Reference in New Issue
Block a user