Agenttien havainnointi: Hookit, Alloy ja Grafana
> Kytkimme Claude Code -työkalun ja Codexin samaan Grafana-pinoon OpenTelemetryn ja Alloyn avulla ja käytimme sitten jäljityksiä ja lokeja löytääksemme ja korjataksemme agenttien käyttäytymisongelmat niiden lähteellä.
Agenttijärjestelmät epäonnistuvat oudoilla tavoilla.
Joskus malli on ongelma. Joskus työkalu on ongelma. Joskus MCP-palvelimesi on kunnossa, mutta agentti valitsi väärän erikoisosaajan, tai käytti puolet istunnosta kuoritöihin, joita et odottanut, tai poltti hiljaa kustannuksia silmukassa, joka näytti ulospäin tuottavalta.
Jos et näe eroa, et oikeasti operoi agenttijärjestelmää. Arvailet.
Joten rakensimme havainnointipinon omalle työnkulullemme: Claude Code, Codex, Claude-hook-tapahtumat, Codex-notify-tapahtumat, natiivi OpenTelemetry, Grafana Alloy ja toisella puolella Grafana Cloud.
Mielenkiintoinen osa ei ole “teimme kojelaudan”. Mielenkiintoinen osa on se, että meidän piti jakaa telemetria kahteen eri virtaan, koska mikään yksittäinen syöte ei antanut meille koko kuvaa.
Ongelma: agenttien telemetria on pirstoutunutta
Modernit koodausagenit lähettävät jo jonkin verran telemetriaa. Se auttaa, mutta ei riitä.
Natiivi OTEL osaa vastata hyvin kysymyksiin kuten:
- Kuinka monta pyyntöä teimme?
- Kuinka paljon istunto maksoi?
- Missä jäljitykset (spans ja traces) ovat?
- Piikkikö viive?
Se on paljon huonompi vastaamaan kysymyksiin kuten:
- Mihin MCP-palvelimeen agentti nojasi?
- Oliko epäonnistuminen
Bash:ssa, sisäänrakennetussa tiedostotyökalussa vai MCP-kutsussa? - Mikä taito oikeasti aktivoitui?
- Minkä tyyppinen alaagentti lähetettiin?
- Tekikö istunto hyödyllistä työtä vai vain rimpuiliko paikallaan?
Tuo toinen kysymysluokka elää lähempänä hookeja kuin jäljityksiä.
Mutta myös käänteinen pätee: jotkin tärkeimmistä suorituskykykysymyksistä elävät lähempänä jäljityksiä kuin hookeja.
Jos haluat tietää, mihin viive todella kertyi, mitkä spanit olivat hitaita tai poltettiinko istunnossa aikaa mallikutsuihin vai työkalujen suoritukseen, tarvitset jäljitysdataa semanttisten tapahtumien lisäksi.
Arkkitehtuuri, johon päädyimme
Ajamme kahta telemetriapolkua rinnakkain.
Claude Code
native OTEL -> Alloy -> Grafana Cloud
hooks -> send_event.py -> Grafana Cloud Loki
Codex
native OTEL -> Alloy -> Grafana Cloud
notify hook -> codex_notify.py -> shared Loki schema
Tuo jako on tarkoituksellinen.
Se on myös epäsymmetrinen. Claude Code antaa meille paljon rikkaamman elinkaari-hook-pinnan. Codex antaa meille natiivin OTEL:in plus notify-pinnan, joten normalisoimme ohuemmat vuoron valmistumistapahtumat samaan lokiskeemaan sen sijaan että teeskentelisimme molempien ajoympäristöjen paljastavan samat säätimet.
Natiivi OTEL antaa meille perusvirtan: lokit ja jäljitykset itse ajoympäristöstä sekä metriikat siellä, missä ajoympäristö niitä todella lähettää.
Hook- ja notify-tapahtumat antavat meille semanttisen kerroksen: asioita kuten PreToolUse, PostToolUse, PostToolUseFailure, UserPromptSubmit, SubagentStop, SkillActivated, ja luokitellun metadatan, josta oikeasti välitämme agenttien käyttäytymistä vianetsittäessä. Claude Code antaa tässä rikkaamman tapahtumavirran. Codex antaa ohuemman mutta silti hyödyllisen normalisoidun virran.
Miksi hookit ylipäätään ovat olemassa
Hook-putkemme rikastaa tapahtumat ennen kuin ne osuvat Lokiin.
Sen sijaan että vain sanoisimme “työkalu ajettiin”, luokittelemme tapahtuman kenttiin kuten:
tool_type: builtin, mcp, skill, agent, bashmcp_server: mikä MCP-taustajärjestelmä käsitteli kutsunbash_cli: shell-komennon perhesubagent_type: minkälainen erikoisosaaja lähetettiinagent_tool: oliko lähde Claude Code vai Codex
Se tarkoittaa, että voimme kysyä operatiivisesti merkityksellisiä kysymyksiä:
{service_name="claude-code-hooks"} | agent_tool="codex-cli"
{service_name="claude-code-hooks"} | tool_type="mcp"
{service_name="claude-code-hooks"} | json | bash_cli="git"
Ne eivät ole turhia kenttiä. Ne ovat ero sen välillä, että “agentti tuntui hitaalta” ja sen välillä, että “agentti käytti viimeiset kymmenen minuuttia shell-painotteisiin git-operaatioihin, joissa työkalujen epäonnistumisaste oli korkea”.
Yksi toteutusyksityiskohta, joka näyttää oudommalta kuin onkaan: jaettu Loki-virta käyttää yhä service_name="claude-code-hooks":ta tunnisteena silloinkin, kun tapahtuma tuli Codexista. Todellinen jako ajoympäristöjen välillä tapahtuu kentässä agent_tool.
Miksi Alloy istuu keskellä
Grafana Alloy ei ole tässä asetelmassa vain edelleenlähettäjä. Se on käytäntörajapinta.
Ohjaamme Claude Coden ja Codexin natiivin OTEL-virran paikalliseen Alloy-proxyyn osoitteessa localhost:4318 ja annamme sitten Alloyn siivota hyötykuorman ennen sen edelleenlähetystä Grafana Cloudiin.
Se merkitsee, koska raaka agenttitelemetria on täynnä korkean kardinaliteetin kenttiä, jotka ovat hyödyllisiä analyysille mutta kauheita indeksoituina tunnisteina:
session_idprompt_id- token-määrät
- kestot
- työkalun parametriblobit
Jos indeksoit kaiken, saat tunnisteräjähdyksen ja huonon päivän.
Joten Alloy tekee meille kolme asiaa:
- Pitää hyvin pienen joukon matalan kardinaliteetin tunnisteita indeksoituna.
- Siirtää meluisat mutta hyödylliset kentät rakenteelliseen metadataan.
- Pudottaa puhtaan kohinan kokonaan.
Tärkeä idea on yksinkertainen: havainnoi enemmän, indeksoi vähemmän.
Miksi hook-virta ohittaa Alloyn
Hook-virta on jo muotoiltu Lokia varten.
Siihen mennessä, kun send_event.py työntää tapahtuman, olemme jo päättäneet, mitkä kentät ansaitsevat tunnistekohtelun ja mitkä kuuluvat rakenteelliseen JSON-runkoon. Tuo virta menee suoraan Grafana Cloudin OTLP-yhdyskäytävään ilman toista kierrosta Alloyn kautta.
Järjestelmässä on siis selkeä työnjako:
- Alloy kesyttää raa’an natiivin OTEL-virran.
- Hook-rikastus tekee semanttisista tapahtumista kyselykelpoisia.
Se pitää arkkitehtuurin yksinkertaisempana kuin yrittää pakottaa kaikki yhden polun läpi.
Mitä kojelauta oikeasti näyttää
Alla oleva kuvakaappaus on yksi agenttityönkulkumme takana olevista havainnointikojelaudoista. Se ei ole vertailuarvo, ja luvut ovat vain hetkellinen siivu. Pointti on datan muoto: aktiviteettivirta, työkalukutsut, epäonnistumiset, kehotteet ja jaottelut agentin, sisäänrakennettujen työkalujen, MCP-käytön, shell-komentojen ja taitojen mukaan.
Hyödyllinen osa on se, että tämä kojelauta elää samassa Grafana-pinossa kuin muu agenttitelemetria. Voimme suodattaa lähdeagentin ja työkaluperheen mukaan ja tarkastella eri ajoympäristöjä keksimättä erilaista havainnointitarinaa jokaiselle järjestelmälle.
Miksi jäljitykset merkitsevät enemmän kuin ne aluksi näyttävät
Lokit kertovat, minkä kategorian työtä tapahtui. Jäljitykset kertovat, miten työ eteni ajan myötä.
Tuo ero merkitsee agenttijärjestelmissä, koska “hidas” on liian tylppä ollakseen hyödyllinen.
Jäljitys voi kertoa meille, tuliko kipu:
- mallin viiveestä
- työkalun suoritusajasta
- toistuvista uudelleenyrityksistä
- yhdestä erityisen kalliista MCP-vuorovaikutuksesta
- pitkästä hännästä pieniä operaatioita, jotka näyttivät erikseen harmittomilta
Käytännössä käytämme hook-virtaa ja Tempo-jäljityksiä yhdessä.
- Hook-lokit vastaavat: minkälaista asiaa tapahtui?
- Jäljitykset vastaavat: mihin aika meni?
Yhdistelmä on se, mikä muuttaa havainnoinnin kojelaudasta selitykseksi.
Mihin Codex sopii
Codex on osa samaa pinoa, mutta se ei ole identtinen Claude Coden kanssa.
Codexille kytkemme kaksi osaa:
- Natiivin OTEL:in Codexista Alloyyn
- Notify-webhookin osoitteeseen
codex_notify.py, joka kartoittaa vuoron valmistumiset samaan Loki-skeemaan, jota käytämme hook-tapahtumille
Se antaa meille yhtenäisen suodattimen kuten agent_tool="codex-cli" saman lokivirran sisällä.
Rehellinen varaus: Codexin notify-hyötykuorma on tällä hetkellä ohuempi kuin Claude Coden hook-hyötykuorma, koska kyseessä ei ole samanlainen integraatiopinta. Nykyisessä asetuksessamme Codexin vuoron valmistumiset voidaan normalisoida jaettuun skeemaan, mutta rikas työkalu-työkalulta-poiminta on yhä parempi natiivissa OTEL-virrassa kuin notify-sillassa.
Se ei ole syy välttää tätä postausta. Se on postauksen pointti. Todelliset havainnointijärjestelmät rakennetaan epätäydellisistä signaaleista.
Grafana MCP:n yli muuttaa peliä
Suurempi muutos on se, että Grafana ei ole enää vain paikka, jossa ihmiset käyvät selaimessa.
Tässä repositoriossa paljastamme Grafanan myös MCP:n kautta. Se tarkoittaa, että agentti voi kysellä Lokia, Prometheusta ja Tempoa suoraan sen sijaan, että odottaisi ihmisen tarkastavan kojelaudat käsin ensin.
Se muuttaa havainnoinnin aktiiviseksi syötteeksi työnkulkuun.
Agentti voi kysyä:
- Mitkä työkaluperheet epäonnistuivat eniten viimeisen tunnin aikana?
- Mikä MCP-palvelin hallitsi istuntoa?
- Vähensivätkö viimeaikaiset muutokset työkaluepäonnistumisia vai siirsivätkö ne vain työn shell-painotteisempiin polkuihin samoilla virheillä?
- Mitkä jäljitykset näyttävät suurimman viiveen tai toistuvat uudelleenyritykset?
Kun sinulla on tuo, olet hyvin lähellä itseparannussilmukkaa.
Kojelaudasta palautesilmukkaan
Tämä on osa, jonka löydämme kiinnostavimmaksi.
Kun havainnointipino on kyseltävissä agenttikerroksesta, telemetria lakkaa olemasta passiivinen raportointipinta ja muuttuu ohjaussignaaliksi.
Silmukka näyttää tältä:
- Agentin toiminta lähettää jäljityksiä, metriikoita ja rikastettuja hook-lokeja.
- Grafana tallentaa todisteet Lokiin, Tempoon ja Prometheukseen, missä metriikoita on.
- Agentit kyselevät noita todisteita Grafana MCP:n kautta.
- Järjestelmä tunnistaa huonon työkalusekoituksen, hauraat taidot, heikon reitityksen tai shell-painotteiset työnkulut, jotka jatkavat vältettävien virheiden tuottamista.
- Agentit tai operaattorit säätävät kehotteita, agenttikonfiguraatioita, taitokuvauksia, reitityssääntöjä tai työkalupääsyä.
- Seuraava istunto tuottaa uuden telemetriamuodon, ja kierto toistuu.
Näin siirrytään “mielenkiintoisesta kojelaudasta” “mitattavaan parannusjärjestelmään”.
Tavoite ei ole maksimoida yhtä työkaluluokkaa. Se on löytää oikea sekoitus CLI:tä, sisäänrakennettuja työkaluja, MCP-kutsuja ja taitoja siihen työhön, jota oikeasti tehdään.
Mihin tämä antaa meille vastauksen
Kun molemmat ajoympäristöt päätyvät samaan Grafana-pinoon, voimme vastata operatiivisiin kysymyksiin paljon nopeammin:
- Keskittyvätkö epäonnistumiset yhteen työkaluperheeseen?
- Luovatko shell-painotteiset työnkulut vältettäviä virheitä, joissa korkeamman tason työkalun pitäisi olla olemassa?
- Mitkä MCP-palvelimet kantavat työtaakan?
- Maksammeko agenttitoiminnasta, joka ei tuota merkityksellistä edistystä?
- Onko istunto epäterve mallin, työkalujen vai orkestrointikerroksen vuoksi?
Tämä on erityisen hyödyllistä moniagenttisissa työnkuluissa, joissa “agentti oli kiireinen” ei kerro melkein mitään.
Jos yhtä erikoisosaajaa jatketaan lähettämään ja se tuottaa korkeita epäonnistumisasteita, se on reititys- tai kehotemuotoiluongelma.
Jos yksi MCP-palvelin hallitsee kaikkia kutsuja, se saattaa olla hyvää arkkitehtuuria tai merkki siitä, että kaikki muu on kuollutta painoa.
Jos työkaluepäonnistumiset piikkaavat kustannusten pysyessä korkeina, sinulla on operatiivinen ongelma, ei laatuongelma.
Jos shell-työ jatkuvasti epäonnistuu ennustettavilla, vältettävillä tavoilla, joissa korkeamman tason työkalun pitäisi olla olemassa, se on tuotesignaali.
Jos yksi taito aktivoituu jatkuvasti muttei paranna lopputuloksia, se on kehote- tai reitityssignaali.
Todellinen opetus
Syvempi opetus tässä on se, että agenttien havainnointi tarvitsee sekä ajoympäristön telemetriaa että työnkulun telemetriaa.
Ajoympäristön telemetria kertoo, mitä järjestelmä teki.
Työnkulun telemetria kertoo, mitä agentti luuli tekevänsä.
Tarvitsemme molempia.
Jos säilytät vain jäljitykset ja laskurit, menetät semanttisen kerroksen. Jos säilytät vain hook-tapahtumat, menetät viiveen, spanit ja laajemman ajoympäristökuvan.
Ja jos säilytät molemmat mutta et koskaan syötä niitä takaisin agenttikerrokseen, sinulla on valvontaa, ei sopeutumista.
Yhdistelmä on se, mikä tekee järjestelmästä tarpeeksi selitettävän operoitavaksi ja tarpeeksi viritettävän parannettavaksi.
Mikä on yhä epätäydellistä
Siellä on yhä karkeita reunoja.
- Kaikki hook-tapahtumat eivät sisällä kesto- ja token-dataa, jota haluaisimme.
- Osa parhaista ajoitusnäkymistä tulee yhä Tempo-jäljityksistä, ei hook-lokeista.
- Codex on tänään semanttisesti köyhempi kuin Claude Code rikastetussa tapahtumavirrassa.
- Kojelaudan kuvakaappaus on live-operaatiopinta, ei viimeistelty markkinointiartefakti.
Tuo viimeinen kohta on tarkoituksellinen. Näytämme mieluummin todellisen mittaritaulun kuin teeskentelemme agenttijärjestelmien olevan maagisesti itseselittäviä.
Miksi tämä merkitsee Maguyvalle
Maguyva antaa agenteille parempaa koodiälyä. Mutta kun agentit oikeasti tekevät hyödyllistä työtä, uusi vaatimus ilmestyy välittömästi: sinun täytyy nähdä, miten ne käyttäytyvät.
Haun laatu, reitityksen laatu, työkalun valinta ja kontekstin tehokkuus muuttuvat kaikki havaittaviksi ongelmiksi.
Siksi ajattelemme tämän olevan kirjoittamisen arvoinen. Tulevaisuuden agenttipino ei ole vain kehotteita ja työkaluja. Se on kehotteita, työkaluja ja instrumentointikerros, joka kertoo, toimiiko koko homma.
Jos rakennat vakavia agenttityönkulkuja, havainnointi ei ole valinnainen infrastruktuuri. Se on osa tuotetta.
Aiheeseen liittyvää
Lisää Maguyva-projektin rakennuslokista
Miksi päivitimme koodihaun malliin voyage-4-large_
Siirsimme koodiupotuksemme malliin voyage-4-large — joka on tällä hetkellä julkisen RTEB-koodinoutorankinglistan kärjessä. Rehellinen versio: kompromissi, jonka teemme, mitä todella indeksoimme ja miksi maksamme premium-upotuksista.
Kielten rekursiivinen itseparannus: koodiälyn hiominen noin 280 kielessä_
Tuemme koodiälyä noin 280 kielelle. Kukaan ihminen ei pysty auditoimaan sitä käsin. Siksi rakensimme kielten rekursiivisen itseparannussilmukan — pistokoe, LLM tuomarina, korjaa yksi asia, validoi uudelleen — ja ajamme sitä eristettyjen agenttien parvella, kunnes poiminta on todella oikein, ei vain vihreä.
Monimodaalinen fuusiohaku: oikean hakukoneen valinta jokaiselle kyselylle_
Kysely kuten "missä parseConfig on määritelty" haluaa erilaisen haun kuin "miten todennus toimii". Maguyva luokittelee tarkoituksen, painottaa neljää hakumodaliteettia sen mukaisesti ja yhdistää tulokset painotetulla Reciprocal Rank Fusionilla.