Jemand überreicht dir eine Word‑Vorlage und eine Frist. Welche Daten benötigt sie? Die übliche Antwort ist, sie zu öffnen, zu scrollen, zu raten, sie auszuführen, den Fehler zu lesen und sie erneut auszuführen. Mit lokal laufendem GroupDocs.Assembly.Mcp (dnx GroupDocs.Assembly.Mcp --yes) fragt Claude Desktop, Cursor oder Copilot die Vorlage direkt: get_template_fields gibt jedes Tag, die von ihr verwendeten Datennamen und ein JSON‑Skelett zum Ausfüllen zurück, ohne die Engine zu starten, und wenn ein Lauf fehlschlägt, sagt der Fehler, was geändert werden muss:

Welche Daten benötigt order-lines.docx? Wenn es nicht generiert wird, sag mir warum und wie die Vorlage zu korrigieren ist.

Die schrittweise Version mit Konfiguration und Fehlersuche befindet sich in der Dokumentation: How to find out what a template needs and why it failed.

Warum prüfen, bevor du füllst?

Weil Versuch und Irrtum der teure Weg ist, ein Schema zu lernen. Ein Agent, der Feldnamen aus dem sichtbaren Text eines Dokuments rät, wird CustomerName vorschlagen, wenn die Vorlage customer.Name enthält, und jeder falsche Tipp kostet einen Round‑Trip und einen verwirrenden Fehler. Eine Vorlage ist kein Fließtext; sie ist ein Programm mit einem Datenvertrag, und der Vertrag kann gelesen werden.

Das ist alles, was get_template_fields tut. Es analysiert die <<…>>‑Tags, ermittelt die Namen und erstellt das Skelett:

-> get_template_fields {"template":{"filePath":"order-lines.docx"}}
<- { "tagCount": 3,
     "dataSourceNames": [ "lines" ],
     "fields": [ "lines[].Title", "lines[].Quantity" ],
     "dataSkeleton": { "lines": [ { "Title": "", "Quantity": "" } ] },
     "notes": [ "fields and dataSkeleton are inferred from the tags,
       not from the engine; values computed by Select/GroupBy
       projections are not followed." ] }

Der Hinweis ist ehrlich bezüglich der Methode: Dies ist eine statische Inspektion. Ein Feld, das innerhalb einer Select‑Projection erzeugt wird, wird nicht verfolgt. Für eine normale Vertrags‑, Brief‑ oder Rechnungs‑Vorlage ist das Skelett genau das, was ausgefüllt werden muss.

Das Skelett ändert auch das Gespräch mit dir. Statt „Ich habe versucht, die Bestellung zu erzeugen, und es ist fehlgeschlagen“, kann der Agent sagen „Diese Vorlage benötigt eine Liste von Zeilen, jede mit einem Titel und einer Menge; ich habe drei in deiner E‑Mail gefunden, hier sind sie“, und erst dann generieren. Inspektion ist günstig, benötigt keine Daten und berührt nichts, daher ist sie der richtige erste Aufruf für jede Vorlage, die der Agent noch nicht gesehen hat, und der richtige Aufruf erneut, sobald jemand die Vorlage bearbeitet hat.

Drei Fehler, drei Antworten

template problem          what the server says          the fix
------------------------  ----------------------------  -------------------
{{name}} placeholders     "2 '{{...}}' placeholder(s).  write <<[name]>>
                          ... does not process that
                          syntax"
<<foreach>> never closed  "Unexpected end of template.  add <</foreach>>
                          A block tag is not closed"
data lacks a field        "The template reads 'Email',  add it, or
                          which the data does not have" allowMissingMembers

Die falsche Syntax.
Viele Vorlagen in der Praxis wurden für andere Engines geschrieben und verwenden {{name}}. GroupDocs.Assembly lässt diese als Text stehen, und die Inspektion weist darauf hin, bevor jemand einen Lauf verschwendet:

-> get_template_fields {"template":{"filePath":"shipping-notice.docx"}}
<- { "tagCount": 0, "notes": [ "No <<…>> tags were found: ...",
     "The template contains 2 '{{…}}' placeholder(s). GroupDocs.Assembly
      does not process that syntax and leaves it as text; write
      <<[name]>> instead." ] }

Der nicht geschlossene Block.
Unsere order-lines.docx öffnet ein <<foreach>> und schließt es nie. Die Inspektion listet die Tags gerne auf; die Generierung nicht:

-> assemble_document {"template":{"filePath":"order-lines.docx"},
     "dataJson":"{\"lines\":[{\"Title\":\"Cable\",\"Quantity\":2}]}"}
<- Document assembly failed for 'order-lines.docx': ...
   Unexpected end of template. A block tag is not closed: every
   <<foreach>> needs <</foreach>> and every <<if>> needs <</if>>.

Das fehlende Feld.
Wenn die Daten etwas vermissen, das die Vorlage liest, nennt der Fehler das Feld, sagt, dass Namen case‑sensitive sind, und bietet den Schalter an: allowMissingMembers: true gibt nichts für fehlende Mitglieder und leere Listen aus, anstatt zu fehlschlagen.

Wenn die Vorlage voller Fehler ist

Einige Vorlagen haben mehrere Fehler, und sie einzeln durch fehlgeschlagene Durchläufe zu beheben, ist langsam. inlineErrors: true verwandelt die Vorlage in einen eigenen Fehlerbericht: Das Dokument wird erzeugt und jeder fehlerhafte Tag erhält seine Meldung daneben geschrieben. Auf der Beispielvorlage aus den GroupDocs.Assembly‑Beispielen:

-> assemble_document {"template":{"filePath":"inline-error.docx"},
     "dataJson":"{\"name\":\"x\"}","inlineErrors":true}
<- Assembled 'inline-error.docx' ... The template has errors: each one
   is written into the output next to its tag, starting with 'Error!'

Die Ausgabe enthält << var [name] Error! An assignment operator is expected. >> an der Stelle im Dokument, an der das Tag steht. Öffne die Datei, korrigiere jedes markierte Tag und führe den Vorgang ohne das Flag erneut aus.

Was die Inspektion nicht sehen kann

Binäre Outlook‑Vorlagen sind die Ausnahme. Die Tags einer .msg‑Datei können nicht gelesen werden, ohne sie zu generieren, und der Server teilt dies mit, anstatt eine leere Liste zurückzugeben, die wie „keine Felder“ aussieht:

-> get_template_fields {"template":{"filePath":"contracts-table.msg"}}
<- { "readable": false, "notes": [ "Tags cannot be read from a .msg
     template without generating it. Save the template as DOCX, XLSX,
     PPTX or EML to inspect it, or generate it with assemble_document
     and inlineErrors=true to see which fields fail." ] }

Eine weitere Falle, in die wir geraten sind: Eine Liste, die in den Daten leer ist, hat keine Elementtypen. Unsere Vertragsvorlage multipliziert item.Quantity * item.UnitPrice; bei "items": [] und allowMissingMembers: true schlug die Generierung dennoch mit “Can not apply operator ‘’ to operands of type ‘System.Object’ and ‘System.Object’”* fehl. Lass den Agenten prüfen, dass eine Liste nicht leer ist, bevor er generiert, und frage dich, wie ein leerer Vertrag aussehen soll.

Ehrliche Grenzen

  • Inspektion ist statisch: Select‑ und GroupBy‑Projektionen werden nicht verfolgt, und .msg‑Vorlagen können nicht gelesen werden.
  • Vorlagen sind vertrauenswürdige Eingaben; Bild‑ und Dokument‑Tags laden die Pfade und URLs, die ihre Ausdrücke zurückgeben.
  • Evaluierungsmodus: Jede Ausgabe beginnt mit “Evaluation Only. Created with GroupDocs.Assembly 26.7…”.
  • Daten: übergebe 2026-11-12T00:00:00 und formatiere in der Vorlage mit :"d MMMM yyyy"; ein reiner Datums‑String wurde auf einer UTC+2‑Maschine um einen Tag verschoben, und "12.11.2026" wurde als 11. Dezember gelesen.

FAQ

Wie sehe ich, welche Felder eine Word‑Vorlage benötigt?
Bitte den Agenten, get_template_fields dafür aufzurufen. Du erhältst die Tags, die Datennamen und ein JSON‑Skelett, lokal, ohne etwas zu generieren.

Warum gibt meine Vorlage {{name}} aus statt des Wertes?
Weil GroupDocs.Assembly‑Tags <<[name]>> sind. Die Inspektion des Servers markiert {{…}}‑Platzhalter und sagt, was stattdessen zu schreiben ist.

Kann Markdown eine Vorlage sein?
Ja. Unser product-readme.md mit den Tags <<[product]>> und <<[description]>> wurde wie eine Word‑Datei inspiziert und direkt zu DOCX generiert.

Tiefer einsteigen