本章总览
query 是 Claude Code 的 Agent 心脏:根文件 src/query.ts 实现 async function* query() 主循环;src/query/ 子目录把配置快照、依赖注入、Token 预算、状态转移标记与 Stop Hook 编排从巨型文件中拆出。本页为模块索引,但重点不是罗列文件,而是建立一次 iteration 的真实顺序:准备上下文、流式 API、按 needsFollowUp 分支、执行工具或结束 turn。
总览图
学完本章你应该能
- 区分 query.ts 主循环与 query/ 子模块的职责边界
- 建立 config → deps → loop → stopHooks → tokenBudget 的阅读顺序
- 理解 queryLoop 的 while(true) 与 Continue/Terminal 返回语义
- 会从源码树跳转到子章节与根 query.ts 高亮
建议学习步骤
- 阅读下方架构图,定位 query.ts 在 REPL / SDK 调用链中的位置
- 点击源码树中的 query.ts(高亮)与子目录文件
- 建议子章节顺序:config-deps → transitions → token-budget → stop-hooks
- 对照 mod-services/compact 理解 deps.autocompact 插入点
模块在架构中的位置
query 是 src/ 下的一级目录,共 5 个文件、660 行。一句话概括:Claude Code 的心脏:驱动 tool_use 循环、流式 API 调用、上下文压缩、工具编排、权限检查。
模块 UML 图表
Turn 终止决策
概览
| 指标 | 数值 |
|---|---|
| 行数 | 660 |
| 文件 | 5 |
架构:根文件与子目录
Claude Code 每次用户 turn 最终进入 query(params)。调用方包括 REPL.tsx、main.tsx(-p / SDK)、AgentTool 子代理、runForkedAgent 等。
REPL / SDK / AgentTool
↓
query.ts — query() 包装 consumedCommandUuids 生命周期
↓
queryLoop() — while(true) 迭代
├─ buildQueryConfig() ← query/config.ts(每 turn 快照)
├─ deps.* ← query/deps.ts(callModel / compact / uuid)
├─ microcompact → autocompact → callModel → tools
├─ handleStopHooks ← query/stopHooks.ts
├─ checkTokenBudget ← query/tokenBudget.ts(TOKEN_BUDGET feature)
└─ state.transition ← Continue 原因记录在 State(见 transitions 章)
query.ts 仍持有绝大部分循环体(流式 API、工具编排、413 恢复、max_output_tokens 恢复等)。query/ 是正在进行的模块化提取:注释中明确目标是把 loop 收成 step(state, event, config) 纯 reducer。
| 路径 | 行数级 | 职责 |
|---|---|---|
query.ts | ~1730 | 主循环、yield StreamEvent/Message |
query/config.ts | ~47 | QueryConfig 不可变快照 |
query/deps.ts | ~41 | QueryDeps 注入(测试友好) |
query/tokenBudget.ts | ~94 | +500k 自动续跑决策 |
query/transitions.ts | 占位 | transitionQueryState;Continue/Terminal 类型锚点 |
query/stopHooks.ts | ~474 | turn 结束 Stop/TeammateIdle/TaskCompleted |
子章节导航
| 子章节 | id | 核心文件 |
|---|---|---|
| config 与 deps | query-config-deps | query/config.ts, query/deps.ts, productionDeps |
| Token 预算 | query-token-budget | query/tokenBudget.ts, utils/tokenBudget.ts, compact 联动 |
| Continue / Terminal | query-transitions | State.transition, query/transitions.ts |
| Stop Hooks | query-stop-hooks | query/stopHooks.ts, utils/hooks.ts Stop 事件 |
一次 iteration 时间线
query 主循环是否继续,不可靠地看 API stop_reason,而是看流式解析过程中是否见过 tool_use block,并据此设置 needsFollowUp。一次 iteration 可以按五段读:
- 准备:yield
stream_request_start,执行 snip / microcompact / autocompact;autocompact 成功会更新 messages,但仍在同一 iteration 内继续请求 API。 - 流式 API:
deps.callModel产出 assistant chunks;只要出现 tool_use,就把needsFollowUp置为 true。 - 无工具分支:进入 413/max_tokens recovery、Stop hooks、Token budget 检查;可能 return Terminal,也可能写入 meta nudge 后 continue。
- 有工具分支:StreamingToolExecutor 或 runTools 收集 tool_result,随后处理 attachment、memory/skill prefetch、队列 drain。
- 下一轮:工具路径提交
transition.reason = 'next_turn',带着新 transcript 回到 loop 顶部。
目录树扫描 src/query/ 子目录;query.ts 作为根级主循环文件单独高亮挂载。点击文件名:已有专题页则跳转子章节,否则滚动至页内锚点。
与相邻模块的边界
mod-services/api-claude:deps.callModel 即 queryModelWithStreaming。mod-services/compact:deps.microcompact / deps.autocompact 在每轮 API 前运行。mod-hooks/useCanUseTool:canUseTool 经 QueryParams 注入,query 不 import React。mod-utils/shell-hooks:Stop 事件由 stopHooks.ts 调 executeStopHooks,与 React hooks 目录无关。
读 query 时务必同时打开 query.ts 行 307–728(单轮迭代骨架)与 query.ts 行 1258–1357(stop hook + token budget 出口)。
本章小结与延伸
query = AsyncGenerator 驱动的 tool_use 循环。主逻辑在 query.ts;query/ 是可测试接缝。下一章建议读 mod-services/compact 或 mod-hooks/useCanUseTool。 继续学习: