Главная / Статьи

Разработка, основанная на оценке, для ИИ-агентов: контракты, трейсы и судьи

Рассматривайте оценки как систему CI/CD для агентов: версии запросов — как контракты, отслеживайте выполнения с помощью OpenTelemetry и Tempo, затем тестируйте с помощью детерминистичных проверок и судьи в виде большой языковой модели.

Издатель: REACTAPP.TOP13 мин чтения3072 слов

Источники: **Eval-Driven Development: A Software Engineering Approach to Production-Grade AI Agents**

Большинство команд, разрабатывающих агентные ИИ, рано попадают в ловушку стандартизированных фреймворков. Поиск идеального оркестратора кажется очевидным первым шагом, но тяжелые, абстрактные фреймворки оказываются не решением проблемы, к тому же некоторые из них быстро ухудшаются между версиями. Автоматизация проверки кода, созданная без использования каких-либо фреймворков, показала, насколько мало для этого нужно. Чего не хватало, так это элементов, заимствованных из обычной инженерии программного обеспечения: механизмов оценки, которые функционируют подобно системам CI/CD для агентов.

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

Эта система намеренно является с открытым исходным кодом и не связана с сервисами какого-либо конкретного поставщика. Pydantic AI — это фреймворк агентов, легкая библиотека, ориентированная на схемы, которая не вмешивается в работу системы и рассматривает процедуры оценки как важную функцию. Grafana Tempo с хранилищем S3 хранит трейсы вместо специализированной платформы для мониторинга, а код, сгенерированный ИИ, выполняет запросы к этим трейсам и фильтрует их в зависимости от типа оценки.

Почему большинство агентов не выдерживают нагрузок в производстве

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

Традиционное программное обеспечение обеспечивает непрерывное качество благодаря пайплайнам CI/CD, тестам на единицы, тестам на интеграцию и тестам на регрессию. В недетерминированном мире агентов типичной фатальной проблемой является отсутствие автоматизированной системы оценки и отсутствие механизмов операционного контроля. Для создания зрелых агентов необходимо вернуться к основам: использовать открытую инфраструктуру и рабочий процесс разработки, основанный на оценке (Eval-Driven Development, EDD), способный к масштабированию.

Производственный пайплайн

1. Контракт: версионирование промптов отдельно

Промпты и связанные с ними элементы являются самой важной частью агентной системы, поэтому их не следует хранить внутри кода агента. Код представляет собой лишь «тело» системы, которое довольно легко стабилизировать и версионировать, в то время как промпты постоянно развиваются по мере улучшения моделей.

Пайплайн начинается с версионированного контракта, в котором указано, что должно выполняться: агент, промпт, модель и политика оценки.

[
  {
    "agent_id": "financial_market_headlines",
    "version": 1,
    "agent_model": "openai:gpt-4",
    "prompt": "What are today's major financial market headlines?",
    "eval": {
      "contains": ["market"],
      "max_model_requests": 3,
      "min_tool_calls": 1,
      "max_tool_calls": 5,
      "judge_rubric": "The answer should be a useful response to the user's financial markets question. It should summarize market-relevant information, avoid obviously unrelated content, avoid investment advice, and avoid claiming certainty beyond what the retrieved information supports."
    }
  }
]

Здесь запрос и критерии оценки преднамеренно сокращены в демонстрационных целях, поскольку реальные запросы обычно бывают длинными и подробными. Контракт связывает запрос с запросом для оценки с использованием ИИ-судьи, а также с проверками, не связанными с ИИ, такими как сопоставление ключевых слов с помощью оператора «contains» и установление минимального или максимального количества вызовов инструментов.

2. Время выполнения: движок исполнения

Время выполнения агента отвечает за исполнение контракта. Он вызывает модель, при необходимости использует внешние инструменты через MCP и выполняет саму работу.

Выбор в основном пал на LangGraph против Pydantic AI. Python — не единственный вариант; у Rust тоже есть библиотека в Rig. Однако скорость работы языка сама по себе имеет незначительное значение по сравнению с временем ожидания вывода от ИИ и сетевыми запросами к инструментам MCP, поэтому побеждает крупная и зрелая экосистема ИИ для Python. Pydantic AI был выбран благодаря первоклассной поддержке процедур оценки.

В производственной среде среда выполнения обычно основывается на Kubernetes. Соблазн переусердствовать с архитектурой, моделируя каждый агент как пользовательский ресурс, велик, но циклы синхронизации для быстро меняющихся запросов снизят скорость работы. Сохраняйте лаконичность среды выполнения.

3. Слой наблюдаемости: без слепых зон

Среда выполнения генерирует трейсы, логи, счетчики использования, вызовы моделей и инструментов, показатели задержек и ошибки; всё это фиксируется с помощью OpenTelemetry и хранится в таких системах, как Tempo, Loki и Prometheus. Grafana затем отображает, что делает система в производстве.

4. Слой оценки: CI/CD для ИИ

Именно здесь всё соединяется воедино. Трейсы выполнения из слоя наблюдаемости напрямую поступают в слой оценки, где против реальных трейсов выполняются два вида тестов: детерминистические правила и недетерминистические оценки.

Цикл никогда не прекращается: определить, выполнить, наблюдать, оценить, улучшить, повторить.

Навязывание детерминизма недетерминистической системе

Оценки делятся на две группы. Детерминистические можно точно протестировать с помощью обычного кода. Простым примером может служить запрос к большой языковой модели к сложению двух чисел с последующей проверкой ответа с помощью теста единиц.

В данном случае в запросе требуется информация о новостях финансового рынка на сегодняшний день, что означает, что модель должна хотя бы один раз использовать предоставленный инструмент поиска в интернете. Эта часть является детерминистической и позволяет провести полезный тест. Если результат должен содержать определённые строки, их наличие можно проверить с помощью оператора «Contains».

Уровень 1: тесты детерминизма в реальном времени

Этот набор тестов запускает сегодняшнего агента против версионированного контракта. Pydantic Evals включает в себя параметр MaxToolCalls и проверку наличия текста с помощью оператора Contains. Недостающие элементы, такие как MinToolCalls, добавляются в виде простых обёрток.

uv run python tests/unittest_eval_agent.py

Оценщики собираются в зависимости от конкретного случая:

evaluators=[
    *[Contains(value, case_sensitive=False) for value in case.eval.contains],
    MaxModelRequests(case.eval.max_model_requests),
    MinToolCalls(case.eval.min_tool_calls),
    MaxToolCalls(case.eval.max_tool_calls),
]

Каждый запуск проходит несколько раз, поскольку модели являются недетерминистичными. Одна и та же модель с идентичным запросом и настройками может использовать инструмент в одном запуске и пропустить его в другом. Это особенно заметно у дешевых, менее мощных моделей, и если, скажем, десять запусков завершаются неудачей, это указывает на необходимость более подробного запроса. Запуск с тремя повторениями выглядит так:

(financial-agent2) alex@pop-os:/ssd/ai_works/financial_agent2$ uv run python tests/unittest_eval_agent.py
Running each eval case 3 time(s)
Evaluating task ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 100% 0:00:00
                               Evaluation Summary: task
┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━┳━━━━━━━━━━┓
┃ Case ID                             ┃ Metrics               ┃ Assertions ┃ Duration ┃
┡━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━╇━━━━━━━━━━┩
│ financial_market_headlines_v1 [1/3] │ tool_calls: 1         │ ✔✔✔✔       │    18.8s │
│                                     │ requests: 2           │            │          │
│                                     │ input_tokens: 1,325   │            │          │
│                                     │ output_tokens: 278    │            │          │
│                                     │ cost: 0.0564          │            │          │
├─────────────────────────────────────┼───────────────────────┼────────────┼──────────┤
│ financial_market_headlines_v1 [2/3] │ tool_calls: 1         │ ✔✔✔✔       │     8.8s │
│                                     │ requests: 2           │            │          │
│                                     │ input_tokens: 1,195   │            │          │
│                                     │ output_tokens: 82     │            │          │
│                                     │ cost: 0.0408          │            │          │
├─────────────────────────────────────┼───────────────────────┼────────────┼──────────┤
│ financial_market_headlines_v1 [3/3] │ tool_calls: 1         │ ✔✔✔✔       │    13.5s │
│                                     │ requests: 2           │            │          │
│                                     │ input_tokens: 1,292   │            │          │
│                                     │ output_tokens: 388    │            │          │
│                                     │ cost: 0.0620          │            │          │
├─────────────────────────────────────┼───────────────────────┼────────────┼──────────┤
│ Averages                            │ requests: 2.00        │ 100.0% ✔   │    13.7s │
│                                     │ output_tokens: 249.3  │            │          │
│                                     │ tool_calls: 1.00      │            │          │
│                                     │ cost: 0.0531          │            │          │
│                                     │ input_tokens: 1,270.7 │            │          │
└─────────────────────────────────────┴───────────────────────┴────────────┴──────────┘

Уровень 2: детерминистическая регрессия на основе трейсов

Второй набор не запускает агента заново. Он считывает завершённые трейсы из Tempo:

uv run python tests/regression_eval_traces.py

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

Trace: ff5a53e3392dc26cd0a2890782be70ec
Eval case: financial_market_headlines v1
Status: PASS
Model requests: 2
Tool calls: 1
contains('market'): PASS
MaxModelRequests: PASS
MaxToolCalls: PASS

Это дешево и возможно к повторению, поскольку происходит повторная оценка уже собранных доказательств.

Уровень 3: недетерминистические тесты с судьей в виде большой языковой модели

В контракте также приведена шкала оценки для тестирования запроса. Это снова тот же краткий контракт:

[
  {
    "agent_id": "financial_market_headlines",
    "version": 1,
    "agent_model": "openai:gpt-4",
    "prompt": "What are today's major financial market headlines?",
    "eval": {
      "contains": ["market"],
      "max_model_requests": 3,
      "min_tool_calls": 1,
      "max_tool_calls": 5,
      "judge_rubric": "The answer should be a useful response to the user's financial markets question. It should summarize market-relevant information, avoid obviously unrelated content, avoid investment advice, and avoid claiming certainty beyond what the retrieved information supports."
    }
  }
]

Поскольку сам агент работает на GPT-4, судье требуется более мощная модель, и именно GPT-5 выполняет эту роль. Он определяет, был ли ответ полезным и релевантным, не преувеличивался ли он по сравнению с тем, что подтверждается полученными данными, и не превращался ли он в инвестиционные советы.

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

Для более глубокого изучения темы стоит прочитать исследовательскую статью «A Survey on LLM-as-a-Judge» (arXiv 2411.15594). В зависимости от целей использования в конечном итоге потребуются системы, способные оценивать работу самих судей, с использованием обратной связи от людей или других методов.

Суита загружает тот же сохранённый окончательный результат и запускает Pydantic Evals LLMJudge с использованием критериев контракта:

LLMJudge(
    rubric=case.eval_case.eval.judge_rubric,
    model=args.judge_model,
    include_input=True,
    score={"evaluation_name": "judge_score", "include_reason": True},
    assertion={"evaluation_name": "judge_pass", "include_reason": True},
)

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

uv run python tests/regression_llm_judge_traces.py   --sample-percent 50
Trace selection: fetched=1 sampled=1 judging=1 lookback_minutes=1440 sample_percent=50 max_traces=5
Trace case: trace_id=3891f0b8432c9bbcb00e5e8adce1600b agent_id=financial_market_headlines prompt_version=1 answer_chars=207
Judging 1 trace(s) with openai:gpt-5.4
Evaluating task ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 100% 0:00:00
                                                   Evaluation Summary: task
┏━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━┓
┃ Case ID              ┃ Inputs               ┃ Outputs              ┃ Scores               ┃ Assertions          ┃ Duration ┃
┡━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━┩
│ financial_market_he… │ {'trace_id':         │ Today's major        │ judge_score: 0.000   │ judge_pass: ✗       │    469µs │
│                      │ '3891f0b8432c9bbcb00 │ financial market     │   Reason: The        │   Reason: The       │          │
│                      │ e5e8adce1600b',      │ headlines can be     │ response does not    │ response does not   │          │
│                      │ 'agent_id':          │ found on major       │ summarize any actual │ summarize any       │          │
│                      │ 'financial_market_he │ business and finance │ market headlines or  │ actual market       │          │
│                      │ adlines',            │ news outlets         │ provide              │ headlines or        │          │
│                      │ 'prompt_version': 1, │ including CNBC,      │ market-relevant      │ provide             │          │
│                      │ 'agent_model':       │ Yahoo Finance,       │ information; it only │ market-relevant     │          │
│                      │ 'openai:gpt-4',      │ Reuters, and         │ redirects the user   │ information; it     │          │
│                      │ 'judge_model':       │ Bloomberg. For more  │ to news websites. It │ only redirects the  │          │
│                      │ 'openai:gpt-5.4',    │ specific stories,    │ avoids investment    │ user to news        │          │
│                      │ 'prompt': "What are  │ please visit their   │ advice, but it is    │ websites. It avoids │          │
│                      │ today's major        │ websites.            │ not a useful answer  │ investment advice,  │          │
│                      │ financial market     │                      │ to the user's        │ but it is not a     │          │
│                      │ headlines?"}         │                      │ question.            │ useful answer to    │          │
│                      │                      │                      │                      │ the user's          │          │
│                      │                      │                      │                      │ question.           │          │
│                      │                      │                      │                      │                     │          │
│                      │                      │                      │                      │                     │          │
├──────────────────────┼──────────────────────┼──────────────────────┼──────────────────────┼─────────────────────┼──────────┤
│ Averages             │                      │                      │ judge_score: 0.000   │ 0.0% ✔              │    469µs │
└──────────────────────┴──────────────────────┴──────────────────────┴──────────────────────┴─────────────────────┴──────────┘

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

uv run python tests/regression_llm_judge_traces.py  --sample-percent 10 --lookback-minutes 30
Trace selection: fetched=1 sampled=1 judging=1 lookback_minutes=30 sample_percent=10 max_traces=5
Trace case: trace_id=38fa3a54134d8818c7d7a5afbf50967e agent_id=financial_market_headlines prompt_version=1 answer_chars=654
Judging 1 trace(s) with openai:gpt-5.4
Evaluating task ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 100% 0:00:00
                                             Evaluation Summary: task
┏━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━┓
┃ Case ID            ┃ Inputs             ┃ Outputs           ┃ Scores             ┃ Assertions        ┃ Duration ┃
┡━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━┩
│ financial_market_… │ {'trace_id':       │ Here are today's  │ judge_score: 0.450 │ judge_pass: ✗     │    441µs │
│                    │ '38fa3a54134d8818c │ major financial   │   Reason: The      │   Reason: The     │          │
│                    │ 7d7a5afbf50967e',  │ market headlines: │ response is        │ response is       │          │
│                    │ 'agent_id':        │                   │ market-related and │ market-related    │          │
│                    │ 'financial_market_ │ 1. Wall Street's  │ avoids investment  │ and avoids        │          │
│                    │ headlines',        │ riskiest trades   │ advice, but it     │ investment        │          │
│                    │ 'prompt_version':  │ are suddenly back │ mostly lists       │ advice, but it    │          │
│                    │ 1, 'agent_model':  │ on top: Chart of  │ article headlines  │ mostly lists      │          │
│                    │ 'openai:gpt-4',    │ the Day - Yahoo   │ and links rather   │ article headlines │          │
│                    │ 'judge_model':     │ Finance           │ than providing a   │ and links rather  │          │
│                    │ 'openai:gpt-5.4',  │ [Link](https://fi │ useful summary of  │ than providing a  │          │
│                    │ 'prompt': "What    │ nance.yahoo.com/) │ the key financial  │ useful summary of │          │
│                    │ are today's major  │ 2. S&P 500        │ market             │ the key financial │          │
│                    │ financial market   │ notches           │ developments.      │ market            │          │
│                    │ headlines?"}       │ record-high close │                    │ developments.     │          │
│                    │                    │ as rate-hike      │                    │                   │          │
│                    │                    │ worries ease -    │                    │                   │          │
│                    │                    │ Reuters           │                    │                   │          │
│                    │                    │ [Link](https://ww │                    │                   │          │
│                    │                    │ w.reuters.com/mar │                    │                   │          │
│                    │                    │ kets/us/)         │                    │                   │          │
│                    │                    │ 3. Treasury       │                    │                   │          │
│                    │                    │ yields rise as    │                    │                   │          │
│                    │                    │ U.S. threatens    │                    │                   │          │
│                    │                    │ Iran with more    │                    │                   │          │
│                    │                    │ economic          │                    │                   │          │
│                    │                    │ sanctions - CNBC  │                    │                   │          │
│                    │                    │ [Link](https://ww │                    │                   │          │
│                    │                    │ w.cnbc.com/)      │                    │                   │          │
│                    │                    │ 4. Latest stock   │                    │                   │          │
│                    │                    │ market, financial │                    │                   │          │
│                    │                    │ and business news │                    │                   │          │
│                    │                    │ - MarketWatch     │                    │                   │          │
│                    │                    │ [Link](https://ww │                    │                   │          │
│                    │                    │ w.marketwatch.com │                    │                   │          │
│                    │                    │ /)                │                    │                   │          │
│                    │                    │ 5. Latest finance │                    │                   │          │
│                    │                    │ and stock market  │                    │                   │          │
│                    │                    │ news covering the │                    │                   │          │
│                    │                    │ Dow, S&P 500,     │                    │                   │          │
│                    │                    │ banking,          │                    │                   │          │
│                    │                    │ investing and     │                    │                   │          │
│                    │                    │ regulation - WSJ  │                    │                   │          │
│                    │                    │ [Link](https://ww │                    │                   │          │
│                    │                    │ w.wsj.com/finance │                    │                   │          │
│                    │                    │ )                 │                    │                   │          │
├────────────────────┼────────────────────┼───────────────────┼────────────────────┼───────────────────┼──────────┤
│ Averages           │                    │                   │ judge_score: 0.450 │ 0.0% ✔            │    441µs │
└────────────────────┴────────────────────┴───────────────────┴────────────────────┴───────────────────┴──────────┘mar

Проведение таких тестов для каждой трассы может стать слишком дорогостоящим и медленным. Лучшим вариантом является случайная выборка. Если продукт предоставляет возможность сбора отзывов пользователей, идентификатор трассы позволяет напрямую перейти к тем компонентам в потоке, где возникли проблемы, и тестируются только они. Товарные решения вроде LangSmith и Arize Phoenix уже обеспечивают такую функциональность, но схема на базе S3 в сочетании с этим набором инструментов дает аналогичные возможности; к тому же существует настройка с использованием docker compose.

После первоначальных тестов на уровне модулей стало ясно, что как промпт, так и критерии оценки требуют обновления, в связи с чем контракт перешел на версию 2:

  {
    "id": "financial_market_headlines",
    "version": 2,
    "agent": "websearch",
    "prompt": "Use the web-search tool to find and verify today's major financial-market headlines. Report the 3 to 5 most consequential developments across equities, rates, currencies, commodities, or macroeconomic policy. For each item, state what happened, identify the affected market or region, explain briefly why it matters, and name the source with a link when available. Include the relevant date and units for numerical claims. Cross-check any surprising index level, percentage move, policy decision, or economic release against a second reliable source; if it cannot be verified, omit it or clearly label it as unconfirmed. State when the information was current, distinguish facts from developing reports or interpretation, and say when reliable current information is insufficient. Do not invent facts, present stale information as today's news, or give personalized investment advice.",
    "contains": ["market"],
    "max_model_requests": 4,
    "min_tool_calls": 1,
    "max_tool_calls": 7,
    "judge_rubric": "The response should provide 3 to 5 current, consequential financial-market developments based on web research. Each item should identify what happened, the affected market or region, why it matters, and its source, preferably with a link. Numerical claims should include meaningful dates and units; surprising figures should be corroborated by a second reliable source or explicitly marked unconfirmed. The answer should state when the information was current, distinguish verified facts from developing reports or interpretation, and acknowledge insufficient evidence rather than inventing details. It must stay relevant, avoid stale news presented as current, avoid unsupported certainty, and avoid personalized investment advice. A polished but uncited answer containing an implausible or unverifiable market figure should fail."
  },

От шаблона до пайплайна выпуска

Когда каждый след ведет к соответствующему контракту, пайплайн выпуска может собирать различные виды доказательств на каждом этапе, что даёт более полную картину, чем просто показатель прохождения тестов. Оценка выпуска должна осуществляться по нескольким критериям:

  • успешность выполнения задачи
  • качество результата с семантической точки зрения
  • правильность использования инструментов
  • соответствие стандартам безопасности и политикам
  • затраты в виде запросов и токенов
  • задержки и надёжность

Дополнительная литература

На инженерном блоге Anthropic есть статья о том, как происходит оценка ИИ-агентов, по адресу https://www.anthropic.com/engineering/demystifying-evals-for-ai-agents, в которой рассматриваются более общие аспекты.

Связанная литература

  • Оценка агентов и навыков на практике: траектории, системы оценки, критерии прохождения и инструменты — Как оценивать агентов и навыки: наборы действий для запуска и выполнения, порядок значимости систем оценки, точность и воспроизводимость, различия между критериями pass@k и pass^k, небольшой инструментарий на Python и рекомендации по выбору инструментов.
  • От оценок к самосовершенствующимся агентам: пять этапов оценки агентов — Сегодня оценка агентов подразумевает анализ их действий. Узнайте, как детерминистические проверки, модели LLM и судьи-агенты, диагностика и специальные инструменты создают безопасный цикл совершенствования.
  • Практические заметки: Агентный SDLC: как ИИ преобразует разработку программного обеспечения — Подробное руководство по Практическим заметкам: Агентный SDLC: как ИИ преобразует разработку программного обеспечения, включающее контракты, проверки и готовые блоки кода для команд, использующих эту модель.