Skip to content
GitLab
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in
Toggle navigation
Menu
Open sidebar
math_tutor_dev
public_math_tutor
Commits
e7f264b2
Commit
e7f264b2
authored
Feb 10, 2026
by
Kantz
Browse files
anpassung der History Übergabe.
parent
fc285ec3
Changes
4
Hide whitespace changes
Inline
Side-by-side
math-tutor/backend/app/LLM_services/decision_LLM.py
View file @
e7f264b2
...
@@ -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
(
f
"
{
context_sheet
}
\n\n
"
{
"Historie:
\n
"
"role"
:
"user"
,
f
"
{
history
}
\n\n
"
"content"
:
"Kontextblatt:
\n
"
"Treffe eine Entscheidung."
f
"
{
context_sheet
}
\n\n
"
"Beachte die folgende Historie."
,
}
)
)
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"
:
Tru
e
,
"reason"
:
str
(
result
)}
return
{
"needs_more_context"
:
Fals
e
,
"reason"
:
"needs_more_context wurde nicht gesetzt"
+
str
(
result
)}
return
{
"needs_more_context"
:
Tru
e
,
"reason"
:
llm_client
.
get_message_content
(
resp
)
or
"No tool_call returned"
}
return
{
"needs_more_context"
:
Fals
e
,
"reason"
:
"No tool_call returned"
+
str
(
resp
)
}
math-tutor/backend/app/LLM_services/hint_LLM.py
View file @
e7f264b2
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
=
"
\n
Historie:
\n
"
+
history
+
"
\n
"
+
prompt
if
sources
:
if
sources
:
prompt
=
"
\n
Kontext:
\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
+=
"
\n
Gebe 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\n
Gib 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
math-tutor/backend/app/deterministic_services/context_store.py
View file @
e7f264b2
...
@@ -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
)
...
...
math-tutor/backend/app/deterministic_services/orchestrators/orchestrator_tutor.py
View file @
e7f264b2
...
@@ -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_t
ext
=
context_store
.
format_
history
(
messages
)
history_t
urns
=
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_t
ext
,
sheet_text
)
decision
=
decision_LLM
.
needs_more_context
(
history_t
urns
,
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
)
...
...
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment