Настройка, расширение, параметры платформы и справочник API для Pi.

Пользовательский Models

Добавляйте пользовательских поставщиков и модели (Ollama, vLLM, LM Studio, прокси) через ~/.pi/agent/models.json.

Оглавление

Минимальный пример

Для локальных моделей (Ollama, LM Studio, vLLM) для каждой модели требуется только id:

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

Значение apiKey является заполнителем, поскольку Оллама его игнорирует. pi по-прежнему рассматривает модели как требующие аутентификации, прежде чем они появятся в /model, поэтому локальные серверы без ключа должны сохранять фиктивное значение, сохранять ключ для этого провайдера с помощью /login или передавать --api-key при выборе модели.

Некоторые OpenAI-совместимые серверы не понимают роль developer, используемую для моделей, способных рассуждать. Для этих провайдеров установите для compat.supportsDeveloperRole значение false, чтобы pi вместо этого отправлял системное приглашение в виде сообщения system. Если сервер также не поддерживает reasoning_effort, установите также compat.supportsReasoningEffort на false.

Вы можете установить compat на уровне поставщика, чтобы применить его ко всем моделям, или на уровне модели, чтобы переопределить конкретную модель. Обычно это относится к Ollama, vLLM, SGLang и аналогичным серверам, совместимым с 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
        }
      ]
    }
  }
}

Полный пример

Переопределите значения по умолчанию, если вам нужны определенные значения:

{
  "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 }
        }
      ]
    }
  }
}

Файл перезагружается каждый раз, когда вы открываете /model. Редактировать во время сеанса; перезагрузка не требуется.

Пример Google AI Studio

Используйте google-generative-ai с baseUrl, чтобы добавить модели из Google AI Studio, включая пользовательские записи 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
        }
      ]
    }
  }
}

baseUrl требуется при добавлении пользовательских моделей к типу google-generative-ai API.

Поддерживается APIс

API Описание
openai-completions Завершения чата OpenAI (наиболее совместимые)
openai-responses Ответы OpenAI API
anthropic-messages Антропные сообщения API
google-generative-ai Генеративный искусственный интеллект Google

Установите api на уровне поставщика (по умолчанию для всех моделей) или уровне модели (переопределение для каждой модели).

Конфигурация поставщика

Поле Описание
baseUrl API URL-адрес конечной точки
api тип API (см. выше)
apiKey Дополнительная конфигурация API key (см. разрешение значений ниже). Опустите его, если аутентификация обеспечивается с помощью /login/auth.json или CLI --api-key.
oauth Динамический тип OAuth поставщика. В настоящее время поддерживает "radius"; требуется шлюз baseUrl.
headers Пользовательские заголовки (см. разрешение значений ниже)
authHeader Установите true, чтобы автоматически добавлять Authorization: Bearer <apiKey>.
models Массив конфигураций модели
modelOverrides Переопределения для каждой модели для встроенных или зарегистрированных в расширении моделей этого поставщика.

Для поставщиков с models для конфигураций невстроенных поставщиков требуются baseUrl и значение api либо на уровне поставщика, либо на уровне модели. apiKey не требуется для загрузки файла: модели становятся доступными, когда аутентификация настроена через /login/auth.json, CLI --api-key или провайдера apiKey. Если аутентификация не настроена, модели загружаются, но остаются недоступными в /model и --list-models.

Разрешение значений

Поля apiKey и headers поддерживают выполнение команд, интерполяцию среды и литералы:

  • Команда оболочки: "!command" в начале выполняет все значение как команду и использует stdout
    "apiKey": "!security find-generic-password -ws 'anthropic'"
    "apiKey": "!op read 'op://vault/item/credential'"
  • Интерполяция среды: "$ENV_VAR" или "${ENV_VAR}" использует значение именованной переменной. Интерполяция работает внутри больших литералов.
    "apiKey": "$MY_API_KEY"
    "apiKey": "${KEY_PREFIX}_${KEY_SUFFIX}"
    $FOO_BAR — переменная FOO_BAR; используйте ${FOO}_BAR, когда BAR — это буквальный текст. Отсутствие переменных среды делает значение неразрешенным.
  • Эскейп: "
    quot;
    выдает литерал "
    quot;
    ; "$!" выдает литерал "!", не запуская выполнение команды.
    "apiKey": "$literal-dollar-prefix"
    "apiKey": "$!literal-bang-prefix"
  • Буквальное значение: Используется напрямую. Обычные строки в верхнем регистре, такие как MY_API_KEY, являются литералами; используйте $MY_API_KEY для переменных среды.
    "apiKey": "sk-..."

Для models.json команды оболочки обрабатываются во время запроса. pi намеренно не применяет встроенную логику TTL, устаревшего повторного использования или восстановления для произвольных команд. Разным командам нужны разные стратегии кэширования и отказов, и pi не может сделать правильный выбор.

Если ваша команда медленная, дорогая, ограничена по скорости или должна продолжать использовать предыдущее значение при временных сбоях, оберните ее в свой собственный сценарий или команду, которая реализует желаемое поведение кэширования или TTL.

/model проверки доступности используют настроенное присутствие аутентификации и не выполняют команды оболочки.

Пользовательские заголовки

{
  "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": [...]
    }
  }
}

Конфигурация модели

Поле Необходимый По умолчанию Описание
id Да Идентификатор модели (передается в API)
name Нет id Читаемая человеком этикетка модели. Используется для сопоставления (шаблоны --model) и отображается как вторичный подробный текст модели.
api Нет api провайдера Переопределить API поставщика для этой модели.
reasoning Нет false Поддерживает расширенное мышление
thinkingLevelMap Нет опущен Сопоставляет уровни мышления «пи» со значениями поставщика и отмечает неподдерживаемые уровни (см. ниже).
input Нет ["text"] Типы ввода: ["text"] или ["text", "image"]
contextWindow Нет 128000 Размер контекстного окна в токенах
maxTokens Нет 16384 Максимальное количество токенов вывода
samplingParams Нет опущен Параметры выборки дословно объединены в тело каждого запроса (см. ниже).
cost Нет все нули Ставки за миллион токенов с дополнительными ценовыми уровнями входных данных для всего запроса
compat Нет провайдер compat Переопределяет совместимость поставщика. Объединяется с уровнем провайдера compat, если оба установлены.

Уровень затрат предоставляет полный набор альтернативных тарифов и применяется к полному запросу, когда общее использование входных данных (input + cacheRead + cacheWrite) превышает inputTokensAbove. При совпадении нескольких уровней выигрывает наивысший порог.

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

Текущее поведение:

  • /model, --list-models, а в интерактивном нижнем колонтитуле записи отображаются по модели id.
  • Настроенный name используется для сопоставления модели и дополнительного подробного текста модели. Он не заменяет идентификатор модели нижнего колонтитула/строки состояния.

Параметры выборки

samplingParams — это объект свободной формы, дословно включаемый в каждое тело запроса модели после того, как поля pi задаются сами собой, поэтому его ключи выигрывают. Используйте его для отправки параметров выборки, которые pi не моделирует, включая специфичные для сервера, такие как min_p llama.cpp или top_k vLLM:

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

Его применяют только OpenAI-совместимые API (openai-completions, openai-responses, azure-openai-responses); другие API игнорируют это. Ключи переопределяют именованные поля запроса pi (например, ключ temperature здесь превосходит температуру уровня запроса), поэтому предпочитайте его как единственный источник истинности выборки для модели. В modelOverrides, samplingParams объединяется по ключу со значением базовой модели.

Карта уровня мышления

Используйте thinkingLevelMap в модели, чтобы описать элементы управления мышлением, специфичные для модели. Ключи — это уровни Пи-мышления: off, minimal, low, medium, high, xhigh, max. Карты могут содержать дыры; например, модель может выставлять high и max, не выставляя xhigh.

Значения имеют три состояния:

Ценить Значение
опущен Стандартные уровни до high используют сопоставление поставщика по умолчанию; расширенные уровни xhigh и max не поддерживаются
нить Уровень поддерживается, и это значение отправляется провайдеру.
null Уровень не поддерживается и скрыт/пропущен/зарезан

Пример модели, которая поддерживает только рассуждения «выключено», «высокое» и «максимальное»:

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

Пример модели, в которой мышление невозможно отключить:

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

Миграция: старые конфигурации, использовавшие compat.reasoningEffortMap, должны переместить это сопоставление на уровень модели thinkingLevelMap. Используйте null для уровней, которые не должны отображаться в пользовательском интерфейсе.

Переопределение встроенного Providers

Направьте встроенного провайдера через прокси без переопределения модели:

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

Все встроенные модели Anthropic остаются доступными. Существующая аутентификация OAuth или API key продолжает работать.

Чтобы объединить пользовательские модели со встроенным поставщиком, включите массив models:

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

Семантика слияния:

  • Встроенные модели сохраняются.
  • Пользовательские модели обновляются с помощью id внутри поставщика.
  • Если пользовательская модель id соответствует встроенной модели id, пользовательская модель заменяет эту встроенную модель.
  • Если пользовательская модель id новая, она добавляется вместе со встроенными моделями.

Переопределения для каждой модели

Используйте modelOverrides, чтобы настроить встроенные модели и соответствующие модели, зарегистрированные в расширении, без замены полного списка моделей поставщика.

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

modelOverrides поддерживает следующие поля для каждой модели: name, reasoning, thinkingLevelMap, input, cost (частично), contextWindow, maxTokens, samplingParams (объединены по ключу), headers, compat.

Direct OpenAI GPT-5.6 Sol, Terra и Luna по умолчанию используют контекстное окно 272000, поэтому запросы остаются в пределах ценовой категории OpenAI с коротким контекстом. Чтобы включить контекстное окно OpenAI размером 1,05M, увеличьте его для каждой используемой вами модели:

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

При переопределении сохраняются встроенные метаданные цен. Запросы с общим количеством входных токенов более 272 000 используют скорость GPT-5.6 для длинного контекста для всего запроса. При необходимости примените то же переопределение к gpt-5.6-terra или gpt-5.6-luna.

Замечания по поведению:

  • modelOverrides применяются к моделям встроенных поставщиков и соответствующим моделям поставщиков, зарегистрированным в расширении.
  • Неизвестные идентификаторы моделей игнорируются.
  • Вы можете комбинировать baseUrl/headers уровня поставщика с modelOverrides.
  • Переопределение name изменяет только соответствие модели и текст дополнительных сведений; в нижнем колонтитуле и списках основных моделей по-прежнему отображается модель id.
  • Если для поставщика также определено models, пользовательские модели объединяются после встроенных переопределений. Пользовательская модель с тем же id заменяет переопределенную запись встроенной модели.

Совместимость антропных сообщений

Для провайдеров или прокси, использующих api: "anthropic-messages", используйте compat для управления совместимостью запросов, специфичных для Anthropic.

По умолчанию pi отправляет eager_input_streaming: true для каждого инструмента. Если прокси-сервер или серверная часть, совместимая с Anthropic, отклоняет это поле, установите для supportsEagerToolInputStreaming значение false. Pi будет опускать tools[].eager_input_streaming и вместо этого отправлять устаревший бета-заголовок fine-grained-tool-streaming-2025-05-14 для запросов с поддержкой инструментов.

Некоторые антропные модели требуют адаптивного мышления (thinking.type: "adaptive" плюс output_config.effort) вместо устаревшей полезной нагрузки мышления, основанной на бюджете. Встроенные модели устанавливают это автоматически. Для пользовательских поставщиков или псевдонимов, которые направляются к этим моделям, установите от forceAdaptiveThinking до true.

Некоторые провайдеры, совместимые с Anthropic, выдают блоки мышления с пустыми подписями и все равно ожидают их воспроизведения. Установите от allowEmptySignature до true только для этих поставщиков; настоящий Антропик отвергает пустые мыслительные сигнатуры.

Встроенные антропные модели включают supportsStrictTools в метаданных модели. Пользовательские модели, совместимые с Anthropic, должны установить для него значение true, если их конечная точка принимает строгие определения инструмента схемы 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"]
        }
      ]
    }
  }
}
Поле Описание
supportsEagerToolInputStreaming Принимает ли поставщик eager_input_streaming для каждого инструмента. По умолчанию: true. Установите значение false, чтобы опустить это поле и использовать устаревший заголовок бета-версии детальной потоковой передачи инструмента для запросов с поддержкой инструмента.
supportsLongCacheRetention Принимает ли поставщик Anthropic длительное хранение кэша (cache_control.ttl: "1h"), когда срок хранения кэша равен long. По умолчанию: true.
sendSessionAffinityHeaders Отправлять ли x-session-affinity из идентификатора сеанса, когда кэширование включено. По умолчанию: определяется автоматически для известных поставщиков.
supportsCacheControlOnTools Принимает ли поставщик маркеры cache_control в стиле Anthropic в определениях инструментов. По умолчанию: true.
forceAdaptiveThinking Отправлять ли адаптивное мышление (thinking.type: "adaptive" плюс output_config.effort) для этой модели. Встроенные адаптивные модели устанавливают это автоматически. По умолчанию: false.
allowEmptySignature Следует ли воспроизводить пустые мыслительные подписи как signature: "" вместо преобразования мыслей в текст. По умолчанию: false.
supportsStrictTools Принимает ли поставщик строгие определения инструмента схемы JSON. По умолчанию: false; встроенные антропные модели позволяют использовать его в сгенерированных метаданных.

Совместимость с OpenAI

Для провайдеров с частичной совместимостью с OpenAI используйте поле compat.

  • На уровне поставщика compat применяет значения по умолчанию ко всем моделям этого поставщика.
  • compat на уровне модели переопределяет значения уровня поставщика для этой модели.
{
  "providers": {
    "local-llm": {
      "baseUrl": "http://localhost:8080/v1",
      "api": "openai-completions",
      "compat": {
        "supportsUsageInStreaming": false,
        "maxTokensField": "max_tokens"
      },
      "models": [...]
    }
  }
}
Поле Описание
supportsStore Провайдер поддерживает поле store
supportsDeveloperRole Используйте роль developer и system
supportsReasoningEffort Поддержка параметра reasoning_effort
supportsUsageInStreaming Поддерживает stream_options: { include_usage: true } (по умолчанию: true)
supportsFinishReason Включают ли потоковые ответы finish_reason. Когда false, pi выводит stop или toolUse, когда поток заканчивается. По умолчанию: true.
maxTokensField Используйте max_completion_tokens или max_tokens.
requiresToolResultName Включайте name в сообщения о результатах работы инструмента.
requiresAssistantAfterToolResult Вставьте сообщение помощника перед сообщением пользователя после результатов инструмента.
requiresThinkingAsText Преобразуйте мыслительные блоки в обычный текст
requiresReasoningContentOnAssistantMessages Включать пустой reasoning_content во все воспроизводимые сообщения помощника, если включено рассуждение.
thinkingFormat Используйте reasoning_effort, openrouter, deepseek, together, baseten, zai, qwen, chat-template или qwen-chat-template параметры мышления.
chatTemplateKwargs значения chat_template_kwargs для thinkingFormat: "chat-template"; используйте { "$var": "thinking.enabled" } или { "$var": "thinking.effort" } для значений мышления, контролируемых числом Пи
chatTemplateArgs значения chat_template_args для thinkingFormat: "baseten"; используйте { "$var": "thinking.enabled" } или { "$var": "thinking.effort" } для значений мышления, контролируемых числом Пи
cacheControlFormat Используйте маркеры cache_control в стиле Anthropic в системной подсказке, последнем определении инструмента и текстовом содержимом последнего пользователя, помощника или результата инструмента. В настоящее время поддерживается только anthropic.
sendSessionAffinityHeaders Для openai-completions отправляйте заголовки привязки сеанса из идентификатора сеанса, когда кэширование включено. По умолчанию: false.
sessionAffinityFormat Для openai-completions и openai-responses формат заголовка привязки к сеансу: openai отправляет session_id/x-client-request-id (дополнения также x-session-affinity), openai-nosession опускает заголовок session_id, содержащий подчеркивание, openrouter отправляет x-session-id. Не влияет на параметр тела prompt_cache_key. По умолчанию: определяется автоматически.
supportsStrictMode Принимает ли поставщик строгие определения инструмента функции схемы JSON. Значения по умолчанию зависят от API; встроенные модели OpenAI содержат явные метаданные о возможностях.
supportsOpenAIGrammarTools Используют ли OpenAI-совместимые API пользовательские инструменты грамматики Lark/regex. Когда false, инструменты с грамматическими ограничениями возвращаются к обычным функциональным инструментам. По умолчанию: false; встроенный каталог моделей позволяет использовать его для моделей GPT-5+ на OpenAI, OpenAI Codex, Azure OpenAI, GitHub Copilot, opencode и Cloudflare AI Gateway.
deferredToolsMode Используйте отложенную сериализацию инструмента для конкретного поставщика. В настоящее время для OpenAI-совместимого формата завершения чата Кими поддерживается только "kimi".
supportsLongCacheRetention Принимает ли поставщик длительное хранение кэша, когда сохранение кэша равно long: prompt_cache_retention: "24h" для кэширования подсказок OpenAI или cache_control.ttl: "1h", когда cacheControlFormat равно anthropic. По умолчанию: true.
openRouterRouting Настройки маршрутизации провайдера OpenRouter. Этот объект отправляется как есть в поле provider поля OpenRouter API request.
vercelGatewayRouting Конфигурация маршрутизации Vercel AI Gateway для выбора провайдера (only, order)

openrouter использует reasoning: { effort }. together использует reasoning: { enabled }, а также reasoning_effort, когда supportsReasoningEffort включено. qwen использует верхний уровень enable_thinking. Используйте qwen-chat-template для локальных Qwen-совместимых серверов, которым требуются chat_template_kwargs.enable_thinking и preserve_thinking. Используйте chat-template для шаблонов чатов vLLM/Hugging Face, для которых требуется настраиваемый chat_template_kwargs, например chatTemplateKwargs: { "thinking": { "$var": "thinking.enabled" } } для шаблонов DeepSeek V3.x. Используйте thinkingFormat: "baseten" с chatTemplateArgs для поставщиков, которые предоставляют элементы управления переключением через chat_template_args и при необходимости поддерживают reasoning_effort верхнего уровня.

cacheControlFormat: "anthropic" предназначен для поставщиков, совместимых с OpenAI, которые предоставляют кэширование подсказок в стиле Anthropic с помощью маркеров cache_control в текстовом содержимом и определениях инструментов.

Пример:

{
  "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
              }
            }
          }
        }
      ]
    }
  }
}

Пример шлюза 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"]
            }
          }
        }
      ]
    }
  }
}