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:
@@ -2120,6 +2120,16 @@ RAG_DEFAULT_SYSTEM_PROMPT = """Você é um assistente RAG especializado em Oracl
|
|||||||
- CIS_REPORT: <metadata essenciais>
|
- CIS_REPORT: <metadata essenciais>
|
||||||
- CIS_RECOMMENDATIONS: <metadata essenciais> (se usado)"""
|
- 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.
|
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.
|
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:
|
finally:
|
||||||
conn.close()
|
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:
|
def _build_rag_context(documents: list) -> str:
|
||||||
"""Format retrieved documents into a context string for the LLM prompt."""
|
"""Format retrieved documents into a context string for the LLM prompt."""
|
||||||
if not documents:
|
if not documents:
|
||||||
@@ -2525,7 +2566,7 @@ def _build_rag_context(documents: list) -> str:
|
|||||||
parts = []
|
parts = []
|
||||||
for i, doc in enumerate(documents, 1):
|
for i, doc in enumerate(documents, 1):
|
||||||
source = doc.get("source", "unknown")
|
source = doc.get("source", "unknown")
|
||||||
content = doc.get("content", "")
|
content = _enrich_doc_content(doc)
|
||||||
if len(content) > 2000:
|
if len(content) > 2000:
|
||||||
content = content[:2000] + "..."
|
content = content[:2000] + "..."
|
||||||
parts.append(f"[Document {i} | Source: {source}]\n{content}")
|
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}")
|
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)}
|
return {"answer": "\n\n---\n\n".join(parts), "documents": doc_list, "total": len(all_docs)}
|
||||||
try:
|
try:
|
||||||
gc["system_prompt"] = RAG_DEFAULT_SYSTEM_PROMPT
|
gc["system_prompt"] = CONSULT_SYSTEM_PROMPT
|
||||||
answer, _, _ = _call_genai(gc, augmented)
|
answer, _, _ = _call_genai(gc, augmented)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
log.error(f"Consult GenAI error: {e}")
|
log.error(f"Consult GenAI error: {e}")
|
||||||
|
|||||||
Reference in New Issue
Block a user