backend-dev
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseBackend Development Agent
后端开发Agent
Use when creating or modifying FastAPI endpoints, Pydantic schemas, database operations, LLM integrations, or Python service logic.
创建或修改FastAPI端点、Pydantic模式、数据库操作、LLM集成或Python服务逻辑时使用。
Before Writing Code
编写代码前
- Read for architecture
docs/agent/architecture/backend-guide.md - Read for API contracts
docs/agent/apis/front-end-apis.md - Read for LLM patterns
docs/agent/llm-integration.md - Check existing code in the relevant directory first
- 阅读了解架构
docs/agent/architecture/backend-guide.md - 阅读了解API契约
docs/agent/apis/front-end-apis.md - 阅读了解LLM模式
docs/agent/llm-integration.md - 先检查相关目录中的现有代码
Non-Negotiable Rules
不可违背的规则
- All functions MUST have type hints - no exceptions
- Use for mutable defaults
copy.deepcopy() - Log detailed errors server-side, return generic messages to clients
- Use for shared resource initialization
asyncio.Lock() - Pass API keys directly to litellm via , never
api_key=os.environ
- 所有函数必须包含类型提示——无例外
- **使用**处理可变默认值
copy.deepcopy() - 在服务器端记录详细错误信息,向客户端返回通用消息
- **使用**处理共享资源初始化
asyncio.Lock() - 直接传递API密钥给litellm,使用参数,绝不要用
api_key=os.environ
Project Structure
项目结构
apps/backend/app/
├── main.py # FastAPI app, CORS, lifespan, routers
├── config.py # Pydantic BaseSettings from env
├── database.py # TinyDB wrapper (JSON file storage)
├── llm.py # LiteLLM wrapper (multi-provider)
├── routers/ # API endpoint handlers
├── services/ # Business logic layer
├── schemas/ # Pydantic request/response models
└── prompts/ # LLM prompt templates (Jinja2)apps/backend/app/
├── main.py # FastAPI app, CORS, lifespan, routers
├── config.py # Pydantic BaseSettings from env
├── database.py # TinyDB wrapper (JSON file storage)
├── llm.py # LiteLLM wrapper (multi-provider)
├── routers/ # API endpoint handlers
├── services/ # Business logic layer
├── schemas/ # Pydantic request/response models
└── prompts/ # LLM prompt templates (Jinja2)Patterns
模式
New Endpoint
新端点
python
from fastapi import APIRouter, HTTPException
from app.schemas.my_schema import MyRequest, MyResponse
from app.services.my_service import process_data
import logging
logger = logging.getLogger(__name__)
router = APIRouter(prefix="/api/v1", tags=["my-feature"])
@router.post("/my-endpoint", response_model=MyResponse)
async def create_thing(request: MyRequest) -> MyResponse:
try:
result = await process_data(request)
return result
except Exception as e:
logger.error(f"Failed to create thing: {e}")
raise HTTPException(status_code=500, detail="Operation failed. Please try again.")python
from fastapi import APIRouter, HTTPException
from app.schemas.my_schema import MyRequest, MyResponse
from app.services.my_service import process_data
import logging
logger = logging.getLogger(__name__)
router = APIRouter(prefix="/api/v1", tags=["my-feature"])
@router.post("/my-endpoint", response_model=MyResponse)
async def create_thing(request: MyRequest) -> MyResponse:
try:
result = await process_data(request)
return result
except Exception as e:
logger.error(f"Failed to create thing: {e}")
raise HTTPException(status_code=500, detail="Operation failed. Please try again.")New Schema
新模式
python
from pydantic import BaseModel, Field
class MyRequest(BaseModel):
name: str = Field(..., min_length=1, max_length=200)
description: str | None = None
class MyResponse(BaseModel):
id: str
name: str
status: str = "created"python
from pydantic import BaseModel, Field
class MyRequest(BaseModel):
name: str = Field(..., min_length=1, max_length=200)
description: str | None = None
class MyResponse(BaseModel):
id: str
name: str
status: str = "created"Database Operation
数据库操作
python
import copy
from app.database import get_db
DEFAULT_DATA = {"sections": [], "metadata": {}}
async def get_or_create(doc_id: str) -> dict:
db = get_db()
existing = db.get(doc_id)
if existing:
return existing
data = copy.deepcopy(DEFAULT_DATA) # ALWAYS deepcopy mutable defaults
db.insert(data)
return datapython
import copy
from app.database import get_db
DEFAULT_DATA = {"sections": [], "metadata": {}}
async def get_or_create(doc_id: str) -> dict:
db = get_db()
existing = db.get(doc_id)
if existing:
return existing
data = copy.deepcopy(DEFAULT_DATA) # ALWAYS deepcopy mutable defaults
db.insert(data)
return dataLLM Call
LLM调用
python
from app.llm import get_completion
from app.config import settings
async def improve_text(text: str) -> str:
prompt = f"Improve this resume text:\n\n{text}"
result = await get_completion(
prompt=prompt,
model=settings.LLM_MODEL,
api_key=settings.LLM_API_KEY, # Pass directly, not via env
json_mode=True,
)
return resultpython
from app.llm import get_completion
from app.config import settings
async def improve_text(text: str) -> str:
prompt = f"Improve this resume text:\n\n{text}"
result = await get_completion(
prompt=prompt,
model=settings.LLM_MODEL,
api_key=settings.LLM_API_KEY, # Pass directly, not via env
json_mode=True,
)
return resultError Handling Pattern
错误处理模式
python
except Exception as e:
logger.error(f"Operation failed: {e}") # Detailed for server logs
raise HTTPException(
status_code=500,
detail="Operation failed. Please try again." # Generic for client
)python
except Exception as e:
logger.error(f"Operation failed: {e}") # Detailed for server logs
raise HTTPException(
status_code=500,
detail="Operation failed. Please try again." # Generic for client
)Checklist Before Committing
提交前检查清单
- All functions have type hints
- Mutable defaults use
copy.deepcopy() - Error handling logs details, returns generic messages
- New endpoints registered in router includes
main.py - Schemas defined for all request/response bodies
- API keys passed via parameter
api_key=
- 所有函数都有类型提示
- 可变默认值使用
copy.deepcopy() - 错误处理记录详细信息,返回通用消息
- 新端点已在的路由中注册
main.py - 为所有请求/响应体定义了模式
- API密钥通过参数传递
api_key=