Langkau ke kandungan
cd /blog

Observabiliti Ejen: Hooks, Alloy, dan Grafana

[Observabiliti][Grafana][OpenTelemetry][Seni Bina]

> Kami menyambungkan Claude Code dan Codex ke dalam satu stack Grafana dengan OpenTelemetry dan Alloy, kemudian menggunakan trace dan log untuk mencari dan membaiki isu gelagat ejen pada puncanya.

Sistem ejen gagal dengan cara yang pelik.

Kadangkala model itu masalahnya. Kadangkala tool itu masalahnya. Kadangkala MCP server anda baik-baik sahaja, tetapi ejen memilih spesialis yang salah, atau menghabiskan separuh sesi melakukan kerja shell yang tidak anda jangkakan, atau secara senyap membazir kos dalam gelung yang kelihatan produktif dari luar.

Jika anda tidak dapat melihat perbezaannya, anda sebenarnya bukan mengendalikan sistem ejen. Anda sedang meneka.

Jadi kami membina stack observabiliti untuk aliran kerja kami sendiri: Claude Code, Codex, event hook Claude, event notify Codex, OpenTelemetry native, Grafana Alloy, dan Grafana Cloud di hujung yang satu lagi.

Bahagian yang menarik bukanlah “kami membina dashboard.” Bahagian yang menarik ialah kami terpaksa memecahkan telemetri kepada dua stream berbeza kerana tiada satu feed pun yang memberi kami gambaran keseluruhan.

Masalahnya: Telemetri Ejen Berpecah-belah

Ejen pengekodan moden sudah pun memancarkan sedikit telemetri. Itu membantu, tetapi tidak mencukupi.

OTEL native pandai menjawab soalan seperti:

  • Berapa banyak permintaan yang kami buat?
  • Berapa kos sesuatu sesi?
  • Di mana span dan trace berada?
  • Adakah kependaman melonjak?

Ia jauh lebih lemah dalam menjawab soalan seperti:

  • MCP server mana yang ejen bergantung kepadanya?
  • Adakah kegagalan ini berlaku dalam Bash, tool fail terbina-dalam, atau panggilan MCP?
  • Skill mana yang benar-benar diaktifkan?
  • Jenis subagent mana yang dihantar?
  • Adakah sesi itu melakukan kerja yang berguna, atau sekadar berpusing-pusing tanpa hala tuju?

Kelas soalan kedua itu lebih hampir kepada hooks berbanding trace.

Tetapi sebaliknya juga benar: sebahagian soalan prestasi yang paling penting lebih hampir kepada trace berbanding hooks.

Jika anda ingin tahu di mana kependaman sebenarnya terkumpul, span mana yang perlahan, atau sama ada sesi itu membazir masa dalam panggilan model berbanding pelaksanaan tool, anda memerlukan data trace selain event semantik.

Seni Bina Yang Akhirnya Kami Gunakan

Kami menjalankan dua laluan telemetri secara bersebelahan.

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

Pemisahan itu sengaja dilakukan.

Ia juga tidak simetri. Claude Code memberi kami permukaan hook lifecycle yang jauh lebih kaya. Codex memberi kami OTEL native ditambah permukaan notify, jadi kami menormalkan event penyempurnaan giliran (turn-completion) yang lebih nipis kepada skema log yang sama, dan bukan berpura-pura kedua-dua runtime mendedahkan kawalan yang sama.

OTEL Native memberi kami stream garis dasar: log dan trace daripada runtime itu sendiri, ditambah metrik di mana runtime benar-benar memancarkannya.

Event hook dan notify memberi kami lapisan semantik: perkara seperti PreToolUse, PostToolUse, PostToolUseFailure, UserPromptSubmit, SubagentStop, SkillActivated, dan metadata terklasifikasi yang benar-benar kami pedulikan semasa menyahpepijat gelagat ejen. Claude Code menyumbang stream event yang lebih kaya di sini. Codex menyumbang stream ternormal yang lebih nipis tetapi masih berguna.

Mengapa Hooks Wujud Langsung

Saluran paip hook kami memperkaya event sebelum ia sampai ke Loki.

Selain sekadar mengatakan “satu tool telah berjalan,” kami mengklasifikasikan event itu ke dalam medan seperti:

  • tool_type: builtin, mcp, skill, agent, bash
  • mcp_server: backend MCP mana yang mengendalikan panggilan itu
  • bash_cli: keluarga arahan shell
  • subagent_type: jenis spesialis yang dihantar
  • agent_tool: sama ada sumbernya Claude Code atau Codex

Ini bermakna kami dapat bertanya soalan yang penting dari segi operasi:

{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"

Itu bukan medan hiasan semata-mata. Ia adalah perbezaan antara “ejen terasa perlahan” dengan “ejen menghabiskan sepuluh minit terakhir dalam operasi git yang sarat shell dengan kadar kegagalan tool yang tinggi.”

Satu butiran pelaksanaan yang kelihatan lebih pelik daripada sebenarnya: stream Loki kongsi masih menggunakan service_name="claude-code-hooks" sebagai label walaupun apabila event itu datang daripada Codex. Pemisahan sebenar antara runtime berlaku pada agent_tool.

Mengapa Alloy Berada Di Tengah

Grafana Alloy bukan sekadar forwarder dalam persediaan ini. Ia adalah sempadan polisi.

Kami mengarahkan stream OTEL native daripada Claude Code dan Codex ke proxy Alloy setempat pada localhost:4318, kemudian membenarkan Alloy membersihkan payload sebelum meneruskannya ke Grafana Cloud.

Itu penting kerana telemetri ejen yang mentah sarat dengan medan kardinaliti tinggi yang berguna untuk analisis tetapi teruk sebagai label yang diindeks:

  • session_id
  • prompt_id
  • kiraan token
  • tempoh
  • blob parameter tool

Jika anda mengindeks segala-galanya, anda akan mendapat letupan label dan hari yang teruk.

Jadi Alloy melakukan tiga perkara untuk kami:

  1. Mengekalkan set label berkardinaliti rendah yang sangat kecil untuk diindeks.
  2. Memindahkan medan yang bising tetapi berguna ke dalam metadata berstruktur.
  3. Membuang bunyi bising tulen sepenuhnya.

Idea pentingnya mudah: perhatikan lebih banyak, indeks lebih sedikit.

Mengapa Stream Hook Memintas Alloy

Stream hook sudah dibentuk untuk Loki.

Pada masa send_event.py menolak sesuatu event, kami sudah pun menentukan medan mana yang layak dilabel dan mana yang tergolong dalam badan JSON berstruktur. Stream itu terus ke gateway OTLP Grafana Cloud tanpa melalui satu lagi laluan menerusi Alloy.

Jadi sistem itu mempunyai pembahagian kerja yang jelas:

  • Alloy menjinakkan stream OTEL native yang mentah.
  • Pengayaan hook menjadikan event semantik boleh dipertanyakan (queryable).

Itu mengekalkan seni bina lebih ringkas berbanding cuba memaksa segala-galanya melalui satu laluan.

Apa Yang Dashboard Sebenarnya Tunjukkan

Tangkapan skrin di bawah diambil daripada salah satu dashboard observabiliti di sebalik aliran kerja ejen kami. Ia bukan penanda aras, dan angka-angka itu hanyalah cebisan pada satu-satu masa. Intinya ialah bentuk data itu: feed aktiviti, panggilan tool, kegagalan, prompt, dan pecahan mengikut ejen, tool terbina-dalam, penggunaan MCP, arahan shell, dan skill.

Bahagian yang berguna ialah dashboard ini berada pada stack Grafana yang sama dengan selebihnya telemetri ejen. Kami dapat menapis mengikut ejen sumber dan keluarga tool serta melihat merentasi runtime tanpa perlu mencipta cerita observabiliti yang berbeza untuk setiap sistem.

Dashboard Grafana menunjukkan feed aktiviti, kiraan panggilan tool, kegagalan, prompt, dan pecahan mengikut ejen, tool terbina-dalam, penggunaan MCP, arahan CLI, dan skill untuk aliran kerja ejen.
Salah satu dashboard langsung di sebalik aliran kerja ejen kami. Tangkapan skrin ini hanyalah satu cebisan daripada stack Grafana kongsi yang turut menerima telemetri daripada runtime dan sistem ejen kami yang lain. Klik imej untuk versi resolusi penuh.

Mengapa Trace Lebih Penting Daripada Yang Kelihatan Pada Mulanya

Log memberitahu kami kategori kerja apa yang berlaku. Trace memberitahu kami bagaimana kerja itu berlaku sepanjang masa.

Perbezaan itu penting dalam sistem ejen kerana “perlahan” terlalu kabur untuk berguna.

Satu trace boleh memberitahu kami sama ada kesukaran itu datang daripada:

  • kependaman model
  • masa pelaksanaan tool
  • percubaan semula yang berulang
  • satu interaksi MCP yang amat mahal
  • ekor panjang operasi kecil yang kelihatan tidak berbahaya secara berasingan

Dalam praktiknya kami menggunakan stream hook dan trace Tempo bersama-sama.

  • Log hook menjawab: apa jenis perkara yang berlaku?
  • Trace menjawab: ke mana masa itu pergi?

Gabungan itulah yang mengubah observabiliti daripada sekadar dashboard kepada satu penjelasan.

Di Mana Codex Sesuai

Codex adalah sebahagian daripada stack yang sama, tetapi ia tidak sama seperti Claude Code.

Untuk Codex kami menyambungkan dua bahagian:

  • OTEL native daripada Codex ke Alloy
  • Webhook notify ke codex_notify.py, yang memetakan penyempurnaan giliran kepada skema Loki yang sama yang kami gunakan untuk event hook

Itu memberi kami penapis bersatu seperti agent_tool="codex-cli" di dalam stream log yang sama.

Peringatan jujur: payload notify Codex kini lebih nipis berbanding payload hook Claude Code kerana ia bukan jenis permukaan integrasi yang sama. Dalam persediaan kami hari ini, penyempurnaan giliran Codex boleh dinormalkan kepada skema kongsi, tetapi pengekstrakan tool demi tool yang kaya masih lebih baik dalam stream OTEL native berbanding dalam jambatan notify.

Itu bukan alasan untuk mengelakkan penulisan ini. Itulah sebenarnya intipati penulisan ini. Sistem observabiliti sebenar dibina daripada isyarat yang tidak sempurna.

Grafana Menerusi MCP Mengubah Segalanya

Peralihan yang lebih besar ialah Grafana bukan sekadar tempat manusia melawat dalam browser.

Dalam repositori ini kami turut mendedahkan Grafana menerusi MCP. Ini bermakna ejen dapat mempertanyakan Loki, Prometheus, dan Tempo secara langsung dan bukannya menunggu manusia memeriksa dashboard secara manual terlebih dahulu.

Itu mengubah observabiliti menjadi input aktif kepada aliran kerja.

Ejen boleh bertanya:

  • Keluarga tool mana yang paling banyak gagal dalam sejam yang lepas?
  • MCP server mana yang mendominasi sesuatu sesi?
  • Adakah perubahan terkini mengurangkan kegagalan tool atau sekadar memindahkan kerja itu ke laluan yang lebih sarat shell dengan kesilapan yang sama?
  • Trace mana yang menunjukkan kependaman tertinggi atau percubaan semula yang berulang?

Sebaik sahaja anda mempunyai itu, anda sangat hampir kepada gelung penambahbaikan kendiri.

Daripada Dashboard Kepada Gelung Maklum Balas

Inilah bahagian yang kami dapati paling menarik.

Sebaik sahaja stack observabiliti boleh dipertanyakan daripada lapisan ejen, telemetri berhenti menjadi permukaan pelaporan pasif dan menjadi isyarat kawalan.

Gelung itu kelihatan seperti ini:

  1. Aktiviti ejen memancarkan trace, metrik, dan log hook yang diperkaya.
  2. Grafana menyimpan bukti itu dalam Loki, Tempo, dan Prometheus di mana metrik wujud.
  3. Ejen mempertanyakan bukti itu menerusi Grafana MCP.
  4. Sistem mengenal pasti campuran tool yang buruk, skill yang rapuh, penghalaan yang lemah, atau aliran kerja sarat shell yang terus menghasilkan kesilapan yang boleh dielakkan.
  5. Ejen atau operator menyelaraskan prompt, config ejen, penerangan skill, peraturan penghalaan, atau akses tool.
  6. Sesi seterusnya menghasilkan bentuk telemetri baharu, dan kitaran itu berulang.

Itulah caranya anda beralih daripada “dashboard yang menarik” kepada “sistem penambahbaikan yang boleh diukur.”

Matlamatnya bukan untuk memaksimumkan satu kategori tool. Ia adalah untuk mencapai campuran yang tepat antara CLI, tool terbina-dalam, panggilan MCP, dan skill untuk kerja yang benar-benar sedang dilakukan.

Apa Yang Ini Membolehkan Kami Jawab

Sebaik sahaja kedua-dua runtime mendarat pada stack Grafana yang sama, kami dapat menjawab soalan operasi dengan jauh lebih pantas:

  • Adakah kegagalan tertumpu pada satu keluarga tool?
  • Adakah aliran kerja sarat shell mencipta kesilapan yang boleh dielakkan di mana sepatutnya wujud tool peringkat lebih tinggi?
  • MCP server mana yang menanggung beban kerja?
  • Adakah kami membayar untuk aktiviti ejen yang tidak menghasilkan kemajuan yang bermakna?
  • Adakah sesuatu sesi tidak sihat kerana model, tool, atau lapisan orkestrasi?

Ini amat berguna dalam aliran kerja pelbagai-ejen, di mana “ejen itu sibuk” hampir tidak memberitahu anda apa-apa.

Jika satu spesialis terus-menerus dihantar dan menghasilkan kadar kegagalan yang tinggi, itu adalah masalah penghalaan atau pembentukan prompt.

Jika satu MCP server mendominasi semua panggilan, itu mungkin seni bina yang baik atau tanda bahawa segala-galanya yang lain adalah beban yang tidak berguna.

Jika kegagalan tool melonjak sementara kos kekal tinggi, anda mempunyai masalah operasi, bukan masalah kualiti.

Jika kerja shell terus gagal dengan cara yang boleh dijangka dan boleh dielakkan di mana sepatutnya wujud tool peringkat lebih tinggi, itu adalah isyarat produk.

Jika satu skill sentiasa diaktifkan tetapi tidak meningkatkan hasil, itu adalah isyarat prompt atau penghalaan.

Pengajaran Sebenar

Pengajaran yang lebih mendalam di sini ialah observabiliti ejen memerlukan kedua-dua telemetri runtime dan telemetri aliran kerja.

Telemetri runtime memberitahu anda apa yang sistem lakukan.

Telemetri aliran kerja memberitahu anda apa yang ejen fikir ia sedang lakukan.

Kami memerlukan kedua-duanya.

Jika anda hanya menyimpan trace dan counter, anda terlepas lapisan semantik. Jika anda hanya menyimpan event hook, anda terlepas kependaman, span, dan gambaran runtime yang lebih luas.

Dan jika anda menyimpan kedua-duanya tetapi tidak pernah menyalurkannya semula ke lapisan ejen, anda hanya mempunyai pemantauan, bukan penyesuaian.

Gabungan itulah yang menjadikan sistem cukup boleh dijelaskan untuk dikendalikan dan cukup boleh diselaraskan untuk diperbaiki.

Apa Yang Masih Tidak Sempurna

Masih ada bahagian yang kasar.

  • Tidak setiap event hook merangkumi data tempoh dan token yang kami mahukan.
  • Sebahagian daripada paparan masa terbaik masih datang daripada trace Tempo, bukan log hook.
  • Codex hari ini kurang kaya secara semantik berbanding Claude Code dalam stream event yang diperkaya.
  • Tangkapan skrin dashboard adalah permukaan operasi langsung, bukan artifak pemasaran yang digilap.

Perkara terakhir itu adalah sengaja. Kami lebih suka menunjukkan panel instrumen sebenar berbanding berpura-pura sistem ejen secara ajaib menjelaskan diri sendiri.

Mengapa Ini Penting Untuk Maguyva

Maguyva adalah tentang memberi ejen code intelligence yang lebih baik. Tetapi sebaik sahaja ejen benar-benar melakukan kerja yang berguna, satu keperluan baharu muncul serta-merta: anda perlu melihat bagaimana mereka berkelakuan.

Kualiti carian, kualiti penghalaan, pemilihan tool, dan kecekapan konteks semuanya menjadi masalah yang boleh diperhatikan.

Itulah sebabnya kami rasa ini berbaloi ditulis. Stack ejen masa depan bukan sekadar prompt dan tool. Ia adalah prompt, tool, dan lapisan instrumentasi yang memberitahu anda sama ada keseluruhannya berfungsi.

Jika anda membina aliran kerja ejen yang serius, observabiliti bukan infrastruktur pilihan. Ia adalah sebahagian daripada produk.

Bacaan berkaitan

Lagi daripada log pembinaan Maguyva