Создайте структурированную сводку документа

PythonBeginner
Практиковаться сейчас

Введение

Команде эксплуатации нужна структурированная сводка короткого отчёта об инциденте. Модель может создавать убедительный текст, но приложению нужны предсказуемые поля и отклонение недопустимого вывода. Вы запросите сводку JSON через Bedrock Converse, разберёте её в Python и проверите отказ на явно обозначенных локальных примерах.

Вы должны знать основы Python, JSON и запросы Converse предыдущей работы. Каждая новая VM предоставляет документ, настроенную идентификацию и лимит вывода. Файлы и учётные данные предыдущих VM не нужны.

Связь с сертификацией

Сертификация Задача экзамена Практика
AI Practitioner (AIF-C01) Задача 3.2 Задать формат и проверить ответ до использования приложением.

Концептуальная схема draw.io: документ поступает в Bedrock Converse; разбор и проверка выбирают пригодную сводку или контролируемое отклонение.

Изучите документ и обязательные поля

На этом шаге вы изучите предоставленный синтетический отчёт и определите структуру для использующего сводку приложения.

Начните в рабочем каталоге:

cd /home/labex/project

Документ — обычный текст. Прочитайте его командой cat, выводящей файл:

cat incident.txt

Он описывает INC-204: ошибка настройки оформления заказа вызвала 30 минут неудачных оформлений. Команда вернула предыдущую настройку и восстановила сервис. Дополнительный тест настройки запланирован, но не завершён. Эти факты ограничивают сводку.

Приложение ожидает ровно три поля: incident_id, impact и next_action, каждое с непустой строкой. Схема описывает эту форму; корректного JSON недостаточно, поскольку список, пропущенное поле или число также могут быть корректным JSON. Прочитайте предоставленную схему:

cat summary-schema.json

Справка объясняет желаемый результат. Вы обеспечите поля обычным Python; сама справка не гарантирует соблюдения моделью. Запросить JSON и проверить JSON — разные обязанности.

Создайте и проверьте структурированную сводку

На этом шаге вы создадите небольшой Python-командный скрипт, который запрашивает сводку и проверяет текст до сообщения об успехе.

boto3 — AWS SDK для Python. Он установлен в предоставленной среде и использует настроенные учётные данные и endpoint. Код вызывает converse, уже изученную операцию CLI. maxTokens ограничивает вывод; клиент отключает автоматические повторы, чтобы неоднозначный сбой незаметно не отправил ещё один запрос модели.

Создайте summary.py с этим кодом. parse_response проверяет причину завершения, разбирает текст через json.loads, проверяет точные ключи и типы. ValueError обозначает контролируемое отклонение; ClientError или ошибка соединения сообщаются без раскрытия учётных данных и полной ошибки сервиса. Необязательный --response-file читает локальный ответ для теста парсера и не отправляет запрос модели:

cat > summary.py <<'EOF'
import argparse
import json
from pathlib import Path
import boto3
from botocore.config import Config
from botocore.exceptions import BotoCoreError, ClientError


def parse_response(response):
    if not isinstance(response, dict):
        raise ValueError("invalid_response")
    if response.get("stopReason") != "end_turn":
        raise ValueError("incomplete_response")
    try:
        text = response["output"]["message"]["content"][0]["text"]
        value = json.loads(text)
        expected = {"incident_id", "impact", "next_action"}
        if not isinstance(value, dict) or set(value) != expected:
            raise ValueError("invalid_fields")
        if any(not isinstance(v, str) or not v.strip() for v in value.values()):
            raise ValueError("invalid_field_type")
        if value["incident_id"] != "INC-204":
            raise ValueError("unexpected_incident")
        return value
    except (KeyError, IndexError, TypeError, json.JSONDecodeError) as error:
        raise ValueError("invalid_response") from error


def main():
    parser = argparse.ArgumentParser()
    parser.add_argument("--response-file", type=Path)
    args = parser.parse_args()
    try:
        if args.response_file:
            response = json.loads(args.response_file.read_text())
        else:
            client = boto3.client("bedrock-runtime", config=Config(
                connect_timeout=5, read_timeout=150,
                retries={"total_max_attempts": 1}))
            response = client.converse(
                modelId="labex.text-v1:0",
                system=[{"text": "Summarize only facts supplied in the incident document. Return exactly one JSON object with string fields incident_id, impact and next_action. No Markdown fences, extra keys or surrounding prose. Do not turn planned work into completed work."}],
                messages=[{"role": "user", "content": [
                    {"text": Path("incident.txt").read_text()}]}],
                inferenceConfig={"maxTokens": 768, "temperature": 0})
            Path("response.json").write_text(json.dumps(response, indent=2))
        value = parse_response(response)
    except (ValueError, KeyError, TypeError):
        print(json.dumps({"status": "rejected", "reason": "invalid_model_output"}))
        return 2
    except (BotoCoreError, ClientError):
        print(json.dumps({"status": "unavailable", "reason": "inference_failed"}))
        return 3
    print(json.dumps({"status": "ok", "summary": value}, indent=2))
    return 0


if __name__ == "__main__":
    raise SystemExit(main())
EOF

Запустите скрипт установленной Python-средой AWS. Заключительное > summary.json сохраняет напечатанный результат:

/opt/labex/aws/venv/bin/python summary.py > summary.json

Дождитесь приглашения и изучите результат:

cat summary.json

Успешный запуск содержит "status": "ok" и объект summary с тремя строковыми полями. Прочитайте также исходный ответ Converse:

python3 -m json.tool response.json

response.json сохраняет реальный вывод, причину завершения и токены. Разверните завершённый запрос в AWS View и сравните текст. Формулировки могут отличаться. Проверьте, что impact отражает неудачные оформления, а next_action — запланированную работу. Соответствие схеме не доказывает точность этих утверждений.

Реальная AWS View VM: завершённый запрос содержит JSON-сводку, токены и остаток лимита. Формулировки, время и лимит могут отличаться.

Если скрипт отклонил результат, прочитайте исходный ответ перед повтором. Модель может обрезать текст или игнорировать формат; не подменяйте сводку успехом, зашитым в код. Неудачный запрос может расходовать лимит.

Проверьте границу недопустимых ответов

На этом шаге вы подтвердите отказ для ошибочного JSON, неверных типов и обрезанных ответов без нового запроса модели.

В fixtures/ находятся намеренно подготовленные входы для тестирования парсера. Это локальные данные, не результаты вывода. Выведите их список:

ls fixtures

Запустите скрипт на примере ошибочного JSON:

/opt/labex/aws/venv/bin/python summary.py --response-file fixtures/malformed.json

Ожидается {"status": "rejected", "reason": "invalid_model_output"}. Код выхода 2 обозначает контролируемое отклонение. echo $? выводит код непосредственно предыдущей команды:

echo $?

Ответ может быть корректным JSON и нарушать схему. Проверьте пример с числовым impact:

/opt/labex/aws/venv/bin/python summary.py --response-file fixtures/wrong-type.json

Он должен дать такое же отклонение. Даже полный на вид объект нужно отклонить, если модель достигла предела токенов. Проверьте эту границу:

/opt/labex/aws/venv/bin/python summary.py --response-file fixtures/truncated.json

Пример отклоняется, потому что его stopReason — max_tokens. Тесты не печатают успешных сводок и не добавляют запросы в AWS View.

Наконец, снова разберите реальный сохранённый ответ:

/opt/labex/aws/venv/bin/python summary.py --response-file response.json

Он должен вернуть status: ok. Вы проверили пригодный реальный ответ и контролируемые ошибочные входы. Примеры парсера не являются доказательством работы модели: завершённый запрос и исходный ответ доказывают это отдельно.

Удалите созданные файлы упражнения

На этом шаге после функциональных проверок вы удалите свой скрипт и два файла результата.

Документ, схема и примеры парсера относятся к новой среде. Сохраните их и backend-сервис. rm удаляет только три названных файла учащегося:

rm summary.py summary.json response.json

Убедитесь, что предоставленные входы остались:

ls

Converse не создаёт постоянный сервер для удаления. Удаление локальных файлов не возвращает credits и не стирает реальные записи AWS View.

Заключение

Вы получили структурированную сводку из реального ответа Bedrock Converse, обеспечили имена и типы полей, проверили завершение и отклонили контролируемые недопустимые ответы. Вы также отделили проверку фактов от схемы и удалили только свои файлы.

Подробнее см. в документации AWS: Содержимое ответа, причины остановки и использование Converse.