| name | llm-arena-backend |
| description | FastAPI Python backend for LLM Arena game server. Use when working on API endpoints, LLM provider integration via LiteLLM, game move processing, prompt engineering for AI players, error handling, or backend testing. |
| compatibility | Python 3.10+, FastAPI, LiteLLM, network access required for LLM API calls |
| metadata | {"tags":"fastapi, python, llm, api"} |
LLM Arena Backend Skill
When to Use This Skill
Use this skill when:
- Creating or modifying API endpoints
- Integrating new LLM providers
- Engineering prompts for game AI
- Handling LLM response parsing
- Debugging API errors
- Writing backend tests
- Configuring CORS or middleware
Directory Structure
backend/
├── SKILL.md # This file
├── main.py # FastAPI application with all endpoints
├── requirements.txt # Python dependencies
└── test_game.py # Test scenarios for game logic
MCP Server Integration
Sequential Thinking MCP
Use for complex backend reasoning tasks:
Prompt Engineering:
Think step-by-step about creating an optimal game prompt:
Step 1: What game state information does the LLM need?
Step 2: How should winning/blocking moves be prioritized?
Step 3: What output format ensures valid, parseable moves?
Step 4: How to handle edge cases (full board, no valid moves)?
Step 5: What examples help the LLM understand the task?
Debugging API Errors:
Analyze this 500 error step-by-step:
Step 1: What endpoint was called and with what data?
Step 2: At what point in the code did execution fail?
Step 3: What external dependencies were involved?
Step 4: What are the possible root causes?
Step 5: How to fix and prevent recurrence?
Qdrant MCP Server
Store and retrieve backend-specific knowledge:
Storage Keys:
llm-arena:backend:progress:{timestamp} # Progress snapshots
- After the completion of every task store the progress in Qdrant vector store using qdrant-store
- Save the progress in the format progress.md
- The file needs to include: TODO TASK, IN PROGRESS TASK, COMPLETED TASK
Context7 MCP
Pull live documentation for:
- FastAPI: Middleware, dependencies, request/response models
- LiteLLM: Provider configuration, model names, error handling
- Pydantic: Model validation, field constraints, serialization
- Python: Async patterns, exception handling, JSON parsing
Example:
Context7: Get latest FastAPI CORS middleware configuration
Context7: Get LiteLLM Gemini provider model naming conventions
Context7: Get Pydantic v2 validator syntax
API Reference
POST /api/move
Process a game move request from an LLM player.
Request Schema:
class MoveRequest(BaseModel):
player_config: PlayerConfig
game_type: str
board_state: List[Optional[str]]
valid_moves: List[int]
role: str
class PlayerConfig(BaseModel):
provider: str
model: str
api_key: str
Response Schema:
class MoveResponse(BaseModel):
move: int
reasoning: str
Common Pitfalls
1. JSON Parsing Failures
Problem: LLM returns markdown-wrapped JSON or malformed response
Symptoms: json.JSONDecodeError, 500 errors
Solution:
content = response.choices[0].message.content
content = content.strip()
if content.startswith("```json"):
content = content[7:]
elif content.startswith("```"):
content = content[3:]
if content.endswith("```"):
content = content[:-3]
content = content.strip()
try:
result = json.loads(content)
except json.JSONDecodeError as e:
print(f"Failed to parse: {content[:200]}")
raise HTTPException(status_code=500, detail=f"Invalid JSON from LLM: {str(e)}")
2. Invalid Move Selection
Problem: LLM hallucinates a move outside valid_moves
Symptoms: Game crashes or invalid state
Solution:
move = result.get("move")
if move is None:
raise HTTPException(status_code=500, detail="LLM response missing 'move' field")
try:
move = int(move)
except (ValueError, TypeError):
raise HTTPException(status_code=500, detail=f"Invalid move type: {type(move)}")
if move not in request.valid_moves:
raise HTTPException(
status_code=500,
detail=f"LLM selected invalid move {move}. Valid: {request.valid_moves}"
)
3. Provider Model Name Mismatch
Problem: LiteLLM doesn't recognize the model
Symptoms: 404 errors, "Model not found"
Solution:
model_name = request.player_config.model
if request.player_config.provider == "gemini":
if not model_name.startswith("gemini/"):
model_name = f"gemini/{model_name}"