Попросите AI‑агента «написать сервисный договор для Contoso», и он сделает это своими словами, со своими заголовками и с подсчитанной в уме суммой. Это неправильное распределение труда. При локальном запуске GroupDocs.Assembly.Mcp (dnx GroupDocs.Assembly.Mcp --yes) Claude Desktop, Cursor или Copilot запрашивают у вашего шаблона Word, какие поля нужны, заполняют их из ваших заметок, а движок рендерит контракт, таблицу и арифметику, не позволяя модели трогать макет:
Составьте сервисный договор для этого заказа, используя contract-template.docx, и сохраните его как PDF: Contoso Pharma, Keizersgracht 210 Amsterdam, контакт Dr. Lena Brandt; 12 месяцев управляемого хостинга по цене 4 800 EUR, 12 месяцев поддержки по цене 1 200 EUR, один вводный воркшоп по цене 3 500 EUR; скидка 5 процентов.
Пошаговая версия с конфигурацией и устранением неполадок находится в документации: How to generate documents from templates with AI agents using MCP.
Почему модель не должна писать документ?
Потому что сгенерированный документ может иметь ошибки, которые трудно заметить. Макет отклоняется от одобренного юридическим отделом. Пункт перефразируется так, что звучит хорошо, но означает другое. Сумма получается из предсказания следующего токена, а не из умножения. И каждый запуск немного отличается, поэтому обзор прошлого месяца ничего не говорит о контракте текущего месяца.
Шаблон меняет ситуацию. Юридический отдел владеет contract-template.docx со своими заголовками, блоком подписи и тегами <<[customer.Name]>>. Задача модели сводится к тому, в чём она хороша: чтению письма или набора заметок и преобразованию их в структурированные значения. Движок делает остальное, каждый раз одинаково.
Как агент знает, что заполнять?
Он запрашивает шаблон. get_template_fields считывает теги без запуска движка и возвращает имена, используемые шаблоном, все поля, которые он читает, и JSON‑скелетон для заполнения. Это то, что сервер вернул для нашего шаблона контракта:
-> get_template_fields {"template":{"filePath":"contract-template.docx"}}
<- { "tagCount": 17,
"dataSourceNames": [ "contract", "customer", "items" ],
"dataSkeleton": {
"contract": { "Number": "", "Date": "", "Discount": "" },
"customer": { "Name": "", "Address": "", "Contact": "",
"Email": "" },
"items": [ { "Title": "", "Quantity": 0, "UnitPrice": 0 } ] } }
Этот скелет — контракт между моделью и документом. Агент заполняет его из текста заказа и передаёт обратно как dataJson.
Что происходит, если агент забывает поле?
Ему указывают точно. В нашем тесте первая попытка агента пропустила адрес электронной почты клиента. Сервер отказал и указал на пробел:
-> assemble_document {"template":{...},"dataJson":"{... no Email ...}"}
<- Document assembly failed for 'contract-template.docx': ...
Can not get the value of member 'Email' on type ''. The template
reads 'Email', which the data does not have. Check the spelling
(names are case-sensitive) with get_template_fields and add it to
the data. ... pass allowMissingMembers=true to output nothing for
missing members and empty lists.
Модель, пишущая свободный текст, тихо оставила бы эту строку пустой. Здесь агент может спросить у вас адрес или решить вместе с вами, что поле может оставаться пустым.
Полный обмен
user agent Assembly MCP server
| "Make the contract for this order: ..." |
|-------------->| |
| |-- get_template_fields {"template": |
| | "contract-template.docx"} ------------->|
| |<- dataSkeleton: contract, customer, items --|
| | (fills the skeleton from the order text) |
| |-- assemble_document {"dataJson":"{...}", |
| | "format":"pdf"} ----------------------->|
| |<- Saved to: .../contract-template_ |
| | assembled.pdf ----------------------------|
|<- "Contract ready: 3 items, total 75500 EUR, 5% discount." |
layout, table and arithmetic come from the template
После добавления электронной почты второй вызов завершился успешно:
-> assemble_document {"template":{"filePath":"contract-template.docx"},
"dataJson":"{...}","format":"pdf"}
<- Assembled 'contract-template.docx' with inline JSON (JSON object)
as PDF
Saved to: .../contract-template_assembled.pdf
Документ содержит таблицу сборов из трёх строк, построенную с помощью <<foreach>> в строке таблицы, суммы, вычисленные шаблоном (<<[item.Quantity * item.UnitPrice]>>), общую сумму 75500 EUR из items.Sum(...) и строку «A discount of 5 percent applies.", которая существует только потому, что тег <<if>> нашёл скидку в данных. Модель ничего из этого не вычисляла.
Является ли это лучше, чем сервис шаблонов в облаке?
Это иной компромисс. Сервисы шаблонов в облаке принимают ваш шаблон и данные через HTTPS, рендерят их в своей облачной инфраструктуре и взимают плату за документ или за кредит. Здесь шаблон, данные и результат остаются в папке на вашем компьютере; движок — это GroupDocs.Assembly, работающий в процессе, и ничего не слушает на порту. То, что передаётся вашему поставщику модели, — это текст заказа, который вы вставляете, и скелет, который заполняет агент, а не отрендеренный контракт. Архитектура описана в посте семейства о on-premise AI document processing.
Честные ограничения
- Режим оценки: каждый сгенерированный документ начинается строкой «Evaluation Only. Created with GroupDocs.Assembly 26.7…», сохранённые книги получают дополнительный лист, а шаблоны электронной почты сохраняют только их текстовое тело. Файл лицензии или метерные ключи удаляют всё это.
- Синтаксис шаблона —
<<[name]>>. Заполнители{{name}}остаются как текст;get_template_fieldsуказывает на это. - Шаблоны считаются доверенным вводом: теги изображений и документов загружают любой путь или URL, возвращаемый их выражением. Смонтируйте одну папку для сервера.
- Даты: записывайте их как
2026-11-12T00:00:00и форматируйте в шаблоне (<<[contract.Date]:"d MMMM yyyy">>). Дата без времени"2026-11-12"выводилась как 11 November на машине с UTC+2 в нашем тесте. - Агент является источником данных. Попросите его перечислить значения, которые он извлек, перед рендерингом, и проверьте их.
FAQ
Может ли AI‑агент заполнить мой шаблон Word без его загрузки?
Да. Сервер работает локально через stdio и читает шаблон из папки, которую вы указываете; результат записывается рядом с ним.
В каких форматах может быть шаблон?
Word, Excel, PowerPoint, Markdown, HTML, текстовые и шаблоны электронной почты; каждый может быть сохранён в собственном формате или в PDF и других. get_supported_formats перечисляет их для каждого шаблона.
Что если шаблон поддерживается кем‑то другим?
В этом и смысл. Тот, кто владеет шаблоном, меняет пункты и макет; агент продолжает заполнять тот же скелет, а get_template_fields покажет ему любые новые поля при следующем запросе.
Углубиться
- Документация, канонический гайд: How to generate documents from templates with AI agents using MCP
- Из письма или заметок в документ: How to turn notes or an email into a finished document with an AI agent
- Центр документации: GroupDocs.Assembly MCP Server
- Связанные: A hundred personalised PDFs from one prompt: mail merge with an AI agent
- Связанные: What does this template need? Ask it.
- Связанные: The chart comes from the template, the numbers come from the data
- Связанные: Your repo already has the data; let the agent make the PDF
- Что нового в движке: GroupDocs.Assembly for .NET 26.7
- On-premise и модель безопасности: 3 architectures for AI document processing, and the one that keeps files inside your network
- Вопросы: GroupDocs Assembly forum
- Исходный код: GroupDocs.Assembly.Mcp on GitHub · NuGet package