AI連携でレコードをRAGの知識ベースに同期する
標準の「AI連携」は、期限付きテーブル・記録テーブルのレコードをMarkdownファイルに変換し、DifyまたはOpenAIの知識ベースへ送る機能です。サーバースクリプトを書かずに、業務データを外部AIが参照する文書として登録できます。
最初にファイル出力で文書の内容を確かめ、次に外部サービスへ接続すると、項目の置換とAPI接続の問題を切り分けられます。ファイル出力はプリザンター1.5.8.1の検証環境で確認しています。外部サービスへの実接続・回答生成は未検証です。
全体の流れ
図を読み込み中…
プリザンター側が行うのは文書の出力・登録・更新・削除です。質問を受け付けて回答するアプリは連携先で用意します。保存時にAIを呼んで要約や分類をレコードへ書き戻したい場合は、サーバースクリプトから生成AIを使うを参照してください。
以下では、サーバー側の有効化、テーブル側の設定、出力内容の確認、外部接続、更新・削除の運用を順に説明します。回答する画面まで用意したい場合は、OpenAIのRAGでプリザンター画面にBotを付けるへ進んでください。
連携先を選ぶ
| 連携先 | プリザンターで選ぶ方式 | 文書の取り込み | 回答する仕組み |
|---|---|---|---|
| Dify | Dify | 標準機能がデータセットへ送信 | Dify側で検索対象のナレッジを使うアプリを構成 |
| OpenAI | OpenAi | 標準機能がVector Storeへ登録 | Responses APIのfile_searchを呼ぶBot |
| Azure AI Search + Azure OpenAI | MarkdownFile | 出力ファイルをBlob Storageへ転送し、Searchのインデクサーで取り込む | 検索結果をAzure OpenAIへ渡すBotなどを別途実装 |
| Amazon Bedrock Knowledge Bases | MarkdownFile | 出力ファイルをS3へ転送し、ナレッジベースの取り込みを実行 | 検索・回答生成APIを呼ぶBotを別途実装 |
本体が用意する方式はMarkdownFile・Dify・OpenAiの3つです。Azure・AWSの構成は、ファイル出力を入口にする追加実装です。Azure OpenAIのURLを標準OpenAi方式のEndpointへ入れれば同じ設定で使える、という説明ではありません。標準方式はOpenAIのFiles・Vector Store APIとBearer認証を使います。方式の定義、OpenAIの登録API
1. サーバー側で有効にする
Implem.Pleasanter/App_Data/Parameters/AiConnect.jsonを編集します。以下は変更する項目の抜粋です。既存のFormatTemplateやリトライ設定は残してください。
{
"Rag": {
"Enabled": true,
"DeleteEnabled": false,
"OutputFilePath": "C:\\Pleasanter\\AiConnect"
}
}| 項目 | ソースの既定値 | 設定の意味 |
|---|---|---|
Rag.Enabled | false | AI連携を有効にする |
Rag.OutputFilePath | null | Markdownの出力先ルート。Dify・OpenAIを使う場合も必須 |
Rag.DeleteEnabled | false | レコード削除に伴う連携文書の削除を有効にする |
Rag.FormatTemplate | タイトル・管理情報・内容・コメントなどのテンプレート | AI連携設定を新規作成するときの連携フォーマットの初期値 |
出力先はプリザンターの実行ユーザーが書き込める場所を指定します。Linuxでは、例えば/var/lib/pleasanter/ai-connectのようなパスに置き換えてください。設定を反映するため、プリザンターを再起動します。
FormatTemplateは新しいAI連携設定を作るときにコピーされます。すでに作成した設定の送信内容は、テーブル側の「連携フォーマット」を編集します。
根拠はAiConnect.jsonの既定値、フォーマットの初期化、出力先とフォーマットの検査です。
2. ファイル出力で送信内容を確かめる
対象のテーブルで「テーブルの管理」→「AI連携」を開き、「新規作成」で次の設定を追加します。
| 画面項目 | 設定例 |
|---|---|
| タイトル | ナレッジ出力確認 |
| 連携方式 | マークダウンファイル(内部値はMarkdownFile) |
| 連携フォーマット | 下のテンプレート |
| 無効 | オフ |
# [Title]
状況: [Status]
## 内容
[Body]
## 補足
[DescriptionA]
---
URL: {Url}DescriptionAを使う場合は、対象テーブルで長文項目Aを有効にしてください。不要なら「補足」の部分を削除します。[Title]などは項目の表示値、{Url}はレコード編集画面の絶対URLに置換されます。既定のテンプレートにはコメントも含まれますが、上の例では本文と補足に絞っています。
「追加」でダイアログを閉じた後、テーブル管理画面の「更新」で設定を保存します。「全て無効化」がオフであることも確認してください。
次に、ダミーのタイトル・本文・補足を入れたレコードを1件作成または更新し、次のパスにファイルが出力されることを確認します。通常更新の送信は内部タスクになる場合があるため、保存直後に見つからなければシステムログも確認します。
C:\Pleasanter\AiConnect\<テナントID>\<サイトID>\
pleasanter-<テナントID>-<サイトID>-<連携先ID>-result-<レコードID>.md記録テーブルはresult、期限付きテーブルはissueになります。同じテナント・サイト・連携設定・レコードでは同じファイル名で書き出します。文字コードはUTF-8(BOMなし)です。
確認する点は、タイトルや本文が置換されていること、必要な長文項目が含まれていること、外部へ渡したくない項目が含まれていないことです。MarkdownFileは外部APIを呼ばないため、ここで失敗した場合は出力先・書き込み権限・フォーマットから調べます。
根拠は項目・URLの置換、出力パス、ファイル名・文字コード、MarkdownFileの送信処理です。
3. DifyまたはOpenAIへ接続する
ファイルの内容を確認したら、「テーブルの管理」→「AI連携」で設定を開き、「連携方式」を変更します。「連携設定」に次のJSONを入力し、「変更」でダイアログを閉じ、管理画面の「更新」で保存します。設定を追加する場合は「新規作成」→「追加」→「更新」です。
Dify
セルフホスト環境をこれから用意する場合は、AzureにDifyを構築してプリザンターと連携するでVMの作成からHTTPS、ナレッジ、回答アプリまで説明しています。
接続先のデータセットIDと、そのナレッジAPIへアクセスできるAPIキーを用意します。次の値を実際の接続情報に置き換えてください。
{
"Endpoint": "https://dify.example.com/v1",
"DatasetId": "YOUR_DATASET_ID",
"ApiKey": "YOUR_DIFY_KNOWLEDGE_API_KEY"
}本体は、Markdownファイルをdatasets/<DatasetId>/document/create-by-fileへ送信します。既存文書の更新にはupdate-by-fileを使います。新規登録のindexing_techniqueはhigh_quality、process_rule.modeはautomaticで送信されます。この2項目を変更するサイト設定はありません。
根拠はDifyの接続設定の解決、登録・更新リクエストです。
OpenAI
接続先のVector Store IDとAPIキーを用意します。OpenAiは設定ファイル中の識別子、OpenAIは画面の表示名です。
{
"Endpoint": "https://api.openai.com/v1",
"VectorStoreId": "YOUR_VECTOR_STORE_ID",
"ApiKey": "YOUR_OPENAI_API_KEY"
}本体はfilesへファイルをアップロードし、vector_stores/<VectorStoreId>/filesへ登録します。ファイルの送信成功と、Vector Storeでのインデックス完了は別の段階です。連携先で文書を参照できる状態になってから、回答アプリで利用してください。
根拠はOpenAIの接続設定の解決、アップロードとVector Storeへの登録です。
Endpointの省略と通信条件
サイト側のEndpointが空文字列なら、AiConnect.jsonのProviderEndpointsにある同じ方式の値を使います。例えば、共通のDify接続先を次のように指定できます。
{
"ProviderEndpoints": {
"Dify": "https://dify.example.com/v1",
"OpenAi": "https://api.openai.com/v1"
}
}ProviderEndpointsは既定URLの設定です。接続先を制限する許可リストではなく、サイトのEndpointに別のHTTPS URLを指定できます。サイト側とパラメータ側の両方が空なら接続できません。
通常はHTTPSが必要です。HTTPが認められるのは、AllowInsecureLoopbackEndpointをtrueにし、接続先がループバックの場合だけです。別ホストで動くDifyへHTTPで接続するための設定ではありません。
public static bool AllowedEndpoint(string endpoint)
{
if (Uri.TryCreate(endpoint, UriKind.Absolute, out var uri) == false)
{
return false;
}
if (uri.Scheme == Uri.UriSchemeHttps)
{
return true;
}
if (uri.Scheme == Uri.UriSchemeHttp)
{
return Parameters.AiConnect?.AllowInsecureLoopbackEndpoint == true
&& uri.IsLoopback;
}
return false;
}出典: Implem.Pleasanter/Libraries/AiConnect/AiConnectUtilities.cs(31–47行・8d29c7b)
ここではURLのスキームとループバックを検査しています。ProviderEndpointsとの一致は検査していません。
Azure・AWSへファイル出力を取り込む
この節はクラウド側の接続を組み立てるための構成例です。クラウドへのデプロイ・実接続は未検証です。プリザンター側は、先に説明したMarkdownFile方式を使います。
図を読み込み中…
Azure AI Search + Azure OpenAI
Azure AI SearchのBlobインデクサーはMarkdownを読み取れます。1ファイルを1文書として扱うoneToOneと、見出し単位に複数文書へ分けるoneToManyがあります。プリザンターの出力は1レコード1ファイルですが、Search側で分割する構成なら、各検索結果から元のレコードへ戻れる識別情報も保持します。Markdown取り込みの仕様
構成する順序は次のとおりです。
- 対象テーブルを
MarkdownFileで出力します。 - 対象のテナント・サイトのフォルダだけを、専用Blobコンテナーへ転送します。複数の連携設定があればファイル名の接頭辞でも対象を絞ります。
- Azure AI Searchに検索インデックス、Blobのデータソース、インデクサーを作成します。
- インデクサーの設定で
parsingModeをmarkdownにし、文書の分け方を指定します。次は設定部分の例です。 - インデクサーを実行し、ダミーの本文を検索して取得できることを確認します。
- Botのサーバー側でSearchへ質問を送り、取得した本文と参照元を回答生成へ渡します。
{
"parameters": {
"configuration": {
"parsingMode": "markdown",
"markdownParsingSubmode": "oneToMany",
"markdownHeaderDepth": "h2"
}
}
}Azure AI Searchの検索とLLMへの受け渡しをアプリが担当する構成をClassic RAGと呼びます。Azure AI SearchとAzure OpenAIは別の役割で、文書をBlobへ置いただけでチャット画面が完成するわけではありません。AzureのRAG構成
Amazon Bedrock Knowledge Bases
Bedrock Knowledge BasesはUTF-8のMarkdown(.md)を取り込めます。プリザンターの出力ファイルを専用S3バケットまたはプレフィックスへ転送し、S3をデータソースとするナレッジベースに取り込みます。対応する文書形式
- 対象テーブルを
MarkdownFileで出力します。 - 対象サイトのファイルだけを専用S3プレフィックスへ転送します。
- BedrockでS3をデータソースとするナレッジベースを作成し、利用する埋め込みモデル・保存先を設定します。
- データソースの「Sync」または
StartIngestionJobで取り込みを開始します。S3へのアップロードと取り込みは別の処理です。 - 取り込みの状態と失敗件数を確認し、ダミーの本文が取得できることを確かめます。取り込みと状態確認の仕様
- Botのサーバー側から検索・回答APIを呼び、回答と引用を画面へ返します。
通常のKnowledge BasesではRetrieveAndGenerateで検索と回答生成をまとめて呼べます。Managed Knowledge BasesはこのAPIの対象外なので、採用する種類に応じてRetrieveなどの対応APIを選びます。名称だけで同じAPIを使えると判断しないでください。RetrieveAndGenerateの仕様と対象
更新と削除をつなぐ
プリザンターのRag.DeleteEnabledが削除するのは、標準連携先の文書とローカルの出力ファイルです。MarkdownFile方式から別途転送したBlob・S3オブジェクトは、その削除処理に含まれません。
追加実装では、ファイルの転送、クラウド上の古いファイルの削除、検索インデックスへの削除反映までを別々に確認します。出力フォルダ全体を無条件にミラーする構成では、他サイトのファイルも対象になります。転送対象は専用フォルダ・プレフィックスに限定してください。
Botの画面スクリプトは質問・回答の表示として共通化できますが、このサイトのOpenAI BotのサーバーコードをAzure・AWSへそのまま流用はできません。呼び出すAPI、認証、応答中の引用の取り出し方を連携先に合わせた実装が必要です。
4. 既存レコードを同期する
接続設定を「変更」→テーブル管理画面の「更新」で保存したら、「AI連携」の一覧で対象の設定を1件だけ選択し、「同期」を実行します。初回登録や、連携フォーマットを変えて既存レコードも書き直したい場合に使います。
「同期」は差分だけを追加する処理ではありません。Dify・OpenAIでは、その連携設定が登録した文書を削除してから、対象テーブルのレコードを再登録します。
図を読み込み中…
削除対象の識別にはpleasanter-<テナントID>-<サイトID>-<連携先ID>-という接頭辞を使います。環境を複製して同じID構成になった検証環境と本番環境では、接続先とAPIキーを分けてください。同じ接続先へ同期すると、互いの文書を削除するおそれがあります。
Rag.DeleteEnabledはレコード削除時の連動を制御します。「同期」の事前削除は別の処理で、DeleteEnabledがfalseでも実行されます。MarkdownFileの全件削除処理は何もしないため、ファイル出力だけの場合は「同期」で古いファイルが一掃されるわけではありません。
根拠は同期の選択・実行条件、削除後の再登録、Difyの削除対象、MarkdownFileの全件削除です。
5. 更新・削除を運用する
通常更新と全件同期の実行方式
永続化されたバックグラウンドキューを使う条件は、次の3つです。
BackgroundJobs.jsonのBackgroundQueueがtrue。Queueライセンスオプションが利用できる。BackgroundJobs.jsonのOutputFilePathが設定されている。
AiConnect.jsonのRag.OutputFilePathはMarkdownの出力先、BackgroundJobs.jsonのOutputFilePathはキュー側の出力先です。別の設定なので、一方だけ設定してもキュー条件は満たしません。
| 操作 | キュー条件を満たす | キュー条件を満たさない |
|---|---|---|
| 通常のレコード作成・更新・削除 | ジョブとして登録 | 通常はプロセス内のタスクで実行。待機中・実行中の処理数が100を超えると同期実行 |
| 「同期」ボタンによる全件再同期 | ジョブとして登録し、処理IDを返す | リクエスト内で全件処理し、結果を返す |
キューなしの通常更新は、同時実行数4で、同じレコード・連携設定の処理を順番に実行します。全件同期ではキューなしでもすぐ画面が戻るとは限りません。件数が多い環境では、キュー設定と処理結果を確認してから実行してください。
根拠はキューの判定、キューの有効化条件、通常更新のタスク実行、全件同期の実行方式です。
削除と停止の違い
レコード削除に合わせて連携文書とローカルファイルも削除したい場合は、Rag.DeleteEnabledをtrueにします。Enabledがtrueであり、対象の連携設定と「全て無効化」が無効になっていないことも必要です。
「無効」「全て無効化」は処理を止める設定です。停止中の削除も連携しないため、停止を連携先の文書削除の代わりに使わないでください。
根拠は削除の実行条件、外部文書とファイルの削除順序です。
APIキーの保管
APIキーは画面では********でマスクされ、マスク値を保存し直した場合は保存済みのキーが使われます。ただし、設定の記録にはConnectionSettingの文字列をそのまま保持します。マスク表示は保存値の暗号化ではありません。サイトパッケージを渡す前に認証情報を確認してください。
根拠はキーのマスクと保存値の復元、連携設定の記録です。
送信できないときの切り分け
| 症状 | 確認するところ |
|---|---|
| 「AI連携」タブがない | Rag.Enabledがtrueか、設定が反映されているか |
| ファイルが出ない | Rag.OutputFilePath、書き込み権限、連携フォーマット、個別の「無効」と「全て無効化」 |
| ファイルは出るが外部に登録されない | 接続設定のJSON、APIキー、Dataset ID / Vector Store ID、Endpointの解決結果とHTTPS条件 |
| 設定を保存できても送信に失敗する | 保存時の接続設定検査はJSONオブジェクトとして読めるかの検査。保存成功だけでAPI疎通は確認できない |
| 「同期」を押せない・拒否される | 1件だけ選択しているか、設定が無効でないか、出力先が設定されているか |
| 既存レコードが連携先にない | AI連携設定の追加だけで全件登録されるわけではない。「同期」を実行したか |
| 保存が終わったのに文書がまだ使えない | ジョブ・内部タスクの完了と、連携先のインデックス状態 |
| 削除したレコードが連携先に残る | Rag.DeleteEnabled、停止設定、削除処理の失敗ログ |
システムログでは、TenantId・SiteId・AiProviderId・ReferenceIdで対象を絞り、PhaseとMessageを確認します。ファイル出力のログにはOutputFilePath・Body・Writeなどの段階が記録されます。レコード保存の成功だけで外部送信の成功とは判断せず、出力ファイルと連携先の文書の両方を確認してください。
根拠は保存時のJSON検査、出力エラーのログ項目です。