Pydantic schema for sentiment results
The prompt forces the model to return a JSON object of a specific shape, but the prompt alone is not a contract. A contract lives in code. Pydantic gives you that contract. When the service returns an AnalyzeResponse, callers know exactly what fields exist, what types they are, and what ranges they live in.
Where Pydantic sits in the pipeline
Pydantic acts as the boundary contract between the LLM and the caller. Bad shapes fail fast inside the service.
from pydantic import BaseModel, Field
from typing import List, Optional, Literal
class SentimentResult(BaseModel):
label: Literal["positive", "negative", "neutral"]
score: float = Field(..., ge=-1.0, le=1.0)
rationale: Optional[str] = None
class AnalyzeRequest(BaseModel):
text: str = Field(..., min_length=1, max_length=20000)
tasks: List[str] = Field(
default_factory=lambda: ["sentiment", "entities", "keywords", "summary", "emotion"],
)
class AnalyzeResponse(BaseModel):
text: str
tasks: List[str]
sentiment: Optional[SentimentResult] = None
errors: dict = Field(default_factory=dict)Literal restricts label to three valid strings. Field(ge=-1.0, le=1.0) enforces the score range. min_length and max_length on the request stop empty strings and abusive 200KB payloads.
Literal turns a string field into a closed enum at the type level. If the model returns "positve" with a typo, Pydantic raises a ValidationError before the response ever leaves your service. A plain str would pass the typo straight through to the caller, who would have to do their own validation. Literal is the single cheapest safety net you can add to an LLM pipeline.
Quiz: Quiz
Loading practice…