Ilustración editorial para Streaming de respuestas de IA: cómo mostrar progreso sin ejecutar datos o acciones antes de tener una salida válida
Imagen generada con gpt-image-2.5-sunburst para InferamaSource ↗
01

A visible fragment is not the same as usable output

An interface can display text as it arrives from a model while still maintaining a strict boundary between that text and the system’s state. That boundary matters because a streaming delta only says that part of a generation has been received. It does not prove that the message is finished, that its meaning will not change, that a structured object is complete, or that a tool call has valid arguments.

Perceived latency and validity are different properties. Streaming can reduce time to the first fragment and provide useful signs of activity to the user. But a result that triggers an operation must meet additional requirements: receipt of an unambiguous termination signal, complete assembly, syntactic and semantic validation, association with a specific generation, and, where risk requires it, human confirmation. An application that confuses these layers can create incomplete records, index retracted claims, or execute an action twice after an interruption.

It is useful to treat what is rendered during transmission as a provisional projection. It can be useful for reading, review, and cancellation, but it must be identified as a draft. Business state, by contrast, should derive from a final representation controlled by the server or another trusted component. This rule applies to conversational assistants, document extraction, code generation, administrative automation, and tool-using agents alike.

Provider APIs do not all use the same event names or offer exactly the same guarantees. Some document incremental events, response identifiers, and a completion event; others describe execution states or a result signal. The integration must be based on the specific contract of the chosen API, rather than inferring completeness because no traffic has arrived for a few seconds.

02

Design an explicit state machine

The clearest way to prevent the interface from becoming an execution path is to model the lifecycle of every generation. The internal generation identifier should be created before the connection is opened and linked, when available, to the identifier returned by the provider. It should also be associated with the session, authorized user or principal, prompt or configuration version, and requested business operation.

The first state is received: an event has arrived with transport metadata, but its content has not yet been accepted. Next, the event enters a provisional buffer, where it is retained in sequence order or according to the position defined by the protocol. The client can read this buffer to render a draft. If the flow delivers parts of several items, such as text, non-displayed reasoning, and tool arguments, separate buffers must be maintained by item and type.

In assembly, the consumer transforms fragments into a complete candidate representation: final text, a structured object, or a tool request. This step is not validation. For example, the fact that a concatenation can be parsed as JSON does not prove that it contains permitted fields, that values are within accepted ranges, or that the user authorized the resulting action.

An output becomes validated only after checking the documented terminal event or final state, the order and integrity of required events, the expected schema, and business rules. Confirmed result additionally means that the system has persisted the validated version under a stable key and recorded the decision. Action executed is a later state, not a synonym for validated: it requires an authorization policy, an idempotency key, and evidence of its outcome.

Alternative terminal states deserve separate treatment. Cancelled means the user or system asked to stop the experience; incomplete means a required part is missing or the provider reported an unsatisfactory completion; failed represents a processable error; expired means it is no longer safe to resume. None of these states should promote the provisional buffer to a final result.

Recommended generation transition

  1. 01Create an internal generation and record the purpose of the operation.
  2. 02Receive events and verify that they belong to the expected generation.
  3. 03Order or deduplicate events before adding them to provisional buffers.
  4. 04Display only the provisional projection permitted by the interface.
  5. 05After the documented terminal signal, assemble the candidate representation.
  6. 06Validate integrity, schema, business rules, and authorization.
  7. 07Persist a confirmed, immutable version of the validated output.
  8. 08If a tool is involved, request confirmation where applicable and execute with an idempotency key.
03

Decide what may be displayed, stored, indexed, or executed

The policy should not depend only on whether content appears reasonable. It should depend on its state and on the class of flow. An informational chat can allow the user to see a draft clearly marked as such. An extraction flow that feeds a knowledge base requires a final version before indexing. A tool that creates a reservation, sends a communication, or changes permissions needs additional controls, even if its arguments have already passed schema validation.

Storing transport telemetry is not the same as persisting output as business content. It can be legitimate to retain a minimal received-event record for debugging interruptions and reconciling sessions, subject to applicable privacy and retention policies. That must be distinguished from storing partial text as an approved answer. Likewise, a log must not turn secrets, personal data, or potentially sensitive instructions into an uncontrolled copy.

Indexing requires a particularly conservative decision. Partial fragments can contain an intermediate conclusion that disappears by the end of the response. Indexing them creates future retrieval of unconfirmed material and makes it harder to explain what a person saw and which version the system adopted. Index the validated version, with its generation and version identifiers, and allow that version to be withdrawn or replaced in an auditable way.

Decision matrix by state

StateShow to the personPersist as a resultIndexExecute an external action
Event receivedNot necessarily; first verify membership and formatNoNoNo
Provisional bufferYes, as a draft and with cancellation availableOnly minimal technical traces if policy permitsNoNo
Assembled objectOptionally, still as provisionalNot as a confirmed resultNoNo
Validated outputYes, as a final resultYes, with version and identifierYes, if the flow requires itNot yet by default
Confirmed resultYesYesYes, where appropriateOnly if the action policy authorizes it
Action executedYes, with status and available evidenceYes, record the decision and outcomeNot applicableAlready performed; do not repeat without idempotency
04

Consume the transport without assuming packets are messages

In a server-sent event flow, the protocol defines how events are formed and allows reconnections. The transport uses UTF-8 encoded text, and the boundary of a network packet is not the boundary of a character, an event line, or a JSON object. The consumer must therefore use an incremental decoder and an event parser; it must not turn every byte read into an independent string and assume that it contains one complete event.

After reconstructing a protocol event, the API contract still needs to be interpreted. Text may arrive through deltas; function-call arguments may be distributed across fragments; output items may be interleaved. The consumer must group them using documented identifiers, such as generation, item, or output index, and apply sequence numbers when available. A repeated delivery must not duplicate characters, create two objects, or cause a second execution.

The end of a connection is not sufficient proof of success either. The connection can close because of cancellation, a proxy, a timeout, or an error. Only the terminal signal and state documented by the provider can classify the generation as completed, incomplete, or failed. If that evidence is absent, the correct state is uncertain or incomplete, and promotion and execution must be blocked.

Not every API provides a checksum, final version, or resume mechanism. When a response identifier and sequence cursor exist, retain them together with the last accepted event. If they do not exist, reconnection may need to create a new generation from the business perspective. It is not safe to infer that two similar sequences are the same response merely from their content.

05

Tool calling: complete does not mean authorized

Tool calls deserve an independent barrier because they transform generated text into effects outside the model. The appearance of a function name or part of its arguments does not constitute an executable request. Arguments must be accumulated until the corresponding completion signal, converted into a structured representation, and validated against a strict schema. Unknown fields, implicit conversions, and values outside policy must be rejected or require a new interaction.

Schema validation is necessary but insufficient. A transfer tool can receive a correctly formatted amount and still exceed a limit, lack authorization, or target a recipient that is not allowed. Business rules must run in the service that controls the action, not only in the client rendering the conversation. For material operations, user confirmation should show a stable description of the action derived from arguments that have already been validated.

Execution must carry an idempotency key calculated or assigned by the server. That key must be tied to the confirmed intent, not to each network retry. Before retrying, the executor checks the operation record to determine whether that key already has an outcome. This matters because retrying a non-idempotent operation is unsafe when it cannot be determined whether the original request was applied.

The tool outcome also needs reconciliation. If the external provider accepts the operation but its response is lost, the state is not “not executed”: it is unknown until an operation identifier can be queried or a compensation procedure is applied. Designing for this case from the beginning prevents a retry button from becoming a duplicate order.

Controls for an external tool

StageMinimum controlOutcome if it fails
Partial argumentsAccumulate by call identifier; do not interpret for executionKeep as draft or discard
Complete argumentsValidate JSON, schema, and permitted fieldsReject the call
IntentApply authorization, limits, and business rulesBlock it and explain why
ConfirmationRequest it when the risk policy requires itDo not create the external order
ExecutionUse an idempotency key and record the attemptCheck status before retrying
External responseStore an identifier and verifiable outcomeMark as unknown or pending reconciliation
06

Interruptions, cancellations, resumption, and product experience

After an interruption, the application must preserve the distinction between what was seen and what was confirmed. It can leave the draft visible with an interruption notice, offer a retry, or attempt resumption when the protocol and provider support it. If it resumes, it must request or process only events after the last confirmed cursor and deduplicate any repetition. If continuity cannot be proved, it is preferable to start a new generation and label it as such.

User cancellation requires two separate operations: stopping the display of, or request for, additional content, and deciding what happens to work already started. Cancelling a subscription does not necessarily mean that the provider has stopped computation. The system must record the cancellation request, prevent unwanted later promotions, and handle any subsequent events according to a defined policy. An external action already sent requires a query or compensation, not an assumption based on the interface being closed.

In the product experience, indicators should communicate activity without promising completion. A typing cursor, a “generating” state, and a stop option are appropriate for a draft. A “result ready” label should be reserved for validated output. If draft editing is permitted, the human edit must create a separate branch or version; it must not be confused with the system-confirmed response.

Session recovery should be able to explain what happened. Preserve the relationship between the generation, accepted events, last cursor, validated version, and, if present, the external operation. This traceability does not require storing all text indefinitely; the level of detail should match data sensitivity and retention obligations.

Response to a disconnection

  1. 01Mark the stream as interrupted without declaring success.
  2. 02Retain the last accepted identifier or cursor and the state of buffers.
  3. 03Attempt resumption only through the mechanism documented by the provider.
  4. 04Deduplicate events using a sequence, event identifier, or both.
  5. 05Require a valid terminal signal again before validating output.
  6. 06If continuity cannot be demonstrated, close as incomplete and offer a new generation.
  7. 07Block any pending tool until a complete intent has been reconstructed and validated.
07

Telemetry and testing before deployment

Metrics must separate perceived speed from correctness. Record time to first fragment, time to termination, time to validation, and, in tool flows, time to confirmation and execution. Also record abandonment, cancellations, reconnections, events discarded as duplicates, incomplete generations, and discrepancies between provisional content and the confirmed version. These signals make it possible to detect when a visual improvement is hiding a degradation in completeness.

Do not use complete text as the only basis for observability. A generation identifier, provider identifier where available, sequence, event type, state transitions, and rejection reasons are often enough to investigate many incidents. When content must be retained for audit, apply access controls, minimization, and an explicit retention policy.

Chaos tests must intervene at every boundary, not only disconnect before the first token. Simulate interruptions inside a multibyte character, between event lines, inside JSON, after apparently complete tool arguments, and immediately before the terminal signal. Simulate event replays, ordering changes where the contract does not prohibit them, terminal error responses, late cancellations, and loss of the external system response. The main criterion is that no scenario turns incomplete content into a confirmed result or causes a second action for the same purpose.

As a deployment check, verify that the client does not hold credentials capable of directly executing sensitive actions; that validation is centralized; that the idempotency store survives reasonable restarts; and that dashboards distinguish an abandoned generation from a confirmed action. Also consult the internal Learn, Compare, and Discover routes to align this integration decision with product patterns and capabilities.

Open questions

  • The availability of sequence identifiers, resumption cursors, and unambiguous terminal events varies across APIs and versions.
  • The ability to resume a stream and the behavior of repeated events must be verified in the specific provider contract.
  • Rules requiring human confirmation depend on tool risk, user authorization, and each organization’s policies.
  • Retention of buffers, traces, and confirmed content must be defined according to data sensitivity and applicable requirements.
08

Keep exploring

08

Sources consulted

03

Corrections and transparency

If you spot incorrect or outdated information, send us a correction with the page and source we should review.

Submit a correction