Obserwowalność agentów: ślady, wywołania narzędzi, koszty i logi audytowe
Obserwowalność agentów to eksport telemetrii każdego agenta kodującego (sesji, zapytań do modelu, wywołań narzędzi, decyzji o uprawnieniach i kosztów) przez OpenTelemetry, oznaczanie każdego przebiegu identyfikatorami, które wiążą go z pull requestem i z późniejszymi incydentami, oraz dłuższe przechowywanie zdarzeń audytowych niż analitycznych. Claude Code i Codex eksportują OpenTelemetry natywnie; w Cursorze lukę wypełniają hooki i proweniencja commitów.
Ta strona jest dla dewelopera, który uruchamia pętle agentów w CI, dla tech leada, który odpowiada za autonomię pętli, i dla CTO, który podpisuje budżet i politykę audytu. Sytuacja, którą rozwiązuje: we wtorek zmiana napisana przez agenta wywołała incydent na produkcji, a w środę nikt nie potrafi powiedzieć, która sesja ją napisała, co agent uruchomił, kto zatwierdził wywołania narzędzi ani ile ta pętla kosztuje w przeliczeniu na zmianę, która się utrzymała. Masz logi swoich usług i żadnych logów tego, co te usługi pisze.
Co zyskujesz dzięki tak zbudowanej obserwowalności agentów
Dział zatytułowany „Co zyskujesz dzięki tak zbudowanej obserwowalności agentów”- Kolektor ze spseudonimizowanym potokiem analitycznym i potokiem audytowym z tożsamościami.
- Ustawienia eksportu dla Claude Code i Codeksa oraz sprawdzoną ścieżkę dla Cursora.
- Cztery klucze łączenia, które prowadzą od commita do pull requesta, sesji i wywołań narzędzi.
- Dashboard z ośmioma panelami i jego SQL, szablon retencji i trzy prompty do skopiowania.
Dlaczego przebiegi agentów potrzebują własnej telemetrii?
Dział zatytułowany „Dlaczego przebiegi agentów potrzebują własnej telemetrii?”Telemetria usług odpowiada na pytanie „co zrobił system?”. Telemetria agentów odpowiada na inne: „co zrobiło to, co zmieniło system, z czyjego upoważnienia i za ile?”. Raport Faros AI AI Engineering Report 2026: The Acceleration Whiplash (kwiecień 2026, dwa lata telemetrii 22 000 deweloperów z własnej platformy Farosa) podaje wzrost mediany czasu w review o 441,5% i liczby incydentów na pull request o 242,7%. Gdy recenzenci nie są w stanie przeczytać wszystkiego, dowody o przebiegu musi dać telemetria.
Trzy cechy odróżniają telemetrię agentów:
- Jednostką jest przebieg, nie żądanie. Jeden przebieg to sesja z wieloma wywołaniami modelu i narzędzi, czasem z subagentami. O sukcesie decyduje się kilka dni później, gdy pull request zostanie scalony i się utrzyma.
- Tożsamość należy do dewelopera. Claude Code przypisuje każde wywołanie narzędzia deweloperowi, który uruchomił sesję; nie działa na osobnym koncie usługowym (dokumentacja monitoringu Claude Code, sprawdzone 2026-09-26). Te same dane są jednocześnie śladem audytowym i potencjalnym narzędziem inwigilacji.
- Treść jest domyślnie wrażliwa. Prompty, argumenty narzędzi i odpowiedzi modelu mogą zawierać sekrety i dane klientów. Oba narzędzia nie wysyłają treści w telemetrii, dopóki świadomie tego nie włączysz.
Co emituje każde z narzędzi?
Dział zatytułowany „Co emituje każde z narzędzi?”Skonfiguruj każde narzędzie osobno i znormalizuj dane potem.
| Pojęcie | Claude Code 2.1.283 | Codex CLI 0.157.1 | Cursor |
|---|---|---|---|
| Mechanizm eksportu | Metryki i zdarzenia logów OTel; ślady w wersji beta | Logi, ślady i metryki OTel z tabeli [otel] | Eksportu OTel nie udało się zweryfikować 2026-09-26; użyj hooków i narzędzi proweniencji |
| ID sesji lub przebiegu | session.id (OTel); session_id w claude -p --output-format json | conversation.id (OTel); thread_id w codex exec --json | ID przebiegów z Cloud Agents API i webhooki statusChange (zweryfikowane 2026-08-28) |
| Koszt | claude_code.cost.usage (USD); total_cost_usd dla przebiegu headless | Metryka codex.turn.cost_microusd; zdarzenie codex.turn_cost z usage.estimated_usd | Niezweryfikowane |
| Tokeny | claude_code.token.usage według type, model, effort | codex.turn.token_usage; usage w każdym turn.completed | Niezweryfikowane |
| Wywołania narzędzi | claude_code.tool_result (tool_name, success, duration_ms) | codex.tool_result; metryka codex.tool.call | Hooki (JSON przez stdio); nazw zdarzeń nie zweryfikowano |
| Decyzje o uprawnieniach | claude_code.tool_decision, claude_code.permission_mode_changed | codex.tool_decision, codex.sandbox_outcome | Niezweryfikowane |
| Powiązanie z commitem | vcs.ref.head.revision w tool_result udanego git commit (wymaga OTEL_LOG_TOOL_DETAILS=1) | Brak; zapisz thread_id w pull requeście | Trailer commita Entire-Checkpoint z Entire CLI |
| Dashboard dostawcy | claude.ai/analytics/claude-code (Team, Enterprise); platform.claude.com/claude-code (Console) | Dashboard analityczny Enterprise (źródło wtórne: strony pomocy OpenAI widziane tylko we fragmentach wyników wyszukiwania) | Niezweryfikowane 2026-09-26 (cursor.com niedostępny) |
Źródła: dokumentacja Claude Code o monitoringu i analityce; kod źródłowy Codeksa z tagu rust-v0.157.1 (codex-rs/otel, codex-rs/config/src/types.rs, codex-rs/exec/src/exec_events.rs), wszystko czytane 2026-09-26. Serwis cursor.com był 2026-09-26 nieosiągalny, więc strona nie wymienia endpointów analitycznych ani audytowych Cursora.
Wdróż obserwowalność agentów krok po kroku
Dział zatytułowany „Wdróż obserwowalność agentów krok po kroku”-
Spisz kartę pomiaru, zanim zaczniesz cokolwiek zbierać. Jeden akapit podpisany przez CTO: na jakie pytania odpowiadają dane (skuteczność przebiegów, koszt przyjętej zmiany, audyt), kto widzi tożsamości (zespół bezpieczeństwa, przez SIEM), kto widzi pseudonimy (wszyscy pozostali) i że żadna metryka nie służy do oceny konkretnej osoby. Strona o frameworkach metryk wyjaśnia, dlaczego liczba PR-ów i tokenów staje się celem do obejścia, a prywatność i przetwarzanie danych omawia warunki danych u dostawców i retencję. Telemetrię, którą inżynierowie uznają za narzędzie inwigilacji, wyłączają we własnych powłokach.
-
Postaw jeden OpenTelemetry Collector z rozdzielonymi potokami. Każde narzędzie wysyła OTLP do tego samego kolektora. Dla backendów analitycznych kolektor zastępuje e-mail hashem z kluczem, usuwa pozostałe identyfikatory użytkownika i argumenty narzędzi; SIEM dostaje niezmieniony strumień audytowy:
# otel-collector.yaml (dystrybucja OpenTelemetry Collector contrib)receivers:otlp:protocols:grpc: { endpoint: 0.0.0.0:4317 }http: { endpoint: 0.0.0.0:4318 }processors:batch: {}# Hash z kluczem: PSEUDONYM_SALT to sekret znany tylko kolektorowi.transform/pseudonymize:error_mode: ignorelog_statements:- context: logstatements:- set(attributes["user.email"], SHA256(Concat([attributes["user.email"], "${env:PSEUDONYM_SALT}"], ""))) where attributes["user.email"] != nilmetric_statements:- context: datapointstatements:- set(attributes["user.email"], SHA256(Concat([attributes["user.email"], "${env:PSEUDONYM_SALT}"], ""))) where attributes["user.email"] != nilattributes/drop-ids:actions:- key: user.account_uuidaction: delete- key: user.account_idaction: delete- key: user.idaction: delete- key: enduser.idaction: deleteattributes/strip-content:actions:- key: tool_parametersaction: delete- key: tool_inputaction: delete- key: erroraction: deleteexporters:prometheus:endpoint: 0.0.0.0:8889otlphttp/analytics:endpoint: https://logs.internal.example.com/otlpotlphttp/siem:endpoint: https://siem.internal.example.com:4318service:pipelines:metrics:receivers: [otlp]processors: [transform/pseudonymize, attributes/drop-ids, batch]exporters: [prometheus]logs/analytics:receivers: [otlp]processors: [transform/pseudonymize, attributes/drop-ids, attributes/strip-content, batch]exporters: [otlphttp/analytics]logs/audit:receivers: [otlp]processors: [batch]exporters: [otlphttp/siem]Claude Code dołącza do każdej metryki i zdarzenia
user.email,user.account_uuid,user.account_id(ID z API administracyjnych) iuser.id(trwały identyfikator instalacji); zahashowanie samego e-maila zostawia trzy drogi powrotu do konkretnej osoby. Akcjahashprocesora attributes nie używa soli, więc lista firmowych adresów e-mail ją odwraca.logs.internal.example.comisiem.internal.example.comoznaczają twój magazyn logów i odbiornik OTLP twojego SIEM-a. -
Włącz eksport w każdym narzędziu. Maszyny deweloperów dostają go przez konfigurację zarządzaną; joby CI ustawiają go same.
Umieść ustawienia eksportera w ustawieniach zarządzanych (managed settings). Claude Code ignoruje zmienne eksportera OpenTelemetry w repozytoryjnych
.claude/settings.jsoni.claude/settings.local.json, więc repozytorium nie może włączyć telemetrii, przekierować jej ani przechwytywać treści. Gdy ustawienia zarządzane ustawiająOTEL_EXPORTER_OTLP_ENDPOINT, Claude Code przy starcie usuwa endpointy per sygnał ustawione przez dewelopera (od v2.1.217).{"env": {"CLAUDE_CODE_ENABLE_TELEMETRY": "1","OTEL_METRICS_EXPORTER": "otlp","OTEL_LOGS_EXPORTER": "otlp","OTEL_EXPORTER_OTLP_PROTOCOL": "grpc","OTEL_EXPORTER_OTLP_ENDPOINT": "https://otel-collector.internal.example.com:4317","OTEL_METRICS_INCLUDE_REPOSITORY": "true","OTEL_LOG_TOOL_DETAILS": "1"}}OTEL_LOG_TOOL_DETAILS=1dodaje do zdarzeń polecenia Basha, nazwy serwerów i narzędzi MCP oraz wejście narzędzi. Dzięki temu aktywność MCP daje się audytować, a wynik narzędzia dlagit commitzawiera SHA commita; to także miejsce, w którym lądują sekrety wpisane w linii poleceń, dlatego kolektor z kroku 2 usuwa te atrybuty ze wszystkiego poza strumieniem SIEM, a endpoint musi używać TLS (https://) albo być osiągalny tylko przez sieć prywatną. Treść promptów pozostaje wyłączona, dopóki nie ustawiszOTEL_LOG_USER_PROMPTS=1.Dla przebiegu headless w CI ustaw te same zmienne w jobie i nadaj przebiegowi własne ID sesji, żeby pull request mógł je przenieść:
.github/workflows/agent-issue-to-pr.yml name: agent-issue-to-pron:workflow_dispatch:inputs:issue:description: Issue number to implementrequired: truetype: numberpermissions: {}env:ISSUE: ${{ inputs.issue }}BRANCH: agent/issue-${{ inputs.issue }}jobs:issue-to-pr:# Runs the agent. Read-only token: nothing here can push.runs-on: ubuntu-latesttimeout-minutes: 30permissions:contents: readissues: readoutputs:session_id: ${{ steps.sid.outputs.id }}env:CLAUDE_CODE_ENABLE_TELEMETRY: "1"OTEL_METRICS_EXPORTER: otlpOTEL_LOGS_EXPORTER: otlpOTEL_EXPORTER_OTLP_PROTOCOL: http/protobufOTEL_EXPORTER_OTLP_ENDPOINT: ${{ secrets.OTEL_ENDPOINT }}OTEL_EXPORTER_OTLP_HEADERS: ${{ secrets.OTEL_HEADERS }}OTEL_RESOURCE_ATTRIBUTES: ci.run_id=${{ github.run_id }},loop.name=issue-to-prOTEL_METRICS_INCLUDE_RESOURCE_ATTRIBUTES: "false"steps:- uses: actions/checkout@v7with:persist-credentials: false- uses: actions/setup-node@v7with:node-version: 22- name: Install Claude Coderun: npm install -g @anthropic-ai/claude-code- name: Prepare the branch and the promptenv:GH_TOKEN: ${{ github.token }}run: |git config user.name "issue-to-pr agent"git config user.email "issue-to-pr-agent@users.noreply.github.com"git switch -c "$BRANCH"{ cat .github/prompts/issue-to-pr.md; echogh issue view "$ISSUE" --json number,title,body \--jq '"Issue #\(.number): \(.title)\n\n\(.body)"'} > "$RUNNER_TEMP/prompt.md"- name: Pick a session IDid: sidrun: echo "id=$(cat /proc/sys/kernel/random/uuid)" >> "$GITHUB_OUTPUT"- name: Run the agentenv:ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }}SID: ${{ steps.sid.outputs.id }}run: |status=0claude -p "$(cat "$RUNNER_TEMP/prompt.md")" \--session-id "$SID" --output-format json \--max-budget-usd 10 --permission-mode dontAsk \--allowedTools "Read,Grep,Glob,Edit,Write,Bash(npm test *),Bash(git commit *)" \> "$RUNNER_TEMP/run.json" || status=$?jq -c '{session_id, is_error, subtype, num_turns, total_cost_usd, duration_ms}' \"$RUNNER_TEMP/run.json" >> "$RUNNER_TEMP/runs.jsonl"exit "$status"- name: Keep the run recordif: always()uses: actions/upload-artifact@v7with:name: agent-run-${{ github.run_id }}path: ${{ runner.temp }}/runs.jsonlif-no-files-found: ignore- name: Bundle the agent's commitsenv:BASE: ${{ github.sha }}run: git bundle create "$RUNNER_TEMP/agent.bundle" "$BRANCH" "^$BASE"- uses: actions/upload-artifact@v7with:name: agent-commits-${{ github.run_id }}path: ${{ runner.temp }}/agent.bundleif-no-files-found: erroropen-pr:# Holds the write token. Runs no code from the agent's commits.needs: issue-to-prruns-on: ubuntu-latesttimeout-minutes: 5permissions:contents: writepull-requests: writesteps:- uses: actions/checkout@v7with:persist-credentials: false- uses: actions/download-artifact@v7with:name: agent-commits-${{ github.run_id }}path: ${{ runner.temp }}- name: Push and open the pull requestenv:GH_TOKEN: ${{ github.token }}AGENT_SESSION_ID: ${{ needs.issue-to-pr.outputs.session_id }}run: |git fetch "$RUNNER_TEMP/agent.bundle" "$BRANCH:$BRANCH"gh auth setup-gitgit push origin "refs/heads/$BRANCH"gh pr create --head "$BRANCH" --title "Fix #$ISSUE (agent)" \--body "Closes #$ISSUE. Agent session: $AGENT_SESSION_ID"OTEL_METRICS_INCLUDE_RESOURCE_ATTRIBUTES=falsezostawiaci.run_idw zdarzeniach, ale usuwa go z etykiet metryk, gdzie tworzyłby osobny szereg czasowy dla każdego przebiegu CI. Polesubtypemówi, dlaczego przebieg się zatrzymał:success,error_max_turns,error_max_budget_usd,error_during_executionalboerror_max_structured_output_retries. Przebieg uruchamiasz ręcznie (workflow_dispatchwymaga uprawnień zapisu do repozytorium), a checkout pobiera ref wybrany przy uruchomieniu: gałąź domyślną, chyba że osoba uruchamiająca wskaże inną w polu „Use workflow from” albo podagh workflow run --ref. Kroki w jobie agenta nie są od siebie odizolowane:Edit,WriteiBash(npm test *)pozwalają agentowi przepisać skrypt testów i uruchomić dowolny kod, treść zgłoszenia, na której pracuje, jest niezaufana, a ten kod może odczytaćANTHROPIC_API_KEYi nagłówki OTLP oraz dopisać coś do$GITHUB_ENVlub$GITHUB_PATH, co dziedziczą wszystkie późniejsze kroki tego samego joba. Dlatego job agenta ma tylkoGITHUB_TOKENdo odczytu, a wypchnięcie zmian odbywa się w osobnym jobieopen-pr: dostaje on commity jako artefakt w postaci git bundle, ID sesji bierze z kroku wykonanego przed agentem i nie uruchamia żadnego kodu z tych commitów. Jeśli agent nie zrobił żadnego commita,git bundle createodmawia utworzenia pustego bundle’a i przebieg kończy się przedopen-pr. Przeczytaj zgłoszenie, zanim uruchomisz przebieg; dla workflowów uruchamianych przez niezaufanych kontrybutorów najpierw zastosuj zasady bezpieczeństwa CI.gh pr createzGITHUB_TOKENdziała tylko wtedy, gdy w ustawieniach Actions repozytorium lub organizacji włączono „Allow GitHub Actions to create and approve pull requests”, a pull request otwarty tym tokenem nie uruchamia workflowówpull_request, więc PR agenta nie przechodzi przez CI. Jeśli CI ma się na nim uruchomić, otwieraj PR tokenem GitHub App albo fine-grained personal access tokenem. Rekord przebiegu powstaje także wtedy, gdy agent zatrzyma się z błędem, więc nieudane przebiegi też trafiają doruns.jsonl.Ślady są w wersji beta: dodaj
CLAUDE_CODE_ENHANCED_TELEMETRY_BETA=1iOTEL_TRACES_EXPORTER=otlp. W sesjachclaude -pi Agent SDK Claude Code czytaTRACEPARENTze swojego środowiska, więc jego spanyclaude_code.interactionzagnieżdżają się pod śladem twojego joba CI.Codex czyta tabelę
[otel]zconfig.toml. W wersji 0.157.1 eksportery logów i śladów mają domyślnie wartośćnone, ametrics_exporterdomyślniestatsig, czyli wewnętrzne miejsce docelowe metryk Codeksa; ustaw wszystkie trzy jawnie, żeby metryki trafiały tam, gdzie każe twoja polityka.# ~/.codex/config.toml (albo plik zapisywany przez job CI w trakcie przebiegu)[otel]environment = "ci"log_user_prompt = falseexporter = { otlp-http = { endpoint = "https://otel-collector.internal.example.com:4318/v1/logs", protocol = "binary" } }trace_exporter = { otlp-http = { endpoint = "https://otel-collector.internal.example.com:4318/v1/traces", protocol = "binary" } }metrics_exporter = { otlp-http = { endpoint = "https://otel-collector.internal.example.com:4318/v1/metrics", protocol = "binary" } }[otel.span_attributes]"loop.name" = "issue-to-pr"Nagłówki uwierzytelniające kolektora trafiają jawnym tekstem do tabeli inline
headers = { ... }w każdym eksporterze, więc zapisuj ten plik w jobie CI z sekretu i nigdy go nie commituj. Gałąź main Codeksa dodaje po wersji 0.157.1 opcjelog_agent_responsesilog_guardian_assessments; w 0.157.1 ich nie ma (sprawdzone 2026-09-26), więc nie kopiuj ich do konfiguracji tej wersji.Przy przebiegach headless
codex exec --jsonwypisuje zdarzenia JSONL. Pierwsze tothread.startedzthread_id, czyli tym samym ID wątku, które zdarzenia OTel niosą jakoconversation.id.turn.completedzawiera zużycie tokenów, aturn.failedluberroroznacza nieudany przebieg:Okno terminala # Krok CI (Codex CLI 0.157.1), OPENAI_API_KEY z sekretucodex exec --json --sandbox workspace-write \"$(cat .github/prompts/issue-to-pr.md)" > events.jsonljq -c -s '{thread_id: (map(select(.type == "thread.started"))[0].thread_id),failed: any(.[]; .type == "turn.failed" or .type == "error"),output_tokens: (map(select(.type == "turn.completed") | .usage.output_tokens) | add)}' events.jsonl >> runs.jsonlZanim zbudujesz na nich panele, uruchom jeden test dymny na każdym obrazie CI i potwierdź, że zdarzenia
codex.*docierają do kolektora zcodex exec, a nie tylko z sesji interaktywnych (otwarte zgłoszenie openai/codex#12913 mówi, żecodex execnie emituje metryk OTel; status niezweryfikowany na 2026-09-26). Jeśli metryk brakuje, oprzyj panele kosztów Codeksa na zużyciuoutput_tokenszapisanym wruns.jsonl.Dla Cursora 2026-09-26 nie udało się zweryfikować eksportu OpenTelemetry, więc sprawdzona ścieżka to proweniencja i API chmurowe:
-
Hooki. Cursor uruchamia hooki, które dostają zdarzenia agenta jako JSON przez stdio (zweryfikowane 2026-08-28). Hook może dopisywać każde zdarzenie do pliku logu, który czyta twój kolektor.
-
Entire CLI (
entireio/cli, v0.11.3, 5,1 tys. gwiazdek na GitHubie 2026-09-26) instaluje hooki gita i hooki agenta w.cursor/hooks.json. Gdy agent tworzy commit, Entire wiąże z nim prompty, transkrypt, wywołania narzędzi, zmienione pliki i tokeny przez trailerEntire-Checkpoint::Okno terminala # Terminal, w repozytorium (najpierw instalacja: brew install --cask entireio/tap/entire)entire enable --agent cursorentire statusEntire przechowuje transkrypty w twoim repozytorium gita, a jego redagowanie sekretów jest tylko częściowe (nie gwarantuje wyłapania wszystkiego). W publicznym repozytorium skieruj je do prywatnego przez
--checkpoint-remote. -
Cloud Agents. Przebiegi uruchamiane przez Cloud Agents API zgłaszają webhooki
statusChange(zweryfikowane 2026-08-28). Zapisuj ID przebiegu i jego status końcowy wruns.jsonldokładnie tak, jak w pozostałych zakładkach.
-
-
Oznacz każdy przebieg czterema kluczami łączenia i zapisz je w pull requeście. Telemetria, której nie połączysz z wynikami, mówi tylko, ile wydałeś. Każdy przebieg niesie:
Klucz Claude Code Codex Cursor Gdzie trafia Sesja UUID z --session-idthread_idID checkpointu Entire lub ID przebiegu w chmurze provenance.sessionw pakiecie dowodówPrzebieg CI ci.run_idwOTEL_RESOURCE_ATTRIBUTES[otel.span_attributes]runs.jsonlruns.jsonl, zdarzeniaPętla Atrybut zasobu loop.nameAtrybut spanu loop.nameruns.jsonlGrupowanie na dashboardzie Zadanie URL zgłoszenia w prompcie i w pakiecie Tak samo Tak samo provenance.taskw pakiecie dowodówPakiet dowodów w pull requeście ma już pole
provenance.session; job CI wypełnia je zAGENT_SESSION_IDalbo zthread_id. Łącz po sesji, nie po SHA commita: squash merge tworzy nowy SHA, więc SHA zapisany w chwiligit commitnigdy nie pojawia się na gałęzi domyślnej. W planach Team i Enterprise z aplikacją GitHub analityka Claude Code oznacza też scalone pull requesty etykietąclaude-code-assisted; ta kontrola krzyżowa nie działa przy Zero Data Retention. -
Załaduj wyniki i policz dashboard. Panele wynikowe licz w hurtowni, bo backendy metryk nie złączą danych z GitHubem, z dwóch tabel:
agent_runs(zruns.jsonl, z kosztem z telemetrii zgrupowanym po sesji) ipull_requests(z API GitHuba, z sesją odczytaną z pakietu dowodów i 14-dniową flagą poprawek zdefiniowaną na stronie o metrykach).-- Tygodniowe panele wyników dla każdej pętli. Zmiana jest przyjęta, gdy została scalona-- i nie była cofnięta ani poprawiana przez 14 dni, więc ostatnie dwa tygodnie są wstępne.WITH pr AS ( -- jeden wiersz na sesję, więc przebieg z kilkoma PR-ami liczy się razSELECT repo, agent_session,count(*) AS prs,count(*) FILTER (WHERE merged_at IS NOT NULLAND NOT followup_within_14d) AS acceptedFROM pull_requestsWHERE agent_session IS NOT NULLGROUP BY repo, agent_session)SELECTdate_trunc('week', r.started_at) AS week,r.loop_name,count(*) AS runs,avg(CASE WHEN r.completed_ok THEN 1.0 ELSE 0 END) AS run_completion_rate,sum(CASE WHEN r.completed_ok AND p.prs > 0 THEN 1 ELSE 0 END)::numeric/ NULLIF(sum(CASE WHEN r.completed_ok THEN 1 ELSE 0 END), 0) AS run_to_pr_rate,sum(coalesce(p.accepted, 0)) AS accepted_changes,sum(r.cost_usd) / NULLIF(sum(coalesce(p.accepted, 0)), 0) AS run_cost_per_accepted_changeFROM agent_runs rLEFT JOIN pr pON p.repo = r.repo AND p.agent_session = r.session_idGROUP BY 1, 2ORDER BY 1 DESC, 2;completed_oktoNOT is_errordla Claude Code iNOT faileddla Codeksa. To zapytanie liczy tylko koszt przebiegów; pełny koszt przyjętej zmiany w organizacji dodaje licencje i koszt platformy, zgodnie z definicjami metryk i stroną o ekonomii. -
Połącz incydenty z przebiegami. Gdy incydent prowadzi do wdrożenia, łańcuch wygląda tak: wdrożenie, commit scalający, pull request,
provenance.session, a potem każde zdarzenie z tymsession.idlubconversation.id, uporządkowane wedługevent.timestamp(event.sequencerozstrzyga remisy) i w Claude Code zgrupowane poprompt.id. Zdarzeniatool_decisionpokazują, czy ryzykowne wywołanie dopuściła konfiguracja, hook czy człowiek. Dodaj link do sesji do zapisu incydentu w procesie obsługi incydentów agentów, a przyczynę oznacz według taksonomii błędów. -
Ustal retencję i dostęp dla każdego strumienia i zapisz to. Szablon znajdziesz w następnej sekcji; skonfiguruj go w backendach, a dla lokalnych transkryptów w ustawieniu
cleanupPeriodDaysClaude Code.
Co powinno się znaleźć na referencyjnym dashboardzie?
Dział zatytułowany „Co powinno się znaleźć na referencyjnym dashboardzie?”Osiem paneli odpowiada na cotygodniowe pytania tech leada i comiesięczne pytania CTO. Grupuj według pętli, repozytorium i narzędzia, nigdy według osoby.
| Panel | Definicja | Źródło | Na co uważać |
|---|---|---|---|
| Odsetek ukończonych przebiegów | Przebiegi zakończone bez błędu ÷ przebiegi rozpoczęte | runs.jsonl | Spadek po zmianie modelu, promptu lub harnessu |
| Odsetek przebiegów z PR | Przebiegi, które otworzyły pull request ÷ przebiegi ukończone | runs.jsonl + GitHub | Przebiegi, które się kończą, ale nie dają niczego do review |
| Odsetek przyjętych zmian | Scalone i bez poprawek w ciągu 14 dni ÷ otwarte pull requesty | GitHub | Rzeczywista przepustowość; kanoniczna jest definicja |
| Koszt przebiegów na przyjętą zmianę | Koszt przebiegów ÷ przyjęte zmiany (SQL powyżej) | Hurtownia | Rosnący koszt przy stałej liczbie przyjętych zmian |
| Wydatki według modelu i wysiłku | claude_code.cost.usage według model, effort, query_source; codex.turn.cost_microusd według reasoning_effort | Metryki | Niezauważony wzrost wydatków subagentów lub zapytań pomocniczych |
| Odsetek błędów narzędzi | tool_result z success=false ÷ wszystkie, według tool_name | Zdarzenia | Zepsuty serwer MCP albo polecenie testowe, które spala tury |
| Tarcie wokół uprawnień | Odrzucenia w tool_decision według source; zdarzenia permission_mode_changed | Zdarzenia | Pętle zablokowane na zatwierdzeniach albo ciche eskalacje trybu |
| Zatrzymania przez budżet i ponowienia | Podtypy error_max_budget_usd i error_max_turns; zdarzenia claude_code.api_error | runs.jsonl, zdarzenia | Za ciasne budżety albo awarie dostawcy |
Od pierwszego dnia ustaw trzy alerty: pojedyncza sesja powyżej twojego limitu kosztu, każde zdarzenie permission_mode_changed, którego to_mode to bypassPermissions poza runnerem w piaskownicy, oraz wyczerpane ponowienia powyżej tygodniowej bazy. Dla skali: dokumentacja kosztów Anthropic (sprawdzone 2026-09-26) podaje typowy koszt Claude Code w przedsiębiorstwie jako „around $13 per developer per active day and $150-250 per developer per month”; progiem alertu powinna jednak być twoja własna baza po czterech tygodniach.
Jak długo przechowywać telemetrię agentów?
Dział zatytułowany „Jak długo przechowywać telemetrię agentów?”Retencja wynika z tego, co zawiera dany strumień. Traktuj poniższe wartości jako politykę startową do korekty przez właścicieli bezpieczeństwa i spraw prawnych; obowiązki wynikające z AI Act i przepisy sektorowe w branżach regulowanych mogą wymagać dłuższego okresu.
| Strumień | Zawiera | Magazyn | Retencja startowa | Kto ma dostęp |
|---|---|---|---|---|
| Metryki | Koszty, tokeny, sesje, linie i spseudonimizowani użytkownicy | Backend metryk | 13 miesięcy, dla porównań rok do roku | Inżynieria |
| Zdarzenia operacyjne | tool_result, api_request, api_error, spseudonimizowane | Magazyn logów | 90 dni | Inżynieria |
| Zdarzenia audytowe | tool_decision, permission_mode_changed, hook_execution_complete, auth, mcp_server_connection, plugin_installed, managed_settings_resolved; codex.tool_decision, codex.sandbox_outcome | SIEM | Zgodnie z polityką logów bezpieczeństwa (często rok lub dłużej) | Bezpieczeństwo |
| Treść | Prompty, odpowiedzi, wyniki narzędzi i surowe treści zapytań API | Domyślnie wyłączone; jeśli włączone, magazyn z ograniczonym dostępem | Najkrócej, jak się da, na przykład 30 dni | Wskazane osoby obsługujące incydenty |
| Dowody zmian | Pakiet dowodów, link do sesji i trailery checkpointów | Git i platforma kodu | Przez cały okres życia repozytorium | Wszyscy z dostępem do repozytorium |
| Lokalne transkrypty | Pliki sesji Claude Code na maszynach deweloperów | Dysk | cleanupPeriodDays (domyślnie 30), przypięte w ustawieniach zarządzanych | Deweloper |
Claude Code emituje zdarzenie claude_code.retention_sweep przy każdym takim sprzątaniu; niezerowe files_past_cutoff oznacza, że pliki przetrwały dłużej niż skonfigurowany okres, co samo w sobie jest ustaleniem audytowym.
Prompty do skopiowania: obserwowalność agentów
Dział zatytułowany „Prompty do skopiowania: obserwowalność agentów”Skąd wiesz, że telemetria jest poprawna?
Dział zatytułowany „Skąd wiesz, że telemetria jest poprawna?”Dashboard, który pokazuje zero albo podwójne wartości, jest gorszy niż żaden. Sprawdzaj sam potok:
- Dostarczanie. Po każdej zmianie konfiguracji sprawdź, czy przychodzi
claude_code.session.count(metryki) alboclaude_code.user_prompt(zdarzenia). Jeśli nic nie przychodzi, uruchom Claude Code zclaude --debug-file /tmp/claude-otel.logi szukaj błędów[3P telemetry]. W Codeksie uruchom jednocodex execi szukajcodex.conversation_starts. - Pokrycie złączeń. Co tydzień policz scalone pull requesty agentów, których
provenance.sessionwskazuje co najmniej jedno zdarzenie telemetrii. Poniżej 95% któryś workflow gubi ID sesji; prompt do audytu instrumentacji go znajdzie. - Uzgadnianie kosztów. Dokumentacja Claude Code nazywa metryki kosztu przybliżeniami. Raz w miesiącu porównaj zsumowane
claude_code.cost.usagei szacowany koszt Codeksa z fakturą lub z Console, dla każdego workspace’u. Rozbieżność większa niż kilka procent zwykle oznacza nieraportowane przebiegi CI albo drugą ścieżkę rozliczeń. - Przebieg kanarkowy. Zaplanowany job CI raz dziennie uruchamia stały, tani prompt i kończy się błędem, jeśli jego rekord w
runs.jsonli zdarzenia jego sesji nie trafią do hurtowni w ciągu godziny.
| Kto | Odpowiada za | Podpisuje |
|---|---|---|
| Zespół platformowy lub developer experience | Kolektor, ustawienia zarządzane, szablony config.toml i przebieg kanarkowy | Zmiany w potoku |
| Tech lead | Nazwy pętli i przegląd dashboardu na cotygodniowym retro | Zmiany autonomii na podstawie paneli |
| Bezpieczeństwo | Potok audytowy, reguły SIEM i zgody na logowanie treści | Retencję i dostęp |
| CTO | Kartę pomiaru i miesięczny widok kosztów | Limity budżetowe i kartę pomiaru |
Co się psuje przy instrumentacji agentów kodujących?
Dział zatytułowany „Co się psuje przy instrumentacji agentów kodujących?”Telemetria jest włączona, ale nic nie przychodzi. Claude Code nie ma domyślnego protokołu OTLP, więc każdy eksporter otlp potrzebuje OTEL_EXPORTER_OTLP_PROTOCOL albo jego wariantu per sygnał. Jak wyjść: ustaw protokół, a potem sprawdź plik debugowania pod kątem błędów [3P telemetry]. Linie z prefiksem [Anthropic telemetry] to własna telemetria operacyjna Anthropic, nie twój potok.
Koszt przechowywania metryk eksploduje. ID przebiegów w OTEL_RESOURCE_ATTRIBUTES i domyślne session.id w metrykach tworzą nowy szereg dla każdego przebiegu. Jak wyjść: ustaw OTEL_METRICS_INCLUDE_RESOURCE_ATTRIBUTES=false, a w dużych organizacjach także OTEL_METRICS_INCLUDE_SESSION_ID=false; ID przebiegów i sesji trzymaj w zdarzeniach, gdzie wysoka kardynalność jest tania.
W magazynie logów pojawia się sekret. OTEL_LOG_TOOL_DETAILS=1 zapisuje pełne polecenia Basha, a razem z nimi token podany w linii poleceń. Jak wyjść: zrotuj sekret, usuń rekordy, kieruj szczegóły narzędzi wyłącznie do potoku audytowego i dodaj regułę w kolektorze albo alert w SIEM dla wzorców poświadczeń. Nigdy nie włączaj OTEL_LOG_RAW_API_BODIES poza ograniczonym w czasie dochodzeniem; ta opcja eksportuje całą rozmowę.
Panel kosztów nie zgadza się z fakturą. Koszt w telemetrii to szacunek po stronie klienta, Claude Code przed v2.1.214 liczył podwójnie koszt i tokeny na strumieniach, które wysyłają wiele skumulowanych ramek message_delta, a przebiegi CI bez telemetrii są niewidoczne. Jak wyjść: zaktualizuj narzędzie, uzgadniaj koszty co miesiąc i raportuj fakturę jako liczbę wiążącą, a telemetrię jako jej rozbicie.
Commity nie łączą się z sesjami. Squash i rebase merge przepisują SHA, a Codex CLI 0.157.1 nie emituje SHA commita w telemetrii. Jak wyjść: łącz po provenance.session z pakietu dowodów i niech sprawdzenie pull requesta kończy się błędem, gdy to pole jest puste.
Dashboard zamienia się w ranking. Ktoś sortuje koszty według deweloperów. Jak wyjść: karta pomiaru tego zabrania, potok analityczny widzi tylko hash e-maila z kluczem, bez identyfikatorów konta i instalacji, a widok per osoba istnieje wyłącznie w SIEM na potrzeby dochodzeń bezpieczeństwa.
Metryki Codeksa trafiają tam, gdzie ich nie wysłałeś. Brak ustawienia metrics_exporter w 0.157.1 oznacza domyślne statsig. Jak wyjść: w dystrybuowanym szablonie config.toml ustaw je jawnie na swój kolektor albo na "none".
Dokąd dalej po obserwowalności agentów
Dział zatytułowany „Dokąd dalej po obserwowalności agentów”Telemetria mówi, co zrobiły przebiegi. Kolejne strony używają jej do klasyfikowania błędów, obsługi incydentów i dbania o zdrowie kodu.