# Schema 1 class Cat: name breed litter_preference class Dog: name breed ball_preference class Gerbil: name breed seed_preference
# Schema 2 class Pet: name breed species attributes class Attribute: name value
Migrations
Migrations then are applied with the deterministic process:
alembic
A system for asynchronously processing tasks outside the request-response cycle, either offloading or scheduling them.
Often called other names, but they're all basically the same thing:
Enqueues jobs in response to events. Importantly, only needs to ensure description of task is stored in queue.
Responsibilities:
Storage and distribution of jobs.
Additional Features:
Execute jobs from the queue.
Importantly, workers are horizontally scalable.
We can implement various types of guarantees for job delivery/execution.
At-most-once: Job might be lost, never duplicated
At-least-once: Job always delivered, might be duplicated
Exactly-once: Job delivered once and only once
User uploads profile photo:
ProcessProfilePictureJob
Redis is an in memory data store
Common uses: Cache, session store, real-time analytics, job queues
How do LLMs like ChatGPT and Claude do things like search the internet?
"Find the cheapest flights from NYC to London next week with reasonable travel times"
Task Execution:
How does an LLM know what tools it has?
pydantic-ai
User Message ↓ ┌──────────────────────┐ │ TaskDetectionAgent │ ← Is this actionable? └──────────┬───────────┘ ↓ ┌──────────────┐ │ PlanningAgent│ ← Generate execution plan └──────┬───────┘ ↓ ┌──────────────────┐ │ ExecutionAgent │ ← Execute with tools └──────┬───────────┘ ↓ [Tools: web_search, mark_progress] ↓ Redis Progress Updates → Final Result
User Message ↓ ┌──────────────────────┐ │ TaskDetectionAgent │ ← Is this actionable? └──────────┬───────────┘ ↓ ┌──────────────┐ │ PlanningAgent│ ←──────┐ └──────┬───────┘ │ ↓ │── Job Queue ┌──────────────────┐ │ │ ExecutionAgent │ ←──┘ └──────┬───────────┘ ↓ [Tools: web_search, mark_progress] ↓ Redis Progress Updates → Final Result
@self.agent.tool_plain async def web_search(search_query: str, freshness: str = "pw") -> str: """Perform a real web search and return formatted results.""" search_results = search_web(search_query, self.context.tools, freshness) return format_results(search_results) @self.agent.tool_plain async def mark_progress(message: str) -> str: """Stream a progress update to the user in real-time.""" update = TaskUpdate( status=TaskStatus.EXECUTING, content=message, timestamp=datetime.now(timezone.utc) ) self.context.execution.redis_client.publish_task_update( self.context.agent.chat_id, update ) return " Progress update sent"
# From agentic_job.py - RQ job function def execute_agentic_task_job(task_context: AgentContext, plan: TaskPlan): """Job function executed by RQ worker""" # Convert to context bundle context_bundle = AgentContextBundle.create( user_id=task_context.user_id, chat_id=task_context.chat_id, response_id=task_context.response_id, original_message=task_context.original_message, redis_client=get_redis_client(settings.redis_url) ) # Create execution agent and run execution_agent = ExecutionAgent(context_bundle) result = await execution_agent.execute_plan(plan) return result