Doramagic Project Pack · Human Manual

instructor

structured outputs for llms

Overview & Getting Started

Related topics: Architecture, Modes & Provider System, Validation, Retries, Streaming & Hooks

Section Related Pages

Continue reading this section for the full explanation and source context.

Section Pydantic-driven response validation

Continue reading this section for the full explanation and source context.

Section Retries, validators, and reasks

Continue reading this section for the full explanation and source context.

Section Streaming and partial responses

Continue reading this section for the full explanation and source context.

Related topics: Architecture, Modes & Provider System, Validation, Retries, Streaming & Hooks

Overview & Getting Started

1. Project Purpose and Scope

Instructor is a Python library that turns Pydantic models into structured-output interfaces for Large Language Model (LLM) providers. It wraps each provider's native SDK so that a developer can pass a response_model to a chat-completion call and receive a validated, typed Python object back, instead of raw text or unverified JSON. The README frames the project as "the most popular Python library for extracting structured data from LLMs" and positions it against three alternatives: raw JSON mode, LangChain/LlamaIndex, and ad-hoc custom solutions. Source: README.md.

The library supports many providers (OpenAI, Anthropic, Google Gemini, Google GenAI, Cohere, Writer, Bedrock, and others) and exposes a v2 hierarchical registry under instructor/v2/ that decouples provider-specific request preparation, response parsing, and templating from the core client loop. Source: instructor/v2/providers/writer/client.py.

In addition to the Python implementation, README.md points to official ports in TypeScript, Ruby, Go, Elixir, and Rust, and to a Discord community, documentation site, blog, and curated examples directory. Source: README.md.

2. High-Level Architecture

The v2 codebase is organized around three cooperating layers: a core that owns the client, mode, provider, and patch primitives, a providers/* package that registers per-provider handlers, and a dsl layer that defines streaming and partial-response helpers. Each provider exposes its own client.py, handlers.py, schema.py, and templating.py modules. Source: instructor/v2/providers/writer/client.py.

A from_<provider>(client, mode=..., model=...) factory wraps the provider's native SDK and returns an Instructor or AsyncInstructor. Handlers are registered automatically on import through decorators keyed by (Provider, Mode). For example, the Writer package supports TOOLS, JSON_SCHEMA, and MD_JSON modes, and WriterMDJSONHandler.prepare_request injects a system message containing the Pydantic JSON schema when tool calling is not used. Source: instructor/v2/providers/writer/handlers.py.

flowchart LR
    User[User code] -->|response_model| Factory[from_<provider>() factory]
    Factory --> Core[Instructor / AsyncInstructor core]
    Core -->|prepare_request| Handler[Mode-specific handler]
    Handler -->|native kwargs| SDK[Provider SDK call]
    SDK -->|raw response| Handler
    Handler -->|model_validate| Pydantic[Validated Pydantic object]
    Pydantic -->|retries on ValidationError| Handler
    Pydantic --> User

Schema generation is provider-specific but shares a common OpenAI entry point. generate_openai_schema parses the model's docstring with docstring_parser to enrich parameter descriptions, computes the required list from properties without defaults, and returns a {"name", "description", "parameters"} dict suitable for function-calling. Source: instructor/v2/providers/openai/schema.py. generate_anthropic_schema reuses that result and repackages it as {"name", "description", "input_schema": model.model_json_schema()}. Source: instructor/v2/providers/anthropic/schema.py.

The Google provider module ships two schema helpers: a deprecated generate_gemini_schema (which warns to migrate to google-genai) and a new generate_gemini_schema style entry. Source: instructor/v2/providers/gemini/schema.py. Shared Google utilities such as _OPENAI_TO_GEMINI_MAP, map_to_gemini_function_schema, and _default_safety_thresholds live in instructor/v2/providers/gemini/utils.py. Source: instructor/v2/providers/gemini/utils.py.

3. Core Capabilities

Pydantic-driven response validation

Instructor's headline feature is that a Pydantic BaseModel doubles as the LLM response schema. The provider-specific schema helpers convert the model into the format expected by the underlying API (OpenAI function schema, Anthropic tool schema, Gemini FunctionDeclaration, or a system-prompt JSON block for markdown modes). Source: instructor/v2/providers/openai/schema.py. The Anthropic JSON_SCHEMA handler extracts the last text block from the response and calls response_model.model_validate_json with optional strict validation. Source: instructor/v2/providers/anthropic/handlers.py.

Retries, validators, and reasks

When validation fails, Instructor automatically re-prompts the model with the error feedback. The examples/validators/readme.md walkthrough shows a QuestionAnswerNoEvil model whose answer field is guarded by a BeforeValidator(llm_validator(...)); the example produces a ValidationError whose message comes from the LLM judge. Source: examples/validators/readme.md. Community issue #2222 asks that completion:error and completion:last_attempt hooks be enriched with attempt metadata, indicating that retry telemetry is a first-class extension point. Source: community evidence for issue #2222.

Streaming and partial responses

For long outputs, Instructor offers Partial and PartialBase types that progressively validate JSON as it streams in. The Google utilities expose Partial for re-asking during streaming. Source: instructor/v2/providers/gemini/utils.py. Release v1.14.3 added JsonCompleteness for completeness-based validation during streaming, and v1.14.2 fixed model-validator crashes by deferring them until streaming completes. Source: release notes v1.14.2 and v1.14.3 in community context.

Multimodal inputs

Multimodal helpers are exposed as Audio, Image, and PDF in the core, and Gemini/GenAI utilities import them from instructor.v2.core.multimodal. Source: instructor/v2/providers/gemini/utils.py. Release v1.15.1 tightened the Bedrock surface by rejecting remote HTTP(S) image URLs in _openai_image_part_to_bedrock and by limiting PDF.to_bedrock to base64 data and s3:// sources, mitigating SSRF risks. Source: release notes v1.15.1 in community context.

Provider templating

Each provider implements a small templating.process_message that knows how to walk its native message shape and apply a Jinja2-style template. OpenAI templates message["content"] when it is a string. Source: instructor/v2/providers/openai/templating.py. Anthropic walks the content list and templates text parts. Source: instructor/v2/providers/anthropic/templating.py. Gemini templates parts, Cohere templates a message string, and GenAI templates Content.parts via types.Content and types.Part.from_text. Source: instructor/v2/providers/gemini/templating.py, instructor/v2/providers/cohere/templating.py, and instructor/v2/providers/genai/templating.py.

4. Getting Started and Common Pitfalls

A minimal workflow is: install the package, import instructor, pick a provider factory such as instructor.from_openai(client), and call it with response_model=<PydanticModel>. The examples/codegen-from-schema/readme.md recipe extends this by generating FastAPI application code and models.py from a JSON schema and a Jinja2 prompt template. Source: examples/codegen-from-schema/readme.md. The examples/citation_with_extraction/README.md shows a production-style FastAPI service that streams structured facts with span citations via SSE. Source: examples/citation_with_extraction/README.md.

Developers contributing to the documentation can use the helper scripts under scripts/: make_clean.py normalizes Unicode whitespace and dash characters in docs/, check_blog_excerpts.py ensures every blog post contains an <!-- more --> tag, fix_api_calls.py rewrites legacy client.chat.completions.create* calls to the simplified client.create* form, and make_sitemap.py produces a sitemap.yaml with summaries, keywords, and cross-links using an OpenAI call. Source: scripts/README.md.

Several recent issues are worth noting for new users:

  • Image.autodetect is annotated as returning Image but only handles str and Path; passing bytes causes an AttributeError downstream (issue #2344).
  • handle_gemini_json accesses new_kwargs["messages"][0]["role"] without guarding for missing or empty messages (issue #2335). Source: instructor/v2/providers/gemini/utils.py shows the surrounding utility module where the fix should land.
  • Cohere's handle_templating raises KeyError when chat_history is absent (issue #2331); the templating helper in instructor/v2/providers/cohere/templating.py is the related file.
  • The jsonref dependency is not declared in pyproject.toml despite being imported (issue #2288); verify your environment has it before relying on $ref resolution.
  • Feature request #2334 proposes an OWASP Agent Memory Guard to mitigate memory-poisoning attacks when retries accumulate untrusted context.

See Also

Source: https://github.com/567-labs/instructor / Human Manual

Architecture, Modes & Provider System

Related topics: Overview & Getting Started, Validation, Retries, Streaming & Hooks, Multimodal, Batch, CLI & Security

Section Related Pages

Continue reading this section for the full explanation and source context.

Section Schema helpers

Continue reading this section for the full explanation and source context.

Section Templating layer

Continue reading this section for the full explanation and source context.

Related topics: Overview & Getting Started, Validation, Retries, Streaming & Hooks, Multimodal, Batch, CLI & Security

Architecture, Modes & Provider System

Overview & Purpose

Instructor is a structured-output extraction library that wraps multiple LLM provider SDKs behind a uniform response_model interface. Internally it is organized as a provider × mode matrix: each provider (OpenAI, Anthropic, Gemini, GenAI, Writer, Cohere, Bedrock, …) ships its own client factory, schema helpers, and message-templating module. A central mode-handler registry binds a (Provider, Mode) pair to a concrete handler class that prepares the request and parses the response, so the user-facing client.create(..., response_model=User) call is identical across vendors.

The design goal of this layer is twofold:

  1. Decouple provider quirks from user code — every backend-specific detail (e.g. Anthropic's input_schema, OpenAI's tools[], Writer's client.chat.chat) is encapsulated inside per-provider files.
  2. Make new providers plug-in compatible — adding a backend is a matter of dropping a new directory under instructor/v2/providers/ and registering handlers via decorators, without touching the core client.

Source: instructor/v2/providers/writer/client.py:1-58

Provider Modules

Every backend follows the same directory layout under instructor/v2/providers/<name>/:

FileResponsibility
client.pyFactory (from_<provider>) that builds a sync or async Instructor instance, optionally using @overload to type-narrow.
handlers.pyConcrete handler subclasses registered against (Provider, Mode) tuples.
schema.pyConverts a Pydantic BaseModel into the provider's native function/tool schema.
templating.pyprocess_message() adapter that applies Jinja2 templates to the provider's message shape.
utils.pyBackend-specific helpers (system-message extraction, message-shape conversion).

The Writer factory is a representative example: it imports Writer/AsyncWriter from the writerai SDK lazily, imports its own handlers module for side-effect registration, and exposes from_writer(client, mode=Mode.TOOLS, model=None, **kwargs). The two @overload signatures give static type checkers the correct sync vs. async return type while a single def provides the runtime implementation. Source: instructor/v2/providers/writer/client.py:1-58

Mode Handler Registry

Modes describe how a provider is asked to produce structured output. Common values include TOOLS (native function calling), JSON_SCHEMA (provider-enforced JSON Schema), MD_JSON (extract JSON from a markdown code block as a fallback), and provider-specific entries such as GEMINI_TOOLS or Responses.

Each handler implements two methods:

  • prepare_request(response_model, kwargs) — mutates the kwargs that will be sent to the underlying SDK call. For TOOLS it registers a tool definition, for MD_JSON it injects a system message containing the JSON schema, etc. Source: instructor/v2/providers/writer/handlers.py:1-110
  • A response-parsing hook that converts the raw provider object back into the user's Pydantic model (or raises IncompleteOutputException for retryable failures).

Handlers self-register via the register_mode_handler(Provider, Mode) decorator imported from instructor.v2.core.decorators, so merely importing the handlers module wires the backend into the global registry. This is why from instructor.v2.providers.writer import handlers # noqa: F401 appears at the top of client.py. Source: instructor/v2/providers/writer/client.py:1-58

The legacy google-generativeai path is intentionally separated from the modern google-genai (Generative AI / Vertex) path. instructor/v2/providers/gemini/schema.py emits a DeprecationWarning and imports google.generativeai.types lazily, signalling that new code should prefer the genai provider. Source: instructor/v2/providers/gemini/schema.py:1-35

Schema Generation & Templating

Schema helpers

Schema generation is shared as much as possible. generate_openai_schema() is lru_cache'd (size 256) and merges the model's model_json_schema() output with parsed docstring parameters to enrich field descriptions. Anthropic reuses it and wraps the result in the {name, description, input_schema} shape that the Claude API expects. Source: instructor/v2/providers/openai/schema.py:1-50, instructor/v2/providers/anthropic/schema.py:1-22

Templating layer

Each provider's templating.py exports a process_message(message, context, apply_template) function that knows where string content lives in that provider's message envelope:

flowchart LR
  User[User code<br/>client.create response_model=M] --> Patch[patch_v2 / core.client]
  Patch --> Registry{Registry lookup}
  Registry -->|Provider, Mode| Handler[ModeHandler subclass]
  Handler --> Schema[generate_<provider>_schema]
  Handler --> Template[process_message templating]
  Schema --> SDK[(Provider SDK call)]
  Template --> SDK
  SDK --> Parser[Response parser]
  Parser --> Result[Pydantic instance]

Common Failure Modes & Community Issues

Several recurring issues map directly to the architecture:

  • Cohere KeyError on templating (#2331): handle_templating() assumes a chat_history companion key whenever a Cohere-style message key is present. The provider-side process_message in cohere/templating.py only touches the message field, so the fix has to live in the shared templating dispatcher. Source: instructor/v2/providers/cohere/templating.py:1-15
  • Gemini empty messages crash (#2335): handle_gemini_json in instructor/v2/providers/gemini/utils.py unconditionally indexes new_kwargs["messages"][0]["role"]. The provider module is the right place to add a guard, since it owns the Gemini message-shape conversion. Source: instructor/v2/providers/gemini/utils.py
  • Image.autodetect returning None (#2344): A multimodal helper that is supposed to return an Image falls through and returns None for bytes sources, producing a confusing AttributeError downstream. Multimodal adapters sit next to the provider handlers, so the fix is localized.
  • Legacy vs. modern Gemini: generate_gemini_schema now raises a DeprecationWarning, nudging users to the genai provider, which is the recommended path going forward. Source: instructor/v2/providers/gemini/schema.py:1-35

See Also

  • Streaming & Partial Validation — completeness-based validation (JsonCompleteness) and PartialLiteralMixin for streaming responses.
  • Hooks & Retriescompletion:error / completion:last_attempt hooks and attempt metadata.
  • Multimodal AdaptersImage, PDF, and provider-specific multimodal conversion (Bedrock SSRF hardening in v1.15.1).

Source: https://github.com/567-labs/instructor / Human Manual

Validation, Retries, Streaming & Hooks

Related topics: Overview & Getting Started, Architecture, Modes & Provider System, Multimodal, Batch, CLI & Security

Section Related Pages

Continue reading this section for the full explanation and source context.

Related topics: Overview & Getting Started, Architecture, Modes & Provider System, Multimodal, Batch, CLI & Security

Validation, Retries, Streaming & Hooks

Instructor's core value proposition is the closed loop between four subsystems: a validation layer that enforces Pydantic schemas, a retry layer that re-asks the model on failure, a streaming layer that yields partial objects as the model generates them, and a hooks layer that lets user code observe and instrument every step. Together they turn raw LLM text into validated, retryable, observable structured output.

Validation

Validation is built on top of Pydantic. Each provider's schema helper converts a Pydantic BaseModel into the wire format the underlying SDK expects. The OpenAI helper parses the model's docstring with docstring_parser to merge field descriptions and then marks every parameter without a default as required. Results are memoized with functools.lru_cache(maxsize=256) because the same model is usually re-validated across retries — see instructor/v2/providers/openai/schema.py. The Anthropic wrapper simply repackages the OpenAI schema under input_schema and adds a name/description pair in instructor/v2/providers/anthropic/schema.py.

Two validation styles are available out of the box:

  • Schema validation — the provider guarantees a shape and Instructor parses it into a Pydantic model. Native JSON-schema providers (Anthropic structured outputs, OpenAI JSON mode) flow through model_validate_json(text_content, context=validation_context, strict=strict) in instructor/v2/providers/anthropic/handlers.py.
  • LLM validation — the llm_validator helper shown in examples/validators/readme.md is wired in with Annotated[str, BeforeValidator(llm_validator("..."))] so a second model call judges the first model's output. v1.15.0 fixed Validator to require an is_valid field, ensuring every validator returns a parseable boolean wrapper.

Schemas that use $ref require the jsonref package to dereference them at validation time — see issue #2288.

Retries

When validation fails, Instructor re-asks the model. The retry pipeline is driven by exceptions raised during parsing:

ExceptionSourceTrigger
IncompleteOutputExceptioninstructor/v2/providers/anthropic/handlers.pyresponse.stop_reason == "max_tokens" (truncated output)
ResponseParsingErrorinstructor/v2/providers/anthropic/handlers.pyEmpty text blocks in structured-output responses

A failed reask re-enters the same prepare_requestparse loop. Each provider implements handle_reask to mutate kwargs with the failure context (e.g., appending the error message to the last user turn) and try again. The Writer provider's WriterMDJSONHandler falls back to extract_json_from_codeblock when tool calling is unavailable, as shown in instructor/v2/providers/writer/handlers.py.

max_retries caps the loop, and v1.14.3 fixed a crash where Stream objects interacted badly with reask handlers at retry boundaries.

Streaming

Partial wraps a model so that every token of an in-flight response yields an incrementally-valid snapshot. Two long-standing failure modes were resolved in v1.14.2 and v1.14.3:

  1. Model validators crashed mid-stream because the partial model lacked the fields they expected. v1.14.2 skips model validators until the stream is structurally complete.
  2. Self-referential models (e.g., TreeNode whose children: List["TreeNode"] referenced itself) caused infinite recursion during incremental validation. v1.14.2 detects and short-circuits this case.
  3. Partial JSON validity is tracked by a new JsonCompleteness class added in v1.14.3; only structurally complete fragments are fed to Pydantic for the first time.

Stream consumers must therefore expect *partial* BaseModel instances that may not yet satisfy every validator — this is by design and not an error.

Hooks

Hooks are an event bus emitted by the Instructor client. The example in examples/hooks/README.md registers five built-in events:

  • completion:kwargs — fired before the call leaves Instructor
  • completion:response — fired on a successful model response
  • completion:error — fired on a transport / API failure
  • completion:last_attempt — fired on the final retry (success or failure)
  • parse:error — fired when model_validate rejects the model's output

Issue #2222 pointed out that completion:error and completion:last_attempt only received the exception object, so callers could not distinguish an intermediate retryable failure from a final one. v1.15.1 ships attempt metadata (e.g. attempt_number) on those hooks, enabling clean retry-aware logging.

sequenceDiagram
    participant Caller
    participant Hooks
    participant RetryLoop
    participant Provider

    Caller->>Hooks: emit completion:kwargs
    Caller->>RetryLoop: prepare_request(kwargs)
    loop attempt 1..N
        RetryLoop->>Provider: chat.completions.create
        alt transport error
            Provider-->>RetryLoop: raise
            RetryLoop->>Hooks: emit completion:error(attempt)
        else parse error
            RetryLoop-->>Hooks: emit parse:error
            RetryLoop->>RetryLoop: handle_reask(kwargs)
        else success
            Provider-->>RetryLoop: response
            RetryLoop->>Hooks: emit completion:response
        end
    end
    RetryLoop->>Hooks: emit completion:last_attempt
    RetryLoop-->>Caller: validated model

Templating cross-cuts

Templating is provider-specific — see the per-provider process_message functions in instructor/v2/providers/openai/templating.py, anthropic/templating.py, cohere/templating.py, and genai/templating.py. Issue #2331 reports a KeyError when the Cohere provider is given a Jinja2 context without chat_history — a useful reminder that templating contracts differ across providers.

See Also

  • Providers overview
  • Pydantic integration
  • Multimodal inputs (Image, PDF, Audio)

Source: https://github.com/567-labs/instructor / Human Manual

Multimodal, Batch, CLI & Security

Related topics: Overview & Getting Started, Architecture, Modes & Provider System, Validation, Retries, Streaming & Hooks

Section Related Pages

Continue reading this section for the full explanation and source context.

Section Core Multimodal Types

Continue reading this section for the full explanation and source context.

Section Provider-Specific Adapters

Continue reading this section for the full explanation and source context.

Section Cross-Provider Templating

Continue reading this section for the full explanation and source context.

Related topics: Overview & Getting Started, Architecture, Modes & Provider System, Validation, Retries, Streaming & Hooks

Multimodal, Batch, CLI & Security

Instructor extends Pydantic-style structured extraction beyond plain text into multimedia inputs, batched long-running jobs, a developer-facing command-line tool, and hardened defaults for safe deployment. This page surveys the in-repo primitives that power these features and the security posture baked into v1.15.x.

Multimodal Content

Core Multimodal Types

The core multimodal module defines three container classes — Image, Audio, and PDF — that wrap raw bytes, paths, and URLs into a uniform object that providers can convert to their wire formats. Image.autodetect inspects the source and returns a fully populated Image, but its dispatch table is intentionally narrow: it only resolves str and Path inputs. Any other source (e.g. raw bytes) falls through and the function implicitly returns None, which is a known footgun documented in community issue #2344. Callers that subsequently access .source, .media_type, or .data then receive a misleading AttributeError rather than a clear type error. Source: instructor/v2/core/multimodal.py

Provider-Specific Adapters

Each provider has a dedicated module that knows how to translate the core Image/Audio/PDF objects into the SDK shapes that particular backend expects. The OpenAI adapter materializes content as {"type": "image_url", "image_url": {...}} parts and handles URLs, data URIs, and local file paths. Source: instructor/v2/providers/openai/multimodal.py. The Anthropic adapter emits a tool_use content block with an input payload matching the model's image schema. Source: instructor/v2/providers/anthropic/multimodal.py. The Google GenAI and Mistral adapters follow the same pattern, emitting Part.from_data or the Mistral equivalent. Sources: instructor/v2/providers/genai/multimodal.py and instructor/v2/providers/mistral/multimodal.py.

Cross-Provider Templating

Jinja2-style templating is applied to message content via a per-provider process_message helper, keeping the templating step provider-agnostic at the dispatcher level. OpenAI templates walk message["content"] strings, Anthropic walks list content parts where type == "text", and Cohere walks the V1 message key. Sources: instructor/v2/providers/openai/templating.py, instructor/v2/providers/anthropic/templating.py, and instructor/v2/providers/cohere/templating.py. Cohere's V1 path is a known sharp edge: when users call the instructor client with a Cohere provider, a Jinja2 template context, and an initial message, handle_templating() raises a KeyError because it assumes a chat_history key exists. Source: community issue #2331. Google GenAI and VertexAI templating instead operate on typed Content/Part objects from the google.genai and vertexai.generative_models SDKs. Sources: instructor/v2/providers/genai/templating.py and instructor/v2/providers/vertexai/templating.py.

flowchart LR
    A[User Code] -->|Image, Audio, PDF| B[core/multimodal]
    B -->|autodetect| C{Provider}
    C -->|openai| D[openai/multimodal]
    C -->|anthropic| E[anthropic/multimodal]
    C -->|genai| F[genai/multimodal]
    C -->|mistral| G[mistral/multimodal]
    D --> H[Provider SDK]
    E --> H
    F --> H
    G --> H

Batch Operations & Schema Helpers

While instructor's headline usage is interactive client.create(...) calls, large-scale workloads lean on batch primitives. Batch jobs reuse the same response-model machinery, so schema generation must be stable and cached. The OpenAI schema helper is lru_cache-wrapped with a maxsize=256 and produces a function-calling payload enriched by parsed docstrings via docstring_parser. Source: instructor/v2/providers/openai/schema.py. The Anthropic variant delegates to the OpenAI schema and reshapes the result into Anthropic's {name, description, input_schema} tool form. Source: instructor/v2/providers/anthropic/schema.py.

For Google-family providers, the Gemini utils module exposes a handle_gemini_json helper that converts OpenAI-style messages to Gemini's role/part structure. A regression in earlier versions caused this helper to crash with a KeyError or IndexError when the messages list was empty or absent. Source: community issue #2335. The same module also exposes safety-settings defaults that block only the highest-severity content for hate speech, harassment, and dangerous content. Source: instructor/v2/providers/gemini/utils.py.

Writers, Cohere, and other providers implement MD_JSON and TOOLS mode handlers that prepare requests and parse responses. Cohere's MD_JSON handler appends a JSON schema instruction to either the V2 messages list or the V1 message field, depending on which format the call site used. Source: instructor/v2/providers/cohere/handlers.py.

ProviderTOOLS modeMD_JSON modeJSON_SCHEMA modeMultimodal adapter
OpenAIyesyesyesopenai/multimodal.py
Anthropicyesyesnoanthropic/multimodal.py
Gemini / GenAIyesyesyesgenai/multimodal.py
VertexAIyesyesyesgenai/multimodal.py
Mistralyesyesyesmistral/multimodal.py
Cohereyesyesno(text-only)
Writeryesyesyes(text-only)

CLI & Developer Tooling

The scripts/ directory ships maintenance scripts that keep the documentation and codebase consistent. The README documents five primary utilities. make_clean.py strips non-breaking spaces, zero-width spaces, and em/en dashes from Markdown under docs/, supporting --dry-run and --docs-dir flags. check_blog_excerpts.py verifies every post in docs/blog/posts/ contains an <!-- more --> tag and exits non-zero otherwise. make_sitemap.py calls the OpenAI API to produce a sitemap.yaml with summary, keywords, topics, references, and a content hash for caching, with configurable concurrency and similarity thresholds. fix_api_calls.py rewrites the old client.chat.completions.create(...) style to the simplified client.create(...) form, and fix_old_patterns.py performs similar legacy cleanups. Source: scripts/README.md.

In addition to maintenance scripts, instructor exposes a CLI that includes a --full-id flag added in v1.15.0 to show complete batch IDs rather than truncated ones. Source: release notes for v1.15.0. A separate fastapi-code-generator example in examples/codegen-from-schema/ shows how to wire schema files and Jinja2 prompt templates into a generated FastAPI service and Pydantic models.py. Source: examples/codegen-from-schema/readme.md.

Security Posture

The v1.15.1 release tightened the multimodal pipeline against Server-Side Request Forgery (SSRF) and unintended local-file disclosure. The Bedrock adapter's _openai_image_part_to_bedrock now rejects remote http:// and https:// image URLs and only accepts data: URIs. The PDF path is similarly hardened: PDF.to_bedrock refuses both remote URLs and local file paths, accepting only base64-encoded payloads or s3:// sources. Source: release notes for v1.15.1.

These mitigations matter because multimodal inputs are user-controlled in most real applications, and a permissive URL fetch would let an attacker pivot through the LLM provider's egress to internal services. Limiting inputs to data: and s3:// sources keeps the trust boundary aligned with what the user actually placed in the payload. The release also exposes attempt metadata (such as attempt_number) on the completion:error and completion:last_attempt hooks so observability tooling can distinguish intermediate retries from terminal failures, as requested in community issue #2222. A separate community proposal (issue #2334) has asked for OWASP Agent Memory Guard integration to guard against memory-poisoning attacks via accumulated retry context, which would extend the security story beyond input validation to state management.

See Also

  • Providers & Modes — how modes like TOOLS, MD_JSON, and JSON_SCHEMA are dispatched per provider
  • Streaming & Partial — Partial models, JsonCompleteness tracking, and self-referential model handling
  • Hooks & Retry — completion:error and completion:last_attempt event metadata
  • Validation & Reask — Pydantic-style reask loop and llm_validator examples

Source: https://github.com/567-labs/instructor / Human Manual

Doramagic Pitfall Log

Source-linked risks stay visible on the manual page so the preview does not read like a recommendation.

high Installation risk requires verification

May increase setup, validation, or first-run risk for the user.

high Installation risk requires verification

May increase setup, validation, or first-run risk for the user.

medium Configuration risk requires verification

May increase setup, validation, or first-run risk for the user.

medium Capability evidence risk requires verification

May increase setup, validation, or first-run risk for the user.

Doramagic Pitfall Log

Found 12 structured pitfall item(s), including 2 high/blocking item(s). Top priority: Installation risk - Installation risk requires verification.

1. Installation risk: Installation risk requires verification

  • Severity: high
  • Finding: Project evidence flags a installation risk. Review the linked source before relying on this workflow.
  • User impact: May increase setup, validation, or first-run risk for the user.
  • Recommended check: Reproduce the official install and quickstart path in an isolated environment.
  • Evidence: community_evidence:github | https://github.com/567-labs/instructor/issues/2222

2. Installation risk: Installation risk requires verification

  • Severity: high
  • Finding: Project evidence flags a installation risk. Review the linked source before relying on this workflow.
  • User impact: May increase setup, validation, or first-run risk for the user.
  • Recommended check: Reproduce the official install and quickstart path in an isolated environment.
  • Evidence: community_evidence:github | https://github.com/567-labs/instructor/issues/2288

3. Configuration risk: Configuration risk requires verification

  • Severity: medium
  • Finding: Project evidence flags a configuration risk. Review the linked source before relying on this workflow.
  • User impact: May increase setup, validation, or first-run risk for the user.
  • Recommended check: Reproduce the official install and quickstart path in an isolated environment.
  • Evidence: community_evidence:github | https://github.com/567-labs/instructor/issues/2335

4. Capability evidence risk: Capability evidence risk requires verification

  • Severity: medium
  • Finding: README/documentation is current enough for a first validation pass.
  • User impact: May increase setup, validation, or first-run risk for the user.
  • Recommended check: Reproduce the official install and quickstart path in an isolated environment.
  • Evidence: capability.assumptions | github_repo:653589102 | https://github.com/567-labs/instructor

5. Runtime risk: Runtime risk requires verification

  • Severity: medium
  • Finding: Project evidence flags a runtime risk. Review the linked source before relying on this workflow.
  • User impact: May increase setup, validation, or first-run risk for the user.
  • Recommended check: Reproduce the official install and quickstart path in an isolated environment.
  • Evidence: community_evidence:github | https://github.com/567-labs/instructor/issues/2331

6. Runtime risk: Runtime risk requires verification

  • Severity: medium
  • Finding: Project evidence flags a runtime risk. Review the linked source before relying on this workflow.
  • User impact: May increase setup, validation, or first-run risk for the user.
  • Recommended check: Reproduce the official install and quickstart path in an isolated environment.
  • Evidence: community_evidence:github | https://github.com/567-labs/instructor/issues/2344

7. Maintenance risk: Maintenance risk requires verification

  • Severity: medium
  • Finding: Project evidence flags a maintenance risk. Review the linked source before relying on this workflow.
  • User impact: May increase setup, validation, or first-run risk for the user.
  • Recommended check: Reproduce the official install and quickstart path in an isolated environment.
  • Evidence: evidence.maintainer_signals | github_repo:653589102 | https://github.com/567-labs/instructor

8. Security or permission risk: Security or permission risk requires verification

  • Severity: medium
  • Finding: no_demo
  • User impact: May increase setup, validation, or first-run risk for the user.
  • Recommended check: Reproduce the official install and quickstart path in an isolated environment.
  • Evidence: downstream_validation.risk_items | github_repo:653589102 | https://github.com/567-labs/instructor

9. Security or permission risk: Security or permission risk requires verification

  • Severity: medium
  • Finding: no_demo
  • User impact: May increase setup, validation, or first-run risk for the user.
  • Recommended check: Reproduce the official install and quickstart path in an isolated environment.
  • Evidence: risks.scoring_risks | github_repo:653589102 | https://github.com/567-labs/instructor

10. Security or permission risk: Security or permission risk requires verification

  • Severity: medium
  • Finding: Project evidence flags a security or permission risk. Review the linked source before relying on this workflow.
  • User impact: May increase setup, validation, or first-run risk for the user.
  • Recommended check: Reproduce the official install and quickstart path in an isolated environment.
  • Evidence: community_evidence:github | https://github.com/567-labs/instructor/issues/2334

11. Maintenance risk: Maintenance risk requires verification

  • Severity: low
  • Finding: issue_or_pr_quality=unknown。
  • User impact: May increase setup, validation, or first-run risk for the user.
  • Recommended check: Reproduce the official install and quickstart path in an isolated environment.
  • Evidence: evidence.maintainer_signals | github_repo:653589102 | https://github.com/567-labs/instructor

12. Maintenance risk: Maintenance risk requires verification

  • Severity: low
  • Finding: release_recency=unknown。
  • User impact: May increase setup, validation, or first-run risk for the user.
  • Recommended check: Reproduce the official install and quickstart path in an isolated environment.
  • Evidence: evidence.maintainer_signals | github_repo:653589102 | https://github.com/567-labs/instructor

Source: Doramagic discovery, validation, and Project Pack records

Community Discussion Evidence

These external discussion links are review inputs, not standalone proof that the project is production-ready.

Sources 12

Count of project-level external discussion links exposed on this manual page.

Use Review before install

Open the linked issues or discussions before treating the pack as ready for your environment.

Community Discussion Evidence

Doramagic exposes project-level community discussion separately from official documentation. Review these links before using instructor with real data or production workflows.

Source: Project Pack community evidence and pitfall evidence