Pi coding agent neturi integruotos analitikos — nematai kiek išleidai, kurį modelį naudoji dažniausiai, ar kokie įrankiai iškviečiami dažniau. Tai galima išspręsti.
Galimi trys keliai:
| PostHog Cloud | PostHog savaeigis | Lokali analitika | |
|---|---|---|---|
| Paskyra reikalinga | Taip | Ne | Ne |
| Internetas reikalingas | Taip | Ne | Ne |
| npm priklausomybės | posthog-node |
posthog-node |
Nė vienos |
| Duomenys išlieka lokaliai | Ne | Taip | Taip |
Šiame įraše sukursime lokalią versiją — vienas TypeScript failas, duomenys saugomi ~/.pi/agent/analytics.jsonl, ir /analytics komanda terminale rodo visą susumuotą statistiką.
Kaip veikia Pi plėtiniai?
Pi turi plėtinių (extension) sistemą — TypeScript moduliai, kurie gali prenumeruoti agento įvykius, registruoti papildomas komandas ir rodyti informaciją terminalo poraštėje.
Plėtiniai aptinkami automatiškai iš ~/.pi/agent/extensions/ direktorijos. Jie nereikalauja kompiliavimo — Pi naudoja jiti paketą, kuris TypeScript vykdo tiesiogiai.
Mums svarbūs keturi įvykių tipai:
| Įvykis | Kada iššaunamas |
|---|---|
session_start |
Pi paleidimo metu |
agent_start / agent_end |
Kiekvienam vartotojo užklausos ciklui |
message_end |
Kai LLM baigia atsakyti — čia gauname žetonų statistiką |
tool_execution_start / tool_execution_end |
Kiekvienam įrankio iškvietimui |
AssistantMessage tipo objektas turi usage lauką su viskuo ko reikia:
interface Usage {
input: number; // įvesties žetonai
output: number; // išvesties žetonai
cacheRead: number; // žetonai iš talpyklos
cacheWrite: number; // žetonai įrašyti į talpyklą
cost: {
total: number; // bendra kaina USD
};
}
Duomenų saugojimas
Kiekvieną užklausą ir kiekvieną įrankio iškvietimą įrašome į ~/.pi/agent/analytics.jsonl — po vieną JSON objektą eilutėje:
{"t":1747834821000,"e":"generation","session_id":"a1b2c3","model":"claude-opus-4-5","provider":"anthropic","input_tokens":4521,"output_tokens":312,"cache_read":1200,"cache_write":0,"cost":0.0187,"latency_ms":4231,"tool_calls":3}
{"t":1747834821050,"e":"tool","session_id":"a1b2c3","tool_name":"bash","duration_ms":892,"is_error":false}
JSONL formatas patogu tuo, kad kiekvieną eilutę galima skaityti savarankiškai — nereikia skaityti viso failo į atmintį. Vėliau galima šį failą atidaryti DuckDB ar bet kuriuo kitu įrankiu.
Plėtinio kodas
Sukurk failą ~/.pi/agent/extensions/local-analytics.ts. Plėtinys neturi jokių npm priklausomybių — naudoja tik Node.js integruotus modulius (node:fs, node:path, node:os) ir Pi paties teikiamus paketus (@earendil-works/pi-tui).
import * as fs from "node:fs";
import * as path from "node:path";
import * as os from "node:os";
import type { ExtensionAPI } from "@earendil-works/pi-coding-agent";
import { Key, matchesKey, truncateToWidth } from "@earendil-works/pi-tui";
const AGENT_DIR =
process.env.PI_CODING_AGENT_DIR ?? path.join(os.homedir(), ".pi", "agent");
const LOG_FILE = path.join(AGENT_DIR, "analytics.jsonl");
Įvykių fiksavimas
Kiekvieną agento ciklą sekame tokiu būdu:
// 1. Sesijos pradžia — nustatome pradinę būseną
pi.on("session_start", async (_event, ctx) => {
sessionId = ctx.sessionManager.getLeafEntry()?.id ?? String(Date.now());
currentModel = ctx.model?.id ?? "";
currentProvider = ctx.model?.provider ?? "";
sessionCost = 0;
sessionPrompts = 0;
ctx.ui.setStatus("analytics", ctx.ui.theme.fg("dim", "⬡ $0.0000"));
});
// 2. Prieš kiekvieną užklausą — nulinuojame kaupiklius
pi.on("agent_start", async () => {
agentStartMs = Date.now();
promptInputTokens = 0;
promptCost = 0;
// ...
});
// 3. Po kiekvieno LLM atsakymo — surenkame žetonų statistiką
pi.on("message_end", async (event) => {
const msg = event.message as { role?: string; usage?: Usage };
if (msg.role !== "assistant" || !msg.usage) return;
promptInputTokens += msg.usage.input;
promptCost += msg.usage.cost?.total ?? 0;
// ...
});
// 4. Ciklo pabaiga — įrašome į diską ir atnaujiname poraštę
pi.on("agent_end", async (_event, ctx) => {
sessionCost += promptCost;
appendEvent({ e: "generation", cost: promptCost, latency_ms: Date.now() - agentStartMs, ... });
ctx.ui.setStatus("analytics", theme.fg("dim", `⬡ ${fmtCost(sessionCost)}`));
});
Įrankių sekimas
pi.on("tool_execution_start", async (event) => {
toolStartTimes.set(event.toolCallId, Date.now());
});
pi.on("tool_execution_end", async (event) => {
const durationMs = Date.now() - (toolStartTimes.get(event.toolCallId) ?? Date.now());
toolStartTimes.delete(event.toolCallId);
appendEvent({
e: "tool",
tool_name: event.toolName,
duration_ms: durationMs,
is_error: event.isError,
});
});
Analitikos skydelis
Komanda /analytics atidaro interaktyvų skydelį terminale. Jis naudoja ctx.ui.custom() — tai Pi mechanizmas, leidžiantis pilnai valdyti terminalo išvedimą su klaviatūros įvestimi:
pi.registerCommand("analytics", {
description: "Rodyti analitikos skydelį (naudojimas: /analytics [reset])",
handler: async (args, ctx) => {
const events = loadEvents();
const stats = computeStats(events);
let scrollOffset = 0;
await new Promise<void>((resolve) => {
ctx.ui.custom((_tui, theme, _kb, done) => {
return {
render(width: number): string[] {
const all = renderDashboard(stats, sessionCost, sessionPrompts, theme, width);
const visible = process.stdout.rows - 4;
return all.slice(scrollOffset, scrollOffset + visible);
},
handleInput(data: string) {
if (matchesKey(data, Key.down)) scrollOffset++;
else if (matchesKey(data, Key.up)) scrollOffset--;
else if (matchesKey(data, Key.enter) || matchesKey(data, Key.escape)) {
done(undefined);
resolve();
}
},
invalidate() {},
};
});
});
},
});
Skydelio vaizdas terminale:
⬡ Pi Local Analytics
~/.pi/agent/analytics.jsonl
────────────────────────────────────────────────────
ŠI SESIJA
Užklausos: 3 Kaina: $0.0187
IŠ VISO
Sesijos: 47
Užklausos: 312
Įvesties žet.: 4.2M
Išvesties žet.: 312k
Vid. delsa: 3.8s
Bendra kaina: $12.3400
DIENOS KAINA (paskutinės 14 dienų)
2026-05-08 $1.2300 ██████████████░░░░░░ (8)
2026-05-21 $0.0187 █░░░░░░░░░░░░░░░░░░░ (3)
MODELIAI
anthropic/claude-opus-4-5 312 užkl. $12.3400 ████████████████████
ĮRANKIAI (viso)
bash 245 išk. 3 kl. vid. 892ms ████████████████████
read 89 išk. 0 kl. vid. 12ms ████████
edit 67 išk. 0 kl. vid. 45ms ██████
↑ ↓ slinkti Esc / Enter uždaryti
Įdiegimas
Visas plėtinio kodas viename faile — galima atsisiųsti arba sukurti rankiniu būdu:
# Sukurk extensions direktoriją jei dar neegzistuoja
mkdir -p ~/.pi/agent/extensions
# Sukurk plėtinio failą (kodas žemiau)
vim ~/.pi/agent/extensions/local-analytics.ts
Pi aptinka plėtinį automatiškai kito paleidimo metu. Jei Pi jau veikia — paleisk /reload.
Naudojimas
# Atidaryti analitikos skydelį
/analytics
# Ištrinti visus duomenis ir pradėti iš naujo
/analytics reset
Kiekvienos sesijos metu Pi poraštėje matysi:
⬡ $0.0187 (3 užklausos)
Tiesioginis duomenų naudojimas
Kadangi duomenys saugomi JSONL formatu, juos galima analizuoti bet kuriuo įrankiu:
# Bendra kaina su jq
cat ~/.pi/agent/analytics.jsonl \
| jq 'select(.e == "generation") | .cost' \
| awk '{s+=$1} END {printf "$%.4f\n", s}'
# SQL užklausos su DuckDB
duckdb -c "
SELECT model, SUM(cost) AS kaina, COUNT(*) AS uzklausos
FROM read_ndjson('~/.pi/agent/analytics.jsonl')
WHERE e = 'generation'
GROUP BY model
ORDER BY kaina DESC
"
Šaltiniai
- Pi coding agent plėtinių dokumentacija https://github.com/earendil-works/pi-mono
- Pi TUI komponentų dokumentacija —
@earendil-works/pi-tui - PostHog LLM analitika (debesijos versija) https://posthog.com/docs/llm-analytics/installation/pi