Feature Testanforderungen: LLM Integration
Version: 1.0 | Stand: 30. Dezember 2025
Übersicht
Dieses Dokument beschreibt alle Tests für die LLM-Integration in LLARS.
Komponenten: LiteLLM Proxy | Model Management | Streaming | Agent Modes
1. LLM Model Management
API: /api/llm/models
Tabelle: llm_models
Model Types
| Type |
Beschreibung |
Beispiele |
llm |
Chat/Completion Models |
GPT-4o, Claude-3, Mistral |
embedding |
Embedding Models |
VDR-2B, MiniLM |
reranker |
Reranking Models |
Cross-Encoder |
Model Tests
| ID |
Test |
Erwartung |
Art |
| LLM-M01 |
GET /api/llm/models |
Liste aller Models |
Integration |
| LLM-M02 |
Filter by type |
Nur type=llm |
Integration |
| LLM-M03 |
Default Model markiert |
is_default=true |
Integration |
| LLM-M04 |
Vision Support Flag |
supports_vision korrekt |
Integration |
| LLM-M05 |
Streaming Support |
supports_streaming korrekt |
Integration |
| LLM-M06 |
Function Calling |
supports_function_calling |
Integration |
| LLM-M07 |
Sync Models |
LiteLLM Sync |
Integration |
2. Chat Completion
API: /api/chatbots/:id/chat, Socket.IO chatbot:stream
Basic Chat
| ID |
Test |
Erwartung |
Art |
| LLM-C01 |
Simple Message |
Response erhalten |
Integration |
| LLM-C02 |
Streaming Response |
Token-by-Token |
Integration |
| LLM-C03 |
System Prompt |
Befolgt System Prompt |
Integration |
| LLM-C04 |
Temperature 0 |
Deterministische Antwort |
Integration |
| LLM-C05 |
Temperature 2 |
Kreative Antwort |
Integration |
| LLM-C06 |
Max Tokens Limit |
Antwort begrenzt |
Integration |
Conversation History
| ID |
Test |
Erwartung |
Art |
| LLM-H01 |
Context Preserved |
Referenz auf vorherige Msgs |
Integration |
| LLM-H02 |
Long Context |
>10 Messages |
Integration |
| LLM-H03 |
Context Window |
Truncation bei Limit |
Integration |
Error Handling
| ID |
Test |
Erwartung |
Art |
| LLM-E01 |
Model nicht verfügbar |
Fallback oder Error |
Integration |
| LLM-E02 |
Rate Limit |
Retry mit Backoff |
Integration |
| LLM-E03 |
Timeout |
Timeout-Error |
Integration |
| LLM-E04 |
Invalid Model ID |
404 Error |
Integration |
3. Vision Models
Capability: supports_vision=true
| ID |
Test |
Erwartung |
Art |
| LLM-V01 |
Image Upload |
Bild wird analysiert |
Integration |
| LLM-V02 |
Multiple Images |
Alle verarbeitet |
Integration |
| LLM-V03 |
Image + Text |
Kombinierte Query |
Integration |
| LLM-V04 |
Große Bilder |
Resize/Compression |
Integration |
| LLM-V05 |
Non-Vision Model + Image |
Error oder Ignoriert |
Integration |
4. Agent Modes
Modes: Basic, ACT, ReAct, ReflAct
Basic Mode
| ID |
Test |
Erwartung |
Art |
| LLM-AB01 |
Direct Response |
Keine Reasoning Steps |
Integration |
| LLM-AB02 |
Simple Query |
Schnelle Antwort |
Integration |
ACT Mode
| ID |
Test |
Erwartung |
Art |
| LLM-AA01 |
Action Selection |
Action Events |
Integration |
| LLM-AA02 |
Tool Use |
Tools korrekt aufgerufen |
Integration |
ReAct Mode
| ID |
Test |
Erwartung |
Art |
| LLM-AR01 |
Thought Events |
Reasoning sichtbar |
Integration |
| LLM-AR02 |
Action Events |
Actions nach Thoughts |
Integration |
| LLM-AR03 |
Observation Events |
Ergebnisse verarbeitet |
Integration |
| LLM-AR04 |
Loop Detection |
Max Iterations |
Integration |
ReflAct Mode
| ID |
Test |
Erwartung |
Art |
| LLM-AF01 |
Reflection Events |
Selbst-Reflexion |
Integration |
| LLM-AF02 |
Quality Check |
Antwort-Verbesserung |
Integration |
| LLM-AF03 |
Iteration Count |
Max Reflections |
Integration |
5. Prompt Engineering
API: /api/prompts
Prompt Management
| ID |
Test |
Erwartung |
Art |
| PRMT-01 |
Create Prompt |
Prompt erstellt |
Integration |
| PRMT-02 |
Update Prompt |
Prompt aktualisiert |
Integration |
| PRMT-03 |
Delete Prompt |
Prompt gelöscht |
Integration |
| PRMT-04 |
Share Prompt |
Mit User geteilt |
Integration |
| PRMT-05 |
Revoke Share |
Zugriff entfernt |
Integration |
Prompt Testing
| ID |
Test |
Erwartung |
Art |
| PRMT-T01 |
Test Prompt |
Response erhalten |
Integration |
| PRMT-T02 |
Test mit Model |
Spezifisches Model |
Integration |
| PRMT-T03 |
Test mit Params |
Temperature etc. |
Integration |
| PRMT-T04 |
JSON Mode |
JSON Response |
Integration |
| PRMT-T05 |
Schema Validation |
Valides Schema |
Integration |
Prompt History
| ID |
Test |
Erwartung |
Art |
| PRMT-H01 |
Version erstellt |
Bei Edit |
Integration |
| PRMT-H02 |
Version abrufen |
History laden |
Integration |
| PRMT-H03 |
Version restore |
Alte Version |
Integration |
6. LLM-as-Judge
API: /api/judge/sessions
Session Management
| ID |
Test |
Erwartung |
Art |
| JUDGE-S01 |
Create Session |
Session erstellt |
Integration |
| JUDGE-S02 |
Start Session |
Status: running |
Integration |
| JUDGE-S03 |
Pause Session |
Status: paused |
Integration |
| JUDGE-S04 |
Resume Session |
Fortgesetzt |
Integration |
| JUDGE-S05 |
Complete Session |
Status: completed |
Integration |
Comparison Execution
| ID |
Test |
Erwartung |
Art |
| JUDGE-C01 |
Pairwise Compare |
A vs B Bewertung |
Integration |
| JUDGE-C02 |
Pillar Evaluation |
Pro Pillar |
Integration |
| JUDGE-C03 |
Winner Selection |
winner: A/B/tie |
Integration |
| JUDGE-C04 |
Reasoning |
Begründung vorhanden |
Integration |
| JUDGE-C05 |
Progress Update |
Via WebSocket |
Integration |
Results
| ID |
Test |
Erwartung |
Art |
| JUDGE-R01 |
Get Results |
Evaluations zurück |
Integration |
| JUDGE-R02 |
Export Results |
CSV/JSON Export |
Integration |
| JUDGE-R03 |
Statistics |
Aggregierte Stats |
Integration |
7. Test-Code
# tests/integration/llm/test_chat.py
import pytest
class TestLLMChat:
"""LLM Chat Tests"""
def test_LLM_C01_simple_message(self, authenticated_client, test_chatbot):
"""Simple Message bekommt Response"""
response = authenticated_client.post(
f'/api/chatbots/{test_chatbot.id}/chat/test',
json={'message': 'Say hello'}
)
assert response.status_code == 200
assert 'response' in response.json
assert len(response.json['response']) > 0
def test_LLM_C02_streaming(self, socket_client, test_chatbot, auth_token):
"""Streaming Response funktioniert"""
socket_client.emit('chatbot:join', {'session_id': 'test'})
socket_client.emit('chatbot:stream', {
'chatbot_id': test_chatbot.id,
'message': 'Count to 5',
'session_id': 'test',
'token': auth_token
})
received = socket_client.get_received(timeout=30)
response_events = [r for r in received if r['name'] == 'chatbot:response']
complete_events = [r for r in received if r['name'] == 'chatbot:complete']
assert len(response_events) > 1 # Multiple chunks
assert len(complete_events) == 1
def test_LLM_C04_temperature_0(self, authenticated_client, test_chatbot):
"""Temperature 0 gibt deterministische Antworten"""
responses = []
for _ in range(3):
response = authenticated_client.post(
f'/api/chatbots/{test_chatbot.id}/chat/test',
json={'message': 'What is 2+2?', 'temperature': 0}
)
responses.append(response.json['response'])
# Bei Temperature 0 sollten Antworten ähnlich sein
assert responses[0] == responses[1] == responses[2]
class TestVisionModels:
"""Vision Model Tests"""
def test_LLM_V01_image_analysis(self, authenticated_client, vision_chatbot, test_image):
"""Vision Model analysiert Bild"""
with open(test_image, 'rb') as f:
response = authenticated_client.post(
f'/api/chatbots/{vision_chatbot.id}/chat/test',
data={
'message': 'What is in this image?',
'image': (f, 'test.png')
},
content_type='multipart/form-data'
)
assert response.status_code == 200
assert 'response' in response.json
class TestAgentModes:
"""Agent Mode Tests"""
def test_LLM_AR01_react_thoughts(self, socket_client, react_chatbot, auth_token):
"""ReAct Mode sendet Thought Events"""
socket_client.emit('chatbot:join', {'session_id': 'test'})
socket_client.emit('chatbot:stream', {
'chatbot_id': react_chatbot.id,
'message': 'Search for information about Python',
'session_id': 'test',
'token': auth_token
})
received = socket_client.get_received(timeout=60)
agent_events = [r for r in received if r['name'] == 'chatbot:agent_status']
# ReAct sollte Thought-Events senden
thought_events = [e for e in agent_events if 'thought' in str(e)]
assert len(thought_events) > 0
class TestPromptEngineering:
"""Prompt Engineering Tests"""
def test_PRMT_01_create_prompt(self, authenticated_client):
"""Prompt erstellen"""
response = authenticated_client.post('/api/prompts', json={
'name': 'Test Prompt',
'content': 'You are a helpful assistant'
})
assert response.status_code == 201
assert 'id' in response.json
def test_PRMT_T04_json_mode(self, authenticated_client):
"""JSON Mode gibt valides JSON"""
response = authenticated_client.post('/api/prompts/test', json={
'prompt': 'Return a JSON with name and age',
'model': 'gpt-4o-mini',
'json_mode': True
})
assert response.status_code == 200
# Response sollte JSON sein
import json
parsed = json.loads(response.json['response'])
assert isinstance(parsed, dict)
class TestJudge:
"""LLM-as-Judge Tests"""
def test_JUDGE_S01_create_session(self, authenticated_admin_client):
"""Judge Session erstellen"""
response = authenticated_admin_client.post('/api/judge/sessions', json={
'name': 'Test Session',
'pillars': [1, 2, 3]
})
assert response.status_code == 201
assert 'session_id' in response.json
def test_JUDGE_C01_pairwise_compare(self, socket_client, judge_session):
"""Pairwise Comparison läuft"""
socket_client.emit('judge:join_session', {'session_id': judge_session.id})
socket_client.emit('judge:get_status', {'session_id': judge_session.id})
received = socket_client.get_received(timeout=5)
status_events = [r for r in received if r['name'] == 'judge:status']
assert len(status_events) > 0
8. E2E Test-Code
// e2e/llm/llm-integration.spec.ts
import { test, expect } from '../fixtures/auth'
test.describe('LLM Integration', () => {
test('chat streaming works', async ({ authenticatedPage }) => {
await authenticatedPage.goto('/chat')
await authenticatedPage.click('.chatbot-item >> nth=0')
await authenticatedPage.fill('.message-input', 'Say hello in one word')
await authenticatedPage.click('button:has-text("Senden")')
// Streaming indicator should appear
await expect(authenticatedPage.locator('.streaming-indicator')).toBeVisible({
timeout: 5000
})
// Response should appear
await expect(authenticatedPage.locator('.message.bot')).toBeVisible({
timeout: 30000
})
})
test('prompt testing works', async ({ adminPage }) => {
await adminPage.goto('/admin?tab=prompts')
await adminPage.click('button:has-text("Test")')
await adminPage.fill('.prompt-input', 'Say hi')
await adminPage.click('button:has-text("Testen")')
await expect(adminPage.locator('.test-response')).toBeVisible({
timeout: 30000
})
})
})
9. Checkliste für manuelle Tests
Chat
Vision
Agent Modes
Prompt Engineering
LLM-as-Judge
10. Model-Verfügbarkeit
| Model |
Type |
Priorität |
Fallback |
| GPT-4o |
llm |
1 |
GPT-4o-mini |
| GPT-4o-mini |
llm |
2 |
- |
| Claude-3.5-Sonnet |
llm |
1 |
Claude-3-Haiku |
| VDR-2B (LiteLLM) |
embedding |
1 |
VDR-2B (Local) |
| VDR-2B (Local) |
embedding |
2 |
MiniLM |
| MiniLM |
embedding |
3 |
- |
Letzte Aktualisierung: 30. Dezember 2025