DEV Community

vectronodeAPI
vectronodeAPI

Posted on

Build an Execution Receipt Wrapper for LLM API Calls

Model integrations are easy to instrument badly.
Logging every prompt creates unnecessary data exposure. Logging only the model name leaves too little evidence when a production response needs investigation.
An execution receipt offers a middle path: preserve operational metadata without copying the full interaction into a general-purpose log.
What belongs in the receipt?
Useful fields include:
request and task identifiers;
prompt, policy, and schema versions;
endpoint alias;
start time and latency;
usage measurements;
validation outcome;
fallback or retry status.
Application request

Redaction and classification

Model endpoint

Output validation

Execution receipt store
Teams evaluating model endpoints for this architecture can place VectorEngine behind the same application-owned wrapper and receipt format.
Disclosure: this article includes an external referral link for readers who want to explore the platform.
TypeScript-style pseudocode
type Receipt = {
requestId: string;
task: string;
promptVersion: string;
endpointAlias: string;
startedAt: string;
latencyMs?: number;
contractPassed?: boolean;
fallbackUsed: boolean;
status: "started" | "completed" | "failed";
};

async function invokeWithReceipt(input: unknown, ctx: Context) {
const started = Date.now();

const receipt: Receipt = {
requestId: ctx.requestId,
task: ctx.task,
promptVersion: ctx.promptVersion,
endpointAlias: ctx.endpointAlias,
startedAt: new Date(started).toISOString(),
fallbackUsed: false,
status: "started"
};

try {
const result = await invokeEndpoint(input, ctx.endpointAlias);

receipt.latencyMs = Date.now() - started;
receipt.contractPassed = validateOutput(result);
receipt.status = "completed";

await appendReceipt(receipt);
return result;
Enter fullscreen mode Exit fullscreen mode

} catch (error) {
receipt.latencyMs = Date.now() - started;
receipt.status = "failed";

await appendReceipt(receipt);
throw error;
Enter fullscreen mode Exit fullscreen mode

}
}
This example intentionally excludes raw input and output. If investigation requires content access, store it under a separate retention and authorization policy rather than embedding it in every receipt.
Receipts should also be append-oriented and versioned. Editing old records in place makes later reconstruction harder.
The goal is modest: retain enough evidence to understand how a model-backed feature executed, while collecting no more content than the workflow requires.

Top comments (0)