Главная / Статьи / После обучающего курса LangGraph: жесткие ребра, схемы и слои безопасности

После обучающего курса LangGraph: жесткие ребра, схемы и слои безопасности

Превратите рабочего агента SQL в защищённый с использованием типизированных механизмов защиты, обновления схемы, оптимизации затрат и многоуровневой проверки.

2742 слов

Зеленая галочка после обучающего материала

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

Ситуация и задача

Учебные материалы предоставляют пути для получения кодов-подарков, но не инварианты. Задачей было сохранить рабочий проект, при этом сделав каждую ветку объяснимой в процессе проверки — особенно те ветки, которые используют SQL.

Действие 1 — две архитектуры, чтобы невозможно было пропустить проверку

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

class JudgeAgentSchema(BaseModel):
    answer: Literal["yes", "no"] = Field(
        description="Return 'yes' if the SQL query ONLY retrieves data (like SELECT). "
                    "Return 'no' if it modifies data (like INSERT, UPDATE, DELETE, DROP)."
    )
    comments: str = Field(default="", description="Reasoning behind the verdict")


llm_judge = llm.with_structured_output(schema=JudgeAgentSchema)

Маршрут с явным условием:

def is_safe_sql_condition(state: AgentSchema) -> str:
    if state.is_safe.lower() == "yes":
        return "Execute_SQL"
    return "Cancel_SQL_if_Not_Safe"

Ошибки валидации возникают, когда модель отклоняется от заданного словаря:

ValidationError: Input should be 'yes' or 'no'
[type=literal_error, input_value='No', input_type=str]
@field_validator('answer', mode='before')
@classmethod
def normalize_answer(cls, v):
    if isinstance(v, str):
        v = v.strip().lower()
    return v if v in ("yes", "no") else "no"   # fail closed
ValidationError: Input should be 'yes' or 'no'
[type=literal_error, input_value='', input_type=str]

Аккуратно задавайте значения типа enum и параметры по умолчанию:

is_safe: Literal["yes", "no"] = Field(default="no")      # fail closed
generated_sql_query: str = Field(default="")
messages: Annotated[list, add] = Field(default_factory=list)  # not default=[]
PydanticJsonSchemaWarning: Default value (...) is not JSON serializable
comments: str = (
    Field(..., description="..."),   # ← trailing comma makes this a tuple
)
def prompt_query_context(state: AgentSchema) -> AgentSchema:
    database_object = Database(connection_details)
    schema_info = database_object.get_schema_details("public")

Действие 2 — структурированный вывод как программируемый компонент

Как только ответы, связанные с безопасностью, становятся литералами, грани преобразуются в код. Модель представляет собой компонент с определенным контрактом, а не элемент, управляющий потоком выполнения.

Действие 3 — загружать схему при каждом запуске

Устаревшая схема в промптах приводит к ошибочному формированию SQL-запросов. Обновление схемы требует токенов; устаревшая схема вызывает проблемы. Предпочтительнее загружать схему при каждом запуске для постоянно меняющихся баз данных, если только не указано конкретное значение версии.

Действие 4 — затраты агента ≠ затраты пайплайна

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

def pick_llm(model_level: str) -> ChatAnthropic:
    if normalized_level == "basic":
        return ChatAnthropic(model="claude-haiku-4-5", temperature=0)
    elif normalized_level == "advanced":
        return ChatAnthropic(model="claude-sonnet-4-6", temperature=0)
    elif normalized_level == "premium":
        return ChatAnthropic(model="claude-opus-4-6", temperature=0)

Обнаружение ошибок при написании кода

Функция-редюсер и узел одновременно добавляют данные

messages: Annotated[list, add] = Field(default_factory=list)
state.messages = state.messages + [response]   # full list: old + new
return state                                    # reducer adds it AGAIN
def sql_node(state: DataAgentSchema):
    response = sql_analyst.invoke({...})
    return {"messages": [AIMessage(content=response["final_answer"])]}

Выберите одного автора: редьюсера или узел, но не обоих.

Передача всего состояния подагента наверх

response = sql_analyst.invoke({...})   # returns the full AgentSchema dict
state.messages = state.messages + [response]

Передавайте только те поля, которые нужны родителю.

Однослойная вероятностная безопасность

Учетные данные БД и парсинг SQL должны подкреплять решения модели:

POSTGRES_USER: agent_user
POSTGRES_PASSWORD: agent_pass
import sqlparse

def is_read_only(sql: str) -> bool:
    statements = sqlparse.parse(sql)
    if len(statements) != 1:          # blocks stacked queries
        return False
    return statements[0].get_type() == "SELECT"
CREATE ROLE agent_readonly LOGIN PASSWORD '...';
GRANT CONNECT ON DATABASE agent_db TO agent_readonly;
GRANT USAGE ON SCHEMA public TO agent_readonly;
GRANT SELECT ON ALL TABLES IN SCHEMA public TO agent_readonly;

Многоуровневая защита: модельный шлюз + парсер + пользователь БД с минимальными привилегиями.

Результат и предел

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

Практики, которые следует сохранять

Напишите ADR для форков архитектуры. Протестируйте неподходящие пути. Фиксируйте версии схемы. Изолируйте права доступа инструментов. Перечитывайте функции-редьюсеры после каждой смены состояния. Учебные материалы заканчиваются на запуске кода; производственная работа начинается с принятых решений.

Работающая числовая интуиция

Предположим, что выполнение целевого шага занимает 10 мс, а проект предлагает 5 токенов с средним коэффициентом принятия 60% для 3 токенов. Фактическая стоимость за принятый токен ниже, чем у обычных шагов с одним токеном, даже с учетом дополнительных затрат проекта, если коэффициент принятия остается высоким. Если коэффициент принятия снижается до примерно 1 токена, схема терпит неудачу. Именно из-за такой чувствительности дашборды превосходят анекдотические примеры.

Протокол регрессии качества

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

Размещение оборудования

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

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

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

Честность относительно оставшихся узких мест

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

Краткое резюме

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

Числовая интуиция

Предположим, что обработка одного шага занимает 10 мс, а проектный вариант предлагает 5 токенов с средним коэффициентом принятия 60% для 3 токенов. Эффективная стоимость за принятый токен оказывается ниже, чем при обработке одного токена, даже с учетом дополнительных затрат проектного варианта, если уровень принятия остается высоким. Если коэффициент принятия снижается до примерно 1 токена, такая схема становится неэффективной. Именно из-за такой чувствительности дашборды превосходят анекдотические примеры.

Протокол контроля ухудшения качества

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

Размещение оборудования

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

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

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

Честность относительно оставшихся узких мест

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

Краткое резюме

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

Числовая интуиция

Предположим, что обработка одного шага занимает 10 мс, а проектный вариант предлагает 5 токенов с средним коэффициентом принятия 60% для 3 токенов. Эффективная стоимость за принятый токен оказывается ниже, чем при обработке одного токена, даже с учетом дополнительных затрат проектного варианта, если уровень принятия остается высоким. Если коэффициент принятия снижается до примерно 1 токена, такая схема становится неэффективной. Именно из-за такой чувствительности дашборды превосходят анекдотические примеры.

Протокол контроля ухудшения качества

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

Размещение оборудования

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

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

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

Честность относительно оставшихся узких мест

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

Краткое резюме

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

Обоснование для рецензентов

В PR необходимо объяснить, почему существуют две архитектуры: один из путей демонстрирует, что пропуск защитных мер невозможен из-за отсутствия крайнего случая. Именно такой диаграммы и нужны аудиторам. Необходимо также предоставить тести, которые не проходят из-за попытки вызвать узел SQL без соответствующего параметра безопасности.

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

Числовая интуиция, проверенная на практике

Предположим, что выполнение целевого шага занимает 10 мс, а проектный вариант предлагает 5 токенов с средним уровнем принятия 60% для 3 токенов. Эффективная стоимость за принятый токен оказывается ниже, чем у стандартных шагов с одним токеном, даже с учётом дополнительных затрат проектного варианта, при условии стабильно высокого уровня принятия. Если уровень принятия снижается до примерно 1 токена, такая схема становится неэффективной. Именно из-за такой чувствительности панели управления превосходят анекдоты.

Протокол обнаружения регрессии качества

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

Размещение оборудования

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

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

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

Честность относительно оставшихся узких мест

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

Краткое резюме

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

Числовая интуиция

Предположим, что обработка одного шага занимает 10 мс, а проектный вариант предлагает 5 токенов с средним коэффициентом принятия 60% для 3 токенов. Эффективная стоимость за принятый токен оказывается ниже, чем при обработке одного токена, даже с учетом дополнительных затрат проектного варианта, если уровень принятия остается высоким. Если коэффициент принятия снижается до примерно 1 токена, такая схема становится неэффективной. Именно из-за такой чувствительности дашборды превосходят анекдотические примеры.

Протокол контроля ухудшения качества

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

Размещение оборудования

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

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

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

Честность относительно оставшихся узких мест

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

Краткое резюме

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

Числовая интуиция

Предположим, что обработка одного шага занимает 10 мс, а проектный вариант предлагает 5 токенов с средним коэффициентом принятия 60% для 3 токенов. Эффективная стоимость за принятый токен оказывается ниже, чем при обработке одного токена, даже с учетом дополнительных затрат проектного варианта, если уровень принятия остается высоким. Если коэффициент принятия снижается до примерно 1 токена, такая схема становится неэффективной. Именно из-за такой чувствительности дашборды превосходят анекдотические примеры.

Протокол контроля ухудшения качества

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

Размещение оборудования

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

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

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

Честность относительно оставшихся узких мест

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

Краткое резюме

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

Числовая интуиция

Предположим, что обработка одного шага занимает 10 мс, а проектный вариант предлагает 5 токенов с средним коэффициентом принятия 60% для 3 токенов. Эффективная стоимость за принятый токен оказывается ниже, чем при обработке одного токена, даже с учетом дополнительных затрат проектного варианта, если уровень принятия остается высоким. Если коэффициент принятия снижается до примерно 1 токена, такая схема становится неэффективной. Именно из-за такой чувствительности дашборды превосходят анекдотические примеры.

Протокол контроля ухудшения качества

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

Размещение оборудования

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

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

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

Честность относительно оставшихся узких мест

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

Краткое резюме

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

Числовая интуиция

Предположим, что обработка одного шага занимает 10 мс, а проектный вариант предлагает 5 токенов с средним коэффициентом принятия 60% для 3 токенов. Эффективная стоимость за принятый токен оказывается ниже, чем при обработке одного токена, даже с учетом дополнительных затрат проектного варианта, если уровень принятия остается высоким. Если коэффициент принятия снижается до примерно 1 токена, такая схема становится неэффективной. Именно из-за такой чувствительности дашборды превосходят анекдотические примеры.

Протокол контроля ухудшения качества

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

Размещение оборудования

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

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

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

Честность относительно оставшихся узких мест

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

Краткое резюме

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