Prompt
How do I set up a chat completion API for extraction workflows with streaming responses?
Latest observation
To set up a chat completion API for extraction workflows with streaming responses, the usual pattern is:
- Send structured extraction instructions
- Use a schema or strict output format
- Stream tokens/events as the model generates them
- Incrementally assemble and validate the partial output
- Finalize into a clean extracted object
1) Define the extraction target
Be explicit about what you want extracted. For example:
- entities: names, dates, amounts, organizations
- fields: invoice number, total, due date
- relations: sender → recipient, product → price
A good prompt says:
- what to extract
- what to ignore
- the required output shape
- how to handle missing values
Example instruction:
Extract the following fields from the document:
- customer_name
- invoice_number
- invoice_date
- total_amount
- currency
Return only valid JSON matching the schema.
If a field is missing, use null.
2) Use a chat completion request
Typical structure:
system: defines role and output constraintsuser: provides the text/document to extract from- optional
response_formator schema enforcement if supported stream: trueto receive incremental output
Example request pattern
{
"model": "your-model",
"stream": true,
"messages": [
{
"role": "system",
"content": "You are an information extraction engine. Return only valid JSON."
},
{
"role": "user",
"content": "Invoice 1042 ... total due $245.80 ..."
}
]
}
3) Prefer a schema-driven output
If your API supports it, use a JSON schema or structured response mode. That makes extraction workflows much more reliable than free-form text.
Example schema:
{
"type": "object",
"properties": {
"customer_name": { "type": ["string", "null"] },
"invoice_number": { "type": ["string", "null"] },
"invoice_date": { "type": ["string", "null"] },
"total_amount": { "type": ["number", "null"] },
"currency": { "type": ["string", "null"] }
},
"required": [
"customer_name",
"invoice_number",
"invoice_date",
"total_amount",
"currency"
],
"additionalProperties": false
}
4) Enable streaming
When streaming is enabled, the server sends partial events/chunks rather than one final response.
Why streaming helps in extraction workflows
- faster perceived latency
- early progress display
- easier handling of long documents
- can stop once enough content is received in some cases
5) Handle streamed chunks
You typically:
- append each chunk to a buffer
- detect when the structured payload is complete
- parse/validate JSON
- recover from partial chunks if needed
Example client logic
Pseudo-code:
buffer = ""
for event in stream:
chunk = event.delta_content
if chunk:
buffer += chunk
# after stream ends
data = json.loads(buffer)
If your API emits SSE-style events, you’ll parse each event and extract the content delta.
6) Validate and normalize results
After streaming finishes:
- parse JSON
- validate against schema
- normalize dates, numbers, and currencies
- flag low-confidence or missing fields
Example normalization:
"245.80"→245.8"07/19/2026"→"2026-07-19""USD"stays"USD"
7) Recommended extraction workflow architecture
A robust setup often looks like this:
Pipeline
- Input document ingestion
- Chunking / OCR / text cleanup
- Chat completion extraction
- Streaming assembly
- Schema validation
- Post-processing
- Persistence to DB or downstream system
For large documents
- split into sections
- extract per section
- merge results
- deduplicate entities
- reconcile conflicting values
8) Example with streaming in practice
Python-style pseudo-code
import json
def extract_with_streaming(client, document_text):
stream = client.chat.completions.create(
model="your-model",
stream=True,
messages=[
{"role": "system", "content": "Return only valid JSON."},
{"role": "user", "content": f"Extract fields from:\n{document_text}"}
]
)
buffer = ""
for event in stream:
if event.choices[0].delta.get("content"):
buffer += event.choices[0].delta["content"]
return json.loads(buffer)
9) Best practices
- Keep prompts short and precise
- Use schemas whenever possible
- Require
nullfor missing fields - Avoid asking for explanation text
- Make outputs machine-parseable
- Add retries for malformed JSON
- Use confidence scores if your workflow needs triage
10) Common pitfalls
- Partial JSON during streaming: don’t parse until complete unless you have incremental parsing logic
- Hallucinated fields: constrain with schema and explicit instructions
- Mixed prose + JSON: instruct “return only JSON”
- Inconsistent formatting: add examples and normalization rules
- Long-document overload: chunk and merge
If you want, I can give you:
- a concrete OpenAI API example for streaming extraction,
- a Node.js example, or
- a FastAPI backend template for an extraction service.
Observation history
Unlock observation history
Create a free Obsurfable account to unlock historical responses, model comparisons, and deeper brand intelligence.
How did Obsurfable measure this prompt?
Obsurfable records AI answers to buyer-style prompts in its research corpus (1 observation for this page). Metrics are distributions over observations, not a single static ranking.
Which AI systems does Obsurfable collect answers from?
OpenAI, ChatGPT, Google, Gemini, Google AI Mode, Anthropic, Claude, Perplexity, Grok, DeepSeek, Mistral, Copilot, and Meta AI.