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 Native — Validates responses into Pydantic models using LiteLLM’s own
response_format, without theinstructordependency (default) - LiteLLM + Instructor — Provider-agnostic client with Pydantic coercion (opt-in)
- BAML — DSL-based framework with type registry and guardrails (opt-in)
How It Works
Cognee uses a unified interface that abstracts the underlying framework:STRUCTURED_OUTPUT_FRAMEWORK environment variable determines which backend processes your requests, but the API remains identical. It defaults to litellm_native, so instructor is no longer in the default call path — set the variable explicitly to opt back into instructor or into baml.
Configuration
- LiteLLM + Instructor
- BAML
- LiteLLM Native (Default)
An opt-in framework — no extra install needed, but you must select it explicitly since the default is Optionally, control how the model is prompted for structured output:
litellm_native. Uses LiteLLM and the instructor library to coerce LLM responses into Pydantic models.Instructor Modes
WhenSTRUCTURED_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.
Ollama’s default is json_schema_mode — it was json_mode in earlier Cognee versions. Ollama 0.5+ enforces the Pydantic schema as a decoder constraint instead of only being asked for “some JSON”, so local models fail first-attempt validation (and trigger InstructorRetryException) far less often. On an Ollama older than 0.5, which has no JSON-schema enforcement, set LLM_INSTRUCTOR_MODE=json_mode to restore the previous behavior.
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.
- set_llm_config
- os.environ
Pass the exact attribute names (
structured_output_framework, llm_instructor_mode) to cognee.config.set_llm_config():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 ownBAML_LLM_*block - Output Consistency: All three produce Pydantic-validated results
- Performance: Framework choice doesn’t significantly impact performance
Troubleshooting
1 validation error for Response: content Input should be a valid string ... input_type=dict
1 validation error for Response: content Input should be a valid string ... input_type=dict
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-5models work with the defaultjson_schema_mode, and so does Ollama 0.5+, which now defaults to it as well. Endpoints that don’t support JSON-schema responses — including an Ollama older than 0.5 — 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=Trueto get back the LLM input rather than a generated answer — see Search Basics. If retrieval succeeds withonly_context=True, the problem is the structured-output configuration above, not your graph.
1 validation error for SummarizedContent: description Input should be a valid string ... input_type=list
1 validation error for SummarizedContent: description Input should be a valid string ... input_type=list
This error appeared during
cognify() (chunk summarization) on small local models — Ollama and llama.cpp setups were the usual reporters.Cause. SummarizedContent has two fields: summary, which Cognee actually consumes, and description, which is unused and kept only for backwards compatibility. Both are still part of the JSON Schema handed to the model, so a model is free to fill description — and smaller models routinely answered it with a list of bullets instead of a string. Strict validation then failed the whole structured-output call, the retries exhausted, and an entire cognify() run died on a field nothing reads.Fix. Upgrade Cognee — description now coerces whatever the model returns instead of rejecting it: None becomes "", a list or tuple is joined with newlines, and anything else is stringified. summary, the field that is actually consumed, keeps strict validation, so a model that fails to produce a usable summary still surfaces as an error. This is a model-level change, so it applies to every structured-output backend; no configuration change is required.AttributeError: type object 'str' has no attribute 'model_json_schema' (Gemini)
AttributeError: type object 'str' has no attribute 'model_json_schema' (Gemini)
This error is raised from To set it in-script, pass it through See LLM Instructor Modes for the full list of modes and per-provider defaults.
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:set_llm_config — llm_instructor_mode is a valid key on the LLM config:ValueError: Unsupported type for BAML mapping: str | None
ValueError: Unsupported type for BAML mapping: str | None
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.Invalid JSON: expected value at line 1 column 1 (litellm_native)
Invalid JSON: expected value at line 1 column 1 (litellm_native)
This error is raised with Cause. The model wrapped otherwise-valid JSON in a markdown code fence. Pydantic’s
STRUCTURED_OUTPUT_FRAMEWORK=litellm_native on the JSON-object fallback path — the path every provider without native schema support lands on (Ollama, llama.cpp, custom OpenAI-compatible endpoints, and any model LiteLLM does not report as schema-capable). It shows up during cognify() for response models such as SummarizedContent or KnowledgeGraph:model_validate_json() sees a backtick at column 1 and rejects the whole reply. The self-correction retry could not rescue it either — a model that fences once fences again — so all three attempts were spent and the run failed.Fix. Upgrade Cognee — the fallback path now strips a code fence that wraps the entire reply before validating, and leaves backticks inside JSON values alone. No configuration change is required.