π΄ RalfBot Code-Flow: Von der User-Eingabe zur Bot-Antwort
1
Frontend: User sendet Nachricht
π index.html - send() Funktion
const obj_response = await fetch(`${STR_SERVER_URL}/chat`, {
method: 'POST',
body: JSON.stringify({
str_prompt: str_text,
str_session_id: str_session_id
})
});
β HTTP POST zu localhost:8000/chat
2
Backend: FastAPI empfΓ€ngt Request
π server_fastAPI.py - chat_endpoint()
@app_endpoint.post("/chat")
async def chat_endpoint(request: ChatRequest):
str_session_id = request.str_session_id or str(uuid.uuid4())
bot = CONFIG.get_session(str_session_id)
return StreamingResponse(
bot.generiere_stream(request.str_prompt),
media_type="text/plain"
)
β Holt Bot-Instanz vom Singleton
3
Singleton: Session-Management
π singleton_llm.py - get_session()
def get_session(self, str_session_id: str):
if (str_session_id not in self.__sessions):
from ralf_bot import RalfBot
self.__sessions[str_session_id] = {
'bot': RalfBot(),
'last_seen': time.time()
}
return self.__sessions[str_session_id]['bot']
β Pro Session eigener Bot mit eigenem Conversation-History
4
RalfBot: Hauptlogik startet
π ralf_bot.py - generiere_stream()
def generiere_stream(self, str_prompt: str) -> Iterator[str]:
bln_needs_web = self.__pruefe_web_bedarf(str_prompt)
if (bln_needs_web):
yield from self.__generiere_antwort_mit_web(str_prompt)
else:
yield from self.__generiere_antwort_ohne_web(str_prompt)
β Entscheidung: Web-Suche oder direktes LLM?
5
Keyword-Erkennung
π ralf_bot.py - __pruefe_web_bedarf()
lst_web_keywords = ['neuigkeiten', 'wetter', 'datum', 'heute', ...]
return ((any((str_keyword in str_prompt.lower())
for str_keyword in lst_web_keywords)) or
(obj_regex.search(r'https?://|www\.', str_prompt) is not None))
β "Wetter in Wachtendonk" triggert Web-Pfad
6
Web-Tools: Externe Daten holen
π ralf_bot.py - __generiere_antwort_mit_web()
if ('wetter' in str_prompt_lower):
yield "π€οΈ Hole Wetterdaten...\n\n"
str_web_results = get_weather(str_location)
elif ('datum' in str_prompt_lower):
yield "π
Hole aktuelles Datum...\n\n"
str_web_results = get_current_datetime()
else:
yield "π Suche im Web...\n\n"
str_web_results = web_search_and_read(str_prompt)
β Externe APIs werden synchron aufgerufen
7
Prompt-Konstruktion mit Web-Daten
π ralf_bot.py
str_full_prompt = (
"<|system|>\n"
"Du bist Ralf. Antworte AUSSCHLIEαΊLICH auf DEUTSCH.\n"
"Web-Ergebnisse:\n\n"
f"{str_web_results}\n\n"
"<|user|>\n"
f"{str_prompt}\n"
"<|assistant|>\n"
)
β LLaMA3-Prompt mit Kontext
8
Thread-Safe Model-Zugriff
π ralf_bot.py - __generiere_model_response()
def __generiere_model_response(self, str_full_prompt: str) -> Iterator[str]:
with obj_LLM_SINGLETON.model_lock:
stream_response = obj_LLM_SINGLETON.model(
str_full_prompt,
max_tokens=512,
temperature=0.0,
top_p=0.9,
repeat_penalty=1.1
)
β Lock verhindert parallele Model-Zugriffe (Race Conditions)
9
LLM generiert Token-Stream
π singleton_llm.py - model Property
for str_chunk in stream_response:
str_token = str_chunk["choices"][0]["text"]
if ((len(str_token) > 0) and (not ("<|" in str_token))):
yield str_token
β Jedes Token wird sofort ausgegeben (Streaming)
10
FastAPI: StreamingResponse sendet Chunks
π server_fastAPI.py
return StreamingResponse(
bot.generiere_stream(request.str_prompt),
media_type="text/plain",
headers={"X-Session-ID": str_session_id}
)
β HTTP Chunked Transfer Encoding
11
Frontend: ReadableStream empfΓ€ngt Daten
π index.html
const obj_reader = obj_response.body.getReader();
const obj_decoder = new TextDecoder();
while (true) {
const obj_chunk = await obj_reader.read();
if (obj_chunk.done) break;
const str_decoded = obj_decoder.decode(obj_chunk.value);
obj_reply_div.textContent += str_decoded;
obj_chat.scrollTop = obj_chat.scrollHeight;
}
β
Token erscheinen in Echtzeit im Chat
π― Zusammenfassung des Code-Flows
Datenfluss:
User Input (JS)
β
FastAPI Endpoint
β
Singleton Session-Manager
β
RalfBot Keyword-Check
β
Web-Tools (API-Calls)
β
Prompt-Building
β
Thread-Lock + LLM-Inference
β
Token-Filtering
β
HTTP Streaming
β
DOM-Update (JS)
Key-Features:
- Session-Management: Jeder User eigene Bot-Instanz mit History
- Thread-Safety: Lock verhindert Crashes bei Multi-User
- Streaming: Token erscheinen sofort, kein Warten auf komplette Antwort
- Tool-Integration: Wetter, Datum, Web-Suche automatisch erkannt
- Halluzination-Prevention: temp=0.0, strikte Prompts, Kontext-Injection