Query Engine 是 ccgo 的核心组件,封装了完整的 LLM 查询 → tool-use → 多轮循环 逻辑。
Engine 结构
internal/query/engine.go:
type Engine struct {
client *api.Client
model string
}Engine 同时实现了两个接口:
agent.QueryRunner— 被 Agent tool 用于运行子 agentskill.QueryRunner— 被 Skill tool 用于运行 skill
两者都通过 RunSubagent() 方法实现,创建新的独立对话轮次。
RunParams
一次 Engine.Run() 调用的参数:
| 参数 | 类型 | 说明 |
|---|---|---|
Messages | []api.MessageParam | 对话历史 |
SystemPrompt | string | 覆盖默认 system prompt |
MaxTurns | int | tool-use 最大轮次(0=无限) |
MaxTokens | int | 覆盖默认 max_tokens |
PermMode | PermissionMode | 权限模式 |
AllowedTools | []string | 限定可用 tool(nil=全部) |
OnTextDelta | func(string) | 流式文本回调 |
OnThinkingDelta | func(string) | 流式 thinking 回调 |
OnToolUse | func(name, input) | tool 调用回调 |
查询循环(query loop)
核心循环在 internal/query/loop.go,流程如下:
1. 组装 system prompt(context.BuildSystemPrompt)
2. 调用 api.Stream() 获取事件流
3. 消费流式事件:
- text_delta / thinking_delta → 透传回调
- tool_use block → 执行 tool(含权限检查和 hooks)
- 将 tool_result 追加到 messages
4. 如果有 tool_use 且未超 MaxTurns → 回到步骤 2
5. 遇到 end_turn 或无 tool_use → 结束
System Prompt 构建
当 RunParams.SystemPrompt 为空时,自动调用 context.BuildSystemPrompt():
- 加载 CLAUDE.md(多级:managed / user / project / local)
- 注入当前日期、git 状态
- 组装工具指引章节
- 有 Skill tool 时注入 skill 使用指引
详见 context-builder。
Terminal 状态
RunResult.Terminal.Reason 枚举:
| 值 | 含义 |
|---|---|
completed | 正常结束(end_turn) |
max_turns_reached | 达到 MaxTurns 上限 |
model_error | API 错误 |
Token Budget
internal/query/token_budget.go 实现 token 预算追踪,支持 +500k 风格的预算指令,配合 Workflow 的 budget.spent() 接口。
子 Agent 执行
func (e *Engine) RunSubagent(ctx context.Context, prompt string, parentCtx ToolContext) (string, error) {
// 以单条用户消息创建新的对话轮次
// 继承 parentCtx 的 PermMode
// 返回 assistant 最终文本
}子 agent 完全隔离于父对话历史,只传递 prompt 和权限模式。
相关页面
- architecture — 调用关系
- api — API 客户端
- context-builder — system prompt 组装
- tools — tool 执行
- compact — 自动压缩