How to Log LLM Requests: The Fields a Model Call Record Needs
Logging an LLM request as if it were a generic HTTP call captures a timestamp, a status code, and a shared key, which answers almost none of the questions an incident or an audit asks. This piece defines the fields a model call record actually needs, why application code is the wrong place to write them, and what a per-decision record looks like in practice, with a concrete schema.
A model call logged like a generic HTTP request produces a line with a timestamp, a destination host, a status code, and the API key that made it. That line confirms a call happened and answers almost nothing else. It cannot say which user or agent was behind the shared key, what class of data the prompt carried, which policy governed the call, or what the model was asked to do. When an incident review or an audit reaches the AI traffic, that thin line is where the trail ends.
I want to define the fields a model call record needs to be useful, explain why the application making the call is the wrong place to write them, and show what a per-decision record looks like as a concrete schema.
The fields a useful model call record carries
A record earns its place by answering the questions someone will ask later. Who made this call, at a user or agent grain, not the shared application key. What data class the prompt carried, so a call touching regulated data is distinguishable from a benign one. Which model and destination region received it. Which policy version was in force and what it decided, allow, block, or redact. When it happened, and what the outcome was. Those fields are the difference between a log that documents an AI decision and one that documents that traffic moved.
The identity field is the one most logs miss and the one incidents most need. If a call is attributed only to service-account-prod, every user of that service is the same actor in the record, and the attribution problem behind shared API keys means the trail goes cold at the credential. Resolving identity to a named user or agent at log time is what makes the rest of the record actionable.
Why the application is the wrong place to write this
Application code can log these fields, and relying on it to do so has two failure modes. First, coverage: every service that calls a model has to implement the same logging, keep it current, and never take a shortcut under deadline, which across a real codebase does not hold. Second, independence: a log written by the application into a store the application controls documents that application's own behavior, and an auditor discounts evidence the audited system could edit.
So the logging belongs at a layer the application cannot skip and does not control. A record produced at the request boundary, by the point that authorizes the call, is written for every call regardless of which service made it, and it is produced independently of that service. The best practices for LLM audit logging develop that independence requirement, and what to log for AI compliance maps the fields onto specific obligations.
A concrete per-decision record
A model call record does not need the full prompt and response to be useful, and often should not retain them. The decision metadata is what answers audit and incident questions, with sensitive content redacted or omitted. A record can look like this:
Every field answers a question a reviewer will ask: who, what data, which model and region, which policy, what happened. Stored per call, these records let you show that a control operated across a period and let responders reconstruct what happened during an incident, which a host-and-status-code line cannot do.
DeepInspect
This is exactly what DeepInspect does. DeepInspect runs as a stateless proxy between your applications, staff, agents, and any LLM, and writes a tamper-evident per-decision record for every model call it evaluates. Each record resolves the individual identity behind the call, classifies the data in the prompt, captures the model and destination, records the policy version and decision, and notes the outcome, with sensitive fields redacted before storage.
Because the records are produced at the request boundary rather than in application code, coverage does not depend on each service logging correctly, and the records are independent of the services they document. They emit to your own log store in a structured schema your SIEM can read. To put consistent, identity-bound logging on your model traffic, book a platform demo.
Frequently asked questions
- What is the minimum I should log for an LLM request?
At minimum: the identity behind the call at a user or agent grain, the model and destination, the data classification of the prompt, the policy decision, the timestamp, and the outcome. That set answers who did what with which data under which rule, which is what audits and incidents need. A timestamp and a status code alone confirm only that a call occurred. The identity and data-classification fields are the ones generic HTTP logging omits and the ones that make the record actionable.
- Should I log full prompts and responses?
Often not. Full prompt and response text can carry sensitive data, which makes the log store itself a exposure risk, and many obligations are satisfied by decision metadata rather than content. The safer default is to log the fields that describe the decision, identity, data class, policy, model, and outcome, with sensitive content redacted or omitted. Where content must be retained for a specific obligation, redact sensitive fields before storage so the record is useful for audit without becoming a new data-leak surface.
- Why not just log from the application?
Application logging depends on every service implementing the same fields correctly and keeping them current, which rarely holds across a codebase under deadline pressure, and it writes evidence into a store the application controls, which an auditor discounts. Logging at the request boundary produces the record for every call regardless of the calling service and produces it independently of that service, which fixes both coverage and independence at once.
- How do these records reach my SIEM?
A record produced at the request boundary can be emitted as structured JSON to your existing log pipeline, where your SIEM ingests it alongside other security logs. Because each record already carries identity, data classification, and policy context, it arrives richer than a network-level view of the same traffic, so correlation and alerting can key on the AI-specific fields. The logging layer forwards; it does not become a separate store you have to query on its own.