Core System
Query Pipeline
The complete journey from pressing Enter to Claude's response
~8 min read
0
Core lines of code
0
Pipeline files
0
Processing stages
The query pipeline is like a complete restaurant ordering process.
You (the customer) say something to the waiter → the waiter translates it into a complete order the kitchen understands (adding your allergies, table number, etc.) → the kitchen cooks (Claude thinks) → if ingredients are needed, someone goes to the storeroom (tool calls) → cooking resumes → the dish is served (response).
The whole process is streaming — like omakase, served course by course, not all at once.
Message Pipeline #
Click each node for details
User Input
Normalize Messages
System Prompt Assembly
Streaming API Call
Tool Execution
Loop / Return
System Prompt Construction #
The complete instructions Claude actually receives
Default system prompt
Defines Claude Code's identity, capabilities, and behavioral norms
User environment
OS, shell, working directory, git status, current date
Tool definitions
Names, descriptions, and input JSON Schemas for 45+ tools
Project rules
User-defined rules from CLAUDE.md / .claude/config.json
Memory attachments
Saved memories and file references from prior conversations
What the API Actually Sees #
Real request and response structures from Claude Code
This is what Claude Code sends to the Anthropic API. The system prompt, conversation history, and all 45+ tool definitions are packed into a single streaming request.
// POST https://api.anthropic.com/v1/messages (stream: true)
{
"model": "claude-sonnet-4-20250514",
"max_tokens": 16384,
"stream": true,
"system": [
{
"type": "text",
"text": "You are Claude Code, Anthropic's official CLI..."
// ~5KB of system prompt
},
{
"type": "text",
"text": "# Environment\nPlatform: darwin\nShell: zsh\nCwd: /Users/dev/myproject\n..."
}
],
"messages": [
{
"role": "user",
"content": "Help me fix the failing test in src/utils.ts"
}
],
"tools": [
{
"name": "Bash",
"description": "Execute shell commands...",
"input_schema": {
"type": "object",
"properties": {
"command": { "type": "string" },
"timeout": { "type": "number" }
},
"required": ["command"]
}
}
// ... 44 more tool definitions
],
"metadata": {
"user_id": "user_abc123"
}
}Streaming #
Why does the response appear character by character?
Imagine the difference between a faucet and a bucket. The traditional approach waits for the bucket to fill up (complete response). Claude Code uses faucet mode — water flows to your glass as soon as it comes out. Technically called an 'async generator', it transmits data bit by bit. Benefits: fast response, low memory, cancel anytime.
Tool Call Loop #
How does Claude keep calling tools until the task is done?
- 1 Claude's response contains tool_use blocks ("I want to read src/main.tsx")
- 2 Permission system evaluates: is this operation safe? → execute if passed
- 3 Tool results appended to conversation history as tool_result messages
- 4 Call the API again with the updated history — Claude sees the results and decides next step
- 5 Repeat until Claude returns stop_reason: "end_turn" (task complete)
Interactive Code Walkthrough #
Click through the query pipeline execution, step by step
Everything starts here. submitMessage() is an async generator that orchestrates the entire conversation turn — from receiving the user's prompt to streaming back Claude's response.
Click highlighted function names to follow the call chain
Related Pages
← → arrow keys to navigate