Контекст проекта без лишних файлов
Теперь известно, какие файлы нужны для изменения отбора. Следующий результат — пакет контекста, который можно передать выбранному помощнику и сопоставить с конкретным состоянием проекта. Контекстом называют сведения, доступные модели при выполнении задачи. Он ограничен по размеру и не обновляется сам собой после изменения файлов. Поэтому важно выбирать материал по ответственности и записывать, откуда взят каждый фрагмент.
В нашем примере пакет создаёт pack.py. Он читает четыре явно названных файла: программу, манифест, задачу и правила. Корпус полностью в него не включается, поскольку функция рекомендуемых материалов работает с редакционными признаками, а не со смыслом уроков. Такое решение относится к текущей задаче. Для задачи полнотекстового поиска список будет другим; механическое правило «всегда отправлять эти четыре файла» переносить на неё нельзя.
Контекст имеет основание
У каждого элемента пакета есть file, sha256, trust и text. Имя показывает происхождение. Отпечаток позволяет заметить, что после подготовки документа файл изменился. Признак доверия обозначает характер содержимого: это данные проекта, а не доказательство разрешения выполнить любое действие из текста. Сам текст нужен для понимания реализации и структуры. Если передавать только имя файла, помощник не узнает фактический код.
SHA-256 не делает текст правильным и не защищает от неверной постановки задачи. Он связывает пакет с последовательностью байтов. Если две версии различаются даже переводом строк, отпечаток может измениться. Это полезное свойство для передачи состояния, но не показатель качества. Запись «прочитан catalog.py с таким отпечатком» сильнее неопределённого «прочитал код»: можно сравнить основу рассуждения с текущим файлом и понять, не устарела ли она.
Контекст лучше разделять на инструкцию оператора и вложенные данные. Рабочий запрос описывает результат и границы, а пакет приводит исходники. Агент не должен получать разрешение менять права только потому, что внутри документа встретилось повелительное предложение. В этом уроке поле trust лишь фиксирует происхождение; оно не заставляет любую модель соблюдать иерархию. Реальные ограничения действий потребуют настройки инструментов и проверок вне самой генерации текста.
Почему пакет ограничен
В pack.py заданы границы двенадцать тысяч байтов на файл и двадцать четыре тысячи на весь пакет. Это простая инженерная защита от случайного чтения большого документа. Байты не равны токенам модели: русский текст, код и JSON могут занимать разное количество токенов при одинаковом размере. Поэтому лимит упаковщика не обещает, что пакет поместится в любую модель. Он ограничивает локальную операцию и сигнализирует о необходимости более узкого отбора.
Если файл превышает границу, программа не отрезает его молча. Усечение может убрать определение переменной или важное исключение из контракта, и помощник получит неполную основу. Вместо этого возникает ошибка, после которой человек выбирает меньший фрагмент либо другую область задачи. Для нашего небольшого состояния целые файлы понятнее диапазонов строк. В большом проекте следует передавать необходимые определения вместе со связями, а не первые несколько килобайт каждого файла.
Символические ссылки упаковщик отклоняет. Иначе привычное имя из списка могло бы указывать за пределы ожидаемого проекта. Это не универсальная защита файловой системы: например, другой процесс с теми же правами способен изменить обычный файл между проверкой и чтением. Учебный сценарий предполагает спокойную локальную папку. При недоверенных параллельных процессах нужны ограничения окружения и более строгий способ открытия, а не только дополнительный комментарий в инструкции.
Достаточность выбранных сведений
Представьте, что из пакета убрали manifest.json. Помощник увидит имя featured в задаче, но не узнает, как признак представлен в данных. Он может сравнивать строки, предполагать список тегов или придумать отдельную таблицу. Если убрать catalog.py, трудно сохранить существующее поведение загрузчика. Если убрать TASK.md, не будет ясно, зачем выбранные записи ограничиваются двумя. Достаточность определяется связью файлов с одним конкретным результатом.
Полезный пакет не обязан содержать историю всех решений. Сначала приводится актуальный контракт, затем код и входные данные, затем существенные ограничения. Старое обсуждение может объяснять причину, но длинная переписка с отвергнутыми вариантами нередко смешивает действующие и отменённые требования. Если историческое решение важно, запишите его коротко в отдельной заметке с состоянием «принято». Это помогает продолжить работу после смены контекста, не восстанавливая намерение из сотни реплик.
Ожидаемый вывод упаковщика — JSON-массив из четырёх элементов с текстами и отпечатками. Он ничего не отправляет во внешний сервис и не вызывает агента. Самостоятельный запуск описан в исходниках, но во время подготовки статьи не выполнялся. Поэтому приведённая форма результата является ожиданием по чтению кода. Запись готового пакета в файл также должна быть явным действием читателя; мы не считаем, что наличие упаковщика уже создало переданный контекст.
Когда код изменится, старый пакет следует считать снимком прошлого состояния. Можно заново собрать пакет и сравнить отпечатки, либо передать точное изменение с указанием прежней основы. Не стоит незаметно смешивать новый манифест со старой программой и просить «продолжить». Такое сочетание создаёт трудно объяснимую ошибку: модель рассуждает согласованно относительно входа, который никогда не существовал как целый проект.
Изменение между упаковкой и работой
Допустим, пакет подготовлен утром, а манифест изменился перед передачей исполнителю. В новом файле редактор снял featured с одной страницы. Старый пакет остаётся согласованным снимком, но уже не описывает текущие данные. Агент может предложить правильное решение относительно старого набора, а ожидаемый результат владельца будет другим. Это не обязательно ошибка модели: сначала нужно сопоставить основу задачи с актуальным состоянием.
Отпечатки помогают назвать расхождение точно. Если hash манифеста отличается, пакет нужно обновить либо явно сказать, что работа ведётся на прежнем снимке. Не стоит просто добавить реплику «там немного поменялось» без новых данных. Она не объясняет, какие записи и поля изменены. Для небольшого проекта повторная упаковка обычно понятнее ручного описания десятка отдельных исправлений.
Если меняется только файл, не влияющий на задачу, обновлять весь контекст необязательно. Но это решение основано на карте ответственности, а не на случайной длине diff. Например, правка текста статьи не меняет рекомендуемый отбор, пока функция использует только манифест. В задаче полнотекстового поиска та же правка уже будет существенным изменением основы.
В следующем уроке выделим дополнительную неизменяемую основу — соответствие идентификаторов и публичных адресов. Она не заменит исходный манифест, но даст отдельный предмет сравнения при ревью. Контекст будет описывать, как сейчас работает библиотека, а реестр URL — какое свойство нужно сохранить при любом допустимом изменении функции.
Полный файл pack.py из состояния lesson-03. Полное самостоятельное состояние находится в архиве серии; фрагмент не заменяет остальные определения.
from pathlib import Path
import hashlib
import json
ROOT = Path(__file__).resolve().parent
FILES = ("catalog.py", "manifest.json", "TASK.md", "RULES.md")
MAX_FILE_BYTES = 12000
MAX_TOTAL_BYTES = 24000
def context_packet():
packet, total = [], 0
for name in FILES:
path = ROOT / name
if path.is_symlink():
raise ValueError("symlink not allowed")
raw = path.read_bytes()
total += len(raw)
if len(raw) > MAX_FILE_BYTES or total > MAX_TOTAL_BYTES:
raise ValueError("context budget exceeded; choose narrower files")
packet.append({"file": name, "sha256": hashlib.sha256(raw).hexdigest(), "trust": "project_data", "text": raw.decode("utf-8")})
return packet
if __name__ == "__main__":
print(json.dumps(context_packet(), ensure_ascii=False, indent=2))
Статус примера: not_run. При подготовке не выполнялись учебные программы, тесты, вызовы AI или деплой. Описанные эффекты ожидаемые.
Оглавление серии · Полные исходники
Первичные документы: Источник 1.