Циклы исправления и проверки
Исправление некорректного вывода
«Циклы исправления и проверки» — бесплатный урок AI Prompt Engineering на CoddyKit. Это урок 4 из 4. Ты можешь прочитать весь урок бесплатно ниже — а потом практиковать его прямо в браузере с встроенным редактором кода и ИИ-репетитором 24/7. Это часть пути обучения AI Prompt Engineering, и твой прогресс синхронизируется между веб-версией и приложением CoddyKit. Курс AI Prompt Engineering содержит 4 уроков всего.
Зачем нужны циклы исправления
Даже при наличии схем результат может оказаться неверным: усечённый из-за ограничения числа токенов JSON, придуманные моделью дополнительные поля, строка вместо требуемого числа или нарушение бизнес-правила. Цикл исправления обнаруживает ошибку и передаёт информацию о ней обратно модели для исправления.
Это страховочная сетка, превращающая показатель успеха 98% в 99,9%.
Цикл проверки и исправления
Классический цикл: сгенерировать результат, проверить его и, если он некорректен, повторить запрос с конкретной ошибкой, но не больше заданного числа попыток.
def generate_valid(prompt, schema, max_tries=3):
msgs = [{'role': 'user', 'content': prompt}]
for _ in range(max_tries):
out = call_model(msgs)
ok, err = validate(out, schema)
if ok:
return out
msgs.append({'role': 'assistant', 'content': out})
msgs.append({'role': 'user',
'content': 'Invalid. Fix this error and resend JSON only: ' + err})
raise ValueError('repair budget exhausted')Конкретные ошибки лучше общих
Качество исправления зависит от точности обратной связи. «Некорректный JSON» мало помогает; «Поле оценки должно содержать целое число от 1 до 5, получено 7» почти всегда исправляет проблему за один цикл.
Передавайте модели точное сообщение об ошибке от вашего средства проверки: путь и причину.
def validate(obj, schema):
v = jsonschema.Draft202012Validator(schema)
errs = sorted(v.iter_errors(obj), key=lambda e: e.path)
if not errs:
return True, None
msg = '; '.join(f"{list(e.path)}: {e.message}" for e in errs)
return False, msgМногоуровневая проверка
Проверка выполняется на нескольких уровнях; сначала проверяйте самый дешёвый:
- Синтаксический — разбирается ли результат как JSON?
- Структурный — соответствует ли результат схеме?
- Семантический — удовлетворяют ли значения бизнес-правилам и инвариантам между полями?
Скидка не может превышать сумму до её вычета, даже если оба значения являются корректными числами; это семантическая проверка.
def semantic_ok(o):
return o['discount'] <= o['subtotal'] and o['total'] == o['subtotal'] - o['discount']Детерминированное предварительное исправление
Прежде чем тратить вызов модели, попробуйте недорогие детерминированные исправления распространённых дефектов:
- Удалите ограждения кода в разметке Markdown.
- Извлеките самый внешний объект JSON из окружающего пояснительного текста.
- Удалите завершающие запятые.
Переходите к исправлению с помощью модели только в том случае, если детерминированная очистка не удалась.
def extract_json(text):
text = text.strip().removeprefix('json').strip()
start, end = text.find('{'), text.rfind('}')
if start != -1 and end != -1:
return text[start:end + 1]
return textОбработка усечения
Если finish_reason == 'length', JSON обрезан; исправлять фрагмент бесполезно. Вместо этого увеличьте max_tokens, уменьшите запрошенный объём данных или передавайте результат потоком и запросите продолжение. Различайте усечение и некорректный результат, поскольку для них требуются противоположные действия.
if resp.choices[0].finish_reason == 'length':
# do NOT feed truncated JSON back; regenerate with more room
return retry_with(max_tokens=resp_max * 2)Ограничьте цикл
Неограниченное исправление создаёт угрозу для затрат и времени отклика, а зависшая модель может зациклиться навсегда. Всегда ограничивайте число попыток, добавляйте бюджет на каждый запрос и определяйте запасной вариант: корректно ухудшить функциональность, поставить запрос в очередь на проверку человеком или вернуть безопасное значение по умолчанию.
try:
data = generate_valid(prompt, schema, max_tries=3)
except ValueError:
log_for_review(prompt)
data = SAFE_DEFAULTИсправление внутри вызовов инструментов
При вызове функций каналом исправления служит результат инструмента. Верните структурированную ошибку, и модель самостоятельно исправится на следующем цикле; отдельный цикл не нужен.
msgs.append({'role': 'tool', 'tool_call_id': call.id,
'content': json.dumps({'error': 'amount must be positive', 'got': args['amount']})})
# next model turn will re-issue the call with a corrected argumentИдемпотентность и побочные эффекты
Если цикл исправления оборачивает действие, а не только генерацию, убедитесь, что повторные попытки идемпотентны. Используйте ключи идемпотентности, чтобы повторный вызов не привёл к двойному списанию средств и не создал дубликат записи. Проверяйте данные до фиксации побочных эффектов, никогда не после.
Отслеживайте долю исправлений
Доля исправлений — ранний показатель качества. Её рост означает ухудшение формулировки запроса, слишком строгую схему или смещение модели. Записывайте в журнал число попыток на успешный результат и наиболее частые пути ошибок, а при их резком росте отправляйте оповещение.
metrics.histogram('llm.repair.attempts', tries)
metrics.increment('llm.repair.error', tags={'path': top_error_path})Сочетайте ограничения с исправлением
Самый надёжный конвейер выстраивает защиту в несколько уровней: ограниченное декодирование или строгий режим схемы для сведения числа ошибок к минимуму, детерминированная очистка для дешёвых исправлений и ограниченный цикл исправления с помощью модели для редких оставшихся случаев. Ни одного уровня по отдельности недостаточно.
Быстрая проверка
API возвращает причину завершения «достигнут лимит длины» и усечённый JSON. Как следует поступить?
Итоги
Надёжные конвейеры исправления:
- Проверяйте результат на синтаксическом, структурном и семантическом уровнях.
- Передавайте модели точные ошибки с указанием пути.
- Выполняйте детерминированную очистку до того, как оплачивать вызов модели.
- Отдельно обнаруживайте усечение и генерируйте результат заново.
- Ограничивайте число попыток, обеспечивайте идемпотентность и отслеживайте долю исправлений.
Вы завершили изучение структурированной генерации. Следующий курс: защитные механизмы и проверка выходных данных.
Часто задаваемые вопросы
Урок «Циклы исправления и проверки» бесплатный?
Да — полный текст урока «Циклы исправления и проверки» бесплатно доступен здесь в веб-версии. Чтобы практиковать его интерактивно (встроенный редактор кода и ИИ-репетитор 24/7) и разблокировать остальной курс AI Prompt Engineering, подпишись на CoddyKit PRO. Курс AI Prompt Engineering содержит 4 уроков всего.
Чему я научусь в уроке «Циклы исправления и проверки»?
Исправление некорректного вывода Ты практикуешь AI Prompt Engineering с помощью реального кода, который запускаешь прямо в браузере, и ИИ-репетитор 24/7 отвечает на твои вопросы во время урока.
Нужен ли мне опыт, чтобы начать AI Prompt Engineering?
Предыдущий опыт не требуется. AI Prompt Engineering на CoddyKit структурирован для всех уровней — от новичков до продвинутых, поэтому ты можешь начать отсюда или с самого начала и учиться в своем темпе. Это урок 4 из 4.
Сколько времени занимает урок «Циклы исправления и проверки»?
Большинство уроков CoddyKit занимают около 5–10 минут. Каждый из них компактный и интерактивный, поэтому ты постоянно делаешь прогресс и продолжаешь с того же места в веб-версии и приложении.
Можно ли писать и запускать код в этом уроке AI Prompt Engineering?
Да. Каждый урок AI Prompt Engineering включает встроенный редактор кода, поэтому ты пишешь и запускаешь реальный код прямо в браузере и получаешь моментальную обратную связь от AI — локальная установка не требуется.
Все уроки этого курса
- Зачем нужен структурированный вывод
- JSON Schema в подсказках
- Схемы инструментов и функций
- Циклы исправления и проверки