Configuração, personalização, ajustes de plataforma e referências de API para Pi.

Personalizado Models

Adicione provedores e modelos personalizados (Ollama, vLLM, LM Studio, proxies) via ~/.pi/agent/models.json.

Índice

Exemplo Mínimo

Para modelos locais (Ollama, LM Studio, vLLM), apenas id é necessário por modelo:

{
  "providers": {
    "ollama": {
      "baseUrl": "http://localhost:11434/v1",
      "api": "openai-completions",
      "apiKey": "ollama",
      "models": [
        { "id": "llama3.1:8b" },
        { "id": "qwen2.5-coder:7b" }
      ]
    }
  }
}

O valor apiKey é um espaço reservado porque Ollama o ignora. pi ainda trata os modelos como exigindo autenticação antes de aparecerem em /model, portanto, os servidores locais sem chave devem manter um valor fictício, salvar uma chave para esse provedor com /login ou passar --api-key ao selecionar o modelo.

Alguns servidores compatíveis com OpenAI não entendem a função developer usada para modelos com capacidade de raciocínio. Para esses provedores, defina compat.supportsDeveloperRole como false para que pi envie o prompt do sistema como uma mensagem system. Se o servidor também não suportar reasoning_effort, defina compat.supportsReasoningEffort para false também.

Você pode definir compat no nível do provedor para aplicar a todos os modelos ou no nível do modelo para substituir um modelo específico. Isso geralmente se aplica a Ollama, vLLM, SGLang e servidores semelhantes compatíveis com OpenAI.

{
  "providers": {
    "ollama": {
      "baseUrl": "http://localhost:11434/v1",
      "api": "openai-completions",
      "apiKey": "ollama",
      "compat": {
        "supportsDeveloperRole": false,
        "supportsReasoningEffort": false
      },
      "models": [
        {
          "id": "gpt-oss:20b",
          "reasoning": true
        }
      ]
    }
  }
}

Exemplo completo

Substitua os padrões quando precisar de valores específicos:

{
  "providers": {
    "ollama": {
      "baseUrl": "http://localhost:11434/v1",
      "api": "openai-completions",
      "apiKey": "ollama",
      "models": [
        {
          "id": "llama3.1:8b",
          "name": "Llama 3.1 8B (Local)",
          "reasoning": false,
          "input": ["text"],
          "contextWindow": 128000,
          "maxTokens": 32000,
          "cost": { "input": 0, "output": 0, "cacheRead": 0, "cacheWrite": 0 }
        }
      ]
    }
  }
}

O arquivo é recarregado cada vez que você abre /model. Editar durante a sessão; não é necessário reiniciar.

Exemplo do Google AI Studio

Use google-generative-ai com baseUrl para adicionar modelos do Google AI Studio, incluindo entradas personalizadas do Gemma 4:

{
  "providers": {
    "my-google": {
      "baseUrl": "https://generativelanguage.googleapis.com/v1beta",
      "api": "google-generative-ai",
      "apiKey": "$GEMINI_API_KEY",
      "models": [
        {
          "id": "gemma-4-31b-it",
          "name": "Gemma 4 31B",
          "input": ["text", "image"],
          "contextWindow": 262144,
          "reasoning": true
        }
      ]
    }
  }
}

O baseUrl é necessário ao adicionar modelos personalizados ao tipo google-generative-ai API.

APIs suportados

API Descrição
openai-completions Conclusões de bate-papo OpenAI (mais compatíveis)
openai-responses Respostas OpenAI API
anthropic-messages Mensagens Antrópicas API
google-generative-ai IA generativa do Google

Defina api no nível do provedor (padrão para todos os modelos) ou no nível do modelo (substituição por modelo).

Configuração do provedor

Campo Descrição
baseUrl API URL do terminal
api API tipo (veja acima)
apiKey Configuração API key opcional (veja a resolução do valor abaixo). Omita quando a autenticação for fornecida por /login/auth.json ou CLI --api-key.
oauth Tipo de provedor dinâmico OAuth. Atualmente suporta "radius"; requer o gateway baseUrl.
headers Cabeçalhos personalizados (veja a resolução do valor abaixo)
authHeader Defina true para adicionar Authorization: Bearer <apiKey> automaticamente
models Matriz de configurações de modelo
modelOverrides Substituições por modelo para modelos integrados ou registrados em extensão neste provedor

Para provedores com models, as configurações de provedor não integradas precisam de baseUrl e um valor api no nível do provedor ou do modelo. apiKey não é necessário para carregar o arquivo: os modelos ficam disponíveis quando a autenticação é configurada por meio de /login/auth.json, CLI --api-key ou provedor apiKey. Se nenhuma autenticação estiver configurada, os modelos serão carregados, mas permanecerão indisponíveis em /model e --list-models.

Resolução de valor

Os campos apiKey e headers suportam execução de comandos, interpolação de ambiente e literais:

  • Comando Shell: "!command" no início executa todo o valor como um comando e usa stdout
    "apiKey": "!security find-generic-password -ws 'anthropic'"
    "apiKey": "!op read 'op://vault/item/credential'"
  • Interpolação de ambiente: "$ENV_VAR" ou "${ENV_VAR}" usa o valor da variável nomeada. A interpolação funciona dentro de literais maiores.
    "apiKey": "$MY_API_KEY"
    "apiKey": "${KEY_PREFIX}_${KEY_SUFFIX}"
    $FOO_BAR é a variável FOO_BAR; use ${FOO}_BAR quando BAR for texto literal. Variáveis ​​de ambiente ausentes tornam o valor não resolvido.
  • Escapes: "
    quot;
    emite um literal "
    quot;
    ; "$!" emite um literal "!" sem acionar a execução do comando.
    "apiKey": "$literal-dollar-prefix"
    "apiKey": "$!literal-bang-prefix"
  • Valor literal: Usado diretamente. Strings simples em maiúsculas como MY_API_KEY são literais; use $MY_API_KEY para variáveis ​​de ambiente.
    "apiKey": "sk-..."

Para models.json, os comandos shell são resolvidos no momento da solicitação. pi intencionalmente não aplica TTL integrado, reutilização obsoleta ou lógica de recuperação para comandos arbitrários. Comandos diferentes precisam de estratégias diferentes de cache e falha, e pi não consegue inferir qual é a correta.

Se o seu comando for lento, caro, com taxa limitada ou precisar continuar usando um valor anterior em falhas transitórias, envolva-o em seu próprio script ou comando que implemente o cache ou o comportamento TTL desejado.

/model verificações de disponibilidade usam presença de autenticação configurada e não executam comandos shell.

Cabeçalhos personalizados

{
  "providers": {
    "custom-proxy": {
      "baseUrl": "https://proxy.example.com/v1",
      "apiKey": "$MY_API_KEY",
      "api": "anthropic-messages",
      "headers": {
        "x-portkey-api-key": "$PORTKEY_API_KEY",
        "x-secret": "!op read 'op://vault/item/secret'"
      },
      "models": [...]
    }
  }
}

Configuração do modelo

Campo Obrigatório Padrão Descrição
id Sim Identificador do modelo (passado para API)
name Não id Etiqueta do modelo legível por humanos. Usado para correspondência (padrões --model) e mostrado como texto de detalhe do modelo secundário.
api Não provedor api Substituir API do provedor para este modelo
reasoning Não false Suporta pensamento estendido
thinkingLevelMap Não omitido Mapeia os níveis de pensamento pi para os valores do provedor e marca os níveis não suportados (veja abaixo)
input Não ["text"] Tipos de entrada: ["text"] ou ["text", "image"]
contextWindow Não 128000 Tamanho da janela de contexto em tokens
maxTokens Não 16384 Tokens de saída máximo
samplingParams Não omitido Parâmetros de amostragem mesclados literalmente em cada corpo da solicitação (veja abaixo)
cost Não todos os zeros Taxas por milhão de tokens com níveis opcionais de preços de entrada para toda a solicitação
compat Não provedor compat Substituições de compatibilidade do provedor. Mesclado com o nível do provedor compat quando ambos estão definidos.

Uma camada de custo fornece um conjunto completo de taxas alternativas e se aplica à solicitação completa quando o uso total de entrada (input + cacheRead + cacheWrite) excede inputTokensAbove. Quando vários níveis coincidem, o limite mais alto vence.

{
  "cost": {
    "input": 5,
    "output": 30,
    "cacheRead": 0.5,
    "cacheWrite": 6.25,
    "tiers": [
      {
        "inputTokensAbove": 272000,
        "input": 10,
        "output": 45,
        "cacheRead": 1,
        "cacheWrite": 12.5
      }
    ]
  }
}

Comportamento atual:

  • /model, --list-models e o rodapé interativo exibem entradas por modelo id.
  • O name configurado é usado para correspondência de modelo e texto de detalhes do modelo secundário. Ele não substitui o ID do modelo do rodapé/barra de status.

Parâmetros de Amostragem

samplingParams é um objeto de formato livre mesclado literalmente em cada corpo de solicitação do modelo, depois que os campos pi se definem, para que suas chaves ganhem. Use-o para enviar parâmetros de amostragem que pi não modela - incluindo aqueles específicos do servidor, como llama.cpp's min_p ou vLLM's top_k:

{
  "id": "deepseek-v4-flash",
  "samplingParams": {
    "temperature": 1.0,
    "top_p": 0.95,
    "top_k": 0,
    "min_p": 0.0
  }
}

Somente APIs compatíveis com OpenAI o aplicam (openai-completions, openai-responses, azure-openai-responses); outros APIs ignoram. As chaves substituem os campos de solicitação nomeados do pi (por exemplo, uma chave temperature aqui supera a temperatura no nível da solicitação), portanto, prefira-a como a única fonte de amostragem verdadeira para um modelo. Em modelOverrides, samplingParams mescla por chave com o valor do modelo base.

Mapa de nível de pensamento

Use thinkingLevelMap em um modelo para descrever controles de pensamento específicos do modelo. As chaves são níveis de pensamento pi: off, minimal, low, medium, high, xhigh, max. Os mapas podem conter buracos; por exemplo, um modelo pode expor high e max sem expor xhigh.

Os valores são tristate:

Valor Significado
omitido Os níveis padrão até high usam o mapeamento padrão do provedor; níveis estendidos xhigh e max não são suportados
corda O nível é suportado e esse valor é enviado ao provedor
null O nível não é suportado e está oculto/ignorado/fixado

Exemplo de um modelo que suporta apenas raciocínios off, high e max:

{
  "id": "deepseek-v4-pro",
  "reasoning": true,
  "thinkingLevelMap": {
    "minimal": null,
    "low": null,
    "medium": null,
    "high": "high",
    "xhigh": null,
    "max": "max"
  }
}

Exemplo de um modelo onde o pensamento não pode ser desativado:

{
  "id": "always-thinking-model",
  "reasoning": true,
  "thinkingLevelMap": {
    "off": null
  }
}

Migração: configurações mais antigas que usavam compat.reasoningEffortMap deveriam mover esse mapeamento para o nível de modelo thinkingLevelMap. Use null para níveis que não devem aparecer na UI.

Substituindo o integrado Providers

Roteie um provedor integrado por meio de um proxy sem redefinir modelos:

{
  "providers": {
    "anthropic": {
      "baseUrl": "https://my-proxy.example.com/v1"
    }
  }
}

Todos os modelos Antrópicos integrados permanecem disponíveis. A autenticação OAuth ou API key existente continua funcionando.

Para mesclar modelos personalizados em um provedor integrado, inclua o array models:

{
  "providers": {
    "anthropic": {
      "baseUrl": "https://my-proxy.example.com/v1",
      "apiKey": "$ANTHROPIC_API_KEY",
      "api": "anthropic-messages",
      "models": [...]
    }
  }
}

Mesclar semântica:

  • Os modelos integrados são mantidos.
  • Os modelos personalizados são atualizados por id no provedor.
  • Se um modelo customizado id corresponder a um modelo integrado id, o modelo customizado substituirá esse modelo integrado.
  • Se um modelo personalizado id for novo, ele será adicionado junto com os modelos integrados.

Substituições por modelo

Use modelOverrides para personalizar modelos integrados e combinar modelos registrados em extensão sem substituir a lista completa de modelos do provedor.

{
  "providers": {
    "openrouter": {
      "modelOverrides": {
        "anthropic/claude-sonnet-4": {
          "name": "Claude Sonnet 4 (Bedrock Route)",
          "compat": {
            "openRouterRouting": {
              "only": ["amazon-bedrock"]
            }
          }
        }
      }
    }
  }
}

modelOverrides suporta estes campos por modelo: name, reasoning, thinkingLevelMap, input, cost (parcial), contextWindow, maxTokens, samplingParams (mesclado por chave), headers, compat.

Direct OpenAI GPT-5.6 Sol, Terra e Luna têm como padrão uma janela de contexto 272000 para que as solicitações permaneçam dentro do nível de preços de contexto curto do OpenAI. Para aceitar a janela de contexto de 1,05M do OpenAI, aumente-a para cada modelo que você usar:

{
  "providers": {
    "openai": {
      "modelOverrides": {
        "gpt-5.6-sol": {
          "contextWindow": 1050000
        }
      }
    }
  }
}

A substituição preserva os metadados de preços integrados. Solicitações com mais de 272 mil tokens de entrada totais usam as taxas de contexto longo do GPT-5.6 para toda a solicitação. Aplique a mesma substituição a gpt-5.6-terra ou gpt-5.6-luna quando necessário.

Notas de comportamento:

  • modelOverrides são aplicados a modelos de provedores integrados e modelos de provedores registrados em extensão correspondentes.
  • IDs de modelo desconhecidos são ignorados.
  • Você pode combinar baseUrl/headers de nível de provedor com modelOverrides.
  • A substituição de name altera apenas a correspondência do modelo e o texto de detalhes secundários; o rodapé e as listas de modelos primários continuam mostrando o modelo id.
  • Se models também for definido para um provedor, os modelos customizados serão mesclados após substituições integradas. Um modelo personalizado com o mesmo id substitui a entrada do modelo integrado substituída.

Compatibilidade de Mensagens Antrópicas

Para provedores ou proxies que usam api: "anthropic-messages", use compat para controlar a compatibilidade de solicitações específicas do Antrópico.

Por padrão, pi envia por ferramenta eager_input_streaming: true. Se um proxy ou back-end compatível com Anthropic rejeitar esse campo, defina supportsEagerToolInputStreaming como false. Pi omitirá tools[].eager_input_streaming e enviará o cabeçalho beta fine-grained-tool-streaming-2025-05-14 herdado para solicitações habilitadas para ferramenta.

Alguns modelos antrópicos requerem pensamento adaptativo (thinking.type: "adaptive" mais output_config.effort) em vez da carga útil de pensamento legado baseado em orçamento. Os modelos integrados definem isso automaticamente. Para provedores personalizados ou aliases que roteiam para esses modelos, defina forceAdaptiveThinking como true.

Alguns provedores compatíveis com o Anthropic emitem blocos de pensamento com assinaturas vazias e ainda os esperam na repetição. Defina allowEmptySignature como true apenas para esses provedores; o verdadeiro Antrópico rejeita assinaturas de pensamento vazias.

Os modelos Antrópicos integrados habilitam supportsStrictTools em seus metadados de modelo. Modelos customizados compatíveis com Anthropic devem defini-lo como true quando seu endpoint aceita definições estritas de ferramenta de esquema JSON.

{
  "providers": {
    "anthropic-proxy": {
      "baseUrl": "https://proxy.example.com",
      "api": "anthropic-messages",
      "apiKey": "$ANTHROPIC_PROXY_KEY",
      "compat": {
        "supportsEagerToolInputStreaming": false,
        "supportsLongCacheRetention": true,
        "forceAdaptiveThinking": true,
        "allowEmptySignature": true
      },
      "models": [
        {
          "id": "claude-opus-4-7",
          "reasoning": true,
          "input": ["text", "image"]
        }
      ]
    }
  }
}
Campo Descrição
supportsEagerToolInputStreaming Se o provedor aceita eager_input_streaming por ferramenta. Padrão: true. Defina como false para omitir esse campo e usar o cabeçalho beta de streaming da ferramenta legada e refinada em solicitações habilitadas para ferramenta.
supportsLongCacheRetention Se o provedor aceita retenção de cache longa antrópica (cache_control.ttl: "1h") quando a retenção de cache é long. Padrão: true.
sendSessionAffinityHeaders Se deve ser enviado x-session-affinity do ID da sessão quando o cache estiver habilitado. Padrão: detectado automaticamente para provedores conhecidos.
supportsCacheControlOnTools Se o provedor aceita marcadores cache_control de estilo antrópico nas definições de ferramentas. Padrão: true.
forceAdaptiveThinking Se deve enviar pensamento adaptativo (thinking.type: "adaptive" mais output_config.effort) para este modelo. Os modelos adaptativos integrados definem isso automaticamente. Padrão: false.
allowEmptySignature Se deve reproduzir assinaturas de pensamento vazias como signature: "" em vez de converter o pensamento em texto. Padrão: false.
supportsStrictTools Se o provedor aceita definições estritas de ferramentas de esquema JSON. Padrão: false; modelos antrópicos integrados permitem isso nos metadados gerados.

Compatibilidade OpenAI

Para provedores com compatibilidade parcial com OpenAI, use o campo compat.

  • O nível de provedor compat aplica padrões a todos os modelos desse provedor.
  • O nível do modelo compat substitui os valores do nível do provedor para esse modelo.
{
  "providers": {
    "local-llm": {
      "baseUrl": "http://localhost:8080/v1",
      "api": "openai-completions",
      "compat": {
        "supportsUsageInStreaming": false,
        "maxTokensField": "max_tokens"
      },
      "models": [...]
    }
  }
}
Campo Descrição
supportsStore O provedor suporta o campo store
supportsDeveloperRole Use a função developer vs system
supportsReasoningEffort Suporte para parâmetro reasoning_effort
supportsUsageInStreaming Suporta stream_options: { include_usage: true } (padrão: true)
supportsFinishReason Se as respostas transmitidas incluem finish_reason. Quando false, pi infere stop ou toolUse quando o fluxo termina. Padrão: true.
maxTokensField Use max_completion_tokens ou max_tokens
requiresToolResultName Incluir name nas mensagens de resultados da ferramenta
requiresAssistantAfterToolResult Insira uma mensagem do assistente antes de uma mensagem do usuário após os resultados da ferramenta
requiresThinkingAsText Converta blocos de pensamento em texto simples
requiresReasoningContentOnAssistantMessages Incluir reasoning_content vazio em todas as mensagens do assistente reproduzidas quando o raciocínio estiver ativado
thinkingFormat Use parâmetros de pensamento reasoning_effort, openrouter, deepseek, together, baseten, zai, qwen, chat-template ou qwen-chat-template
chatTemplateKwargs chat_template_kwargs valores para thinkingFormat: "chat-template"; use { "$var": "thinking.enabled" } ou { "$var": "thinking.effort" } para valores de pensamento controlados por pi
chatTemplateArgs chat_template_args valores para thinkingFormat: "baseten"; use { "$var": "thinking.enabled" } ou { "$var": "thinking.effort" } para valores de pensamento controlados por pi
cacheControlFormat Use marcadores cache_control de estilo antrópico no prompt do sistema, na última definição de ferramenta e no conteúdo de texto do último usuário, assistente ou resultado da ferramenta. Atualmente apenas anthropic é suportado.
sendSessionAffinityHeaders Para openai-completions, envie cabeçalhos de afinidade de sessão do ID da sessão quando o cache estiver ativado. Padrão: false.
sessionAffinityFormat Para openai-completions e openai-responses, o formato do cabeçalho de afinidade de sessão: openai envia session_id/x-client-request-id (conclusões também x-session-affinity), openai-nosession omite o cabeçalho session_id contendo sublinhado, openrouter envia x-session-id. Não afeta o parâmetro do corpo prompt_cache_key. Padrão: detectado automaticamente.
supportsStrictMode Se o provedor aceita definições estritas de ferramentas de função de esquema JSON. Os padrões dependem de API; modelos OpenAI integrados carregam metadados de capacidade explícitos.
supportsOpenAIGrammarTools Se APIs compatíveis com OpenAI emitem ferramentas gramaticais Lark/regex personalizadas. Quando false, as ferramentas com restrição gramatical voltam às ferramentas de função normais. Padrão: false; o catálogo de modelos integrado permite modelos GPT-5+ em OpenAI, OpenAI Codex, Azure OpenAI, GitHub Copilot, opencode e Cloudflare AI Gateway.
deferredToolsMode Use serialização de ferramenta adiada específica do provedor. Atualmente, apenas "kimi" é compatível com o formato de conclusão de bate-papo compatível com OpenAI do Kimi.
supportsLongCacheRetention Se o provedor aceita retenção de cache longa quando a retenção de cache é long: prompt_cache_retention: "24h" para cache de prompt OpenAI ou cache_control.ttl: "1h" quando cacheControlFormat é anthropic. Padrão: true.
openRouterRouting Preferências de roteamento do provedor OpenRouter. Este objeto é enviado como está no campo provider do OpenRouter API request.
vercelGatewayRouting Configuração de roteamento do Vercel AI Gateway para seleção de provedor (only, order)

openrouter usa reasoning: { effort }. together usa reasoning: { enabled } e também reasoning_effort quando supportsReasoningEffort está habilitado. qwen usa enable_thinking de nível superior. Use qwen-chat-template para servidores locais compatíveis com Qwen que requerem chat_template_kwargs.enable_thinking e preserve_thinking. Use chat-template para modelos de bate-papo vLLM/Hugging Face que precisam de chat_template_kwargs configurável, como chatTemplateKwargs: { "thinking": { "$var": "thinking.enabled" } } para modelos DeepSeek V3.x. Use thinkingFormat: "baseten" com chatTemplateArgs para provedores que expõem controles de alternância por meio de chat_template_args e, opcionalmente, suportam reasoning_effort de nível superior.

cacheControlFormat: "anthropic" é para provedores compatíveis com OpenAI que expõem o cache de prompt no estilo Anthropic por meio de marcadores cache_control no conteúdo de texto e definições de ferramentas.

Exemplo:

{
  "providers": {
    "openrouter": {
      "baseUrl": "https://openrouter.ai/api/v1",
      "apiKey": "$OPENROUTER_API_KEY",
      "api": "openai-completions",
      "models": [
        {
          "id": "openrouter/anthropic/claude-3.5-sonnet",
          "name": "OpenRouter Claude 3.5 Sonnet",
          "compat": {
            "openRouterRouting": {
              "allow_fallbacks": true,
              "require_parameters": false,
              "data_collection": "deny",
              "zdr": true,
              "enforce_distillable_text": false,
              "order": ["anthropic", "amazon-bedrock", "google-vertex"],
              "only": ["anthropic", "amazon-bedrock"],
              "ignore": ["gmicloud", "friendli"],
              "quantizations": ["fp16", "bf16"],
              "sort": {
                "by": "price",
                "partition": "model"
              },
              "max_price": {
                "prompt": 10,
                "completion": 20
              },
              "preferred_min_throughput": {
                "p50": 100,
                "p90": 50
              },
              "preferred_max_latency": {
                "p50": 1,
                "p90": 3,
                "p99": 5
              }
            }
          }
        }
      ]
    }
  }
}

Exemplo de gateway Vercel AI:

{
  "providers": {
    "vercel-ai-gateway": {
      "baseUrl": "https://ai-gateway.vercel.sh/v1",
      "apiKey": "$AI_GATEWAY_API_KEY",
      "api": "openai-completions",
      "models": [
        {
          "id": "moonshotai/kimi-k2.5",
          "name": "Kimi K2.5 (Fireworks via Vercel)",
          "reasoning": true,
          "input": ["text", "image"],
          "cost": { "input": 0.6, "output": 3, "cacheRead": 0, "cacheWrite": 0 },
          "contextWindow": 262144,
          "maxTokens": 262144,
          "compat": {
            "vercelGatewayRouting": {
              "only": ["fireworks", "novita"],
              "order": ["fireworks", "novita"]
            }
          }
        }
      ]
    }
  }
}