fix(rag): force rag_search in code, do not rely on LLM tool-calling

The LLM ignores system injections when session history already
contains insurance answers. Now: when doc keywords detected, call
rag_search directly in Python, inject results as fake tool-call
into messages. LLM only needs to format the answer.
This commit is contained in:
Homelab Cursor 2026-03-26 16:48:21 +01:00
parent b9141b6b90
commit e5327cd65e

View file

@ -412,20 +412,39 @@ def ask_with_tools(question: str, tool_handlers: dict, session_id: str = None) -
messages.append({"role": "user", "content": question}) messages.append({"role": "user", "content": question})
# --- RAG-Pflicht: Wenn Dokument-Keywords erkannt, rag_search erzwingen --- # --- RAG-Pflicht: Bei Doc-Keywords rag_search DIREKT aufrufen (nicht LLM) ---
_DOC_KEYWORDS = [ _DOC_KW = [
"versicherung", "vertrag", "verträge", "dokument", "rente", "versicherung", "vertrag", "vertraege", "dokument", "rente",
"finanzamt", "steuer", "grundsteuer", "familienbuch", "urkunde", "finanzamt", "steuer", "grundsteuer", "familienbuch", "urkunde",
"bescheid", "police", "beitrag", "mietvertrag", "arbeitsvertrag", "bescheid", "police", "beitrag", "mietvertrag", "arbeitsvertrag",
"kindergeld", "rechnung", "haftpflicht", "rechtsschutz", "kindergeld", "rechnung", "haftpflicht", "rechtsschutz",
"lebensversicherung", "bauspar", "reisepass", "personalausweis", "lebensversicherung", "bauspar", "reisepass", "personalausweis",
"lvm", "allianz", "ergo", "huk", "nürnberger", "nuernberger", "lvm", "allianz", "ergo", "huk", "nuernberger",
] ]
if route == MODEL_LOCAL and any(k in question.lower() for k in _DOC_KEYWORDS): _q_low = question.lower()
messages.insert(-1, {"role": "system", "content": if route == MODEL_LOCAL and any(k in _q_low for k in _DOC_KW):
"PFLICHT: Diese Frage betrifft persoenliche Dokumente. " _rag_fn = tool_handlers.get("rag_search")
"Du MUSST rag_search aufrufen BEVOR du antwortest. " if _rag_fn:
"Antworte NIEMALS aus dem Gedaechtnis oder der Session-History ohne vorher gesucht zu haben."}) try:
log.info("RAG-Pflicht: forciere rag_search fuer: %s", question[:80])
_rag_res = _rag_fn(query=question, top_k=8)
if _rag_res and not _rag_res.startswith("Keine"):
_fake_tc = [{"id": "forced_rag", "type": "function",
"function": {"name": "rag_search",
"arguments": json.dumps({"query": question, "top_k": 8})}}]
messages.insert(-1, {"role": "assistant", "content": None,
"tool_calls": _fake_tc})
messages.insert(-1, {"role": "tool", "tool_call_id": "forced_rag",
"content": str(_rag_res)[:3000]})
_suffix = (
"\n\n[Oben siehst du die Ergebnisse der Dokumentensuche. "
"Beantworte die Frage NUR basierend auf diesen Ergebnissen. "
"Erfinde nichts dazu.]"
)
messages[-1] = {"role": "user", "content": question + _suffix}
log.info("RAG-Pflicht: %d Zeichen injiziert", len(str(_rag_res)))
except Exception as e:
log.warning("RAG-Pflicht Fehler: %s", e)
# --- Online (Sonar): kein Tool-Calling, Sonar sucht selbst --- # --- Online (Sonar): kein Tool-Calling, Sonar sucht selbst ---
if route == MODEL_ONLINE: if route == MODEL_ONLINE: