40人の新規顧客への歓迎レター、参加者全員への証明書、注文ごとの請求書:同じ文書で、毎回異なるレコード。

GroupDocs.Assembly.Mcp をローカルで実行(dnx GroupDocs.Assembly.Mcp --yes)すると、Claude Desktop、Cursor、または Copilot が 1 回のツール呼び出し assemble_per_record でこれを行います。このツールは JSON 配列の要素ごとに Word テンプレートを埋め、各結果を選択したフィールド名で PDF として保存し、最初のエラーで停止するのではなく失敗したレコードを報告します:

customers.json の各顧客に対して welcome-letter.docx を使用して歓迎レターの PDF を作成し、各ファイルを顧客名で命名してください。

設定とトラブルシューティングを含むステップバイステップ版はドキュメントにあります: AI エージェントでレコードごとに 1 つの文書(メールマージ)を生成する方法.

エージェントにループさせない理由

エージェントは可能で、5 件のレコードであれば問題ありません。しかし、40 回のツール呼び出しのループは、エージェントが数を間違えたり、コンテキストが長くなるとレコードをスキップしたり、“親切に” 手紙を言い換えてしまう可能性が 40 回あります。レコード単位のツールはループをサーバー側に移すことで、呼び出しは 1 回、テンプレートは 1 つ、配列を 1 回走査し、何件のファイルが書き込まれ、どのレコードが失敗したかを正確に報告します。エージェントの仕事はテンプレート、データファイル、命名フィールドを選択し、報告結果を読み取ってユーザーに伝えることです。

エージェントが最初に確認することは何ですか?

2 つのことです:データの形状とテンプレートの内容です。テストでは、customers.json に 5 人の顧客があり、1 ページの歓迎レターです:

-> 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" ] }

テンプレートは 1 つのレコードを customer と呼び、サーバーはそれを自動で判断するため、エージェントが dataSourceName を渡す必要はありません。

1 回の呼び出し、5 件のレコード、1 件の失敗

-> 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 にはデータに最初の請求日がありませんでした。他の 4 通のレターは顧客名で保存され、失敗はレコード番号と欠落しているフィールドとともに返されました。エージェントは「4 通のレターが完了しました;Wingtip Travel には最初の請求日がありません。行を空白のままにしますか、日付が入るのを待ちますか?」と報告します。これは、40 ファイルが生成されどれが間違っているか分からない状況よりも望ましい会話です。

ファンアウトの仕組み

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 ..."

3 つのパラメータが機能します。fileNameField はレコードのフィールド(例: customer.Name や請求書番号)で各出力に名前を付けます。指定しない場合は連番が付与されます。recordsPath は JSON がオブジェクトで配列を保持している場合(例: "customers" や "batch.items")にその配列を指します。そして maxDocuments が上限です。

バッチが暴走するのを防ぐのは何か?

maxDocuments はデフォルトで 100、最大 1000 まで設定可能です。書き込みを行う前にサーバーはレコード数をカウントし、上限を超えると拒否します。ここでは 5 人の顧客に対して 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 全体のエクスポートを指すと、質問が返され、1 万件の PDF が生成されることはありません。

データがスプレッドシートで JSON でない場合

レコード単位の生成は JSON のみを読み取ります:オブジェクトの配列、または 1 つの配列を保持するオブジェクトです。リストが CSV やワークシートにある場合、エージェントはまず行を JSON に変換し(エージェントは得意です)、ストレージフォルダーにファイルを書き込みます。すべての行を一覧にした 1 つの文書(価格表やレジスターなど)が必要な場合は、テンプレート内に <<foreach>> を使用した assemble_document を使い、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 のマシンで日付文字列が 1 日ずれていました。
  • サーバーはファイルを書き込むだけで、送信は行いません。配信は別のステップです。

よくある質問

顧客リストをアップロードせずに Claude でメールマージできますか?
はい。サーバーはローカルで実行され、ストレージフォルダーから customers.json を読み取ります。生成された PDF も同じ場所に書き込まれます。

出力ファイルの名前はどう決まりますか?
fileNameField に指定したレコードフィールドで決まります。この例では顧客名なので Contoso Pharma.pdf になります。指定しない場合は連番が付与されます。

各文書を PDF ではなくメールにできますか?
はい。EML または MSG テンプレートを使用するか、format: "eml" を指定してください。評価モードではメールの HTML 本文が評価文に置き換えられるため、ライセンスを使用してメール出力をテストしてください。

詳細を見る