Pular para o conteúdo principal
O Reasoning Backbone unifica como o ChatCLI pede “pense mais duro” de providers diferentes. Anthropic expõe extended thinking com thinking_budget em tokens; OpenAI o-series expõe reasoning effort como enum low/medium/high. O pipeline abstrai isso em SkillEffort e auto-attacha ao ctx antes de cada chamada LLM dos agents que fazem reasoning pesado.
A abstração cross-provider é pré-existente em llm/client/skill_hints.go. O que o pipeline adiciona é: política de auto-attach (auto para agents listados), session override via /thinking, e exposição em /config quality.

A abstração existente (pré-pipeline)

llm/client/skill_hints.go:
type SkillEffort string

const (
    EffortUnset  SkillEffort = ""
    EffortLow    SkillEffort = "low"
    EffortMedium SkillEffort = "medium"
    EffortHigh   SkillEffort = "high"
    EffortMax    SkillEffort = "max"
)

// Maps to Anthropic thinking budget_tokens
func ThinkingBudgetForEffort(e SkillEffort) int {
    switch e {
    case EffortMedium: return 4096
    case EffortHigh:   return 16384
    case EffortMax:    return 32768
    }
    return 0 // unset/low = no thinking
}

// Maps to OpenAI reasoning.effort
func ReasoningEffortForOpenAI(e SkillEffort) string {
    switch e {
    case EffortLow:               return "low"
    case EffortMedium:            return "medium"
    case EffortHigh, EffortMax:   return "high"
    }
    return ""
}
Providers leem do ctx via client.EffortFromContext(ctx) dentro de seus SendPrompt, traduzem para o campo nativo, e enviam.

Auto-attach: o que o pipeline adiciona

applyAutoReasoning(ctx, cfg ReasoningConfig, agent WorkerAgent) context.Context:
// cli/agent/quality/reasoning.go
func applyAutoReasoning(ctx, cfg, agent) context.Context {
    if cfg.Mode == "off" { return ctx }
    if client.EffortFromContext(ctx) != client.EffortUnset {
        return ctx  // respeita hint existente (skill frontmatter, agent.Effort)
    }
    if cfg.Mode != "on" && !inAutoAgents(agent.Type(), cfg.AutoAgents) {
        return ctx  // auto: só para agents listados
    }
    return client.WithEffortHint(ctx, EffortForBudget(cfg.Budget))
}
EffortForBudget traduz cfg.Budget (tokens) para o tier SkillEffort mais próximo:
Budget (tokens)Tier resultante
≥ 16384EffortMax
≥ 8192EffortHigh
≥ 4096EffortMedium
< 4096 ou 0EffortHigh (default sane)
O default CHATCLI_QUALITY_REASONING_BUDGET=8000EffortHigh (8000 tokens de thinking na Claude, reasoning.effort=high na OpenAI).

Três modos

CHATCLI_QUALITY_REASONING_MODE=auto
CHATCLI_QUALITY_REASONING_AUTO_AGENTS=planner,refiner,verifier,reflexion
Effort hint é attached apenas para agents em AutoAgents. Agents mecânicos (formatter, shell) não pagam pelo thinking mais caro.

Prioridade de resolução

Para uma chamada LLM dentro de um worker, o effort hint é resolvido nesta ordem (último ganha):
1

Skill frontmatter

Se o turn ativou uma skill com effort: high, esse hint já está no ctx antes do dispatcher.
2

Agent default

PlannerAgent tem effort="high" embutido; dispatcher attacha via WithEffortHint.
3

CHATCLI_QUALITY_REASONING_*

applyAutoReasoning só attacha se (1) mode não é off e (2) ctx ainda não tem effort hint.
4

/thinking session override

No chat (cli_llm.go) e no orchestrator turn (agent_mode.go), cli.applyThinkingOverride(skillEffort) ganha de tudo acima para aquele turn.
Isso significa que /thinking off pode forçar zero thinking mesmo se o agente tem default high. Útil para turns onde velocidade importa mais que qualidade.

/thinking — o slash

/thinking on
# alias para /thinking high
O override mora em cli.thinkingOverride:
type thinkingOverrideState struct {
    set    bool           // nil vs set
    effort client.SkillEffort  // EffortUnset quando set=true significa "off"
}

Providers que suportam

ProviderCampo nativoNotas
Anthropic Claudethinking: {type: enabled, budget_tokens: N}Beta header interleaved-thinking-2025-05-14
OpenAI o1 / o3 / o4reasoning: {effort: "low|medium|high"}Via /v1/responses endpoint
Anthropic via BedrockMesma shape, mas via AWS APISuporta thinking
Demais providersIgnoram silenciosamenteFall-through sem erro
CHATCLI_QUALITY_REASONING_MODE=on com um provider que não suporta é no-op — o ctx tem o hint, o provider não usa, zero falha. Você só paga por capacidade real.

Variáveis de ambiente

Env varDefaultValoresO que faz
CHATCLI_QUALITY_REASONING_MODEautooff|auto|onPolítica
CHATCLI_QUALITY_REASONING_BUDGET8000intTokens de thinking (Anthropic); mapeado para tier na OpenAI
CHATCLI_QUALITY_REASONING_AUTO_AGENTSplanner,refiner,verifier,reflexionCSVLista para mode=auto

Override por agent

Cada agent também tem seu próprio default via BuiltinAgentMeta:
# Forçar Planner para thinking máximo
export CHATCLI_AGENT_PLANNER_EFFORT=max

# Diminuir Formatter (ele já é low por default, mas explícito)
export CHATCLI_AGENT_FORMATTER_EFFORT=low
O fluxo: dispatcher lê agent.Effort() → se não-vazio, attacha via WithEffortHint. Isso ganha do applyAutoReasoning (ver passo 2 da priority).

Interação com effort hints de skills

Skills podem declarar effort no frontmatter:
---
name: investigate-crashes
description: Deep dive into crash logs and bug reproduction
effort: high
---
Quando a skill é ativada (auto ou via /skill), skillEffortHint é setado e propagado. A ordem fica:
skill.effort=high → skillEffortHint=EffortHigh → WithEffortHint(ctx, EffortHigh)


                                       dispatcher propaga para workerCtx


                                       applyAutoReasoning detecta hint já setado → skip


                                       provider lê EffortHigh → thinking_budget=16384
Skills e reasoning backbone são ortogonais e compostos. Skill diz “a task toda precisa de effort alto”; quality diz “estes agents específicos sempre pensam”; o usuário pode sobrescrever com /thinking.

Observabilidade

/config quality mostra o estado:
── Reasoning backbone (#7)
  CHATCLI_QUALITY_REASONING_MODE      : auto
  CHATCLI_QUALITY_REASONING_BUDGET    : 8000
  CHATCLI_QUALITY_REASONING_AUTO_AGENTS: planner, refiner, verifier, reflexion
Nos logs de worker, cada call LLM com effort ativo aparece como:
{"level":"info","msg":"SendPrompt with thinking","provider":"anthropic","model":"claude-sonnet-4-6","thinking_budget":8000}
{"level":"info","msg":"SendPrompt with reasoning","provider":"openai","model":"o4-mini","reasoning.effort":"high"}

Custo

Thinking tokens são cobrados separadamente na Anthropic (output-priced). Budget de 8000 tokens adiciona ~$0.12/call com Sonnet. Reasoning effort na OpenAI também aumenta output tokens.
Estratégia de budget recomendada:
CenárioRecomendação
Chat casualCHATCLI_QUALITY_REASONING_MODE=off
Dev diáriomode=auto, budget=8000 (default)
Workflows críticos (refactors grandes, debugging)/thinking max no turn específico
Batch sem user na frentemode=on, budget=16384

Troubleshooting

  1. Check /config quality — confirme CHATCLI_QUALITY_REASONING_MODE != off
  2. Check CHATCLI_QUALITY_REASONING_AUTO_AGENTS inclui o agent que está rodando
  3. Check logs do provider — thinking_budget deve aparecer no request body
  4. Para Anthropic via OAuth: precisa de beta header interleaved-thinking-2025-05-14 (já ativo em claude_client.go:46)
Correto! /thinking on vale para o próximo turn apenas, depois o flag se mantém mas pode ser limpo com /thinking auto ou /thinking off. Cada /thinking substitui o anterior.
O budget default (8000) é calibrado para Sonnet. Para Opus ou GPT-5, considere baixar: CHATCLI_QUALITY_REASONING_BUDGET=4000. Ou use mode=off e dispare manualmente com /thinking só quando faz diferença.

Leia também

Multi-Agent Orchestration

Como os effort hints fluem do dispatcher para workers paralelos.

Skills and Registry

Como skills declaram effort: no frontmatter.

OpenAI Responses API

Documentação oficial do reasoning.effort.

Anthropic Extended Thinking

Documentação oficial do thinking_budget.