Integration

GenZAgents for LangChain — agent receipts via @genzagentsio/langchain

LangChain agents touch dozens of tools per run. @genzagentsio/langchain wraps the AgentExecutor so every run produces a signed receipt automatically — no per-tool callbacks, no manual instrumentation.

Why a wrapper instead of a callback handler

LangChain's standard instrumentation path is the BaseCallbackHandler interface. We started there in v0.4 and hated it: every tool needed manual subscription, every chain change broke the integration, the receipt-issuance latency added up. v0.5 replaced it with `withReceipts(executor)` — one wrap, idempotent, captures every tool call and every intermediate step without per-tool wiring.

What the wrapper captures

Each invocation produces one receipt covering: input query, all tools called in order, intermediate-step reasoning (digest only by default), final output, total runtime cost, model used. Sub-steps are stored as `extensions.langchain_steps` on the receipt — a 12-tool agent run shows up as one receipt with 12 step entries, not 12 receipts.

Streaming + async support

LangChain agents commonly stream tokens for UX. The wrapper supports `executor.stream()` and async iteration; receipts are issued at end-of-stream, not at first token. Latency overhead is ~30ms per receipt (one round-trip to api.genzagents.com), which doesn't affect the user-perceived stream.

LangGraph-aware sub-receipts

LangGraph apps that use the wrapper produce parent-child receipt structures: the top-level graph run is the parent, each node's tool calls are children with parent_run_id pointing back. This makes long graph runs auditable end-to-end — you can see "the planner node decided X, the executor node did Y, the validator node rejected step Z".

Cost tracking across multi-model graphs

A common LangGraph pattern: planner uses GPT-5, executor uses Claude, validator uses Gemini. The wrapper logs cost per node per model. Your dashboard shows "this graph run cost £0.42, split £0.18 planner / £0.20 executor / £0.04 validator". That granularity is what makes multi-model architectures economically tunable.

Server-side deployment patterns

If you ship a LangChain app behind a /api/agent endpoint, configure the wrapper with the per-user `humanId` from the auth context. Every receipt then carries the right per-user attribution, even though the server runs all the LangChain code. Use this pattern for SaaS apps with thousands of end-users — each user's usage shows up as their own receipts on the agent.

Install

$ npm install @genzagentsio/langchain

import { withReceipts } from "@genzagentsio/langchain"
const executor = withReceipts(rawExecutor, {
  agentDid: "did:genz:...",
  apiKey: process.env.GENZAGENTS_API_KEY,
})
await executor.invoke({ input: userQuery })

What we capture

Every AgentExecutor.invoke call: tools used, model, runtime cost, intermediate steps.

Verify it works

Run the wrapped executor → confirm one receipt per invocation on /dashboard.

Common questions

Does the wrapper change the AgentExecutor return type?

No. `withReceipts(executor)` returns the same shape as the original executor. The receipt is issued as a side effect; the caller code is unchanged.

What's the overhead per agent run?

~30ms for the receipt round-trip, fired after the agent finishes. Negligible vs typical agent runtime (5-30s).

Does it work with LangChain Python (via the Python SDK)?

Yes — `genzagents` on PyPI ships an equivalent `with_receipts(executor)` decorator. Same API surface, same receipt shape.

Can I disable receipt issuance per-call?

Yes — pass `metadata: { genzReceipt: false }` into the invoke call. The wrapper sees the flag and skips issuance for that call.

Related

Get the trust layer for your AI work

GenZAgents is the verified work-history layer above every AI provider your team uses. Sign cryptographic receipts, hand off conversations across Claude / ChatGPT / Cursor / Gemini, keep institutional AI knowledge when employees leave.

Last reviewed · 2 min read· Open spec· Changelog