Даніла (Dayfing)
Назад да публікацый
1904 слоў8 хв

Назіральнасць AI-агента: трейсы, затрымка, токены, кошт і памылкі

Чаму агенту патрэбная іншая мадэль назіральнасці

Звычайны API-запыт мае зразумелыя пачатак, апрацоўшчык і адказ. AI-агент дадае цыкл. Ён выбірае мадэль, вырашае, ці выклікаць інструмент, чакае аддаленую сістэму, чытае вынік і можа зноў звярнуцца да мадэлі. Адзін запыт карыстальніка можа ўключаць некалькі выклікаў мадэлі, пошукавых запытаў, выкананняў інструментаў, паўтораў і праверак палітык. Запіс «запыт скончыўся памылкай» не паказвае, якая галіна спажыла час або бюджэт.

Назіральнасць робіць гэты шлях бачным праз звязаныя трейсы, метрыкі і журналы. OpenTelemetry апісвае трейс як шлях запыту, а span як аперацыю ўнутры яго. Выкарыстоўвайце адзін каранёвы span для запуску агента, які бачыць карыстальнік, і даччыныя spans для інферэнсу, пошуку, інструментаў, guardrails і серыялізацыі. Назвы мадэляў і інструментаў павінны мець нізкую кардынальнасць. Ідэнтыфікатары запыту захоўвайце ў кантэксце трейсу або структураваных журналах, не ў метках метрык. Тады аператар бачыць, што адбылося ў адным запуску, як часта гэта паўтараецца і якія workflow закранутыя.

Артыкул выкарыстоўвае схему, незалежную ад пастаўшчыка. Дакументацыя пастаўшчыка застаецца крыніцай дакладных палёў usage і правілаў аплаты. Семантычныя пагадненні OpenTelemetry для GenAI spans і для метрык GenAI даюць агульны слоўнік.

Схема трейсу для цыклу агента

Стварайце каранёвы span, калі праграма прымае запыт, а не падчас першага выкліку мадэлі. Выкарыстоўвайце аперацыю накшталт invoke_agent і атрыбуты service, deployment, environment, версіі workflow і несакрэтнага класа арандатара. Ідэнтыфікатар размовы запісвайце толькі пры наяўнасці і дазволе палітыкі захоўвання. Не змяшчайце паведамленне карыстальніка, поўны prompt або параметры інструмента ў метку метрыкі.

Кожны даччыны span павінен адказваць на адно аперацыйнае пытанне. Мінімальны набор:

Span Што запісваць
agent.run назву і версію workflow, вынік, колькасць спроб, працягласць
gen_ai.inference пастаўшчык, запытаная і фактычная мадэль, аперацыя, stream, прычына завяршэння, токены
gen_ai.retrieval клас індэкса або крыніцы, рэжым запыту, колькасць вынікаў, cache hit
gen_ai.tool назву і тып інструмента, рашэнне аўтарызацыі, timeout, вынік
guardrail.check версію палітыкі, рашэнне, код прычыны, працягласць

Для няўдалай аперацыі задайце статус span і значэнне error.type. Для паўтору запішыце падзею з нумарам спробы, backoff і кодам прычыны. Паўтор не з’яўляецца другім каранёвым запускам. Гэта яшчэ адна спроба той самай лагічнай аперацыі з асобным client span, калі запыт адпраўляецца па сетцы. Так панэль не падвойвае запыты карыстальнікаў, але паказвае спробы пастаўшчыка.

Наступны JSON — форма экспартаванай запісы, а не фармат пэўнага пастаўшчыка. Тут ёсць лічыльнікі і коды, але няма змесціва.

{
  "trace_id": "4bf92f3577b34da6a3ce929d0e0e4736",
  "span_id": "00f067aa0ba902b7",
  "parent_span_id": "b7ad6b7169203331",
  "name": "chat model",
  "kind": "CLIENT",
  "status": "OK",
  "attributes": {
    "gen_ai.operation.name": "chat",
    "gen_ai.provider.name": "provider.example",
    "gen_ai.request.model": "model.example",
    "gen_ai.response.model": "model.example-2026-01",
    "gen_ai.usage.input_tokens": 820,
    "gen_ai.usage.output_tokens": 146,
    "gen_ai.response.finish_reasons": ["stop"],
    "app.agent.attempt": 1
  }
}

Назва span павінна апісваць клас аперацыі, а не ID або тэкст карыстальніка. Захоўвайце версію семантычнага пагаднення ў метаданых інструментацыі. Калі пастаўшчык асобна паведамляе аплачваемыя і апрацаваныя токены, захоўвайце абодва ў прыватным уліку, а для кошту выкарыстоўвайце аплачваемыя. Не змешвайце кліенцкую і серверную інструментацыю аднаго запыту без пазначэння ўзроўню, інакш токены будуць палічаныя двойчы.

Correlation ID і распаўсюджванне кантэксту

Trace ID звязвае сэрвісы. Span ID пазначае адну аперацыю. Уласны request ID карысны падтрымцы, але не замяняе кантэкст трейсу. Перадавайце загаловак W3C traceparent праз API-шлюз, сэрвіс агента, сэрвіс пошуку і адаптары інструментаў. Кіраўніцтва OpenTelemetry па распаўсюджванні кантэксту тлумачыць атрыманне аддаленага кантэксту і стварэнне даччынага span. Той жа кантэкст можна дадаць у структураваныя журналы.

Калі падтрымцы патрэбны кароткі ідэнтыфікатар, стварайце асобны выпадковы request ID. Яго сувязь з trace ID захоўвайце ў журналах, не ў метрыцы з высокай кардынальнасцю. Для чаргі дадавайце кантэкст у метаданыя паведамлення і стварайце consumer span пры апрацоўцы. Для паралельных задач без адзінага бацькі выкарыстоўвайце span links. На публічнай мяжы правярайце ўваходныя tracing headers як недавераныя даныя і не перадавайце ўнутраны baggage пастаўшчыкам або староннім інструментам. Baggage можа ўтрымліваць уліковыя даныя ці персанальную інфармацыю.

Spans інструментаў паказваюць сапраўдныя паводзіны агента

Калі гэта важна, аддзяляйце рашэнне мадэлі ад выканання праграмы. Span мадэлі паказвае, што яна папрасіла інструмент, а span інструмента — што праграма рэальна выканала. Уключайце стабільнае імя tool.name, тып function, extension або datastore, рашэнне палітыкі і знешнюю аперацыю. Метад запыту ці клас пошуку дадавайце толькі без раскрыцця сакрэтаў. Не захоўвайце access token, параметры SQL, змесціва дакумента або поўны URL з query.

Для кожнага выкліку запісвайце час, timeout, клас выніку, колькасць паўтораў і абмежаваны памер выніку. Timeout, бізнес-адмова, забарона палітыкі і upstream 5xx павінны мець розныя коды прычын. Калі інструмент выклікае іншы сэрвіс, перадавайце кантэкст. Калі ён запускае лакальную каманду, захоўвайце сямейства каманды і клас выхаду, а не ўвод карыстальніка.

Паказвайце чаканне, якое не з’яўляецца выклікам інструмента. Дадавайце spans для затрымкі ў чарзе, сну з-за абмежавання хуткасці, адкрытага circuit breaker і струменевага адказу. Інакш павольны span мадэлі можа схаваць чаканне слота канкурэнтнасці. У multi-agent workflow называйце кожны дэлегаваны workflow і звязвайце яго з бацькоўскім трейсам. Не стварайце новы трейс для кожнай унутранай думкі або змены стану.

Улік токенаў і кошту

Бярыце usage з адказу пастаўшчыка, калі ён даступны. Уваходныя, выходныя, кэшаваныя і reasoning-токены могуць мець розныя стаўкі, як і выявы ды адзінкі інструментаў. Дапаможнік OpenAI пра токены тлумачыць, што токенізацыя залежыць ад мадэлі і мовы, а usage у адказе з’яўляецца асновай для завершанага запыту. Лакальны tokenizer ацэньвае папярэдні бюджэт, але не замяняе usage пастаўшчыка пры звяранні.

Для кожнай спробы мадэлі захоўвайце provider, requested model, response model, катэгорыю токена, колькасць, валюту, версію прайсу і cost center. Пасля адказу разлічвайце:

cost = input_billable_tokens * input_price
     + cached_input_tokens * cached_input_price
     + output_billable_tokens * output_price
     + provider_units * unit_price

Цэны павінны быць канфігурацыяй з датай дзеяння, а не канстантай exporter. Захоўвайце сырыя колькасці і разлічаную суму, каб праверыць пазнейшае выпраўленне прайсу. Складайце ўсе спробы, бо няўдалы выклік таксама можа спажыць токены. Ацэначны або адкладзены кошт пазначайце як папярэдні і звярайце са справаздачай пастаўшчыка.

Паказвайце вымярэнні, на якія можа паўплываць уладальнік: workflow, сямейства мадэлі, асяроддзе, клас арандатара і вынік. Не выкарыстоўвайце user ID, prompt або адвольныя аргументы інструмента як вымярэнні. Панэль кошту павінна паказваць агульную суму, кошт завершанага запуску, токены на запуск, долю паўтораў і долю дарагіх мадэляў. Рост выходных токенаў пры нармальнай затрымцы можа азначаць неабмежаваны адказ, цыкл або зменены prompt.

Размеркаванні затрымкі: p50, p95 і p99

Сярэдняе значэнне хавае хвост, які бачыць карыстальнік падчас чакання чаргі або павольнага інструмента. Запісвайце працягласць каранёвага запуску і важных spans як histogram у секундах. Вымярайце time to first token, інтэрвал паміж часткамі stream, калі ён уплывае на паказ, і поўны час. Калі палі даступныя, падзяляйце сервер, чаргу і сетку.

p50 апісвае звычайны выпадак, p95 павольных карыстальнікаў, а p99 рэдкі цяжкі хвост. Гэта кванцілі размеркавання, а не тры сярэднія. Выбірайце buckets вакол фактычнага SLO ад доляў секунды да хвілін і не змешвайце адзінкі. Функцыя Prometheus histogram_quantile ацэньвае квантыль з buckets. Для класічнай histogram спачатку агрэгуйце па le.

histogram_quantile(
  0.95,
  sum by (le, workflow) (
    rate(agent_run_duration_seconds_bucket[10m])
  )
)

Не змяшчайце trace ID у метку метрыкі. Разбівайце па невялікім кантраляваным наборы: workflow, сямейства мадэлі, рэгіён і вынік. Узорам трейсу можна растлумачыць зрух p95. Не сумуйце працягласць паралельных даччыных spans, а выкарыстоўвайце крытычны шлях.

Памылкі, паўторы і абмежаванні хуткасці

Вызначце таксаномію памылак да стварэння alerts. Адрознівайце валідацыю кліента, забарону палітыкі, аўтэнтыфікацыю, rate limit, timeout, upstream error, няправільны адказ мадэлі, збой інструмента і скасаванне. Мапуйце коды пастаўшчыка ў стабільныя класы і захоўвайце абмежаваны арыгінальны код. Чаканае скасаванне карыстальнікам адзначайце асобна ад збою сервера.

Кожны retry павінен мець прычыну, нумар спробы, backoff і канчатковы вынік. Ужывайце абмежаваны экспаненцыяльны backoff з jitter толькі там, дзе гэта дазваляе кантракт. Не паўтарайце валідацыю, аўтарызацыю, рашэнне палітыкі або дэтэрмінаваную памылку схемы. Усталюйце deadline для ўсяго запуску і кожнай спробы. Каранёвы span паведамляе retry_count, attempt_count і вынік, кожная спроба захоўвае свой статус. Высокая доля паўтораў павышае кошт нават пры добрым success rate.

Запісвайце выбар запасной мадэлі асобнай падзеяй або span. Панэль павінна адрозніваць fallback праз rate limit, затрымку, палітыку бяспекі або праверку магчымасцяў. Асобна кантралюйце няправільныя аргументы інструмента і цыклы выпраўлення схемы. Калі repair дазволены, абмяжуйце ітэрацыі і выдавайце loop_limit на мяжы.

Прыватнасць, рэдагаванне і sampling

Промпты і даныя інструментаў могуць утрымліваць персанальную, канфідэнцыйную або security-sensitive інфармацыю. Бяспечнае значэнне па змаўчанні — метаданыя, лічыльнікі токенаў, адбіткі і коды прычын без змесціва. Калі для адладкі патрэбныя прыклады, выкарыстоўвайце асобнае кантраляванае сховішча са згодай, кароткім retention, шыфраваннем, журналам доступу і рэдагаваннем палёў. Рэдагуйце да экспарту.

Ужывайце allowlist атрыбутаў. Выдаляйце загалоўкі аўтарызацыі, cookie, API keys, кантактныя даныя, нумары рахункаў, URL з query і тэкст дакументаў. Хэшаванне не робіць даныя аўтаматычна ананімнымі. Захоўвайце адбітак промпта асобна і дакументуйце, хто можа звязаць яго з тэкстам. Тэсціруйце рэдагаванне фікстурамі з рэалістычнымі сакрэтамі і шматмоўнымі персанальнымі данымі.

Sampling зніжае аб’ём, але не павінен хаваць інцыдэнты. Ужывайце parent-based sampling для цэласнасці трейсу. У Collector выкарыстайце tail sampling, каб захоўваць памылкі, timeout, дарагія і павольныя трейсы, а звычайныя поспехі семпліраваць радзей. Спецыфікацыя sampling OpenTelemetry адрознівае запіс і экспарт, таму лакальны sampler можа не ствараць дарагія атрыбуты. Метрыкі пакідайце без sampling, а traces выкарыстоўвайце для расследавання.

OpenTelemetry, Grafana і Sentry разам

Інструментуйце агента API OpenTelemetry і семантычнымі пагадненнямі, адпраўляйце OTLP у OpenTelemetry Collector, а Collector няхай выконвае batching, memory limits, рэдагаванне, sampling і маршрутызацыю. Экспартуйце traces, metrics і logs у адпаведныя backends з аднолькавымі атрыбутамі service, version, environment, region і deployment. Перад production sampling праверце адзін поўны трейс у staging.

Grafana дае агульны аперацыйны выгляд. Стварыце панэлі для аб’ёму, success ratio, p50/p95/p99 каранёвай затрымкі, часу першага токена, токенаў, кошту, retry rate, працягласці інструмента і стану пастаўшчыка. Дадайце спасылкі на пошук трас і runbook. Дакументацыя Grafana пра alert rules апісвае запыты, умовы, перыяды ацэнкі і апавяшчэнні. Sentry дадае групаванне праблем, кантэкст памылкі і прагляд трейсу. Яго Trace API вяртае spans і памылкі адной трасіроўкі. У любы error backend адпраўляйце толькі адрэдагаваныя даныя і відавочна наладжвайце sampling.

SLO і alerts для аператараў

SLO павінна выражаць абяцанне карыстальніку, а не здароўе Collector. Вызначце даступнасць як долю завершаных запускаў без класіфікаванай памылкі сервера, пастаўшчыка або інструмента. Latency можна вызначыць як долю каранёвых запускаў ніжэй зададзенага парога. Калі кошт з’яўляецца абмежаваннем, адсочвайце budget SLI асобна.

Выбірайце мэты паводле вымеранай базавай лініі і патрабавання прадукту. Аддзяляйце workflow з рознымі чаканнямі. Паказвайце error budget на доўгім акне і кароткі дыягнастычны выгляд для разгортванняў. Дакументацыя Grafana SLO апісвае SLI, спажыванне бюджэту і fast-burn ды slow-burn alerts. Адпраўляйце page толькі калі аператар можа дзейнічаць. Павольны трэнд лепш ператварыць у ticket.

Карысныя alerts: устойлівы рост памылак каранёвых запускаў, хуткае спажыванне error budget, p95 вышэй за кантракт, усплёск provider rate limit, рост retry ratio, адсутныя usage records, нечаканы cost rate і затрымалася чарга. Дадайце workflow, region, deployment, current value, threshold, спасылку на трейс, уладальніка і runbook. Pending period не дазволіць адной кропцы выклікаць page. Групуйце апавяшчэнні па service і severity. Калі імгненнае дзеянне адсутнічае, патрэбная панэль, не alert.

Ад сімптому да прычыны

Пачніце з SLO або паведамлення карыстальніка і выберыце рэпрэзентатыўны трейс. Праверце даччыныя spans кораня і распаўсюджванне кантэксту праз шлюз, чаргу і мяжу інструмента. Калі spans адсутнічаюць, спачатку даследуйце exporter, sampling і injection кантэксту.

Для павольнага запуску параўнайце queue delay, time to first token, output duration, retrieval і крытычныя шляхі інструментаў. Высокі p99 пры звычайным p50 звычайна паказвае на хвоставую залежнасць, абмежаванне канкурэнтнасці або retry. Зрух p50 можа азначаць змену deployment, model, prompt ці region. Пры ўсплёску кошту групуйце па response model, token category, workflow version і спробах, потым звярайце usage са справаздачай пастаўшчыка.

Для памылкі пачынайце з першага няўдалага span, а не з абгорнутага выключэння. Правярайце status, error.type, код пастаўшчыка, timeout budget і retry events. Адрознівайце адмову інструмента, збой пастаўшчыка, няправільны адказ мадэлі і памылку парсера. Пераканайцеся, што рэдагаванне пакінула бяспечны дыягнастычны код. Чаканы policy block лічыце вынікам прадукту і стварайце alert толькі пры нечаканай змене долі.

Падтрымлівайце сінтэтычныя запыты з дэтэрмінаванымі несакрэтнымі фікстурамі. Пасля змены інструментацыі, мадэлі, промпта або маршрутызацыі правярайце, што traces, metrics, запісы токенаў і памылкі маюць адзін correlation ID. Архітэктурны кантэкст ёсць у матэрыялах production AI agent architecture, AI agent evaluations, prompt injection and MCP security і hybrid RAG with pgvector. Гэтыя тэмы вызначаюць патрэбныя spans і прымальны SLO, а назіральнасць застаецца нейтральным пластом доказаў.

Іншыя публікацыі