Commit e7f264b2 authored by Kantz's avatar Kantz
Browse files

anpassung der History Übergabe.

parent fc285ec3
...@@ -27,19 +27,19 @@ WICHTIG: ...@@ -27,19 +27,19 @@ WICHTIG:
- Löse nicht die Aufgabe, sondern bewerte nur die Situation bzgl. der nächsten didaktischen Schritte. - Löse nicht die Aufgabe, sondern bewerte nur die Situation bzgl. der nächsten didaktischen Schritte.
""" """
def needs_more_context(history: str, context_sheet: str, model: str = "ministral-3") -> dict: def needs_more_context(history: list[dict], context_sheet: str, model: str = "ministral-3") -> dict:
user_prompt = ( messages = [{"role": "system", "content": CLASSIFIER_SYSTEM}]
"Kontextblatt:\n" messages.append(
{
"role": "user",
"content": "Kontextblatt:\n"
f"{context_sheet}\n\n" f"{context_sheet}\n\n"
"Historie:\n" "Beachte die folgende Historie.",
f"{history}\n\n" }
"Treffe eine Entscheidung."
) )
if history:
messages = [ messages.extend(history)
{"role": "system", "content": CLASSIFIER_SYSTEM}, messages.append({"role": "user", "content": "Treffe eine Entscheidung."})
{"role": "user", "content": user_prompt},
]
resp, tool_outputs = llm_client.chat_with_tools( resp, tool_outputs = llm_client.chat_with_tools(
messages=messages, messages=messages,
...@@ -52,6 +52,6 @@ def needs_more_context(history: str, context_sheet: str, model: str = "ministral ...@@ -52,6 +52,6 @@ def needs_more_context(history: str, context_sheet: str, model: str = "ministral
result = tool_outputs[0].get("result") result = tool_outputs[0].get("result")
if isinstance(result, dict) and "needs_more_context" in result: if isinstance(result, dict) and "needs_more_context" in result:
return result return result
return {"needs_more_context": True, "reason": str(result)} return {"needs_more_context": False, "reason": "needs_more_context wurde nicht gesetzt"+str(result)}
return {"needs_more_context": True, "reason": llm_client.get_message_content(resp) or "No tool_call returned"} return {"needs_more_context": False, "reason": "No tool_call returned"+str(resp)}
from app.deterministic_services import llm_client from app.deterministic_services import llm_client
def generate_hint( def generate_hint(
query: str, query: str,
task: str, task: str,
LLM_solution: str, LLM_solution: str,
math_solution: str | None = None, math_solution: str | None = None,
history: str | None = None, history: list[dict] | None = None,
sources: str | None = None, sources: str | None = None,
) -> str: ) -> str:
system_prompt = ( system_prompt = (
"Du bist ein didaktischer Tutor. " "Du bist ein didaktischer Mathe-Tutor.\n"
"bestätige richtige Lösungen und Korrigiere Fehler. " "1) Antworte NUR mit einem kurzen Tipp (1-2 Sätze), keine Beispiele, keine Herleitung, keine komplette Lösung.\n"
"Gebe dem Nutzer einen hilfreichen Tipp um mathematische Aufgaben zu lösen." "2) Beziehe dich PRIMÄR auf die 'Aktuelle Frage'. Ignoriere ältere Nebenfragen, außer sie sind nötig.\n"
"Gebe keine Beispiele oder Erklärungen, sondern nur den Tipp." "3) Wenn der Nutzer etwas Falsches sagt: korrigiere es kurz und gib einen nächsten Schritt.\n"
"Gebe keine komplette Lösung der Aufgabe." "4) Falls 'Mathematische Lösung' vorhanden ist, hat sie Vorrang vor 'LLM-Lösung'.\n"
"Die Mathematische Lösung hat immer Vorrang vor der LLM Lösung."
"Halte dich kurz und prägnant."
)
prompt = (
"Aufgabe:\n"
+ task
+ "\n\n"
"Loesung (von einem LLM):\n"
+ LLM_solution
+ "\n"
) )
context_parts = [
f"Aufgabe:\n{task}",
f"LLM-Lösung:\n{LLM_solution}",
]
if math_solution: if math_solution:
prompt += "Mathematische Loesung:\n" + math_solution + "\n" context_parts.append(f"Mathematische Lösung (maßgeblich):\n{math_solution}")
if history:
prompt = "\nHistorie:\n" + history + "\n" + prompt
if sources: if sources:
prompt = "\nKontext:\n" + sources + "\n" + prompt context_parts.append(f"Kontext/Sources:\n{sources}")
if query:
prompt += "\n Aktuelle Frage:" + query messages = [{"role": "system", "content": system_prompt}]
prompt += "\nGebe einen hilfreichen Tipp zum nächsten Schritt der Aufgabe der mir bei meiner aktuellen Frage hilft. Halte dich kurz und prägnant."
result = llm_client.chat( # Kompakter Kontext als eine Nachricht (kein langer Fließtext mit History mischen)
messages=[{"role": "system", "content": system_prompt}, {"role": "user", "content": prompt}], messages.append({"role": "user", "content": "\n\n".join(context_parts)})
)
# History als echte Turns (und ggf. begrenzen, siehe Punkt 2)
if history:
messages.extend(history)
# Aktuelle Frage als letzte Nachricht, fett hervorgehoben durch Struktur/Delimiters
messages.append({
"role": "user",
"content": f"AKTUELLE FRAGE (höchste Priorität):\n{query}\n\nGib einen kurzen Tipp zum nächsten Schritt, der genau diese Frage adressiert."
})
result = llm_client.chat(messages=messages)
return llm_client.get_message_content(result) return llm_client.get_message_content(result)
\ No newline at end of file
...@@ -37,6 +37,14 @@ def format_history(messages: list[dict]) -> str: ...@@ -37,6 +37,14 @@ def format_history(messages: list[dict]) -> str:
lines.append(f"{role}: {content}") lines.append(f"{role}: {content}")
return "\n".join(lines) return "\n".join(lines)
def history_turns(messages: list[dict]) -> list[dict]:
turns: list[dict] = []
for msg in messages:
role = msg.get("role")
content = msg.get("content", "")
if role and content:
turns.append({"role": role, "content": content})
return turns
def init_sheet(chat_id: str, messages: list[dict]) -> dict[str, Any]: def init_sheet(chat_id: str, messages: list[dict]) -> dict[str, Any]:
timestamp = _utc_now() timestamp = _utc_now()
...@@ -145,6 +153,9 @@ def get_task(sheet: dict[str, Any]) -> str: ...@@ -145,6 +153,9 @@ def get_task(sheet: dict[str, Any]) -> str:
def get_history(sheet: dict[str, Any]) -> str: def get_history(sheet: dict[str, Any]) -> str:
return format_history(sheet.get("history", [])) return format_history(sheet.get("history", []))
def get_history_turns(sheet: dict[str, Any]) -> list[dict]:
return history_turns(sheet.get("history", []))
def first_math_solution(sheet: dict[str, Any]) -> str: def first_math_solution(sheet: dict[str, Any]) -> str:
if not sheet["math_solutions"]: if not sheet["math_solutions"]:
return "" return ""
...@@ -205,14 +216,10 @@ def save_sheet(sheet: dict[str, Any]) -> None: ...@@ -205,14 +216,10 @@ def save_sheet(sheet: dict[str, Any]) -> None:
os.makedirs(_LOG_DIR, exist_ok=True) os.makedirs(_LOG_DIR, exist_ok=True)
sheet["updated_at"] = _utc_now() sheet["updated_at"] = _utc_now()
timestamp = datetime.utcnow().strftime("%Y%m%d_%H%M%S")
chat_id = sheet.get("chat_id", "unknown") chat_id = sheet.get("chat_id", "unknown")
snapshot_path = os.path.join(_LOG_DIR, f"{chat_id}_{timestamp}.json")
latest_path = os.path.join(_LOG_DIR, f"{chat_id}_latest.json") latest_path = os.path.join(_LOG_DIR, f"{chat_id}_latest.json")
payload = json.dumps(sheet, ensure_ascii=True, indent=2) payload = json.dumps(sheet, ensure_ascii=True, indent=2)
with open(snapshot_path, "w", encoding="utf-8") as f:
f.write(payload)
with open(latest_path, "w", encoding="utf-8") as f: with open(latest_path, "w", encoding="utf-8") as f:
f.write(payload) f.write(payload)
......
...@@ -64,14 +64,14 @@ def run_chat(messages: list[dict], draft: str | None = None) -> dict: ...@@ -64,14 +64,14 @@ def run_chat(messages: list[dict], draft: str | None = None) -> dict:
_bootstrap_context(sheet, last_user, tool_log) _bootstrap_context(sheet, last_user, tool_log)
sheet["initialized"] = True sheet["initialized"] = True
history_text = context_store.format_history(messages) history_turns = context_store.history_turns(messages)
sheet_text = context_store.format_sheet(sheet) sheet_text = context_store.format_sheet(sheet)
if new_chat: if new_chat:
llm_solution = solver_LLM.solve_question(last_user, sheet_text) llm_solution = solver_LLM.solve_question(last_user, sheet_text)
_append_tool_log(tool_log, "LLM_Solution", {"question": last_user, "sheet": sheet_text}, llm_solution) _append_tool_log(tool_log, "LLM_Solution", {"question": last_user, "sheet": sheet_text}, llm_solution)
context_store.add_LLM_solution(sheet, llm_solution) context_store.add_LLM_solution(sheet, llm_solution)
else: else:
decision = decision_LLM.needs_more_context(history_text, sheet_text) decision = decision_LLM.needs_more_context(history_turns, sheet_text)
_append_tool_log(tool_log, "decision", {"sheet": sheet_text}, decision) _append_tool_log(tool_log, "decision", {"sheet": sheet_text}, decision)
context_store.add_decision(sheet, decision) context_store.add_decision(sheet, decision)
...@@ -86,7 +86,7 @@ def run_chat(messages: list[dict], draft: str | None = None) -> dict: ...@@ -86,7 +86,7 @@ def run_chat(messages: list[dict], draft: str | None = None) -> dict:
"task": context_store.get_task(sheet), "task": context_store.get_task(sheet),
"LLM_solution": context_store.last_LLM_solution(sheet), "LLM_solution": context_store.last_LLM_solution(sheet),
"math_solution": context_store.first_math_solution(sheet), "math_solution": context_store.first_math_solution(sheet),
"history": context_store.format_history(messages), "history": history_turns,
"sources": "\n".join([source.to_string() for source in context_store.get_retrieval(sheet)]), "sources": "\n".join([source.to_string() for source in context_store.get_retrieval(sheet)]),
} }
reply = hint_LLM.generate_hint(**hint_args) reply = hint_LLM.generate_hint(**hint_args)
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment