欢迎信给四十位新客户,每位与会者的证书,每个订单的发票:相同的文档,每次使用不同的记录。使用本地运行的 GroupDocs.Assembly.Mcp(dnx GroupDocs.Assembly.Mcp --yes),Claude Desktop、Cursor 或 Copilot 只需一次工具调用 assemble_per_record,即可对 JSON 数组的每个元素填充 Word 模板,将每个结果保存为以您选择的字段命名的 PDF,并报告失败的记录,而不是在第一个错误时停止:
为 customers.json 中的每位客户使用 welcome-letter.docx 生成欢迎信 PDF,并以客户名称命名每个文件。
带有配置和故障排除的逐步版本请参见文档:如何使用 AI 代理为每条记录生成一个文档(邮件合并).
为什么不让代理循环?
它可以做到,对于五条记录来说这没问题。但四十次工具调用的循环相当于四十次机会,让代理计数出错、在上下文变长时跳过记录,或“好心”地改写某封信。每记录工具将循环移到服务器端:一次调用、一个模板、一次遍历数组,并生成一份报告,准确说明写入了多少文件以及哪些记录未成功。代理的工作是选择模板、数据文件和命名字段,然后把报告读给你听。
代理首先检查什么?
两件事:数据的结构以及模板读取的内容。在我们的测试中,customers.json 中有五位客户,以及一页的欢迎信:
-> get_document_info {"file":{"filePath":"customers.json"}}
<- { "dataKind": "json",
"data": { "root": "array", "length": 5, "keys": null } }
-> get_template_fields {"template":{"filePath":"welcome-letter.docx"}}
<- { "dataSourceNames": [ "customer" ],
"fields": [ "customer.Contact", "customer.Plan", "customer.Name",
"customer.Manager", "customer.FirstInvoice" ] }
模板将单条记录称为 customer;服务器会自行解析,因此代理无需传递 dataSourceName。
一次调用,五条记录,一个失败
-> assemble_per_record {"template":{"filePath":"welcome-letter.docx"},
"data":{"filePath":"customers.json"},"fileNameField":"Name",
"format":"pdf"}
<- Assembled 4 of 5 document(s) from 'welcome-letter.docx' with
'customers.json', one per record (each record as 'customer'), as PDF.
Saved to:
.../Contoso Pharma.pdf
.../Fabrikam Logistics.pdf
.../Tailspin Toys.pdf
.../Litware Labs.pdf
1 record(s) failed:
record 4: InvalidOperationException: ... Can not get the value of
member 'FirstInvoice' on type 'System.Data.DataRow'. The template
reads 'FirstInvoice', which the data does not have. ...
第 4 条记录,Wingtip Travel,在数据中没有 first-invoice 日期。其余四封信已生成,文件名均为对应客户名称,失败信息返回了记录编号和缺失的字段。代理会报告为“已完成四封信;Wingtip Travel 没有 first-invoice 日期,您是希望我将该行留空还是等待日期?”这才是您想要的对话,而不是四十个文件却不知道哪个出错。
fan-out 工作原理
customers.json [ {Name:"Contoso Pharma",...}, {Name:"Fabrikam ..."},
... 5 records ]
|
assemble_per_record {"template":{"filePath":"welcome-letter.docx"},
"data":{"filePath":"customers.json"},
"fileNameField":"Name","format":"pdf"}
|
+--> Contoso Pharma.pdf
+--> Fabrikam Logistics.pdf ... 2 more
'--> "4 of 5 ... 1 record(s) failed: record 4 ..."
三个参数完成此工作。fileNameField 使用记录字段(如 customer.Name 或发票号)为每个输出命名;如果不提供,则文件使用递增编号。recordsPath 在 JSON 为包含数组的对象时指向该数组,例如 "customers" 或 "batch.items"。maxDocuments 则是限制阀。
什么会阻止批处理失控?
maxDocuments,默认值为 100,最高可达 1000。在写入任何文件之前,服务器会先统计记录数;如果超过限制,则拒绝。我们将其设为 3 来对抗我们的五位客户:
-> assemble_per_record {..., "maxDocuments":3}
<- Per-record assembly failed for 'welcome-letter.docx': there are 5
records, more than maxDocuments=3. Raise 'maxDocuments' (up to 1000)
or pass fewer records.
没有写入任何文件。对于实际发送给真实用户的邮件,这是一种合适的默认设置:如果误将整个 CRM 导出作为输入,系统会返回一个提示,而不是生成一万份 PDF。
我的数据是电子表格,而不是 JSON
每记录生成仅支持读取 JSON:对象数组或包含数组的对象。当列表位于 CSV 或工作表中时,代理会先将行转换为 JSON,代理对此处理得很好,并将文件写入存储文件夹。如果您想要的是一个列出所有行的文档,例如价目表或登记册,则使用 assemble_document 并在模板中加入 <<foreach>>,它可以直接读取 CSV 和电子表格。
真实的限制
- 每记录组装仅读取 JSON;CSV 和电子表格数据需先转换。
- 评估模式:每个生成的文件都会以 “Evaluation Only. Created with GroupDocs.Assembly 26.7…” 开头,电子邮件模板仅保留纯文本正文。请在实际邮件发送前为服务器授权。
- 缺少字段会导致该记录失败。设置
allowMissingMembers: true可将其写为空行;自行决定使用哪种方式。 - 日期:请以
2026-12-01T00:00:00的形式写入,并在模板中进行格式化,就像我们的信件使用<<[customer.FirstInvoice]:"d MMMM yyyy">>那样。在我们的测试中,UTC+2 机器上仅日期字符串会偏移一天。 - 服务器只写入文件;不会发送。交付是另一步骤。
常见问题
我可以在不上传客户列表的情况下使用 Claude 进行邮件合并吗?
可以。服务器本地运行,并从您的存储文件夹读取 customers.json;生成的 PDF 也会写入同一位置。
输出文件如何命名?
使用您传入的 fileNameField 对应的记录字段命名,这里是客户名称,例如 Contoso Pharma.pdf。如果未提供,则使用递增编号。
每个文档可以是电子邮件而不是 PDF 吗?
可以:使用 EML 或 MSG 模板,或传入 format: "eml"。在评估模式下,电子邮件的 HTML 正文会被评估行替换,因此请使用授权后测试电子邮件输出。
深入了解
- 文档,权威指南:如何使用 AI 代理为每条记录生成一个文档(邮件合并)How to generate one document per record (mail merge) with an AI agent
- 文档中心:GroupDocs.Assembly MCP Server GroupDocs.Assembly MCP Server
- 从这里开始:让模型填充数据,而不是编写文档 Let the model fill in the data, not write the document
- 相关:这个模板需要什么?问它。 What does this template need? Ask it.
- 相关:图表来自模板,数字来自数据 The chart comes from the template, the numbers come from the data
- 相关:您的仓库已有数据;让代理生成 PDF Your repo already has the data; let the agent make the PDF
- 本地部署与安全模型:AI 文档处理的三种架构,以及保持文件在您网络内部的方案 3 architectures for AI document processing, and the one that keeps files inside your network
- 提问:GroupDocs Assembly 论坛 GroupDocs Assembly forum
- 源码:GroupDocs.Assembly.Mcp 在 GitHub GroupDocs.Assembly.Mcp on GitHub