Після туторіалу LangGraph: жорсткі краї, схеми та шари безпеки
Перетворіть робочого агента SQL на захищеного за допомогою типованих механізмів контролю, оновлення схеми, оптимізації витрат та багатошарових перевірок.
Після туторіалу — зелена позначка
Туторіали 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 для форків архітектури. Протестуйте непридатні шляхи. Логуйте версії схеми. Відокремте IAM інструментів. Перечитуйте редюсери після кожної зміни стану. Туторіали закінчуються на запуску коду; продакшн починається з обґрунтованих рішень.
Функціональна числова інтуїція
Припустимо, що цільовий крок коштує 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 на стороні клієнта. Необхідно відстежувати процес від початку до кінця. Оптимізація в неправильних місцях марнує час інженерів.
Короткий підсумок
Послідовне декодування є структурним тягарем авторегресії. Спекулятивне декодування та раннє завершення зменшують цей тягар за певних умов. Їх слід впроваджувати з такою ж дисципліною, як і будь-яку функцію в продакшені: з використанням метрик, прапорців, можливостей відкату та чітких відповідальних осіб у команді платформи обслуговування.