Docling-Pipelines über HTTP steuern: Von der Projekt-Einrichtung bis zu indizierten Blöcken
Schritt für Schritt durch die Docling Pipelines REST API: Starten Sie den Server, entdecken Sie Operatoren, validieren und führen Sie eine Ingestion-DAG aus sowie lesen Sie die Ausführungstelemetrie dazu.
Quellen: **A Hands-On Guide to the Docling Pipelines REST API**
Um eine Ordnerstruktur mit PDF- und Word-Dateien in suchbare Vektorblöcke umzuwandeln, wird in der Regel Code zur Extraktion, Aufteilung in Blöcke, Einbettung und Indizierung benötigt. Docling Pipelines bündelt diese Schritte als Operatoren hinter einem auf FastAPI basierenden REST-Server, sodass jeder Client – wie beispielsweise eine Node.js-Dienstplattform oder eine Admin-Oberfläche – modulare DAG-Pipelines erstellen, validieren und über HTTP asynchrone Ausführungen auslösen kann. Diese Anleitung startet den Server mit Ollama und OpenSearch und verfolgt einen vollständigen Anfragelebenszyklus, von der Erstellung eines Projekts bis hin zum Abrufen von Ausführungsstatistiken pro Knoten.
Vorbereitung der Hintergrunddienste
Der Server koordiniert die Arbeiten, doch Einbettungen und Speicherung finden an anderer Stelle statt: Hier kommt Ollama für die Modelle und OpenSearch als Vektordatenspeicher zum Einsatz. Starten Sie diese zuerst.
Der schnellste Weg ist das QUICKSTART.md des Projekts, das in wenigen Minuten Ollama, eine Vektordatenbank sowie die erforderlichen Container skriptet. Ein KI-Codeagent wie Cursor, Claude Code oder Copilot kann die Einrichtung und Überprüfung ebenfalls übernehmen; in jedem Fall sollten Sie sicherstellen, dass jede Dienstleistung reagiert.
Wahl der Vektordatenbank
Das ist eine architektonische Entscheidung. OpenSearch eignet sich, wenn Sie eine hybride Suche wünschen, bei der Schlüsselwortabgleich mit dichten Vektoren kombiniert wird. Milvus ist für dedizierte, hochskalierbare Infrastrukturen bei sehr großen Vektorkollektionen geeignet. In dieser Anleitung wird OpenSearch verwendet.
Start des API-Servers
Aktivieren Sie die virtuelle Umgebung, in der das Paket installiert ist, und führen Sie den mitgelieferten Befehl aus:
source .venv/bin/activate
docling-pipelines-api
Für das Hot-Reloading während der Entwicklung sollten Sie die Anwendung direkt über uvicorn ausführen, wobei sie auf allen Interfaces an Port 8080 verfügbar sein muss:
uvicorn docpipe.api.main:app --reload --host 0.0.0.0 --port 8080
Dann stehen vier URLs zur Verfügung:
http://localhost:8080/healthfür Health-Checks;http://localhost:8080/api/v1/docsfür die interaktive Swagger UI;http://localhost:8080/api/v1/redocfür die ReDoc-Dokumentation;http://localhost:8080/api/v1/openapi.jsonfür das rohe OpenAPI-Schema.
Mit TypeScript können Sie die OpenAPI-Dokumentation an einen Client-Generator übergeben, anstatt die Anfragetypen manuell zu schreiben.
Umgebungsvariablen, die den Server beeinflussen
Setzen Sie diese vor dem Start, um das Verhalten anzupassen:
DS_LOG_LEVELlegt die Ausführlichkeit der Protokollierung fest. Standardmäßig ist esINFO, wobei auchDEBUG,INFO,WARNINGoderERRORmöglich sind.DOCPIPE_STORAGE_BACKENDbestimmt, wo die Metadaten gespeichert werden:duckdb(Standard, lokal) oderpostgres.CORS_ORIGINSlistet die Originen auf, die von einer Browser-Oberfläche aus die API aufrufen dürfen. Standardmäßig ist eshttp://localhost:3000.OLLAMA_HOSTweist die Embedding- und LLM-Operatoren auf Ollama hin. Der Standardwert isthttp://localhost:11434; ändern Sie ihn, falls Ollama auf einem anderen Port oder einer anderen Maschine läuft.
Erkunden von Endpunkten in der Swagger UI
Öffnen Sie http://localhost:8080/api/v1/docs in einem Browser; ein lokaler Anmeldevorgang ist nicht erforderlich. Erweitern Sie einen Endpunkt, klicken Sie auf Try it out und senden Sie die untenstehenden Payloads, ohne einen Client schreiben zu müssen.
Der Anfragenlebenszyklus im Überblick
Eine vollständige Hin- und Rückreise umfasst sieben Aufrufe, von der Projektierung bis zum Ausführungssummary:
1. Create Project ──▶ 2. Discover Operators ──▶ 3. Validate Flow ──▶ 4. Create Flow ──▶ 5. Execute Run ──▶ 6. Fetch Logs ──▶ 7. Summary
Schritt 1: Ein Projekt erstellen
Projekte gruppieren Abläufe und erfassen deren aggregierte Ausführungsstatistiken. Erstellen Sie eines mit POST /api/v1/projects:
{
"name": "Sample Docling Pipeline Project",
"description": "Flows for processing invoice documents",
"tags": ["finance", "pdf", "q3"]
}
Die Felder:
nameist ein erforderlicher Zeichenstring von 1 bis 255 Zeichen, der das Projekt eindeutig identifiziert.descriptionist eine optionale kurze Erklärung zum Zweck des Projekts.tagsist ein optionales Array von Zeichenketten zur Kategorisierung.
Bei Erfolg wird 201 Created zurückgegeben zusammen mit einem generierten project_id, einer flow_count von null, Zeitstempeln sowie einem href zum Ressourcen:
{
"project_id": "84c718b2-5f36-4d2c-9a4f-561234bcde01",
"name": "Sample Docling Pipeline Project",
"description": "Flows for processing invoice documents",
"tags": ["finance", "pdf", "q3"],
"flow_count": 0,
"created_on": "2026-09-07T10:00:00Z",
"modified_on": "2026-09-07T10:00:00Z",
"href": "/api/v1/projects/84c718b2-5f36-4d2c-9a4f-561234bcde01"
}
Schritt 2: Entdecken von Operatoren und Modellen
Anstatt die Namen und Optionen der Operatoren zu erraten, fragen Sie den Server.
Metadaten der Operatoren
GET /api/v1/operators/metadata gibt ein detailliertes Schema für jeden Operator zurück – einschließlich der 20+ eingebauten Operatoren sowie aller externen Operatoren, die Sie registriert haben. Der Abfrageparameter internal_features hat standardmäßig den Wert false.
In jedem Eintrag beschreibt features die Spalten, die ein Operator erzeugt, required_features die Spalten, die er von den Vorläuferkomponenten benötigt, und attributes seine Optionen mit Typen und Standardwerten. Der Extract-Operator gibt content sowie doc_id_hash aus; der Chunker benötigt hingegen content:
{
"extract_operator": {
"label": "Extract Operator",
"category": "Extract",
"description": "Extracts structured content from documents using Docling",
"features": {
"content": {
"name": "Document Content",
"description": "The markdown content extracted from the document",
"type": "string",
"required": true
},
"doc_id_hash": {
"name": "Hash ID",
"description": "Hash ID of the document row",
"type": "string",
"required": true
}
},
"required_features": [],
"attributes": {
"text_extraction_mode": {
"type": "string",
"description": "Text extraction strategy (docling_library or docling_serve)",
"required": true,
"default": "docling_library"
},
"entity_extraction_mode": {
"type": "string",
"description": "Entity extraction strategy (litellm, watsonx, docling, or none)",
"required": false,
"default": "none"
}
}
},
"chunker": {
"label": "Chunker Operator",
"category": "Functional",
"description": "Splits documents into smaller semantic or fixed-size passages",
"features": {
"content": { "name": "Chunk Content", "type": "string", "required": true }
},
"required_features": ["content"],
"attributes": {
"chunker_type": {
"type": "string",
"description": "Chunking strategy (fixed, semantic, or hybrid)",
"required": false,
"default": "hybrid"
}
}
}
}
Durch den Vergleich von required_features mit den Ausgaben der Vorläuferkomponenten wird bereits vor dem Absenden überprüft, dass jeder Knoten die benötigten Spalten erhält.
Anbietermodelle
GET /api/v1/providers/{provider}/models ruft einen aktiven Anbieter (ollama oder watsonx) ab, sodass fehlende Modelle oder falsch eingegebene Tags bereits vor der Ausführung sichtbar werden:
curl -s http://localhost:8080/api/v1/providers/ollama/models | jq
Jedes Modell wird mit Namen, Tag, Änderungszeit und Größe in Bytes aufgelistet:
{
"provider": "ollama",
"models": [
{
"name": "nomic-embed-text:latest",
"model": "nomic-embed-text:latest",
"modified_at": "2026-08-15T12:00:00Z",
"size": 274302450
},
{
"name": "llama3:8b",
"model": "llama3:8b",
"modified_at": "2026-08-20T14:30:00Z",
"size": 4661224676
}
]
}
Schritt 3: Den Ablauf vor der Speicherung überprüfen
POST /api/v1/validation/validate_flow überprüft eine DAG auf fehlerhafte Parameter und gebrochene Abhängigkeiten, ohne sie zu speichern oder auszuführen.
global_config legt global gültige Optionen fest (Dokumentspalte, lokale Ausführung, In-Memory-Speicherung, erzwungene Neuverarbeitung). flow listet die Knoten auf, wobei jeder Knoten einen type, eine eindeutige name, eine config sowie ein depends_on-Array enthält, das seine Vorgängerknoten angibt. Der Pipeline-Ablauf ist wie folgt:
- Es werden PDF-, TXT- und DOCX-Dateien aus
./sample_documentsauf dem lokalen Dateisystem verarbeitet; - Der Text wird mithilfe der Docling-Bibliothek extrahiert, wobei die Entitätenextraktion übersprungen wird;
- Der Inhalt wird in Blöcke à 512 Einheiten mit einer Überlappung von 50 Einheiten aufgeteilt;
- Jeder Block wird über LiteLLM eingebettet, wobei auf Ollamas OpenAI-kompatiblen Endpunkt mit dem
nomic-embed-text-Modell verwiesen wird;
feature_mappings auf Indexfelder.{
"flow_name": "complete-document-pipeline",
"global_config": {
"doc_column": "content",
"disable_validation": true,
"force_ingest": true,
"storage": "in-memory",
"execute_type": "local"
},
"flow": [
{
"type": "ingest_source",
"name": "ingest_source_filesystem",
"config": {
"provider": "filesystem",
"connection_params": {
"paths": ["./sample_documents"]
},
"include_filter": "pdf,txt,docx"
}
},
{
"type": "extract_operator",
"name": "extract_with_docling",
"config": {
"text_extraction": {
"provider": "docling_library",
"doc_column": "content"
},
"entity_extraction": {
"provider": "none"
}
},
"depends_on": ["ingest_source_filesystem"]
},
{
"type": "chunker",
"name": "simple_chunker",
"config": {
"chunk_type": "simple",
"chunk_size": 512,
"chunk_overlap": 50,
"retain_original_content": false
},
"depends_on": ["extract_with_docling"]
},
{
"type": "embeddings",
"name": "ollama_embeddings",
"config": {
"provider": "litellm",
"provider_config": {
"model_id": "openai/nomic-embed-text",
"api_base": "http://localhost:11434/v1",
"api_key": "<ollama-api-key>"
},
"embeddings_column": "embeddings",
"overlap_ratio": 0.1
},
"depends_on": ["simple_chunker"]
},
{
"type": "vectordb",
"name": "opensearch_vector_store",
"config": {
"provider": "opensearch",
"doc_id_column": "doc_id_hash",
"embeddings_column": "embeddings",
"vector_dimension": 768,
"create_index": true,
"provider_config": {
"index_name": "sample-documents-index",
"host": "localhost",
"port": 9200,
"username": "${OPENSEARCH_USERNAME}",
"password": "${OPENSEARCH_PASSWORD}",
"use_ssl": false,
"verify_certs": false,
"batch_size": 100,
"engine": "faiss",
"algorithm": "hnsw",
"space_type": "l2"
},
"feature_mappings": [
{ "feature_name": "doc_id_hash", "mapped_column_name": "pk" },
{ "feature_name": "content", "mapped_column_name": "text" },
{ "feature_name": "name", "mapped_column_name": "doc_name" },
{ "feature_name": "path", "mapped_column_name": "file_path" },
{ "feature_name": "embeddings", "mapped_column_name": "vector_embeddings" },
{ "feature_name": "chunk_id", "mapped_column_name": "chunk_id" },
{ "feature_name": "chunk_index", "mapped_column_name": "chunk_index" }
]
},
"depends_on": ["ollama_embeddings"]
}
]
}
Einige Details sind wichtig. vector_dimension (768) muss der Ausgabegröße des Embedding-Modells entsprechen. Anmeldeinformationen werden als Platzhalter im Stil von ${OPENSEARCH_USERNAME} und <ollama-api-key> dargestellt; wahre Geheimnisse sollten in Umgebungsvariablen oder einem Secret-Store aufbewahrt werden, nicht in gespeicherten Workflows. Das Deaktivieren von use_ssl und verify_certs ist lokal in Ordnung, aber nicht auf einem gemeinsamen Cluster. Zudem verwendet der Chunker chunk_type: „simple“, während die Metadaten-Auszüge chunker_type mit fixed, semantic und hybrid dokumentieren; überprüfen Sie, was Ihr Server zurückgibt.
Eine gültige Definition gibt 200 OK, is_valid: true, leere Werte für errors und warnings sowie die Anzahl der Knoten zurück:
{
"is_valid": true,
"errors": [],
"warnings": [],
"node_count": 5
}
Schritt 4: Flow registrieren
Speichern Sie die validierte Definition mit POST /api/v1/flows (is_elyra hat standardmäßig den Wert false). Der Anfragekörper enthält denselben DAG zusammen mit einer Beschreibung und Tags:
{
"flow_name": "complete-document-pipeline",
"description": "Complete document processing pipeline: Ingest -> Extract -> Chunk -> Embed -> Store in OpenSearch",
"tags": ["docling", "embeddings", "opensearch"],
"global_config": {
"doc_column": "content",
"disable_validation": true,
"force_ingest": true,
"storage": "in-memory",
"execute_type": "local"
},
"flow": [
{
"type": "ingest_source",
"name": "ingest_source_filesystem",
"config": {
"provider": "filesystem",
"connection_params": { "paths": ["./sample_documents"] },
"include_filter": "pdf,txt,docx"
}
},
{
"type": "extract_operator",
"name": "extract_with_docling",
"config": {
"text_extraction": { "provider": "docling_library", "doc_column": "content" },
"entity_extraction": { "provider": "none" }
},
"depends_on": ["ingest_source_filesystem"]
},
{
"type": "chunker",
"name": "simple_chunker",
"config": {
"chunk_type": "simple",
"chunk_size": 512,
"chunk_overlap": 50,
"retain_original_content": false
},
"depends_on": ["extract_with_docling"]
},
{
"type": "embeddings",
"name": "ollama_embeddings",
"config": {
"provider": "litellm",
"provider_config": {
"model_id": "openai/nomic-embed-text",
"api_base": "http://localhost:11434/v1",
"api_key": "<ollama-api-key>"
},
"embeddings_column": "embeddings",
"overlap_ratio": 0.1
},
"depends_on": ["simple_chunker"]
},
{
"type": "vectordb",
"name": "opensearch_vector_store",
"config": {
"provider": "opensearch",
"doc_id_column": "doc_id_hash",
"embeddings_column": "embeddings",
"vector_dimension": 768,
"create_index": true,
"provider_config": {
"index_name": "sample-documents-index",
"host": "localhost",
"port": 9200,
"username": "${OPENSEARCH_USERNAME}",
"password": "${OPENSEARCH_PASSWORD}",
"use_ssl": false,
"verify_certs": false,
"batch_size": 100,
"engine": "faiss",
"algorithm": "hnsw",
"space_type": "l2"
},
"feature_mappings": [
{ "feature_name": "doc_id_hash", "mapped_column_name": "pk" },
{ "feature_name": "content", "mapped_column_name": "text" },
{ "feature_name": "name", "mapped_column_name": "doc_name" },
{ "feature_name": "path", "mapped_column_name": "file_path" },
{ "feature_name": "embeddings", "mapped_column_name": "vector_embeddings" },
{ "feature_name": "chunk_id", "mapped_column_name": "chunk_id" },
{ "feature_name": "chunk_index", "mapped_column_name": "chunk_index" }
]
},
"depends_on": ["ollama_embeddings"]
}
]
}
Zwei globale Einstellungen sind hier wichtig:
execute_type: „local“führt den Pipeline-Prozess innerhalb des Serverprozesses aus.force_ingest: trueverarbeitet zuvor eingegangene Dokumente erneut: nützlich beim Iterieren, verschwenderisch im Dauerbetrieb.
Die Antwort lautet 201 Created zusammen mit einer neuen flow_id sowie den gespeicherten Einstellungen:
{
"flow_id": "e2c31e42-7719-482a-a53d-2490b830d971",
"flow_name": "complete-document-pipeline",
"description": "Complete document processing pipeline: Ingest -> Extract -> Chunk -> Embed -> Store in OpenSearch",
"tags": ["docling", "embeddings", "opensearch"],
"global_config": {
"doc_column": "content",
"disable_validation": true,
"force_ingest": true,
"storage": "in-memory",
"execute_type": "local"
},
"created_on": "2026-09-07T10:05:00Z",
"modified_on": "2026-09-07T10:05:00Z"
}
Schritt 5: Eine Ausführung starten
Die Ausführungen sind asynchron. POST /api/v1/job_runs erhält die ID und den Namen des Workflows:
{
"flow_id": "e2c31e42-7719-482a-a53d-2490b830d971",
"flow_name": "complete-document-pipeline"
}
Sofort wird 201 Created zurückgegeben zusammen mit einer job_run_id und dem Status Starting, während die Arbeit im Hintergrund weiterläuft:
{
"job_run_id": "99ecd646-bb8e-494a-a0c5-86b40c1d4f90",
"status": "Starting",
"message": "Job run created successfully"
}
Schritt 6: Status, Metriken und Protokolle abfragen
Man fragt GET /api/v1/job_runs/{job_run_id} ab, wobei include_logs=true gesetzt wird, um Protokolle pro Node zu erhalten, bis der Status endgültig ist (zum Beispiel Completed), idealerweise mit zunehmenden Verzögerungen.
Die lange 200 OK-Antwort enthält node_sequence (Ausführungsreihenfolge), job_stats (Gesamtzähler für den gesamten Job, ergänzt durch node_stats pro Node und batch_node_stats pro Batch) sowie ein übergeordnetes node_metadata-Array. Hier wurden zwei Textdateien an allen fünf Nodes durchgegeben, wodurch vier Blöcke entstanden, die alle indiziert sind:
{
"node_sequence": [
"ca564648-1715-45c3-be67-7c654344a99c",
"49f285b0-3afa-40eb-8111-3ec6a57c4904",
"447e0511-5125-4ffb-8396-edb972976080",
"2636f8b6-ef9a-4805-bda0-9fcaa853e16a",
"0c773955-f1c7-4b68-b157-38966382cb9c"
],
"job_stats": {
"job_id": "9be63026-c08c-49c1-ba12-600838f3b22f",
"job_run_id": "13bd4219-7947-4977-bc69-1ae6628567d3",
"status": "Completed",
"message": "",
"start_time": 1788943163,
"end_time": 1788943166,
"duration": 3,
"heartbeat_timestamp": 0,
"total_docs": 2,
"processed_docs": 2,
"completed_docs": 2,
"failed_docs": 0,
"skipped_docs": 0,
"deleted_doc_count": 0,
"total_pages_processed": 2,
"page_type_stats": {
"txt": 2
},
"execution_time": 0,
"orchestrator": "Python",
"container_kind": null,
"container_id": "",
"flow_id": "unknown",
"user_id": null,
"account_id": null,
"user_entitlements": {},
"report_status": "NOT_AVAILABLE",
"report_generation_started_at": null,
"report_generation_completed_at": null,
"node_stats": {
"ca564648-1715-45c3-be67-7c654344a99c": {
"id": "ca564648-1715-45c3-be67-7c654344a99c",
"name": "extract_with_docling",
"node_status": "Completed",
"error": "",
"start_time": 1788943163,
"end_time": 1788943163,
"time_taken": 0,
"col_names": [
"content",
"doc_id_hash",
"document_format",
"id",
"metadata",
"modified_time",
"name",
"pages_processed",
"path",
"source_id"
],
"total_docs": 2,
"failed_docs": 0,
"skipped_docs": 0,
"docs_completed": 2,
"docs_completed_count": 2,
"node_metadata": {
"node_metadata": {
"failed_docs": [],
"processed_docs": 2,
"node_status": "Completed",
"total_pages_converted": 2,
"page_type_stats": {
"txt": 2
},
"failed_docs_count": 0,
"skipped_docs": [],
"documents_in_scope": 2,
"skipped_docs_count": 0,
"completed_docs_count": 2,
"Progress": "1 of 1 batches (100.0%) | Completed: 1"
},
"id": "ca564648-1715-45c3-be67-7c654344a99c",
"operator": "extract_with_docling"
},
"batch_id": null,
"batch_num": null
},
"49f285b0-3afa-40eb-8111-3ec6a57c4904": {
"id": "49f285b0-3afa-40eb-8111-3ec6a57c4904",
"name": "ingest_source_filesystem",
"node_status": "Completed",
"error": "",
"start_time": 1788943163,
"end_time": 1788943163,
"time_taken": 0,
"col_names": [
"id",
"name",
"document_format",
"metadata",
"source_id",
"path",
"modified_time"
],
"total_docs": 2,
"failed_docs": 0,
"skipped_docs": 0,
"docs_completed": 2,
"docs_completed_count": 2,
"node_metadata": {
"id": "49f285b0-3afa-40eb-8111-3ec6a57c4904",
"operator": "ingest_source_filesystem",
"node_metadata": {
"documents_in_scope": 2,
"processed_docs": 2,
"failed_docs_count": 0,
"failed_docs": [],
"skipped_docs_count": 0,
"skipped_docs": [],
"node_status": "Completed"
}
},
"batch_id": null,
"batch_num": null
},
"447e0511-5125-4ffb-8396-edb972976080": {
"id": "447e0511-5125-4ffb-8396-edb972976080",
"name": "simple_chunker",
"node_status": "Completed",
"error": "",
"start_time": 1788943163,
"end_time": 1788943164,
"time_taken": 1,
"col_names": [
"chunked_content",
"doc_id_hash",
"document_format",
"id",
"metadata",
"modified_time",
"name",
"pages_processed",
"path",
"source_id"
],
"total_docs": 2,
"failed_docs": 0,
"skipped_docs": 0,
"docs_completed": 2,
"docs_completed_count": 2,
"node_metadata": {
"node_metadata": {
"failed_docs": [],
"total_chunks": 4,
"processed_docs": 2,
"node_status": "Completed",
"failed_docs_count": 0,
"skipped_docs": [],
"documents_in_scope": 2,
"skipped_docs_count": 0,
"completed_docs_count": 2,
"Progress": "1 of 1 batches (100.0%) | Completed: 1"
},
"id": "447e0511-5125-4ffb-8396-edb972976080",
"operator": "simple_chunker"
},
"batch_id": null,
"batch_num": null
},
"2636f8b6-ef9a-4805-bda0-9fcaa853e16a": {
"id": "2636f8b6-ef9a-4805-bda0-9fcaa853e16a",
"name": "ollama_embeddings",
"node_status": "Completed",
"error": "",
"start_time": 1788943164,
"end_time": 1788943164,
"time_taken": 0,
"col_names": [
"chunked_content",
"doc_id_hash",
"document_format",
"embeddings",
"id",
"metadata",
"modified_time",
"name",
"pages_processed",
"path",
"source_id"
],
"total_docs": 2,
"failed_docs": 0,
"skipped_docs": 0,
"docs_completed": 2,
"docs_completed_count": 2,
"node_metadata": {
"node_metadata": {
"failed_docs": [],
"processed_docs": 2,
"node_status": "Completed",
"failed_docs_count": 0,
"skipped_docs": [],
"documents_in_scope": 2,
"skipped_docs_count": 0,
"completed_docs_count": 2,
"Progress": "1 of 1 batches (100.0%) | Completed: 1"
},
"id": "2636f8b6-ef9a-4805-bda0-9fcaa853e16a",
"operator": "ollama_embeddings"
},
"batch_id": null,
"batch_num": null
},
"0c773955-f1c7-4b68-b157-38966382cb9c": {
"id": "0c773955-f1c7-4b68-b157-38966382cb9c",
"name": "opensearch_vector_store",
"node_status": "Completed",
"error": "",
"start_time": 1788943164,
"end_time": 1788943165,
"time_taken": 1,
"col_names": [
"chunked_content",
"doc_id_hash",
"document_format",
"embeddings",
"id",
"metadata",
"modified_time",
"name",
"pages_processed",
"path",
"source_id"
],
"total_docs": 2,
"failed_docs": 0,
"skipped_docs": 0,
"docs_completed": 2,
"docs_completed_count": 2,
"node_metadata": {
"node_metadata": {
"failed_docs": [],
"chunks_indexed_successfully": 4,
"processed_docs": 2,
"total_chunks_to_index": 4,
"node_status": "Completed",
"chunks_failed_to_index": 0,
"number_of_batches": 1,
"failed_docs_count": 0,
"skipped_docs": [],
"documents_in_scope": 2,
"skipped_docs_count": 0,
"completed_docs_count": 2,
"Progress": "1 of 1 batches (100.0%) | Completed: 1"
},
"id": "0c773955-f1c7-4b68-b157-38966382cb9c",
"operator": "opensearch_vector_store"
},
"batch_id": null,
"batch_num": null
}
},
"batch_node_stats": {
"2636f8b6-ef9a-4805-bda0-9fcaa853e16a": {
"d9467158-dc5a-422e-92f7-d389776f8e50": {
"id": "2636f8b6-ef9a-4805-bda0-9fcaa853e16a",
"name": "ollama_embeddings",
"node_status": "Completed",
"error": "",
"start_time": 1788943164,
"end_time": 1788943164,
"time_taken": 0,
"col_names": [
"id",
"name",
"document_format",
"metadata",
"source_id",
"path",
"modified_time",
"pages_processed",
"chunked_content",
"embeddings",
"doc_id_hash"
],
"total_docs": 2,
"failed_docs": 0,
"skipped_docs": 0,
"docs_completed": 2,
"docs_completed_count": 2,
"node_metadata": {
"id": "2636f8b6-ef9a-4805-bda0-9fcaa853e16a",
"operator": "ollama_embeddings",
"node_metadata": {
"documents_in_scope": 2,
"processed_docs": 2,
"failed_docs_count": 0,
"failed_docs": [],
"skipped_docs_count": 0,
"skipped_docs": [],
"node_status": "Completed"
}
},
"batch_id": "d9467158-dc5a-422e-92f7-d389776f8e50",
"batch_num": 0
}
},
"0c773955-f1c7-4b68-b157-38966382cb9c": {
"d9467158-dc5a-422e-92f7-d389776f8e50": {
"id": "0c773955-f1c7-4b68-b157-38966382cb9c",
"name": "opensearch_vector_store",
"node_status": "Completed",
"error": "",
"start_time": 1788943164,
"end_time": 1788943165,
"time_taken": 1,
"col_names": [
"id",
"name",
"document_format",
"metadata",
"source_id",
"path",
"modified_time",
"pages_processed",
"chunked_content",
"embeddings",
"doc_id_hash"
],
"total_docs": 2,
"failed_docs": 0,
"skipped_docs": 0,
"docs_completed": 2,
"docs_completed_count": 2,
"node_metadata": {
"id": "0c773955-f1c7-4b68-b157-38966382cb9c",
"operator": "opensearch_vector_store",
"node_metadata": {
"documents_in_scope": 2,
"processed_docs": 2,
"failed_docs_count": 0,
"failed_docs": [],
"skipped_docs_count": 0,
"skipped_docs": [],
"node_status": "Completed",
"number_of_batches": 1,
"total_chunks_to_index": 4,
"chunks_indexed_successfully": 4,
"chunks_failed_to_index": 0
}
},
"batch_id": "d9467158-dc5a-422e-92f7-d389776f8e50",
"batch_num": 0
}
},
"447e0511-5125-4ffb-8396-edb972976080": {
"d9467158-dc5a-422e-92f7-d389776f8e50": {
"id": "447e0511-5125-4ffb-8396-edb972976080",
"name": "simple_chunker",
"node_status": "Completed",
"error": "",
"start_time": 1788943163,
"end_time": 1788943164,
"time_taken": 1,
"col_names": [
"id",
"name",
"document_format",
"metadata",
"source_id",
"path",
"modified_time",
"pages_processed",
"doc_id_hash",
"chunked_content"
],
"total_docs": 2,
"failed_docs": 0,
"skipped_docs": 0,
"docs_completed": 2,
"docs_completed_count": 2,
"node_metadata": {
"id": "447e0511-5125-4ffb-8396-edb972976080",
"operator": "simple_chunker",
"node_metadata": {
"documents_in_scope": 2,
"processed_docs": 2,
"failed_docs_count": 0,
"failed_docs": [],
"skipped_docs_count": 0,
"skipped_docs": [],
"node_status": "Completed",
"total_chunks": 4
}
},
"batch_id": "d9467158-dc5a-422e-92f7-d389776f8e50",
"batch_num": 0
}
},
"ca564648-1715-45c3-be67-7c654344a99c": {
"d9467158-dc5a-422e-92f7-d389776f8e50": {
"id": "ca564648-1715-45c3-be67-7c654344a99c",
"name": "extract_with_docling",
"node_status": "Completed",
"error": "",
"start_time": 1788943163,
"end_time": 1788943163,
"time_taken": 0,
"col_names": [
"id",
"name",
"document_format",
"metadata",
"source_id",
"path",
"modified_time",
"content",
"pages_processed",
"doc_id_hash"
],
"total_docs": 2,
"failed_docs": 0,
"skipped_docs": 0,
"docs_completed": 2,
"docs_completed_count": 2,
"node_metadata": {
"id": "ca564648-1715-45c3-be67-7c654344a99c",
"operator": "extract_with_docling",
"node_metadata": {
"documents_in_scope": 2,
"processed_docs": 2,
"failed_docs_count": 0,
"failed_docs": [],
"skipped_docs_count": 0,
"skipped_docs": [],
"node_status": "Completed",
"page_type_stats": {
"txt": 2
},
"total_pages_converted": 2
}
},
"batch_id": "d9467158-dc5a-422e-92f7-d389776f8e50",
"batch_num": 0
}
}
}
},
"node_metadata": [
{
"id": "ca564648-1715-45c3-be67-7c654344a99c",
"operator": "extract_with_docling",
"node_metadata": {
"failed_docs": [],
"processed_docs": 2,
"node_status": "Completed",
"total_pages_converted": 2,
"page_type_stats": {
"txt": 2
},
"failed_docs_count": 0,
"skipped_docs": [],
"documents_in_scope": 2,
"skipped_docs_count": 0,
"completed_docs_count": 2,
"Progress": "1 of 1 batches (100.0%) | Completed: 1"
}
},
{
"id": "49f285b0-3afa-40eb-8111-3ec6a57c4904",
"operator": "ingest_source_filesystem",
"node_metadata": {
"documents_in_scope": 2,
"processed_docs": 2,
"failed_docs_count": 0,
"failed_docs": [],
"skipped_docs_count": 0,
"skipped_docs": [],
"node_status": "Completed"
}
},
{
"id": "447e0511-5125-4ffb-8396-edb972976080",
"operator": "simple_chunker",
"node_metadata": {
"failed_docs": [],
"total_chunks": 4,
"processed_docs": 2,
"node_status": "Completed",
"failed_docs_count": 0,
"skipped_docs": [],
"documents_in_scope": 2,
"skipped_docs_count": 0,
"completed_docs_count": 2,
"Progress": "1 of 1 batches (100.0%) | Completed: 1"
}
},
{
"id": "2636f8b6-ef9a-4805-bda0-9fcaa853e16a",
"operator": "ollama_embeddings",
"node_metadata": {
"failed_docs": [],
"processed_docs": 2,
"node_status": "Completed",
"failed_docs_count": 0,
"skipped_docs": [],
"documents_in_scope": 2,
"skipped_docs_count": 0,
"completed_docs_count": 2,
"Progress": "1 of 1 batches (100.0%) | Completed: 1"
}
},
{
"id": "0c773955-f1c7-4b68-b157-38966382cb9c",
"operator": "opensearch_vector_store",
"node_metadata": {
"failed_docs": [],
"chunks_indexed_successfully": 4,
"processed_docs": 2,
"total_chunks_to_index": 4,
"node_status": "Completed",
"chunks_failed_to_index": 0,
"number_of_batches": 1,
"failed_docs_count": 0,
"skipped_docs": [],
"documents_in_scope": 2,
"skipped_docs_count": 0,
"completed_docs_count": 2,
"Progress": "1 of 1 batches (100.0%) | Completed: 1"
}
}
]
}
Dieses Beispiel ist nicht vollständig konsistent: Der job_run_id in job_stats unterscheidet sich vom ID des Schritts 5 und flow_id weist den Wert unknown auf. Vergleichen Sie die Ausführungen anhand des IDs, den Sie zu Beginn erhalten haben.
Was man zuerst in der Antwort lesen sollte
job_statsliefert hochrangige Zähler wietotal_docs,processed_docs,completed_docsundduration.
node_stats zeigt die Dauer und den Status jedes Schritts an; prüfen Sie ihn zuerst, wenn eine Ausführung langsam ist oder fehlschlägt.include_logs=true werden formatierte Protokolle am Wurzelort der Antwort hinzugefügt, jeweils mit dem Namen des jeweiligen Nodes gekennzeichnet (vom Ingest-Node bis zum OpenSearch-Speicher).Interpretation der Node-Metadaten
Jeder Operator gibt Telemetriedaten unter node_metadata zurück: Durchsatz, Fehler und Umwandlungen pro Phase. Die wichtigsten Attribute sind:
documents_in_scope: eine Ganzzahl, die die Anzahl der Rohdokumente angibt, die der Ingest-Operator gefunden und geladen hat; dies dient als Basiswert.processed_docs: eine Ganzzahl, die die Anzahl der Dokumente angibt, die dieser Operator während der Ausführung erfolgreich verarbeitet hat; entsprichtdocuments_in_scope, wenn nichts fehlschlägt.failed_docs_count: eine Ganzzahl, die die Anzahl der hier fehlgeschlagenen Dokumente angibt.
failed_docs: ein Array, dessen Einträge einen id, den ursprünglichen Dateinamen name, einen Fehlergrund reason sowie eine document_url enthalten (leer, wenn die Dateien vom lokalen Laufwerk stammen).skipped_docs_count: eine Ganzzahl, die die absichtlich übersprungenen Dokumente angeben, beispielsweise durch Deduplizierung, Branch-Logik oder inkrementelle Ausführungen.skipped_docs: ein Array im selben Aufbau wie failed_docs, wobei der Wert von reason den Grund für das Überspringen erklärt, z. B. "Filtered by branch condition".page_type_stats: nur vom Extraktionsoperator berichtet, ein Wörterbuch, das Dateierweiterungen mit der gezählten Anzahl der analysierten Seiten verknüpft, beispielsweise {"pdf": 45, "docx": 12, "txt": 3}.total_pages_converted die Ganzzahlsumme der Seiten aller Formate darstellt – für digitale Dateien werden die eingebauten Zählwerte und für Scans die OCR-Zählwerte verwendet.Eine schnelle Überprüfung des Zustands: Vergleichen Sie documents_in_scope zum Zeitpunkt der Eingabe mit processed_docs am letzten Knoten; failed_docs und skipped_docs erklären eventuelle Unterschiede.
Schritt 7: Überprüfung der Abläufe und Ausführungshistorie eines Projekts
GET /api/v1/projects/{project_id}/flows listet die Abläufe eines Projekts zusammen mit einem Ausführungssummary (Gesamtanzahl der Ausführungen, ID der letzten Ausführung, Status und Startzeit sowie Zählwerte nach Status), paginiert nach total_count, offset und limit:
{
"flows": [
{
"flow_id": "e2c31e42-7719-482a-a53d-2490b830d971",
"name": "complete-document-pipeline",
"tags": ["docling", "embeddings", "opensearch"],
"created_on": "2026-09-07T10:05:00Z",
"job_run_summary": {
"total_runs": 1,
"last_run_id": "99ecd646-bb8e-494a-a0c5-86b40c1d4f90",
"last_run_status": "Completed",
"last_run_start_time": 1788775200000,
"status_counts": { "Completed": 1 }
}
}
],
"total_count": 1,
"offset": 0,
"limit": 100
}
In diesem Beispiel scheint last_run_start_time in Millisekunden angegeben zu sein, während die start_time-Werte der Jobausführungen in Sekunden liegen – normalisieren Sie daher die Werte vor dem Vergleich.
Kernpunkte
Die API bietet eine headless-Schnittstelle für die end-to-end-Dokumentverarbeitung. Einige Gewohnheiten sorgen dafür, dass sie zuverlässig funktioniert:
- Verwenden Sie
/operators/metadataund/providers/{provider}/models, um die Felder der Operatoren sowie verfügbare Modelltags programmgesteuert zu ermitteln, anstatt sie fest einzubinden. - Führen Sie jede DAG-Definition über
/validation/validate_flowaus, um vor der Ausführung fehlerhafte Parametertypen sowie gebrochene Knotenverbindungen zu erkennen. - Betrachten Sie Ausführungen als asynchrone Aufgaben: Bewahren Sie den
job_run_idauf, abfragen Sie mitinclude_logs=trueund lesen Sienode_statssowienode_metadata, um Fehler nach Phasen zu lokalisieren. - Halten Sie Anmeldeinformationen außerhalb der gespeicherten Flow-Definitionen und überprüfen Sie, ob
vector_dimensionmit Ihrem Embedding-Modell übereinstimmt.
Um es auszuprobieren, starten Sie Ollama und OpenSearch (oder Milvus), führen Sie docling-pipelines-api aus, öffnen Sie die Swagger UI und gehen Sie durch die Abfolge: Projekt, Ablauf, Validierung, Ausführung, Protokolle.