Provider-neutral generation APIs
Connect different model services without hiding their differences.
In this lesson · B3 of 12
All lessons in this track →Progress for this track is saved in this browser only. No completion badge is issued. View your learning.
Start with the idea
Connect different model services without hiding their differences.
Use a shared result format, but preserve status and capability differences. An adapter should translate fields, not invent missing information. Test failures as carefully as normal answers.
Adapter: Code that translates one service’s interface into the interface your application expects.
See the example and check your understanding
A made-up teaching example
Two mock providers use different field names and refusal signals. Their adapters produce a common result. Refusal, partial output and unknown usage stay explicit instead of becoming empty successful answers.
Ask yourself
Is missing usage the same as zero usage?
Show the explanation
No. Keep it unknown. The offline tests show adapter rules, not actual provider or network behavior.
Start with these checks
- Check declared capabilities.
- Keep refusal and partial states visible.
- Reject unknown status values.
Use the different practice case below and check every requirement in its full instructions.
The video explains the main idea. Use the sources, instructions and checks below to complete the practice.
Captions appear here during playback.
Provider-neutral generation APIs
Connect different model services without hiding their differences.
Video playback is unavailable. Read the descriptive transcript below, go directly to practice, or open the video file.
Source-based teaching example · Fictional data · Reviewed 2026-10-03. Microsoft Mark · locally synthesized. On a small screen, use fullscreen for diagram details or read the transcript.
Read the descriptive transcript
0:00 · What you will learn
Connect different model services without hiding their differences.
What appears on screen
Connect different model services without hiding their differences.
0:06 · The idea
Use a shared result format, but preserve status and capability differences. An adapter should translate fields, not invent missing information. Test failures as carefully as normal answers.
What appears on screen
Use a shared result format, but preserve status and capability differences. An adapter should translate fields, not invent missing information. Test failures as carefully as normal answers.
0:22 · One useful term
Adapter. Code that translates one service’s interface into the interface your application expects.
What appears on screen
Code that translates one service’s interface into the interface your application expects.
0:32 · A worked example
Two mock providers use different field names and refusal signals. Their adapters produce a common result. Refusal, partial output and unknown usage stay explicit instead of becoming empty successful answers.
What appears on screen
Two mock providers use different field names and refusal signals. Their adapters produce a common result. Refusal, partial output and unknown usage stay explicit instead of becoming empty successful answers.
0:49 · Your turn to think
Is missing usage the same as zero usage? Pause and decide before continuing.
What appears on screen
Is missing usage the same as zero usage? Pause the video if you need more time.
1:05 · Why this answer works
No. Keep it unknown. The offline tests show adapter rules, not actual provider or network behavior.
What appears on screen
No. Keep it unknown. The offline tests show adapter rules, not actual provider or network behavior.
1:16 · Check 1
Check declared capabilities.
What appears on screen
Check declared capabilities.
1:21 · Check 2
Keep refusal and partial states visible.
What appears on screen
Keep refusal and partial states visible.
1:26 · Check 3
Reject unknown status values.
What appears on screen
Reject unknown status values.
1:32 · Now try a different case
Open the lesson and try its different practice case. Use every check in the full task. Watching alone does not mark the lesson complete.
What appears on screen
Open the lesson Try the new case Check and revise The full task and its requirements are in the linked lesson.
Watching explains the example. Complete the lesson practice to check what you can do. Explore all visual lessons →
What you will be able to do
- Define a minimal provider-neutral contract.
- Normalize response, usage, refusal, and error evidence.
- Document feature gaps and migration risk.
Prerequisites: dictionaries, loops, functions, exceptions and installed Python or paper tracing. Reuse earlier Builder artifacts only when the task requires them.
This curriculum runs self-study on VetsLearn. Where the text calls for an instructor, peer or formal review, use the stated acceptance criteria for self-review. Reflection questions support reflection; they do not replace independent assessment. A peer review is optional unless your actual organization requires it.
Part 1 Technical instruction
Provider neutrality is deliberate containment, not the fiction that every model has identical behavior. Define the smallest application contract - messages or input, constraints, response text or object, request ID, usage, finish state, and structured error. Keep provider-specific translation inside adapters. Capability discovery, snapshot/model selection, streaming events, structured output, refusal semantics, and tool calls must be represented explicitly where the application depends on them. A migration record names the old and new behavior, evaluation set, acceptance rule, and rollback path.
Mechanism and implementation
An adapter translates provider events while exposing capability gaps. Declare input/output modalities, schemas, tools, streaming, state, context limits, usage and supported reasoning controls. Local/cloud is deployment; frontier is a capability claim. Neither substitutes for a manifest. Endpoint-compatible syntax does not imply feature equivalence.
Constructed offline example
Save as topic_example.py and run python topic_example.py with an installed Python 3.11+ interpreter. This standard-library construction uses synthetic values; its checks are not provider measurements.
capabilities = {"tools": True, "schema": False, "reasoning_controls": []}
def normalize(raw):
state = raw.get("state")
if state not in {"complete", "partial", "refusal", "error", "cancelled"}:
state = "error"
return {"status": state, "text": raw.get("text") if state == "complete" else None,
"usage": raw.get("usage")}
assert normalize({"state": "partial", "text": "half"})["text"] is None
assert normalize({"state": "refusal"})["status"] == "refusal"
assert not capabilities["schema"]
print("adapter checks passed")Engineering decisions
- Select the stable application contract.
- Expose or hide a provider feature gap.
- Choose when to pin a model snapshot and what change triggers reevaluation.
Worked example
Two mock adapters return different field names and refusal indicators. The common interface normalizes both into GenerationResult. The application never branches on provider name; it branches on declared capabilities. The pack tests request identifiers, usage, refusal, schema failures, capability declarations and a simulated retry/deadline policy. It does not call provider APIs or prove real network timeout behavior.
Diagnose the failure
Unknown status is an error; refusal and partial are not empty successful strings. Missing usage means unknown, not zero. B3v2 remains the bounded offline reference pack; no live provider behavior is measured.
Part 2 Guided practice
Normalize two mock provider shapes into one contract, retaining request IDs and original status metadata. Reject a requested schema feature absent from the manifest. Independently preserve partial content separately without rendering it as final.
Answer criteria and feedback: Unknown status is an error; refusal and partial are not empty successful strings. Missing usage means unknown, not zero. B3v2 remains the bounded offline reference pack; no live provider behavior is measured.
Continue with the downloadable pack below. If the pack or interpreter is unavailable, trace this self-contained example by hand in an input/expected-status/controlling-rule table and label execution unverified. Do not invent passing output. No account, credential, paid call, purchase or actual deployment is required.
Part 3 Remediation
Start with a single adapter and pass the common contract. Add the second only after the contract is stable. If a feature cannot be represented honestly, declare the gap instead of silently degrading it. After repair, reassess with the alternate scenario in scenario_alt.json. A critical authorization, data-handling, evidence-integrity, or prohibited-action failure cannot be averaged into successful practice; it requires targeted remediation.
Part 4 Sources and currency
Use the workflow reference for capability manifests and task/model/deployment/harness comparisons. Source currency must be checked before any real provider integration. Provider/product behavior is illustrative where mocked; resolve current interfaces only from official documentation in an authorized environment.