Skip to main content

Overview

Content types define the categories of documents your system processes and how the AI should classify and extract information from them. Each content type includes instructions for the AI on what entities and relationships to look for. Navigate to Admin > Model & Define > Artifact Types.

Viewing Content Types

The content types page lists all configured types with:
  • Content type name
  • Number of entity types associated
  • Number of relationship types associated
  • Compatibility status — valid, stale, invalid, or pending review against the current ontology revision (see Ontology Compatibility)
  • Created and last modified dates

Creating a Content Type

Click Add Artifact Type to open the editor on a new content type. Creating and editing use the same editor; the older form editor, and its New Editor toggle, have been removed. Switch between its Multiple View, Json and Canvas views in the header. The Multiple View has two tabs:
  1. Basic Information — the Name, a descriptive name for the document category (e.g., “Contracts”, “Proposals”, “Meeting Notes”); a Description; the Classification Instructions, guidance for the AI on how to identify documents of this type; and the Ingestion extraction settings (below)
  2. Entities & Relationships — which entity types to extract from these documents, with their attributes, and which relationships to identify between them
To get a first draft instead of an empty editor, ask the copilot from the editor: attach a few sample documents and it proposes the details, entity types, attributes and relationships as a card that you apply and save yourself.

Ingestion extraction policy

On the Basic Information tab, the Ingestion extraction section controls how deeply ingestion uses LLMs for this content type:
  • Default mode — full, metadata_and_snippet, or metadata_only
  • Primary model tier — large, medium, or small for primary extraction
  • Validation pass — optional secondary LLM pass (off by default for metadata-only Excel)
  • Excel overrides — separate mode for spreadsheets
See Extraction Policy for mode behavior, system limits, and filter overrides.

Entity and relationship attributes

Entity attributes are chosen from the ontology per entity type. You select which attributes apply, edit extraction instructions (defaults come from the ontology unless you override them), and set whether an attribute is required. Relationship attributes follow the same idea:
  • Attributes available on a relationship come from the ontology definition for that triple (source entity type, relationship type, target entity type).
  • You pick attributes from a dropdown — you do not type arbitrary names; types come from the ontology (shown read-only).
  • Extraction instructions default from the ontology and can be overridden per content type for document-specific wording.
Relationship attributes are included in extraction prompts so the model can fill an attributes object on each extracted edge when the document supports values. See also: Relationship attributes (architecture). To preview which ontology nodes, relationships, and attributes a content type uses, open Ontology and select that type from the toolbar dropdown. Unused nodes and relationships are hidden; unused attributes are greyed out. That filter is view-only and does not change the content type or the ontology.

Test Ingestion

Test Ingestion (dry run): try a file before you ingest. To test an ingestion by uploading a file, open Admin > Model & Define > Artifact Types and click Test Ingestion at the top right of the list, to the left of Add Artifact Type. Test Ingestion is a button on the list, not on a single artifact type. A window titled Test Ingestion (Dry Run) opens: upload a file there and it shows how Experio classifies the file and which entities and relationships it extracts. A test writes nothing to the knowledge graph, so you can try as many files as you like before you ingest real data. The short version has a page of its own: Test Ingestion. Everyone who can open the list sees the button. Running a test needs write access to Graph Managers (a super-admin account has it too); with read access only, the run is refused.
  1. Click Test Ingestion at the top right of the list.
  2. Choose the Mode:
    • Classify & extract — full processing: classification, then entity extraction
    • Only classify — test classification without extraction
    • Only extract — test entity extraction for one artifact type, without classification
  3. Under Allowed Content Types, tick the artifact types the file may be classified as. Only extract needs exactly one.
  4. Optionally set Max Pages, the number of pages used to classify the file (empty: 3 pages; -1: the whole document).
  5. Choose the file and click Run Test. Cancel stops a run.
  6. Review the results:

Test Results

The test results display:
  • Classification Scores — Confidence scores for each content type, with the selected type highlighted
  • Entities Table — Extracted entities showing Type, Name, and Attributes
  • Relationships Table — Extracted relationships showing Source, Type, Target, and Attributes (key/value pairs returned by extraction when present)
  • Raw JSON — Full raw output for debugging
A sample that is a zip inside is refused unread if it expands to more than 200 MB when unzipped, whatever its extension: a Word, PowerPoint or Excel file (.docx, .pptx, .xlsx, .xlsm) is one, and so is a zip under any other name. The test then fails with the file expands to … MB when unzipped, more than the 200 MB limit. The fallback parser is never given a sample with a single part over 100 MB either, whether it runs after the main parser or first (one part of the file expands to …). A sample that passes is read first on the API server, outside the server’s own process, with no OCR: by the main parser, then by the fallback parser if the main one reads nothing. Each runs in a child process the server watches (the main parser runs on Kreuzberg’s own server instead when KREUZBERG_MODE is api). A picture (.png, .jpg, .tif and the other image formats) is the exception: only OCR can read one, so it is read by OCR in the same kind of child process, whatever its size, and it is never handed to the background parser (which reads without OCR and would find no words in it). Because nothing else can read it, its child process may use at least 1,024 MB and 300 seconds, more than the limits below, and a picture that needs more fails with this file is too large to read here. A sample the API server should not read, or cannot read, goes to the background parser instead of failing:
  • A file over ASYNC_PARSE_PRECHECK_MAX_FILE_MB (1 MB by default), or a spreadsheet over ASYNC_PARSE_PRECHECK_MAX_SPREADSHEET_MB (0 by default, so every spreadsheet), is not read on the server at all (a picture, above, is never judged by its size).
  • A reading in a child process is stopped, and its file handed over, when it needs more memory than UPLOAD_EXTRACTION_MAX_MEMORY_MB (512 MB by default), takes longer than UPLOAD_EXTRACTION_TIMEOUT_SECONDS (60 seconds by default, for each of the two parsers), or finds the server’s container or machine with less than 768 MB of memory left.
  • A PDF whose pages are pictures (fewer than 60 letters and digits a page on average) is a scan. The background parser reads it by OCR, without asking.
While the background parser has the sample, the Run Test button reads Waiting for the parser…, and a line under the buttons says where the file is: queued for the parser (which reads large files and scans in the background and can take a few minutes), being read, queued for OCR, or being read with OCR. Click Cancel, or close the window, to stop the test: the file the parser was reading for it is cancelled too. The test waits as long as the server does, up to the queue wait plus the parser’s reading and OCR limits (about two hours with the default settings), and then fails with The parser did not finish reading this file within N minutes. Try again later, or test with a smaller file. A sample counts against the limit on background files that every person has (ASYNC_PARSE_MAX_QUEUED_PER_USER, 10 by default). Over it, the test fails with N of your files are already waiting to be read (at most 10 at a time); wait for some of them to finish (Jobs list), then run the test again. The run shows in Jobs & Monitoring as an Async parse job whose source is Test ingestion. A picture that needs more memory or time than the limits above still fails with this file is too large to read here … or reading this file took too long …, and a zip that expands too far is refused, as above. After a reading on the server is stopped, no other parser on the server tries the sample. Only the first 10,000,000 characters of a sample’s text are kept for the test.
Run test ingestion with representative documents before activating a content type in production. This helps fine-tune classification instructions and entity extraction rules.

Editing Content Types

Click any content type to open its editor. Changes to a content type affect how future documents are processed — previously processed documents are not retroactively re-processed. The editor shows a compatibility panel when this type drifted from the ontology. Fix the entities, attributes, or relationships so they match the current schema, then Re-validate. After an ontology rename that already looks correct, Mark as reviewed returns the type to valid. You can also ask the copilot to do either (see Asking the copilot). In the editor, a Save re-validates the type for you when its status was not valid before the Save (invalid, stale or pending review): a fix stops blocking scans as soon as it is saved, and a type the fix did not repair shows its issues again. A Save of a valid type is not re-checked.
An invalid content type blocks scans for every data source that uses it. Stale types warn in the admin UI but do not block ingestion.
The admin sidebar labels this page Artifact Types; this guide uses Content Types for the same feature.

Asking the copilot

The Admin Copilot has a page pack for these pages. Open it with the Copilot button or ⌘J. It knows the saved ontology, the other content types and the files you attach in the chat, and it can check what ingestion wrote to the graph (see The knowledge-model copilot). For a saved content type it is also given the issue codes behind its status, from the last check against the saved ontology (for example ATTRIBUTE_NOT_IN_ONTOLOGY StatusReport.percent_x), and is told to explain an invalid or stale status only from those codes or its own check, never from a guess. In the editor it reads the content type as drawn, including your unsaved edits, and it can propose changes to it as a card:
  • Details: the description and the classification instructions. On the create page it can also set the name: the new content type isn’t saved yet, so the copilot sets the name you ask for like any other detail (Save’s own check still refuses a name another content type has).
  • Entity types: add one, change its processing type, whether it attaches the document, or its description, or remove it. Removing one also removes the relationships that touch it, unless another entity type on the content type has the same name (see below). Whether an entity type attaches the document decides what the Ingested list of the parsed-document picker holds (see The picker).
  • Attributes: add one, change its extraction instructions or whether it is required, or remove it.
  • Relationships: add, change or remove one.
It never renames anything else: names come from the ontology, and a saved content type keeps its name. It never changes the extraction policy, never runs Test Ingestion and never generates embeddings (you do those on the page), and it never saves or creates a content type. It can tell you where Test Ingestion is (the button at the top right of the list) and take you there. To re-validate, mark reviewed or delete a saved one, it makes a page-action card that you confirm (see Re-validating, reviewing and deleting a content type). Everything it adds must already be in the saved ontology. When something is missing, it proposes the ontology change first; you apply it and click Save on the Ontology page, and then it proposes the content-type change. An edit can only change an entity type or attribute the content type already extracts. When the copilot tries to change one the content type doesn’t extract yet but the saved ontology defines (for example industry on Project), the server refuses it with the fix, an add in the ontology’s spelling carrying the instructions the copilot wrote, and the copilot sends that in the same turn. One the saved ontology doesn’t define either is refused without that fix.

What the server checks first

Every card is checked on the server before you see it. A proposal that fails goes back to the copilot to fix, with every problem at once (the size cap, the checks below, and the ontology change it needs first when there is one), so a large change doesn’t use up its retries one problem at a time:
  • Classification instructions must be plain sentences, never JSON. When the editor loads a content type whose instructions are JSON, it reads them as a set of instructions for the whole type and can replace the entity list with what it finds there. JSON behind an invisible character, such as a byte-order mark, counts too: the editor ignores the character.
  • At most one entity type may attach the document, and it has to be Create Only. Create or Match and Match Only cannot attach. The Ingested list in the parsed-document picker depends on it: a file is listed there only when its content type has an entity type that attaches the document (see The Ingested list is empty after an ingestion).
  • The name, description and classification instructions can’t be empty, and names can’t repeat.
  • A name two rows share is ambiguous. An older content type can hold two entity types with the same name (ignoring case), or two attributes of one entity type with the same name. A card that names such a row is refused, because the name doesn’t say which one. The refusal lists each copy’s id: for an entity type, with how many attributes it has and how many of them have extraction instructions; for an attribute, with the start of its instructions. The copilot is told to remove one copy by its id, the one that holds none of your instructions, or to ask you which to keep. Removing one copy keeps the other, and the relationships that name it, and the card says which copy it removes (Remove the copy of entity “StatusReport” with id …; the other “StatusReport” stays). The first such refusal spends no retry when the duplicate was already there and it is the card’s only problem.
  • The result must pass Save’s own checks against the saved ontology.
  • A card must change something. A card whose result is the content type as it already is (each edit sets a value it already has, or one edit undoes another) is refused. The copilot is told there is nothing to apply, to tell you so if you asked for exactly that, and never to propose some other change in its place.
  • A change that would put the content type out of step with the saved ontology is refused, and the copilot is pointed to the ontology change it needs first.
  • A removal Save would undo is refused. Save puts back the required-upstream chain of an entity type that matches by similarity (its required upstream parent, that parent’s, and so on, until the walk reaches an entity type listed on the content type before the one it started from), whatever the processing type of the entity types in between, and every attribute that an entity type’s vector index reads (see Save will also add), with the ontology’s default instructions instead of yours. The copilot is told why, with each chain that pulls the parent in. To remove a parent, each entity type the refusal names as pulling it in must stop matching by similarity in the same card; the others need no change. To remove an attribute that a vector index reads, the ontology’s vector index has to change first.
A problem the content type already had does not block the card. The card lists it separately and says the change neither causes nor fixes it. The exception is a problem the checks above count as an error: one Save refuses (such as empty classification instructions), JSON-shaped classification instructions, or a name two rows share. It blocks every card until a card fixes it (for a shared name, by removing one copy by its id). The copilot is told about it without spending a retry, and puts the fix in the same card. When every other problem was already there, a name another saved content type already has is still named, and spends a retry, if the change causes it. A new warning, such as a relationship whose end is not one of the entity types or an attribute with no extraction instructions, needs your acknowledgement before Apply.

Save will also add

When you click Save, the server adds what the ontology requires on top of what you drew: the required upstream parent entity types of an entity that matches by similarity, and their parents up the chain (the walk stops at an entity type listed before the one it started from), with their relationships, and the attributes its vector index reads. The card lists these under Save will also add, so they are not a surprise after you save. The copilot can also tell you what Save will add to the content type as it is now.

Applying a card

The copilot makes one card per content type per turn. A card holds the whole content type as it would be after the change, made from the editor as it was when you asked. A second card made from the same editor would undo the first when applied after it. A big change comes as one card, up to the edits one card carries (150 by default); only a larger one comes over several turns, the next part once you have applied (and saved) the one before. See Big changes.
  • Apply puts the proposed details, entity types and relationships into the editor. Nothing is saved until you click Save.
  • Apply replaces the details, entity types and relationships with the card’s version. If the editor no longer holds what the card was made from — you edited or saved since, another card was applied, or the page was reloaded onto a changed content type — Apply asks first, because those newer changes would be replaced too. A card made from exactly what the editor holds applies straight away, even after you left the page and came back. The exception is an older content type whose entity types are stored only in its classification instructions: until its first Save in the editor, every card from an earlier visit asks first.
  • Undo on the card puts back what was there before, until you edit on top of the applied change.
  • A card made for another content type can’t be applied here. A card the copilot made for it from another page has an Open link to that content type’s editor.

Cards for another content type

The copilot can change a content type without its editor being open. On the list page, in another content type’s editor, on the Ontology page, and on the Taxonomies, Data Mapping, Enrichment Rules and Matching Strategies pages, it checks the content type you name as saved and makes a card for it:
  • The card reads Made for “SOW” (Artifact Types) and has an Open “SOW” link. The link opens that content type in its editor, with the card ready to apply there.
  • You apply it in the editor and click Save. It was checked against the content type as saved, so it is refused once that content type has been saved again since (This artifact type was saved since this was proposed — ask the copilot again). Any Save counts, even one that only moved things on the canvas. If the editor has unsaved edits, Apply asks first, because the card replaces them.
  • It passes the same server checks as a card made in the editor, against the saved content type and the saved ontology.
From every one of these pages it can also check a saved content type and tell you what Save will add to it. See Knowledge-model pages share their tools. Reading and checking need the Graph Managers role (read); proposing needs write access too.

Re-validating, reviewing and deleting a content type

Ask the copilot to re-validate a content type, mark it reviewed or delete it, and it makes a page-action card for the Artifact Types list, from the editor or from any knowledge-model page. The copilot never does it: Apply on the list opens a confirmation, and only your own click on its confirm button performs the action, under your account (see Page-action cards). It needs Graph Managers write access. Cancel leaves the card open, and once you confirm, the card reads Saved.
  • Re-validate is offered when the status is not valid. The confirmation shows what the check finds now against the saved ontology: that the type becomes valid and ingestion can use it again, how many issues remain (with the first one), or that it stays stale. A content type that a re-check would leave as it is, with the same status and issues, gets no card: fix it first.
  • Mark reviewed is offered when the status is stale or pending review and the ontology has a saved revision. It is the panel’s own Mark as reviewed: it re-runs the same check and saves the result.
  • Delete is destructive. The confirmation lists what goes with the content type, counted when the card was made: the matching strategies bound to it. The data sources and data-source filters that list it only lose it and stay. It names those data sources, filters and strategies only to someone who can read them (Data Source Managers for the first two, Process Managers for strategies); everyone else gets the counts and a line saying why they are not named. Nothing in the graph is removed: what was ingested as this type stays.
  • The card is refused if the content type was saved or its status changed since it was made, and, for a review card, if the ontology was saved since.