El SDK de Go (sdk/go/ledgersdk) cubre la API manual Record. Las aplicaciones de Go instrumentadas con OTel deberían apuntar su exportador ya existente al receptor OTLP del ledger (/v1/otlp/v1/traces) en su lugar — no hay procesador de spans específico para Go.
go get github.com/bf95/AI_Comp_Ledger/sdk/go/ledgersdk
package main
import (
"time"
"github.com/bf95/AI_Comp_Ledger/sdk/go/ledgersdk"
)
func main() {
l := ledgersdk.New("http://127.0.0.1:4010", ingestKey, "urn:agent:research-assistant")
l.SetTrigger(ledgersdk.Trigger{Type: "human", Subject: "person@example.com"})
provider, model := "anthropic", "claude-fable-5"
tokensIn, tokensOut := 420, 180
response := "The policy provides that…"
span := l.Record(ledgersdk.RecordInput{
ActionType: "llm_call",
Provider: &provider,
Model: &model,
StartedAt: time.Now().Add(-time.Second),
EndedAt: time.Now(),
Status: "success",
Usage: &ledgersdk.Usage{TokensIn: &tokensIn, TokensOut: &tokensOut},
Payloads: []ledgersdk.Payload{{Kind: "response", Content: &response}},
})
l.Flush()
_ = span // el id del span — páselo como ParentRef de otro evento para el linaje de decisiones
}
Record nunca produce un panic dentro de la aplicación anfitriona — los fallos van al Ledger.OnError en su lugar. La mayoría de los campos son punteros porque un valor nil significa "no reportado", lo cual es distinto de un valor cero (por ejemplo, Usage.TokensIn == nil significa desconocido, no cero tokens).
Establezca ParentRef (y HasParentRef: true) en un RecordInput para citar el span que causó este evento:
parent := searchSpan
l.Record(ledgersdk.RecordInput{
ActionType: "llm_call",
ParentRef: &parent,
HasParentRef: true,
// ...
})
Flush() entrega los eventos en buffer y es seguro llamarlo con un temporizador o antes de que el proceso termine. La entrega es al-menos-una-vez — el servidor deduplica por id de span, así que un lote reintentado tras un flush fallido nunca se registra por duplicado.