Skip to main content
Structured output backends ensure reliable data extraction from LLM responses. Cognee supports three frameworks that convert LLM text into structured Pydantic models for knowledge graph extraction and other tasks.
New to configuration?See the Setup Configuration Overview for the complete workflow:install extras → create .env → choose providers → handle pruning.

Supported Frameworks

Cognee supports three structured output approaches:
  • LiteLLM + Instructor — Provider-agnostic client with Pydantic coercion (default)
  • BAML — DSL-based framework with type registry and guardrails
  • LiteLLM Native — Validates responses into Pydantic models using LiteLLM’s own response_format, without the instructor dependency (opt-in)
All three frameworks produce the same Pydantic-validated outputs, so your application code remains unchanged regardless of which backend you choose.

How It Works

Cognee uses a unified interface that abstracts the underlying framework:
The STRUCTURED_OUTPUT_FRAMEWORK environment variable determines which backend processes your requests, but the API remains identical.

Configuration

The default framework — no extra install needed. Uses LiteLLM and the instructor library to coerce LLM responses into Pydantic models.
Optionally, control how the model is prompted for structured output:

Instructor Modes

When STRUCTURED_OUTPUT_FRAMEWORK=instructor, the instructor mode controls how Cognee asks the model for structured output — for example via the model’s native JSON-schema response, a plain JSON object, or a tool/function call. The value of LLM_INSTRUCTOR_MODE is passed directly to the instructor library’s Mode, so it must be one of instructor’s supported mode strings. LLM_INSTRUCTOR_MODE is empty by default. When it is unset, Cognee either applies a provider-specific mode or defers to the underlying Instructor/LiteLLM default, so in most cases you don’t need to set it at all: Common values you can set explicitly include json_schema_mode, json_mode, tool_call, and markdown_json_mode.
Which mode for OpenAI models (e.g. gpt-5-mini)? Leave LLM_INSTRUCTOR_MODE unset, or set json_schema_mode — Cognee applies json_schema_mode to gpt-5 models, and it is the recommended mode for OpenAI models that support native JSON-schema responses. Only override it when you point Cognee at a custom or local OpenAI-compatible endpoint that rejects JSON-schema responses; in that case try json_mode first, then markdown_json_mode or tool_call.

Setting Structured Output in a Script

You don’t have to use .env — the same settings can be configured directly in Python. Both the framework and the instructor mode are attributes on the internal LLMConfig.
Pass the exact attribute names (structured_output_framework, llm_instructor_mode) to cognee.config.set_llm_config():
Switching to BAML at runtime via set_llm_config() does not initialize BAML’s client registry, which is built when the config is first constructed. To use BAML, set STRUCTURED_OUTPUT_FRAMEWORK=baml (and the BAML_LLM_* variables) in .env or via os.environ before importing cognee.

Important Notes

  • Unified Interface: Your application code uses the same acreate_structured_output() call regardless of framework
  • Provider Flexibility: LiteLLM + Instructor and LiteLLM Native reuse the standard LLM_* provider settings; BAML uses its own BAML_LLM_* block
  • Output Consistency: All three produce Pydantic-validated results
  • Performance: Framework choice doesn’t significantly impact performance

Troubleshooting

This error appears during recall() / search() with completion search types such as GRAPH_COMPLETION, GRAPH_SUMMARY_COMPLETION, GRAPH_COMPLETION_COT, and RAG_COMPLETION.Cause. These search types ask the LLM for a plain-text answer (the retriever uses response_model=str). When the configured instructor mode doesn’t match what your model/provider actually supports, the model wraps its answer in a JSON object instead of returning plain text. The instructor backend then can’t coerce that dict into the expected string field, so Pydantic raises Input should be a valid string ... input_type=dict. This is common with OpenAI-compatible, custom, and local (Ollama / LM Studio) endpoints.Fixes:
  • Align the instructor mode with your provider. OpenAI/Azure gpt-4o/gpt-5 models work with the default json_schema_mode. Endpoints that don’t support JSON-schema responses usually need a different mode:
  • Switch to BAML if a small/local model keeps wrapping answers in JSON. BAML bypasses instructor’s coercion and is more forgiving of loose model output:
  • Skip the LLM completion step to confirm retrieval works independently of model output formatting. Pass only_context=True to return the retrieved context directly — see Search Basics. If retrieval succeeds with only_context=True, the problem is the structured-output configuration above, not your graph.
This error is raised from GeminiAdapter.acreate_structured_output during recall() / search() with completion search types (GRAPH_COMPLETION, RAG_COMPLETION, etc.).Cause. These search types request a plain-text answer with response_model=str. Gemini’s default instructor mode is json_mode, which handles str correctly. If you override LLM_INSTRUCTOR_MODE with a schema- or tool-based mode (json_schema_mode, tool_call, mistral_tools, …), Instructor tries to call str.model_json_schema() — a method that only exists on Pydantic models — and crashes.Fix — force json_mode for Gemini. Either leave LLM_INSTRUCTOR_MODE unset so Gemini falls back to its json_mode default, or set it explicitly:
To set it in-script, pass it through set_llm_configllm_instructor_mode is a valid key on the LLM config:
cognee.config.set("llm_instructor_mode", "json_mode") raises InvalidConfigAttributeError: 'llm_instructor_mode' is not a valid attribute of the configuration — the generic config.set() only accepts a fixed set of keys. Use cognee.config.set_llm_config({...}) (or the LLM_INSTRUCTOR_MODE env var) instead.
See LLM Instructor Modes for the full list of modes and per-provider defaults.
This error is raised with STRUCTURED_OUTPUT_FRAMEWORK=baml while BAML builds a dynamic type for a response model that has a PEP 604 optional field (X | None). In practice it surfaces during recall() / search() with completion search types such as GRAPH_COMPLETION, because the completion response model contains str | None fields — so recall fails on local/Ollama + BAML setups.Cause. BAML’s dynamic type builder previously recognized only typing.Union / typing.Optional. PEP 604 unions written as X | None have a different origin (types.UnionType), so they missed the Optional/Union branch and fell through to the unsupported-type error. typing.Optional[str] worked; the equivalent str | None did not.Fix. Upgrade Cognee — BAML now maps PEP 604 X | None unions the same way it maps typing.Optional, so optional fields work with either syntax. No configuration change is required.

LLM Providers

Configure LLM providers for text generation

Overview

Return to setup configuration overview

Custom Prompts

Learn about custom prompt configuration