ガードレールを備えた「デジタルツイン・エージェント」の構築方法

本ブログは、毎週開催しているライブビルドセッション「Build Club」からの第2弾です。本セッションのソースコードは、GitHubリポジトリ「Yourself as a Service」および「Slack Bot App」で公開しています。

本当に解決すべき課題は、受信用インボックスの混雑そのものではありません。問題の本質は、自分自身が他人の作業を止めてしまうボトルネックになっていることにあります。

受信したメッセージの中には、確かにあなたでなければ返答できないものも存在します。しかしその大半は、今期すでに6回も繰り返した質問への回答であったり、昨年作成したドキュメントに記載されている情報であったり、適切な参考情報を提示しさえすれば相手自身で判断できるものばかりです。しかし、より厄介な点は、実際にメッセージを開いて読むまで、どれが「自分で返答すべきもの」で「どれがそうでないか」を区別することができません。その結果、未読スレッドは積み上がり、見落としが発生し、あなたが責任を負うすべての業務の進行が停滞してしまいます。

この課題を解決するために、ある強力なアプローチが登場しました。それが、届いたメッセージを自動分類・整理し、一次回答のドラフトを作成し、本当にあなた自身の対応が必要なメッセージだけを通知・エスカレーションさせる「デジタルツイン・エージェント」です。この設計アプローチは確実にあなたの業務で機能します。

しかし、本当に難しいのはエージェントを構築することではありません。導入初日にベクターデータベースへ機密情報を誤って流出させることなく、安全に本番運用へ乗せることなのです。

DataRobot のSenior Principal Software Engineerである Carson Gee は、Build Club セッションの冒頭で、彼自身が抱える切実な事実を明かしました。彼には、数百件もの未読メッセージが溜まっていたのです。続くセッションでは、彼がこれらのメッセージを整理・対応するために、どのようにデジタルツイン・エージェントを構築したかについて実演と解説が行われました。

以下は、その実践的な手順書です。結論から言えば、DataRobot プラットフォームを活用すれば、約1時間でデジタルツイン・エージェントを立ち上げることができます。しかし、より本質的な話をすれば、重要になってくるのは最後の20分間です。なぜなら、その最後の20分間こそが、モデレーション、オブザーバビリティ、そして単なる「デモ」と「実用(本番運用)」を分ける境界線を決定づけるからです。

デジタルツイン・エージェントの役割

CaaS Slack

デジタルツインは、あなたの判断そのものを代行するものではありません。 あくまで、判断の手前に置くトリアージ(優先度分類)のレイヤーです。Carson はこの仕組みを「Carson-as-a-Service(CaaS)」と名付けました。CaaS が担う役割は、大きく分けて以下の4つです。

CaaS は追加されたすべての Slack チャンネルを監視しますが、反応するのは直接メンションされた時のみです。誰かが Carson に @メンション を送ると、エージェント型のワークフローが起動し、そのメッセージを次のように分類します。

  • 本人の判断が必要か
  • 彼が過去に書いた文書から回答できるか
  • 後回しにして問題ないか

本人の対応が必要だと判断した場合、CaaS は概要を作成して Carson に DM を送信します。本人の対応が不要な場合は、Carson らしいトーンでそのまま自動返答を行います。

CaaS Scheduled Jobs

カスタムの周期で実行できる、プロンプト駆動のスケジュールジョブ

CaaSは、彼が追跡しているトピックに関する深掘り調査(Deep-research)のスケジュールジョブを実行します。また、CarsonのConfluenceページ、ブログ記事、保存されたメモリのデータベースを維持管理しているため、回答が彼本人のように聞こえます。労力と見返りの不均衡(非対称性)は非常に魅力的です。わずか1時間のセットアップで、トリアージ作業時間を毎日およそ30分間、恒久的に削減することができ、さらにチューニングを続けて調整していく選択肢もあります。

このパターンは、オンコール対応を担当するエンジニアから、「これはロードマップに入っていますか?」というあらゆる質問に対応するプロダクトマネージャー、他人の決断のためにカレンダーの予定が埋まってしまうマネージャー、そして以前答えたことのある質問でインボックスがいっぱいになっているサポートリードに至るまで、さまざまな職種に展開できます。

共通する課題の構図はどれも同じで、パターン化された問い合わせが大量に届くものの、実際に本人を必要とするのはそのほんの一部であり、一目見ただけではそれらを判別する良い方法がないという点にあります。

デジタルツイン・エージェントを構築してみよう

以下の手順は、すべてDataRobotのアカウントを持っていることを前提としています。また、「Agentic Starter」アプリケーションテンプレートを使用する必要があります。使用する関連テンプレートはオープンソース化されており、下記からアクセス可能です。

ステップ1:Agentic Starter アプリケーションテンプレートから始める

Agentic Starter アプリケーションテンプレートを使用することで、FastAPIサーバー、デプロイ用スキャフォールド(雛形)、およびLLMをベースとしたエージェントテンプレートが手に入ります。これをフォークするか、DataRobot UIから直接アクセスできます。

Carsonのデジタルツインは、構造的には修正を加えていないこのスターターキットに、Slackアプリ、Files APIに接続されたベクターデータベース、そしてパーソナリティ(人格設定)プロンプトを追加したものです。

ステップ2:Slackリスナーを追加する

DataRobot Slackアプリテンプレートを使用して、ボットトークンとアプリトークンを紐付けます。ここで最も重要なカスタマイズは、ボットが直接メンションされた場合のみ反応するようにSlackリスナーをフィルタリングすることです。この設定を行わないと、ボットが参加しているすべてのチャンネルの全メッセージを記録してしまい、オブザーバビリティ(可視性)上の問題とプライバシー上の問題の両方が生じることになります。

ステップ3:ナレッジベースを組み込む
Agentic Starter

このステップが、デジタルツインが「あなた自身」のように聞こえるか、それとも「汎用的なLLM」のように聞こえるかを左右します。ナレッジベースの参照先には、あなたが実際に執筆したコンテンツ(Confluenceのページ、ブログの下書き、会議の議事録、過去6か月間の長文のSlackメッセージなど)を指定してください。CarsonはMCPコネクタを使用して自身のConfluenceスペースをナレッジベースに読み込み、その上に「メモリー」メカニズムを重ねることで、Slack内からツール呼び出し経由で新しい文脈(コンテキスト)を追加できるようにしました。

ナレッジベースのバックエンドにはDataRobotのベクターデータベースが使用されており、これがLLMブループリントに接続されます。現時点では、元となるファイルの更新によってベクターDBの再構築がトリガーされる仕様となっています。差分更新(インクリメンタル更新)機能は今後のロードマップに含まれているため、当面の間はナレッジの更新を一括(バッチ処理)で行ってください。

ステップ4:パーソナリティ・プロンプトを作成する
Personality Prompt

デフォルトのシステムプロンプトでは、どこにでもある汎用的なアシスタントになってしまいます。それはあなたが求めているものではありません。作成したツインの初期バージョンは、気まぐれすぎたり、直線的すぎたり、真面目すぎたりするはずであり、本当に人々が会話したいと感じるのは2番目のバージョンです。その違いは実際にデプロイして初めて分かります。Carsonのプロンプトでは、モデルに対して「キャラクターを伴いつつ、端的に答える」よう明示的に指示しており、彼が現実で持っている技術的トピックへの持論も含まれています。あなたのプロンプトもそうあるべきです。

ステップ5:本番運用の前にPII(個人識別情報)ガードレールを追加する

これは、ライブセッションの参加者からの指摘によって急遽ビルドに追加されたステップであり、多くのチームがスキップしてしまう工程です。実際のプロセスは次のようになります。

DataRobotには、グローバルなPresidio PII検知モデルが用意されています。DataRobotのモデルレジストリでこれを見つけ、そこからデプロイすることができます。次に、LLMブループリントのバックエンドとなるカスタムモデル上で評価・モデレーションパネルを開き、PII検知器をモデレーションモデルとして追加(アタッチ)します。

モデレーション方法を「置換(replace)」(マイナンバーやクレジットカード番号などの検知されたエンティティを括弧付きのプレースホルダーで匿名化する)または「ブロック(block)」(レスポンス処理自体を即座に中断する)のいずれかに設定します。失敗時の動作をどれほど厳格にしたいかに応じて、確率閾値(スレッショルド)を調整してください。0.5の閾値であれば、ほとんどの明らかな情報漏洩を捕らえるのに十分な感度となります。閾値をこれより低くすると、害のないメッセージに対しても誤検知(偽陽性)が発生し始め、ツインが壊れているように感じられてしまいます。

モデレーションをLLMブループリントモデルに追加します。これは先ほどと同じ評価・モデレーションパネルですが、1つ上のレイヤーに追加することで、すべてのエージェント呼び出しが確実にモデレーションされるようになります。UI側で、モデルのアセット内に moderation_config.yaml が生成されます。

そのYAMLファイルをローカルプロジェクト内のエージェントフォルダにコピーし、ガードレールがデプロイ環境へ一緒に引き継がれるようにします。デプロイ側のスマートディフ(差分検出)機能によって小さな変更は自動的に処理されるため、LLMブループリントの設定に大きな変更を加えた場合のみ、手動でモデレーションを再追加する必要があります。

ステップ6:デジタルツイン・エージェントをデプロイする
DataRobot Tracing

ツインにいくつかのテストプロンプトを送信します。1つは明らかに無害なもの、1つは偽のSSN(社会保障番号)を含むもの、もう1つは偽のクレジットカード番号を含むものです。モデレーションされたレスポンスがSlack上で正しく表示されること、そしてトレース(処理ログ)でモデレーションが作動していることを確認してください。

LLM層にガードレールを設定した場合、エージェントのトレースには生の入力が表示され、その後の処理でモデレーションされた出力が表示されます。一方、エージェント層に設定した場合、トレースには最初から最後までモデレーション済みの入力が反映されます。セキュリティレビューでどちらが求められるかを判断し、ドキュメントに記録してください。

今回のセッションから学んだこと

このセッションは本来、生産性向上のデモとして予定されていました。しかし、私たちが顧客に提供しているモデレーションとオブザーバビリティの適用領域を深く探求するセッションとなりました。この脱線にこそ本質があります。デジタルツインが生産性を向上させることは間違いありませんが、真の課題はそれを安全に本番稼働させられるかという点にあるからです。

セキュリティエンジニアを含む参加者の前で、ライブデモが進行する中で得られた3つの学びは以下の通りです。

  • 「自分のために作ったもの」と「セキュリティ部門に説明・防衛できるもの」の間の溝は、本来あるべき姿よりも広がっています。 あらゆるツインの第1バージョンには、第2バージョンで必要となるガードレールが備わっていません。モデレーションのステップは、単なる「仕上げ(ブラッシュアップ)」として扱うのではなく、最初から計画に組み込んでください。
  • Slack上で動作するエージェントにとって、オブザーバビリティ(可視性)は諸刃の剣となります。 エージェント型のワークフローをデバッグする際、トレース機能は極めて有用です。しかし、誰かがボットに認証情報を貼り付けてしまった場合、トレース機能は望ましくない存在と化します。適切な設計パターンは、機密度に応じてトレースごとに範囲を限定し、保存データ(暗号化済み)をベースにしたマスク表示(伏字化)を行うことです。
  • セルフヒーリング(自己修復・自己最適化)の方向性は本物であり、実験してみる価値があります。 Carsonのツインは自身のシステム定義をFiles APIに書き戻し、パーソナライズされた変異体として再ロードすることで、あなたと対話しているツインのバージョンをあなた専用にチューニングできるようにしています。これはまだスターターキットには含まれていませんが、次回のセッションに含まれる予定です。

実際に試してみる

Build Clubは毎週開催されています。各セッションでは1名のボランティアドライバーが登壇し、1時間で、参加者の投票によって選ばれたアイデアを構築します。このフォーマットは意図的にリハーサルなしで行われます。ライブで構築し、ライブで動作が破綻し、それをライブで修復します。DataRobot上で開発を行っている方や、エンタープライズ対応のエージェント検討中でインスピレーションを得たい方にとって、本シリーズは最適なコンテンツです。

今すぐ始めてみましょう

AI で迅速にビジネス価値向上を実現。今すぐ始めましょう。