В ~/.codex/config.toml у меня стоит model_context_window = 1000000. Codex на GPT-6.1 Sol в каждой задаче сообщает окно 828 400. Я разобрал, откуда берётся это число, поднял его до 900 000 своим каталогом моделей и прогнал синтетический вход на 890 547 токенов с контрольными метками.
Контрольный запуск показал больше основного: тот же вход на 888 330 токенов прошёл и без моей правки, при окне 828 400. Ниже – как устроены эти числа, как я мерил и чего мерить не стал.
Замеры сделаны 27.10.2026 на Codex CLI 0.163.0, вход через подписку ChatGPT. Часть данных – из сентябрьских проб на GPT-6 Astra, это помечено.
Откуда 828 400
Codex берёт параметры модели из каталога, который получает с сервера и кэширует в ~/.codex/models_cache.json. Фрагмент записи GPT-6.1 Sol из свежего кэша:
{
"slug": "gpt-6.1-sol",
"context_window": 500000,
"max_context_window": 872000,
"effective_context_window_percent": 95,
"supports_experimental_context": false
}
context_window – окно по умолчанию. max_context_window – предел, выше которого model_context_window из конфига не поднимет. От результата Codex берёт effective_context_window_percent:
872000 × 0.95 = 828400
Я проверил это не на одной сессии. Собрал по журналам ~/.codex/sessions последние 40 задач: 39 на gpt-6.1-sol и одна у служебного codex-auto-review. У всех 39 в событии token_count стоит model_context_window: 828400.
Как читать окно из журнала
Размер окна лежит в событии token_count, поле info.model_context_window. Скрипт печатает последнее найденное значение из файла задачи:
import argparse
import json
from pathlib import Path
parser = argparse.ArgumentParser()
parser.add_argument("rollout", type=Path)
args = parser.parse_args()
latest = None
with args.rollout.open(encoding="utf-8") as stream:
for line in stream:
try:
event = json.loads(line)
except json.JSONDecodeError:
continue
payload = event.get("payload", {})
if event.get("type") != "event_msg":
continue
if payload.get("type") != "token_count":
continue
info = payload.get("info") or {}
window = info.get("model_context_window")
if window is not None:
latest = {
"timestamp": event.get("timestamp"),
"model_context_window": window,
}
if latest is None:
raise SystemExit("Запись размера окна не найдена")
print(json.dumps(latest, ensure_ascii=False, indent=2))
python3 inspect-context.py ~/.codex/sessions/2026/10/27/rollout-....jsonl
В том же событии есть last_token_usage – фактический вход и выход последнего запроса. По нему ниже и считаю.
Формат журнала не документирован как стабильный. После обновления клиента поле может переехать.
Свой каталог: 900 000
В справке конфигурации есть model_catalog_json – путь к JSON-каталогу, который Codex загружает при старте. Я собрал копию свежего серверного каталога и поменял у gpt-6.1-sol два поля:
|
Поле |
Сервер |
Моя копия |
|---|---|---|
|
|
872000 |
1000000 |
|
|
95 |
90 |
1000000 × 0.90 = 900000
Чтобы не трогать рабочий конфиг, подключал копию только к отдельному запуску:
codex exec --json --skip-git-repo-check -s read-only
-m gpt-6.1-sol
-c model_catalog_json='"/path/to/sol-1m-catalog.json"'
-c model_context_window=1000000
"Ответь одним словом: ОК"
Журнал этой задачи показал model_context_window: 900000. Вход на «ОК» – 57 187 токенов. Это служебная часть моей установки: инструкции, правила, описания инструментов и навыков. В минимальной установке она будет меньше.
Запас в 10% я взял из сентябрьских проб на GPT-6 Astra. Тогда успешный вход был 900 089 токенов, а пробы с наполнителем от 909 000 токенов и выше заканчивались ошибкой переполнения контекста.
Как устроен тест с метками
Нужен вход почти на 900 тысяч токенов, который легко проверить. В сентябре первый вариант на 1 720 376 символов остановился ещё до модели: клиент не пропустил одно сообщение длиннее 1 048 576 символов. Поэтому наполнитель должен быть плотным по токенам.
Я взял случайные иероглифы из диапазона U+4E00-U+9FA4 с фиксированным зерном генератора. Пробный запуск на 30 302 символа дал 115 300 токенов входа, то есть около 1,9 токена на символ поверх служебной части. Под целевой объём хватило 434 302 символов.
import random, sys
n = int(sys.argv[1])
rnd = random.Random(42)
chars = [chr(c) for c in range(0x4E00, 0x9FA5)]
def block(k):
return "".join(rnd.choice(chars) for _ in range(k))
third = n // 3
text = (
"Задача: в тексте ниже спрятаны ровно три метки вида МЕТКА-1: ..., "
"МЕТКА-2: ..., МЕТКА-3: ... Найди их и ответь одной строкой: значения "
"трёх меток через пробел, по порядку. Команды не запускай, файлы не открывай.nn"
"МЕТКА-1: R7K2n" + block(third) +
"nМЕТКА-2: Q9M4n" + block(third) +
"nМЕТКА-3: W3T8n" + block(n - 2 * third) +
"nnКонец текста. Ответь значениями трёх меток."
)
open(sys.argv[2], "w", encoding="utf-8").write(text)
Текст подаётся через stdin: codex exec ... - < big.txt.
Результаты
|
Запуск |
Каталог |
Окно в журнале |
|
Метки |
Время запуска |
|---|---|---|---|---|---|
|
Короткий «ОК» |
свой |
900000 |
57 187 |
– |
– |
|
Калибровка, 30 302 символа |
свой |
900000 |
115 300 |
3 из 3 |
– |
|
Большой, 434 302 символа |
свой |
900000 |
890 547 |
3 из 3 |
62 с |
|
Контроль, тот же текст |
серверный |
828400 |
888 330 |
3 из 3 |
60 с |
В большом запуске cached_input_tokens – 9 216, в контрольном – 0. Время – весь запуск codex exec вместе со стартом клиента.
Разница во входе между последними строками – 2 217 токенов. Наполнитель одинаковый, разница в служебной части между запусками. Точную причину я не разбирал.
Что показал контрольный запуск
Я ждал, что при окне 828 400 вход на 888 тысяч не пройдёт. Он прошёл, ответ правильный.
Значит, model_context_window в Codex не режет одно входящее сообщение. В справке поле описано как «Context window tokens available to the active model». Тибо Сотто из команды Codex, когда показывал настройку миллиона, объяснял так: «A larger context window lets Codex retain more code, tool output, and conversation history before summarizing older material». То есть число окна задаёт, сколько истории клиент держит до автоматического сжатия.
За сам порог сжатия отвечает отдельный параметр model_auto_compact_token_limit. Без него берутся значения модели по умолчанию. Есть и model_auto_compact_token_limit_scope: total считает весь активный контекст, body_after_prefix – только прирост после перенесённого префикса.
Мой тест однократный: один запрос, одна реплика. На скольких токенах Codex начнёт сжимать длинную сессию с окном 828 400 и 900 000, я не мерил.
Где настоящий потолок
На странице GPT-6.1 Sol в документации API указано: окно 1 050 000 токенов, вход не больше 922 000. С сентябрьскими ошибками это сходится: наполнитель от 909 000 токенов плюс служебная часть давал больше 922 000.
Там же написано, что запросы больше 272 тысяч токенов входа в API стоят вдвое дороже. Для подписки, по словам Тибо Сотто, доплаты за длинный контекст у GPT-6.1 Sol нет. В документации я этого не нашёл, только в его посте от 11.10.2026. В том же посте сказано, что окно GPT-6.1 Sol по умолчанию в Codex подняли с 272 тысяч до 500 тысяч.
Сколько лимита подписки съел один запрос на 890 тысяч, я не замерял.
Экспериментальное управление контекстом больше не работает
В первой версии статьи большой раздел был про [features.context_management] experimental_mode = true. 11.09.2026 в 21:13 UTC я проверил продолжение задачи после смены окна: модель восстановила контрольное значение после перехода.
12.09.2026 в 03:20 UTC Тибо Сотто написал, что команда отключила «an opt-in context management experiment that could cause early stops or replies to older messages». По его оценке, это задело 4-5 тысяч пользователей.
Сейчас справка конфигурации описывает параметр так: «The feature is not currently available». У GPT-6.1 Sol, GPT-6.1 Terra и GPT-6 Astra в серверном каталоге supports_experimental_context: false. Флаг в конфиге у меня остался, но ничего не включает. Мой сентябрьский тест прошёл примерно за шесть часов до отключения, повторить его сейчас нельзя.
Риски своего каталога
model_catalog_json заменяет серверный каталог статическим файлом. Это видно на моей же установке.
В сентябре я поднял предел только у gpt-6-astra. Потом основной моделью стала gpt-6.1-sol, а в моей копии у неё остались старые 872 000 и 95%. Прибавка до 900 000 тихо пропала, все рабочие задачи шли на 828 400. Заметил я это при подготовке статьи.
В той же копии нет модели gpt-6.1-terra, которая в серверном каталоге уже есть. У gpt-6.1-sol там старое окно по умолчанию 272 000 вместо серверных 500 000.
Если ставить свой каталог, после каждого обновления Codex его надо собирать заново из свежего models_cache.json и проверять окно в новой задаче.
Итог
-
model_context_window = 1000000на GPT-6.1 Sol даёт 828 400. Предел задаёт серверный каталог. -
Своим каталогом можно поднять до 900 000. Это сдвигает момент сжатия истории, одиночный вход это число не ограничивает.
-
Вход 888-890 тысяч токенов прошёл в обоих вариантах, метки найдены.
-
Потолок входа модели – 922 000 токенов по документации API.
-
Экспериментальное управление контекстом отключено с 12.09.2026.
В моих 39 рабочих задачах самый большой вход был 389 543 токена. Для моей работы 828 тысяч хватает с запасом. Следующий тест – длинная сессия до автосжатия: на каком объёме оно срабатывает при разных окнах и сколько меток остаётся после него.
Больше практической информации по работе с нейросетями Вы можете найти в Telegram-канале «ИИ-агенты: с нуля до своих проектов»
Автор: MaximSamus


