feat: dedicated consult prompt and enriched document content extraction

- Add CONSULT_SYSTEM_PROMPT (concise data viewer, not compliance assistant)
- Add _enrich_doc_content to extract text from metadata.text when TEXT column is short
- Enriches context with recommendation number, chapter, tenancy, section
- Improves RAG context quality for all vector search flows
This commit is contained in:
nogueiraguh
2026-03-11 10:31:24 -03:00
parent 0e8e082b1a
commit ab38e93516

View File

@@ -2120,6 +2120,16 @@ RAG_DEFAULT_SYSTEM_PROMPT = """Você é um assistente RAG especializado em Oracl
- CIS_REPORT: <metadata essenciais>
- CIS_RECOMMENDATIONS: <metadata essenciais> (se usado)"""
CONSULT_SYSTEM_PROMPT = """Você é um consultor de dados vetorizados. Sua função é responder perguntas com base nos documentos recuperados do banco vetorial.
### Regras
- Responda **somente** com informações presentes nos documentos fornecidos.
- Se não encontrar informação relevante, diga claramente.
- Seja direto e objetivo. Apresente os dados de forma organizada.
- Use markdown para formatação (negrito, listas, tabelas quando apropriado).
- Cite de qual tabela/fonte veio cada informação.
- Não invente dados que não estejam nos documentos."""
TF_DEFAULT_SYSTEM_PROMPT = """Você gera somente Terraform HCL para Oracle Cloud Infrastructure (OCI) usando o provider oracle/oci.
Se pedirem AWS, Azure, GCP ou outro provider, recuse educadamente.
@@ -2518,6 +2528,37 @@ def _vector_search(cfg: dict, query_embedding: list, top_k: int = 5, table_name:
finally:
conn.close()
def _enrich_doc_content(doc: dict) -> str:
"""Extract the best text content from a document, checking metadata.text as fallback."""
content = doc.get("content", "")
meta = doc.get("metadata", "")
if isinstance(meta, str) and meta:
try:
meta = json.loads(meta)
except Exception:
meta = {}
if isinstance(meta, dict):
# If TEXT column is short/empty, use metadata.text instead
meta_text = meta.get("text", "")
if meta_text and len(meta_text) > len(content):
header_parts = []
if meta.get("recommendationNumber"):
header_parts.append(f"Recommendation: {meta['recommendationNumber']}")
if meta.get("chapter"):
header_parts.append(f"Chapter: {meta['chapter']}")
if meta.get("header"):
header_parts.append(meta["header"])
header = " | ".join(header_parts)
content = (header + "\n" + meta_text) if header else meta_text
# Also enrich with section/tenancy info if available
elif meta.get("section") or meta.get("tenancy"):
extra = []
if meta.get("tenancy"): extra.append(f"Tenancy: {meta['tenancy']}")
if meta.get("section"): extra.append(f"Section: {meta['section']}")
if extra:
content = " | ".join(extra) + "\n" + content
return content
def _build_rag_context(documents: list) -> str:
"""Format retrieved documents into a context string for the LLM prompt."""
if not documents:
@@ -2525,7 +2566,7 @@ def _build_rag_context(documents: list) -> str:
parts = []
for i, doc in enumerate(documents, 1):
source = doc.get("source", "unknown")
content = doc.get("content", "")
content = _enrich_doc_content(doc)
if len(content) > 2000:
content = content[:2000] + "..."
parts.append(f"[Document {i} | Source: {source}]\n{content}")
@@ -3428,7 +3469,7 @@ async def consult_embeddings(req: ConsultQuery, u=Depends(current_user)):
parts.append(f"**Documento {i}** — `{d.get('source', '?')}` (distância: {d.get('distance', 0):.4f})\n\n{content}")
return {"answer": "\n\n---\n\n".join(parts), "documents": doc_list, "total": len(all_docs)}
try:
gc["system_prompt"] = RAG_DEFAULT_SYSTEM_PROMPT
gc["system_prompt"] = CONSULT_SYSTEM_PROMPT
answer, _, _ = _call_genai(gc, augmented)
except Exception as e:
log.error(f"Consult GenAI error: {e}")