Observabiliti Ejen: Hooks, Alloy, dan Grafana
> 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, bashmcp_server: backend MCP mana yang mengendalikan panggilan itubash_cli: keluarga arahan shellsubagent_type: jenis spesialis yang dihantaragent_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_idprompt_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:
- Mengekalkan set label berkardinaliti rendah yang sangat kecil untuk diindeks.
- Memindahkan medan yang bising tetapi berguna ke dalam metadata berstruktur.
- 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.
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:
- Aktiviti ejen memancarkan trace, metrik, dan log hook yang diperkaya.
- Grafana menyimpan bukti itu dalam Loki, Tempo, dan Prometheus di mana metrik wujud.
- Ejen mempertanyakan bukti itu menerusi Grafana MCP.
- 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.
- Ejen atau operator menyelaraskan prompt, config ejen, penerangan skill, peraturan penghalaan, atau akses tool.
- 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
Mengapa Kami Menaik Taraf Carian Kod kepada voyage-4-large_
Kami mengalihkan embeddings kod kami kepada voyage-4-large — kini berada di puncak leaderboard pengambilan kod RTEB awam. Versi jujurnya: trade yang kami buat, apa yang benar-benar kami indeks, dan mengapa kami membayar untuk embeddings premium.
Penambahbaikan Kendiri Rekursif Bahasa: Menggilap Code Intelligence Merentasi ~280 Bahasa_
Kami menyokong code intelligence untuk ~280 bahasa. Tiada manusia yang mampu mengaudit itu secara manual. Jadi kami membina gelung penambahbaikan kendiri rekursif bahasa — semak rawak, LLM-sebagai-hakim, baiki satu perkara, sahkan semula — dan menjalankannya dengan sepasukan ejen terasing sehingga pengekstrakan benar-benar betul, bukan sekadar hijau.
Carian Fusion Pelbagai-Modal: Memilih Retriever Yang Tepat Untuk Setiap Pertanyaan_
Pertanyaan seperti 'di mana parseConfig ditakrifkan' mahukan carian yang berbeza daripada 'bagaimana auth berfungsi'. Maguyva mengklasifikasikan niat, memberi pemberat kepada empat modaliti pengambilan mengikutnya, dan menggabungkan hasil dengan Reciprocal Rank Fusion berpemberat.