生成AIシステムの6段階の進化/成熟モデルの定義

The GenAI Maturity Model | by Ali Arsanjani

Ali Arsanjani: Director, Google AI


元記事:https://medium.com/@dr-arsanjani/the-genai-maturity-model-a1a42f6f390b


数百ものAIプロジェクトを分析すると、段階的な成長と成熟の傾向が見えてきます。生成AIの成熟モデルはこれを反映し、生成AIソリューションが6つの明確なレベルの洗練度を通じて進化することを枠組みとして明確に示しています。

このような成熟モデルを使用することで、組織は自身が生成AI成熟モデル上で現在どの位置にあるのかを明確に理解し、能力を向上させてビジネス目標を達成するための具体的な戦略を策定することができます。この評価はまた、技術投資、人材獲得、プロセス最適化に関する情報に基づいた決定を行うのに役立ち、ビジネス能力と一致したより成功した生成AIシステムの進化を確実にします。


目次:

生成AIの進化

Gen AI 成熟度モデル:進化するためのステップ

レベル0: データの準備

レベル1: モデルとプロンプトの選択:モデルの選択

レベル2: Retrieval Augmentation: 情報を収集してプロンプトを保管する

レベル2.1: シンプルな検索と生成

レベル2.2: コンテクスト検索と生成

レベル2.3: 動的な取得と生成

レベル2.4: マルチソース検索と生成

レベル2.5: ナレッジグラフを意識した生成

レベル3:ドメイン固有のデータを用いたモデルのチューニング

3.1. 文脈内学習 (In-Context Learning - ICL)

3.2. マルチショット (Multi-shot Using Large Context Windows)

3.3. 小型言語モデルの事前学習 (Pretraining Small Language Models)

3.4. アダプターチューニング (Adaptor Tuning)

3.5. ローランク適応 (Low-Rank Adaptation - LoRA)

3.6. 他のパラメタ効率の良いファインチューニング手法 (Other Parameter-Efficient Fine-Tuning Methods)

3.7. 特定ドメインに特化した事前学習 (Domain-Specific Pretraining)

3.8. 教師ありファインチューニング (Supervised Fine-Tuning)

3.9. モデル全体学習 (Full Fine-Tuning)

3.10. 指示学習 (Instruction Tuning)

3.11. 人間のフィードバックによる強化学習 (Reinforcement Learning with Human Feedback - RLHF)

3.12. 直接的なポリシー最適化 (Direct Preference Optimization - DPO)

3.13. マルチタスクファインチューニング (Multitask Fine-Tuning)

3.14. メタ学習 (Meta-Learning - Learning to Learn)

3.15. 能動学習 (Active Learning)

3.16. 知識蒸留 (Knowledge Distillation)

レベル4: 検索と引用を用いたモデル出力の基盤確立

レベル5: エージェントベースシステム

エージェントベース対マルチエージェントシステム

レベル6: マルチエージェントの複合採用 (The Multi-Agent Multiplier)

水平および垂直ドメイン

水平ドメインにおける生成AIの活用によるROIの向上

垂直ドメインにおける生成AIの活用によるROIの向上

結論とアクションプラン

参考文献


生成AIの進化

生成AIの進化とは、データとAIがどのようにアプリケーションに使用されるかを改善する手法を段階的に整理したものです。

レベル0から始まり、ここでデータを収集、クリーニング、準備します。このデータは生成AIモデルの訓練に不可欠です。

レベル1では、組織は生成AIモデルを選択し、インタラクションのためのプロンプトを作成します。プロンプトはモデルの応答をガイドします。適切なモデルとプロンプトを選択することは、求める結果を得るために重要です。このレベルでは、これらのモデルを特定のタスクに有用にするために、我々が調整します。

レベル2はより複雑になります。ここでは、生成AIモデルがその広大な知識ベースから特定の洞察を引き出します。レベル3では、生成AIモデルを特定のデータで調整します。この調整、またはファインチューニングは、モデルのパフォーマンスを向上させ、よりパーソナライズさせるのに役立ちます。これにより、組織はモデルを自分たちの特定のニーズに適応させることができます。

次のレベルでは、モデルはさらに洗練されます。我々はモデルの応答が正確で、関連性があり、倫理的であることを確認します。我々は、Lead Language Model(LLM)の指導の下で一緒に働く複数の生成AIモデルを使用します。このアプローチは、調整が必要な複雑なタスクに役立ちます。モデルの動作を見ることができ、生成AIライフサイクルをスムーズに管理することが重要です。

高いレベルでは、Tree-of-Thought(ToT)、Graph-of-Thought(GoT)、DSPy、自己修正、ReActなどの先進的な技術が使用できることを覚えておいてください。これらの技術は生成AIモデルの意思決定と問題解決の能力を強化します。それらは、生成型AIができることの限界を押し広げます。

https://miro.medium.com/v2/resize:fit:525/1*gLzVaoaqIyMZ8eIF2nBU0w.png

生成AI成熟度モデル - より良いビジネス結果へのシンプルガイド

成熟度モデルの図は、生成型AIソリューションが7つの段階を通じてどのように複雑で高度になることができるかを示しています。

各レベルのコンポーネントは、レベル(行)を超えて列にグループ化することができることに注意してください。このセットアップは、RAGやモデルチューニングのような特定のエリア内での複雑さの増加を示しています。

Gen AI 成熟度モデル:進化するためのステップ

このモデルは、生成AIソリューションがより高度になるためのステップを示しています。データの準備や適切なモデルの選択などのシンプルなタスクから始まります。次に、微調整や評価などのより複雑なタスクに移行します。最終的には、複数のエージェントが協力して働く、高レベルの意思決定、そしてAIの責任ある使用といった最も進んだ段階に到達します。

レベル0:データの準備

この基本レベルは、生成AI /LLMベースまたはエージェントベースのアプリケーションに必要なデータセットを取得することに焦点を当てています。これには、データの購入、クリーニング、準備、使用許可の取得、合成データの作成、およびデータエンジニアリングと変換タスクの実行が含まれます。

レベル1:モデル&プロンプト選択:モデルの提供

このレベルは言語学習モデル(LLM)を選択し、それに対するプロンプトを作成する、というシンプルがステップです。このレベルにおいて、適切なモデルの特定、それらと対話するためのプロンプトの開発が主たる作業になります。また、プロンプトエンジニアリングによってモデルを指導して特定のタスクに使用するケースもあります。同じプロンプトがLLMによって異なる結果を出すこともあり、その考慮が日つよづエス。

モデル選択、プロンプトエンジニアリング、および検索: 手元のタスクに適したLLMモデルを選択し、特定のデータでそれを微調整することから始まります。丁寧なプロンプトエンジニアリングがモデルの性能の決め手であり、RAGがが社内の知識ベースから関連情報を引き出します。このRAGによる検索ステップは、エンタープライズ検索機能によって強化されケースが多く、AIモデルが組織のリソースから関連文書やデータにアクセスすることを可能にします。

コンテキスト内学習 (In-context learning)とマルチショット学習 (Multi-shot learning)は、モデルの品質を高めることに寄与します。詳しくは、モデルチューニングセクションを参照してください。

レベル2: Retrieval Augmentation: 情報を収集してプロンプトを保管する

この段階では、生成AIモデルを使用して重要な情報を取り出します。モデルと詳細な会話をするようなもので、具体的な洞察や事実を得ることができます。

ここで、独自のユニークなデータを使用して生成AIモデルをトレーニングし始めます。これにより、モデルがより良く機能し、特定のニーズに合わせてカスタマイズすることができます。

取得強化ジェネレーション(RAG)は、情報検索システムとLLMを組み合わせて、より正確で情報に基づいた回答を提供するシステムです。RAGの複雑さは、検索と統合のプロセスがどれほど複雑であるかに基づいて、さまざまなレベルに分解することができます。

RAG(取得強化ジェネレーション): まず内部の情報源から情報を得た後、RAGはVertex AIグラウンディングサービスなどが提供する外部の検索ツールを使用します。外部の知識ベース、ウェブ、その他の関連する情報源を見て、生成物の精度と文脈を改善するための追加情報を見つけます。内部と外部の両方の検索の使用により、主題を完全に理解することができます。

RAGには複数の複雑さのレベルがあります。下記にそれを整理します。

レベル2.1:シンプルな検索と生成

この基本レベルでは、RAGはユーザーのクエリに基づいて知識ベースから関連するドキュメントを検索します。検索した情報はそのままLLMに渡され、検索した内容を元にレスポンスを生成します。このアプローチは比較的直接的ですが、LLMが検索した情報を理解し、統合する能力に依存するため、必ずしも正確で関連性の高い結果を生み出すわけではありません。

レベル2.2:コンテクストに基づく検索と生成

このレベルでは、ユーザーのクエリの内容を考慮したより高度な検索メカニズムが導入されます。単純なキーワードマッチングに基づいたドキュメント検索だけでなく、関連性の高い情報を特定するために、セマンティック検索やクエリ拡張などの技術を利用します。さらに、検索された情報は、関連性や重要性に基づいてフィルタリングやランキングされてからLLMに渡されます。これにより、LLMが提供する情報がより焦点を絞った情報になり、レスポンスの質が向上します。

レベル2.3:ダイナミックな情報取得と生成

このレベルでは、RAGをさらに一歩進め、生成プロセス中に動的にに情報取得を行います。すべての関連情報を最初に取得するのではなく、LLMは必要に応じて追加情報を繰り返し要求し、より包括的で正確なレスポンスを生成することができます。このアプローチにより、LLMは曖昧さを明確にするためや知識のギャップを埋めるために、積極的に追加情報を求める、インタラクティブな会話が可能になります。

レベル2.4:マルチソースの検索と生成

この高度なレベルでは、複数の異なる知識ベース、データベース、あるいはリアルタイムのデータストリームなどから情報を取得することが含まれます。ここでの課題は、異なるフォーマット、構造、信頼性のレベルを持つ様々なソースからの情報を効果的に統合することです。これは、生成された応答が一貫性があり、正確で、最新の情報であることを確保するために、洗練された検索技術と融合技術を必要とします。

レベル2.5: ナレッジグラフを意識した生成

この最高レベルにおいて、RAGは知識グラフや他の構造化された知識表現を取り込み、LLMの取得情報のレベルを強化します。これにより、LLMは取得した知識を意味的に理解し、概念間の関係を特定し、より洞察力のある回答を生成することができます。このアプローチは、深い専門知識や推論能力を必要とする複雑なタスクに特に有用です。

レベル3:ドメイン固有のデータを用いたモデルのチューニング

このレベルでは、成熟度の向上に伴い、パラメータ効率的なファインチューニング、人間のフィードバックによる強化学習(RLHF: Reinforcement Learning with Human Feedback)、監督ファインチューニング(SFT: Supervised Fine Tuning)、全面的なファインチューニング(FFT: Full Fine-uning)を用いてモデルをチューニングする能力が含まれます。

これにより、モデルはその特定の業界やドメインに関連するデータでの訓練が可能になります。長年のビジネスで蓄積されたプライベートデータは所属する業界における企業の価値です。リテール、ヘルスケア、金融サービスなどの業界データに含まれる専門用語、オントロジーのエンティティ、一般的な知識に精通したモデルまたは2つのモデルを訓練することが重要です。

AIモデルのファインチューニングには、単純なコンテキスト調整から高度な強化学習まで、さまざまな方法があります。これらの方法を成熟度と洗練度に応じて詳述します。

3.1. インコンテキストラーニング (ICL: In-Context Learning)

  • 成熟度レベル: 基本
  • 相対コスト: 低
  • 必要なデータサイズ: 最小限 (ゼロショットまたは少数ショットの例)
  • 説明: モデルはプロンプト内で提供されるコンテキストのみに基づいて予測を行い、パラメータを更新しません。プレトレーニングフェーズで取得した知識に依存します [1]。
  • 使用例: 与えられた例やプロンプトに基づいてテキストやその他の出力を迅速かつ効率的に生成する。モデル全体を再訓練せずに迅速な適応が必要なシナリオに最適。

3.2. マルチショット (大きなコンテキストウィンドウの使用)

  • 成熟度レベル: 中級
  • 相対コスト: 中程度
  • 必要なデータサイズ: 最小から中程度 (少数ショットから多数ショットの例を含む広範なコンテキスト)
  • 説明: このアプローチは標準的なインコンテキストラーニングを拡張し、非常に大きなコンテキストウィンドウを活用します。これにより、プロンプトや周囲のテキストから大幅に多くの情報を処理することができます。これにより複雑なタスクの理解が向上するだけでなく、マルチショットインコンテキストラーニングも可能になり、コンテキストウィンドウ内で提供される複数の例からモデルが学習できます。[15]
  • 使用例: 深いコンテキスト理解が必要なタスクに最適:
    • 長文のテキスト生成
    • 複雑な質問応答
    • ドキュメントの要約
    • 多段階の推論タスク
    • 複数の例がモデルの出力を導くタスク

DeepMindの「多ショットインコンテキストラーニング」に関する研究は、コンテキストウィンドウ内に提供される例の数を増やすことで、パフォーマンスの大幅な向上が示されています。これは、単なる理解の向上だけでなく、複数のデモンストレーションから効果的に学習するモデルの潜在能力を強調しています。

3.3. 小規模言語モデルの事前学習

  • 成熟度レベル: 中級
  • 相対コスト: 中程度
  • 必要なデータサイズ: 中程度から大規模 (モデルのサイズと望まれる性能に依存)
  • 説明: これは、小規模な言語モデルをスクラッチから、または限られた量のデータでトレーニングすることを含みます。これらのモデルは、大規模で汎用的なモデルが計算制約やドメイン固有の要件のために実用的でない特定のアプリケーションに使用されることが多いです [3]。
  • 使用例: 特定の用語や限られた計算資源を持つ専門的なドメインでのタスクに効果的。また、さらなるファインチューニングや適応の基盤としても使用できます。

3.4. アダプターチューニング (Adaptor Tuning)

  • 成熟度レベル: 中級
  • 相対コスト: 低から中程度
  • 必要なデータサイズ: 小から中程度 (タスク特定データ)
  • 説明: この技術は、事前学習された言語モデルに小さな訓練可能なアダプターモジュールを導入します。これらのモジュールは、新しいタスクに対してファインチューニングするために特別に設計されており、元のモデルパラメータの大部分を凍結したままにします。これにより、最小限の計算負荷で効率的なタスク特定の適応が可能になります [4]。
  • 使用例: 限られたリソースで大規模なモデルを特定のタスクに適応させるのに最適。元のモデルの効率と知識を維持しながら、迅速かつターゲットを絞ったファインチューニングを可能にします。

3.5. ローランク適応 (Low-Rank Adaptation - LoRA)

  • 成熟度レベル: 中級から上級
  • 相対コスト: 中程度
  • 必要なデータサイズ: 小から中程度 (タスク特定データ)
  • 説明: LoRAは、モデルの重み行列の低ランク近似を調整することでモデルをファインチューニングします。これにより、訓練可能なパラメータの数が劇的に減少し、完全なファインチューニングよりもはるかに効率的になります [5]。
  • 使用例: 自然言語処理やコンピュータビジョンなどのさまざまなタスクに効果的で、大規模なモデルを特定のタスクに適応させる必要があるが、全パラメータを訓練するための完全な計算コストを避けたい場合に適しています。

3.6. その他のパラメータ効率の良いファインチューニング手法 (Other Parameter-Efficient Fine-Tuning Methods)

  • 成熟度レベル: 中級から上級
  • 相対コスト: 中程度
  • 必要なデータサイズ: 小から中程度 (タスク特定データ)
  • 説明: このカテゴリには、プリフィックスチューニング、プロンプトチューニング、BitFitなどの技術が含まれます。これらはすべて、モデルのパラメータや入力の一部だけを調整することでファインチューニングを行い、計算負荷を大幅に軽減します [6]。
  • 使用例: 新しいタスクやシナリオに迅速に適応する必要がある場合や、計算リソースが限られている場合に最適。これらの方法は、効率とモデルの動作を調整する能力のバランスを提供します。

3.7. 特定ドメインに特化した事前学習 (Domain-Specific Pretraining)

  • 成熟度レベル: 上級
  • 相対コスト: 高い
  • 必要なデータサイズ: 大規模 (ドメイン特定のコーパス)
  • 説明: 特定のドメイン(例:法務、医療、金融)に特化した大規模なテキストコーパスでモデルを事前学習します。これにより、モデルがそのドメイン特有のニュアンス、語彙、および知識構造を捉えることができます [7]。
  • 使用例: 一般的なモデルが必要なドメイン専門知識を欠いている場合に、専門分野で非常に価値があります。そのドメイン内でさらにファインチューニングや適応の出発点として使用できます。

3.8. 教師ありファインチューニング (Supervised Fine-Tuning)

  • 成熟度レベル: 上級
  • 相対コスト: 高い
  • 必要なデータサイズ: 大規模 (ラベル付きタスク特定データ)
  • 説明: これは、特定のタスクに特化したラベル付きデータセットでモデル全体をトレーニングする、クラシックなファインチューニングの方法です。モデルのすべてのパラメータがそのタスクでのパフォーマンスを最適化するために更新されます [8]。
  • 使用例: テキスト分類、感情分析、固有表現抽出、質問応答など、豊富なラベル付きデータがあるタスクに非常に効果的です。

3.9. モデル全体学習 (Full Fine-Tuning)

  • 成熟度レベル: 上級
  • 相対コスト: 非常に高い
  • 必要なデータサイズ: 大規模から非常に大規模 (ラベル付きタスク特定データ)
  • 説明: この方法は最も包括的なファインチューニングの形式であり、事前学習されたモデルのすべてのパラメータが新しいタスク特定のデータセットでのトレーニング中に調整されます [8]。
  • 使用例: 特定のタスクでの最大パフォーマンスが重要で、豊富な計算リソースと大規模かつ高品質なデータセットを利用できる状況で通常使用されます。

3.10. 指示学習 (Instruction Tuning)

  • 成熟度レベル: 上級
  • 相対コスト: 高から非常に高い
  • 必要なデータサイズ: 大規模 (多様な指示ベースのデータセット)
  • 説明: このアプローチは、幅広い指示に従ってさまざまなタスクを完了するようにモデルをファインチューニングすることを含みます。モデルは、指示とそれに対応する望ましい出力を含む多様なデータセットで訓練されます [9]。
  • 使用例: 複雑な指示を理解し実行する能力を向上させるため、汎用AIアシスタント、チャットボット、その他の柔軟なタスク実行が必要なアプリケーションに適しています。

3.11. 人間のフィードバックによる強化学習 (Reinforcement Learning with Human Feedback - RLHF)

  • 成熟度レベル: 最先端
  • 相対コスト: 非常に高い
  • 必要なデータサイズ: 変動するが、しばしば大規模 (人間のフィードバックデータ)
  • 説明: RLHFは、強化学習技術と人間ユーザーからのフィードバックを組み合わせます。モデルは、行動とフィードバックに基づいて報酬や罰を受け取り、人間の好みに応じて行動を最適化することを目指します [10]。
  • 使用例: 人間の好みが重要な状況で適用されます。例えば、会話エージェント、推薦システム、およびユーザーと直接対話するその他のアプリケーションです。

3.12. 直接的なポリシー最適化 (Direct Preference Optimization - DPO)

  • 成熟度レベル: 実験的
  • 相対コスト: 非常に高い
  • 必要なデータサイズ: 変動する (ユーザーの好みデータ)
  • 説明: DPOは、ユーザーのフィードバックと好みに基づいてモデルを直接最適化することに焦点を当てます。これには、観察されたユーザーの好みに沿ってモデルのパラメータを調整するための勾配降下法のような技術が含まれることが多いです [10]。
  • 使用例: ユーザー満足度が最重要であり、好みが直接測定され最適化できるアプリケーションに特に適しています。例えば、個人化されたコンテンツ推薦システムやユーザーインターフェースデザインなどです。

3.13. マルチタスクファインチューニング (Multitask Fine-Tuning)

  • 成熟度レベル: 上級
  • 相対コスト: 高から非常に高い
  • 必要なデータサイズ: 大規模 (複数タスクのラベル付きデータ)
  • 説明: マルチタスクファインチューニングでは、モデルを複数の関連するタスクに同時にトレーニングします。これにより、モデルがタスク間で共有される知識や表現を活用できるため、パフォーマンスと一般化が向上する可能性があります [11]。
  • 使用例: 多様なタスクで優れたパフォーマンスを発揮する必要があるシナリオで有益です。例えば、マルチドメインのカスタマーサービスボットや、言語のさまざまな側面を理解する必要があるモデル(例:感情分析、質問応答、テキスト要約)などに適しています。

3.14. メタ学習 (Meta-Learning - Learning to Learn)

  • 成熟度レベル: 最先端
  • 相対コスト: 非常に高い
  • 必要なデータサイズ: 変動するが、しばしば大規模 (メタトレーニングデータ)
  • 説明: メタラーニングは、最小限のデータで新しいタスクに迅速に適応するモデルを訓練することに焦点を当てます。トレーニングフェーズ中にさまざまなタスクでモデルを訓練することで、効率的に学習する方法を学ばせます [12]。
  • 使用例: モデルが少数ショット学習シナリオやパーソナライズされた学習システムなど、限られた例で新しいタスクやドメインに迅速に適応する必要がある状況で特に有用です。

3.15. アクティブラーニング

  • 成熟度レベル: 上級
  • 相対コスト: 高から非常に高い
  • 必要なデータサイズ: 変動するが、通常は反復的 (最初は小規模、モデルがさらにデータを要求することで増加)
  • 説明: アクティブラーニングは、モデルがラベリングに最も有益なデータポイントを積極的に選択することを伴い、これによりファインチューニングプロセスを最適化します [13]。
  • 使用例: データのラベリングが高価または時間のかかる状況で非常に価値があります。最も関連性の高い例に焦点を当てることで、効果的なファインチューニングに必要なラベル付きデータの量を大幅に削減できます。

3.16. 知識蒸留 (Knowledge Distillation)

  • 成熟度レベル: 中級から上級
  • 相対コスト: 中程度から高い
  • 必要なデータサイズ: 中程度から大規模
  • 説明: 大規模で事前学習された教師モデルから、より小さく効率的な生徒モデルへの知識の移転を行います [14]。
  • 使用例: モバイルやエッジデバイスなどのリソースが制約されたデバイスにモデルをデプロイする際に、パフォーマンスを維持するために役立ちます。

これらの各手法は、基本的なコンテキスト調整から、人間のフィードバックや広範なパラメータ調整を伴う高度な技術に至るまで、複雑さとリソース要件の段階的な向上を表しています。手法の選択は、タスクの具体的な要件、利用可能なリソース、および望まれるパフォーマンス結果に依存します。

レベル4: 検索と引用を用いたモデル出力の基盤確立

モデルのファインチューニングに加えて、このレベルでは生成AIシステムの出力の基盤確立と評価を組み込みます。これにより、生成されたコンテンツが事実に基づいて正確であり、関連性があり、倫理的考慮に沿っていることを保証します。

生成AIシステム成熟度モデルのレベル4では、内部エンタープライズ検索とVertex AIの基盤サービスを使用したGoogleライクな外部検索によって強化された、堅牢な基盤確立と評価プロセスを通じて、生成された出力の品質と信頼性を確保することに重点を置きます。

基盤確立と評価

取得された情報は、内部および外部の両方のソースからのものであり、徹底的な基盤確立と評価プロセスを経ます。これには以下が含まれます。

  • 事実の正確性の検証: 使用される情報が正確で最新であることを確認します。
  • 潜在的なバイアスの識別: 取得されたデータのバイアスを認識し、軽減します。
  • 関連性の評価: 情報が生成された出力に対してどれだけ適切であるかを評価します。

Vertex AIの基盤サービスは、このステップで使用される情報に引用と参照を提供することで、生成されたコンテンツに信頼性と透明性を加えます。

基盤確立と評価の主要なステップ:

  1. Post-RAG Refinement: 基盤確立と評価プロセスの後、LLMは受け取ったフィードバックに基づいて生成された出力を精緻化することがあります。この精緻化プロセスは、最終的な出力が正確で関連性があり、信頼できる情報源によって十分にサポートされていることを保証します。
  2. Serving Models: 最終的に、精緻化され検証されたモデルはユーザーに提供されるか、アプリケーションに統合され、検証された情報に基づいた信頼できる有益な応答を提供します。

内部エンタープライズ検索とVertex AIの基盤確立サービスを使用した外部検索が引用と参照の発見にどのように役立つか

内部エンタープライズ検索は、組織の知識リポジトリ内で関連するドキュメント、データ、および情報を迅速に特定するのに役立ちます。これにより、生成された出力を会社の特定の知識と専門知識のコンテキストに基づいて確立するための貴重な出発点が提供されます。

Vertex AIの基盤サービスを使用したGoogleライクな外部検索は、外部ソースの広範な情報へのアクセスを拡大します。これにより、生成された出力が組織の内部知識に限定されず、広範な分野からの最新情報と洞察を取り入れることができます。

これら二つの検索機能を組み合わせることで、生成AIシステムは内部および外部の両方のソースから引用と参照を見つけることができ、生成された出力の信頼性と信憑性を強化します。このPost-RAG基盤確立と評価プロセスは、最終出力が有益であるだけでなく、信頼でき、透明性があることを保証します。

レベル5: エージェントベースシステム

この高度なレベルでは、大規模言語モデル(LLM)が中心にあり、複数の生成AIモデルが協力して動作するマルチエージェントシステムを導入します。これにより、多様な能力の統合と協調が必要となる複雑なタスクが可能になります。また、モデルの挙動を監視し理解するためのオブザーバビリティと、生成AIモデルライフサイクルの運用化(LLMOps)に強く焦点を当てています。

生成AI成熟度モデルのレベル5では、複数の重要な機能が融合し、エージェントベースおよびマルチエージェントシステムへの進化の基盤を形成する高度なシステムが構築されます。

モデル選択、プロンプトエンジニアリング、および情報取得

プロセスは、特定のタスクに基づいて適切なLLMモデルを選択し、独自のデータでファインチューニングすることから始まります。効果的なプロンプトエンジニアリングはモデルの挙動を導き、情報取得メカニズムは様々なソースから関連情報を抽出し、LLMの知識ベースを充実させます。インコンテキストラーニング (In Context Learning)、チェーンオブソート (Chain Of Thought)、明確なステップとXMLのような構造でフォーマットする高度なプロンプトエンジニアリング技術を使用できます。さらに、アウトラインオブソート (Outline of Thought)、ツリーオブソート (Tree of Thought) などの高度な技術を使用し、ReActフレームワークと組み合わせて、LLMの結果を評価し、観察された出力について推論し、再生成し、最終的に行動を取ることができます。レベル5の高度な技術は、LLMOpsとエージェントベースのアーキテクチャの使用だけでなく、高度なプロンプトエンジニアリング技術の深化も含みます。

LLMによるオーケストレーション

レベル5の主要な革新の一つは、オーケストレータとしての中央に置かれるLLMの導入です。このLLMはオーケスとレータとして機能し、他のモデルやコンポーネントの動きを管理します。タスクを割り当て、コミュニケーションを管理し、異なるモデルからの出力を統合して一貫したワークフローを作成します。これは、個々のモデルが専門的な役割を持つエージェントと見なされるエージェントベースシステムへの初めのステップです。

基盤確立と評価

レベル4から継続して、基盤確立メカニズムが使用され、生成された出力の品質と信頼性を確保します。これらのメカニズムは、情報を信頼できるソースと照らし合わせて検証し、応答の潜在的な影響を評価します。評価プロセスはシステムのパフォーマンスを監視し、継続的な改善のためのフィードバックを提供します。

評価、オブザーバビリティ、およびLLMOps

生成AIリファレンスアーキテクチャの各コンポーネントの正式でエンドツーエンドのオブザーバビリティと評価メカニズムの導入は、レベル5の重要な要素です。

このシステムのパフォーマンスの継続的な評価と監視は、アーキテクチャのさまざまなコンポーネントに対するLLM生成コンテンツにとって重要です。プロンプト、RAG出力、チューニングモデルのドリフトやスキュー、基盤確立の出力などです。オブザーバビリティはLLMの挙動に関する洞察を提供し、積極的な調整を可能にします。LLMOpsの実践は、生成AIインフラ全体のデプロイメント、管理、監視を効率化します。

エージェントベース vs. マルチエージェントシステム

これらの二つの概念を区別してみましょう。

  • エージェントベースシステム: 単一のLLMモデルがエージェントとして機能し、タスクを遂行し、意思決定を行い、環境と相互作用します。LLMはさまざまな能力を持つ一つの単一体として見なされます。
  • マルチエージェントシステム: エージェントベースシステムから進化し、複数の専門化されたLLMを導入します。それぞれのLLMは特定の役割や専門知識を持つ独立したエージェントとして機能します。これらのエージェントは協力し、コミュニケーションを取り、行動を調整して、単一のエージェントでは効率的に処理できない複雑な問題を解決します。

レベル5は、複数のモデルを調整するための基本的なインフラストラクチャを確立することで、レベル6のマルチエージェントシステムへのステップとして機能します。組織が特定のタスクを異なるモデルに割り当て、そのパフォーマンスを評価することを可能にします。この実験は、補完的なスキルを持つ多様なモデルが協力して共通の目標を達成する、より高度なマルチエージェントシステムの開発への道を開きます。

レベル5は、単一のLLMモデルから専門化されたエージェントのネットワークへのパラダイムシフトを整えます。それぞれのエージェントが独自の強みを発揮し、ますます複雑な課題に取り組むために協力します。この移行は、生成AIの分野で新たなレベルの効率性、適応性、および革新を解放することを約束します。

レベル6: マルチエージェントマルチプライヤー

生成AIシステムの成熟度の頂点は、Tree-of-ThoughtやGraph-of-Thoughtのような高度な技術を使用して、生成AIモデルの推論および計画能力を向上させることです。これらのアプローチは、より洗練された意思決定と問題解決を可能にします。このレベルでは、LLMが他のLLMをオーケストレートし制御し、高度に自律的で有能な生成AIエコシステムを示します。このフレームワークは責任あるAIを強調し、AI技術の倫理的かつ公平な使用を保証する役割も提供します。

レベル6は、先進技術とフレームワークをシームレスに統合して高価値の機能を実現する、著しい生成AIの成熟度を表します。

  1. Tree-of-Thought/Graph-of-Thoughtによる強化推論: レベル6では、Tree-of-Thought(ToT)やGraph-of-Thought(GoT)フレームワークの力を活用します。これにより、LLMは複雑な問題を小さく管理可能なステップに分解し、潜在的な解決策を体系的に探索し、情報に基づいた意思決定を行うことができます。これにより、生成AIシステムの推論、計画、および問題解決能力が大幅に向上します。
  2. DSPYとReActによる能動的情報収集: レベル6では、DSPY(Demonstrate-Search-Predict)およびReAct(Reasoning and Acting)アプローチのような技術を取り入れます。DSPYは、LLMが外部情報を検索するタイミングを決定し、関連するクエリを予測し、取得した情報を推論プロセスに組み込むことを指導します。ReActは、LLMが環境と能動的に相互作用し、収集した情報に基づいて意思決定を行い、行動を起こすことを可能にします。
  3. 情報取得と統合: レベル6では、さまざまなソースから関連データにアクセスする高度な情報取得技術を利用します。取得した情報は、LLMの推論プロセスにシームレスに統合され、最新かつ文脈的に関連する知識を提供します。
  4. カスタムデータによるモデルチューニング: LLMは、独自またはドメイン特定のデータでファインチューニングされ、その性能を最適化し、特定のタスクおよびドメインに合わせて調整されます。これにより、モデルが正確で関連性のある、文脈的に適切な応答を生成することを保証します。
  5. マルチエージェントのオーケストレーションと制御: レベル6では、複数のLLMが中央のLLMのオーケストレーションと制御のもとで協力して動作するマルチエージェントシステムを展開します。これにより、協調、専門化、および多様な専門知識を必要とする複雑なタスクを処理することができます。
  6. 基盤確立と評価: 生成された出力が事実に基づいて正確で、関連性があり、倫理および安全ガイドラインに沿っていることを確認するために、厳格な基盤確立および評価メカニズムが使用されます。これには、情報を信頼できるソースと照らし合わせて検証し、応答の潜在的な影響を評価することが含まれます。
  7. 評価、オブザーバビリティ、およびLLMOps: レベル6では、生成AIシステムのパフォーマンスの継続的な評価と監視を強調し、その挙動に関する洞察を提供し、積極的な調整を可能にします。堅牢なLLMOpsの実践が、生成AIインフラ全体のデプロイメント、管理、および監視を効率化します。

レベル6は、最先端の技術とベストプラクティスを調和して統合し、生成AIシステムが比類のない推論、意思決定、および問題解決能力を達成することを可能にします。この包括的なアプローチは、システムが強力であるだけでなく、信頼性が高く、倫理的で、進化する要求に適応可能であることを保証します。

水平ドメインと垂直ドメイン

次に、生成AIを水平ドメインと垂直ドメインに戦略的に導入する方法を見てみましょう。

ここで、組織は効率、生産性、顧客満足度、イノベーションを向上させることで大きなROIを得ることができます。これらのメトリクスとKPIは、早期に特定し、測定し、監視し、修正することが非常に重要です。進化し急速に再構築されるビジネス環境で、生成AIの利点を最大化するためには、目標を慎重に定義し、関連するKPIを測定し続け、戦略を適応させることが重要です。

水平ドメインにおける生成AIの活用によるROIの向上

水平ドメインは、組織内のさまざまな業界や事業部門を横断する機能やプロセスを指します。これらのドメインに生成AIを適用することで、効率、生産性、全体的なROIを向上させることができます。

  • マーケティングと営業: 顧客体験をパーソナライズし、ターゲットコンテンツを生成し、マーケティングキャンペーンを最適化することで、顧客エンゲージメント、コンバージョン率、売上を向上させます。
  • カスタマーサービス: 生成AI搭載のチャットボットやバーチャルアシスタントが顧客の問い合わせに対応し、応答を自動化し、問題を効率的に解決することで、顧客満足度を向上させ、サポートコストを削減します。
  • 人事: 採用プロセスを効率化し、従業員のオンボーディングをパーソナライズし、学習と成長の機会を提供することで、従業員のエンゲージメントと生産性を向上させます。
  • 財務と会計: 財務分析を自動化し、異常や不正を検出し、財務プロセスを最適化することで、正確性、効率性、リスク管理を改善します。
  • 運用とサプライチェーン: 在庫管理を最適化し、需要を予測し、物流を効率化することで、コストを削減し、サプライチェーンの効率を向上させます。

垂直ドメインにおける生成AIの活用によるROIの向上

垂直ドメインは、ビジネスドメインや産業、さらにはサブ産業に特有の領域を指し、それぞれのセクターの独自のニーズと課題に合わせてソリューションを提供します。

生成AIは、さまざまな垂直ドメインに展開することで、ROIを向上させることができます。

  • 医療: 医療診断、薬の発見、パーソナライズされた治療計画を支援し、患者の転帰を改善し、医療コストを削減します。
  • 金融: 財務データを分析し、市場動向を予測し、投資の推奨を生成することで、意思決定とリスク管理を強化します。
  • 小売: 製品推奨をパーソナライズし、価格戦略を最適化し、顧客体験を向上させることで、売上と顧客ロイヤルティを向上させます。
  • 製造: 生産プロセスを最適化し、設備の故障を予測し、品質管理を強化することで、コストを削減し、効率を向上させます。
  • 教育: 学習体験をパーソナライズし、フィードバックを自動化し、適応型評価を作成することで、学生の成果とエンゲージメントを向上させます。

結論とアクションプラン

組織、チームプロジェクト、さらには個人の現在の成熟度と洗練度を理解することが重要です。その上で、目標とする成熟度レベルを決定し、そのレベルを達成するために必要なスキルを取得し、開発する必要があります。これにより、技術的な要件を満たし、ビジネスへの影響と成果を提供するために必要な洗練度を達成できます。

組織は、自分たちの現状からビジネス目標を進展させるためのロードマップを定義し、構築するスキルと能力を身に付けることができます。Google Cloud AIのようなプラットフォームを活用することで、あらゆる成熟度レベルをカバーし、目標とする成熟度レベルでのビジネス成果を達成することができます。

参照文献

[1] Brown, T. B., Mann, B., Ryder, N., Subbiah, M., Kaplan, J. D., Dhariwal, P., Neelakantan, A., Shyam, P., Sastry, G., Askell, A., Agarwal, S., Herbert-Voss, A., Krueger, G., Henighan, T., Child, R., Ramesh, A., Ziegler, D. M., Wu, J., Winter, C., … Amodei, D. (2020). Language Models are Few-Shot Learners).

[2] Rae, J., Borgeaud, S., Cai, T., Millican, K., Young, A., Rutherford, E., Hutter, F., Laurenç, P., Humphreys, P., Hawkins, P., Winter, S., Eccles, T., Leike, J., Ring, R., Askell, A., Chen, A., Olsson, C., Welinder, P., McAleese, N., … Irving, G. (2021). Scaling Language Models: Methods, Analysis & Insights from Training Gopher).

[3] Sanh, V., Debut, L., Chaumond, J., & Wolf, T. (2019). DistilBERT, a distilled version of BERT: smaller, faster, cheaper and lighter).

[4] Pfeiffer, J., Kamath, A., Rücklé, A., Cho, K., & Gurevych, I. (2020). MAD-X: An Adapter-Based Framework for Multi-Task Cross-Lingual Transfer).

[5] Hu, E. J., Shen, Y., Wallis, P., Allen-Zhu, Z., Li, S., Wang, L., Wang, L., & Chen, W. (2021). LoRA: Low-Rank Adaptation of Large Language Models).

[6] Li, X. L., & Liang, P. (2021). Prefix-Tuning: Optimizing Continuous Prompts for Generation).

[7] Lee, J., Yoon, W., Kim, S., Kim, D., Kim, S., So, C. H., & Kang, J. (2019). BioBERT: a pre-trained biomedical language representation model for biomedical text mining).

[8] Devlin, J., Chang, M. W., Lee, K., & Toutanova, K. (2018). BERT: Pre-training of Deep Bidirectional Transformers for Language Understanding).

[9] Wei, J., Tay, Y., Bommasani, R., Raffel, C., Zoph, B., Borgeaud, S., Yogatama, D., Bosma, M., Zhou, D., Metzler, D., Chi, E., Hashimoto, T., Vinyals, O., Liang, P., Dean, J., & Fedus, W. (2021). Finetuned Language Models Are Zero-Shot Learners).

[10] Christiano, P., Leike, J., Brown, T., Martic, M., Legg, S., & Amodei, D. (2017). Deep Reinforcement Learning from Human Preferences).

[11] Liu, P., Qiu, X., & Huang, X. (2017). Multi-Task Deep Neural Networks for Natural Language Understanding).

[12] Finn, C., Abbeel, P., & Levine, S. (2017). Model-Agnostic Meta-Learning for Fast Adaptation of Deep Networks).

[13] Settles, B. (2010). Active Learning Literature Survey). University of Wisconsin-Madison.

[14] Hinton, G., Vinyals, O., & Dean, J. (2015). Distilling the Knowledge in a Neural Network).

[15] Wei, J., Bosma, M., Zhao, V., Guu, K., Yu, A. W., Lester, B., … & Hernández, D. (2023). Many-Shot In-Context Learning. arXiv preprint arXiv:2304.11018.(https://arxiv.org/abs/2404.11018)

[16] Yao, S., Zhao, J., Yu, D., Du, N., Shafran, I., Narasimhan, K., & Cao, Y. (2023). Tree of Thoughts: Deliberate Problem Solving with Large Language Models. arXiv preprint arXiv:2305.10601. https://arxiv.org/abs/2305.10601

[17] Besta, M., Blach, N., Kubíček, A., Gerstenberger, R., Podstawski, M., & Bojar, O. (2023). Graph of Thoughts: Solving Elaborate Problems with Large Language Models. arXiv preprint arXiv:2308.05276. https://arxiv.org/abs/2308.05276

[18] Chen, W., Lyu, X., Li, H., Liang, P., & Zhou, D. (2023). DSPy: Towards Domain-Specific Language Model Pre-training with Synthetic Programming Data. arXiv preprint arXiv:2304.06449. https://arxiv.org/abs/2304.06449

[19] Schick, T., & Schütze, H. (2020). Self-Diagnosis and Self-Debiasing: A Proposal for Reducing Corpus-Based Bias in NLP. arXiv preprint arXiv:2005.04636. https://arxiv.org/abs/2005.04636

[20] Yao, S., Zhou, D., Schuurmans, D., Yu, J., & Li, H. (2022). ReAct: Synergizing Reasoning and Acting in Language Models. arXiv preprint arXiv:2210.03629. https://arxiv.org/abs/2210.03629

プロンプトエンジニアリングの時代の終焉(Anthropicでプロンプト生成が自動化)

Is Prompt Engineering Dead?

Jim Clyde Monge Published in Generative AI

最近まで、AIチャットボットのためのプロンプトエンジニアリングは大きな話題で、インターネット上には数百のコースが短期間に登場しました。中にはプロンプトエンジニアリングを職業と考え、自分たちをプロンプトエンジニアと呼ぶ人もいました。

これらのガイドの例としては以下のようなものがあります:

これらのAIモデルがどれほど迅速に進化するかには驚くばかりです。数か月で、言語モデルと画像モデルのプロンプトは自然言語によって駆動されるようになり、特定のルールに縛られることはなくなりました。

今日、トップのAI企業の一つであるAnthropicは、あなたが達成したいことを説明するだけで、製品準備完了のプロンプトを生成することで、プロンプトエンジニアリングを新たなレベルに引き上げています。

Anthropicのプロンプトジェネレータとは何ですか?

プロンプトジェネレータは、ClaudeのようなAIモデルのプロンプトを作成するための便利なツールです。AIから良い返答を得るために何を書くべきか分からないときに最適です。

このツールを使えば、あなたが望むことを言うだけで、プロンプトについての深い理解は必要ありません。データと命令を分けて保持し、明確で関連性のあるAIの応答のために「思考の連鎖」方法を使用するなど、シンプルな戦略を使用します。

どのように機能するのですか?

コンソールダッシュボードを開くと、最初に目にするのはプロンプトの新しいオプションです。

https://miro.medium.com/v2/resize:fit:700/1*FOhSm0tEZpla7zZfS19obA.png

「プロンプトを生成」ボタンをクリックすると、達成したいタスクを説明できるダイアログボックスが開きます。

https://miro.medium.com/v2/resize:fit:700/1*3NzrLu2UXsFmAiHNFzr3_Q.png

For example, you might input:

Prompt: Summarize documents into 10 bullet points max

After clicking “Generate a prompt,” I got the following result:

たとえば、次のように入力するかもしれません:

Prompt: Summarize documents into 10 bullet points max (日本語)プロンプト:文書を最大10の箇条書きに要約する

「プロンプトを生成」をクリックした後、次の結果が得られました:

https://miro.medium.com/v2/resize:fit:700/1*lFlWlYJ4f31UwoMut4rV7g.png

Please carefully read the following document:

{{DOCUMENT}}

After reading through the document, identify the key points and main ideas covered in the text. Organize these key points into a concise bulleted list that summarizes the essential information from the document. The summary should have a maximum of 10 bullet points.

Your goal is to be comprehensive in capturing the core content of the document, while also being concise in how you express each summary point. Omit minor details and focus on the central ideas.

Please output your final bullet point summary inside

tags.

(下記が日本語訳)

次のドキュメントを注意深く読んでください:

{{DOCUMENT}}

ドキュメントを読み終えたら、テキストで取り上げられている主要なポイントと主なアイデアを特定します。これらの主要なポイントを、ドキュメントからの必要な情報を要約した簡潔な箇条書きのリストにまとめます。要約は最大10の箇条書きであるべきです。

あなたの目標は、ドキュメントの中核となる内容を包括的に捉えつつ、各要約ポイントをどのように表現するかについても簡潔であることです。細部の詳細は省き、中心的なアイデアに集中してください。

最終的な箇条書きの要約を

タグ内に出力してください。

このアシスタント機能は本当に便利です。

「編集を開始」をクリックすると、より詳細な変更のためのワークベンチタブに移動します。

https://miro.medium.com/v2/resize:fit:700/1*et9Fy7psQuoVRnYV41sbJQ.png

設定では、あなたのニーズに最適なClaudeモデルを選択できます:

  • Claude 3 Opus: 最も強力で、最も能力が高い。
  • Claude 3 Sonnet: スマートさと速さの良いバランス、ビジネスタスクに最適。
  • Claude 3 Haiku: 非常に高速で小さく、迅速な応答に適しています。
  • Claude 2.1: 改良されたClaude 2、より正確ですがClaude 3ほどではありません。
  • Claude 2.0: 古いバージョン、Claude 3が登場するまでは良かった。
  • Claude Instant 1.2: 安価で軽量なモデル、簡単に使用できます。

Temperatureスライダーはプロンプトがどれだけランダムになるかを変更します。 Max tokens to sampleはプロンプトのトークンの上限を設定します、1,000から4,000まで。

「Run」を押すと、設定とあなたのテキストに基づいてレスポンスを作成します。

https://miro.medium.com/v2/resize:fit:700/1*XHOY8L4G9NqeJtDvo0TPKw.png

あなたはダッシュボードの左パネルで見ることができるプロンプトの名前を保存または変更することができます。残念ながら、これらのプロンプトにはhttps://claude.ai/chatsインターフェイスでアクセスすることはできません。

https://miro.medium.com/v2/resize:fit:633/1*qU1WVYYBqa43rmN9wMt0vA.png

プロンプトデザインについてさらに学びたい方のために、Anthropicはここで追加情報を提供しています。

プロンプトジェネレーターコード

基本的なプロンプトと構造を研究したい場合、AnthropicはGoogle Colabのノートブックを使用できます。ここでClaudeにプロンプトを作成させるためのコードを実行できます:

<span id="178b" data-selectable-paragraph="">prompt = metaprompt.replace(<span>"{{TASK}}"</span>, TASK)<br>assistant_partial = <span>"&lt;Inputs&gt;"</span><br><span>if</span> variable_string:<br>    assistant_partial += variable_string + <span>"\\n&lt;/Inputs&gt;\\n&lt;Instructions Structure&gt;"</span><br><br>message = CLIENT.messages.create(<br>    model=MODEL_NAME,<br>    max_tokens=<span>4096</span>,<br>    messages=[<br>        {<br>            <span>"role"</span>: <span>"user"</span>,<br>            <span>"content"</span>:  prompt<br>        },<br>        {<br>            <span>"role"</span>: <span>"assistant"</span>,<br>            <span>"content"</span>: assistant_partial<br>        }<br>    ],<br>    temperature=<span>0</span><br>).content[<span>0</span>].text</span>

完全なメタプロンプトのコードは、プロンプトジェネレーターのGoogle Colabノートブックで利用可能です。

Claudeプロンプトジェネレーターのサブスクリプションプラン

サインアップすると、無料で5ドルのクレジットがもらえます。

これはあまり長持ちしないかもしれませんが、いくつかのテストプロンプトはカバーできるはず。その後、サブスクリプションプランを選択することができます。Anthropicには三つのオプションがあります:

https://miro.medium.com/v2/resize:fit:700/1*yH2f3R7A2ZR-WS7U6lQu5A.png

Anthropicには3種類のプランがあります:無料と2つの有料。

  1. 評価プラン:これは無料プランです。ユーザーはAnthropicコンソールに限定的にアクセスし、$5の無料クレジットを得ることができます。
  2. ビルドプラン:このプランでは、ユーザーが自分のアカウントにお金を追加して、プロンプトジェネレータへの継続的なアクセスを得ることができます。また、ユーザーがプロンプト作成プロセスを微調整するための調整可能なレート制限も付いています。
  3. スケールプラン:このプランは、大企業や多くのプロンプトが必要な人々を対象としています。ユーザーのニーズに応じて、追加機能、サポート、または特別な価格が付いてくる場合があります。

https://miro.medium.com/v2/resize:fit:700/1*ou7Czwl2mE-bzG5jmhCbvw.png

最終的な考察

Anthropicの新しいプロンプトジェネレーターは便利です。これにより、AIモデルのClaude Opusのユーザーを中心にプロンプトの作成が容易になります。

しかし、いくつかの問題があります。まず、それはAnthropic Consoleダッシュボード上でしか使用できません。チャットセクションでは使用できません。Claudeとチャットするときにそれを使用できると便利です。

二つ目に、それは無料ではなく、支払いをしている人たちにとってもそうです。それが有料の顧客に対して無料であると素晴らしいでしょう。

LangChainでAIエージェントをサクッと作る方法(ビギナー向け)

LangChainでAIエージェントをサクッと作る方法(ビギナー向け)

Beginner’s Guide to Creating AI Agents With LangChain | by Vijaykumar Kartha | Apr, 2024 | Medium

https://vijaykumarkartha.medium.com/beginners-guide-to-creating-ai-agents-with-langchain-eaa5c10973e6

さて、LangChainの実に楽しい機能、AIエージェントの作成について話しましょう。

チェーンを使って言語モデル(LLM)に質問に答えさせる方法を学びました。また、外部データやチャット履歴を使ってLLMが答えを出すのを助ける方法も学びました。

チェーンとAIエージェントの違い

チェーンは固定のアクションの連続です。しかしエージェントでは、LLMがアクションとその順序を選びます。

AIエージェントは、LLMに次に何をするべきかを決定させます。これがいかに素晴らしいかがすぐにわかるでしょう。

ツール

AIエージェントはさまざまなツールを使用できます。彼らはタスクに合ったツールを選びます。

その一つのツールはリトリーバーです。それはベクトルデータベースの中から関連情報を見つけ出します。

別のツールはウェブ検索です。特定の情報をウェブで検索するためにAIエージェントが使用できるAPIは多数あります。

langchain_community.toolsパッケージにはAIエージェント用の多くのツールがあります。

リトリーバーツール

リトリーバーツールはベクトルデータベースから関連データを見つけ出し、それをLLMに送ります。これは、ソースデータが大きすぎてユーザーのプロンプトと一緒に送信するのが困難な場合に役立ちます。例えば、リトリーバーツールは、ウェブサイトhttps://www.dasa.orgからの情報をベクトルデータベースで見つけることができます。

AIエージェントにツールを提供するためには、まずリトリーバーを作成し、その後でツールをインポートする必要があります。

リトリーバーの作成については、私の前の記事、LangChainを使用したリトリーバルチェーンの作成で読むことができます。

from langchain\_community.document\_loaders import WebBaseLoader
loader = WebBaseLoader("https://www.dasa.org")
docs = loader.load()
from langchain\_text\_splitters import RecursiveCharacterTextSplitter
text_splitter = RecursiveCharacterTextSplitter()
documents = text\_splitter.split\_documents(docs)
from langchain_openai import OpenAIEmbeddings
embeddings = OpenAIEmbeddings()
from langchain_community.vectorstores import FAISS
vector = FAISS.from_documents(documents, embeddings)
retriever = vector.as_retriever()

それでは、create_retriever_toolパッケージをインポートしましょう。以下のようにインポートします:

from langchain.tools.retriever import create\_retriever\_tool

次に、名前と説明を付けてツールを作成します。

retriever\_tool = create\_retriever_tool (retriever, "DASA_search", "Search for information about DASA. For any questions about DASA, you must use this tool")

ウェブ検索ツール

インターネットを検索するための別のツールを作成しましょう。これはTavily Searchツールを使用して行うことができます。これには、tavily.comで無料で取得できるAPIが必要です。

import os
os.environ\['TAVILY\_API\_KEY'\] = "<Your Tavily API Key here>"
from langchain\_community.tools.tavily\_search import TavilySearchResults
search = TavilySearchResults()

今、AIエージェントに与えることができる2つのツールを持っています。それらをリストにしましょう。

tools = \[retriever_tool, search\]

AIエージェントを作る

これでツールが揃ったので、それらを使用するエージェントを作成できます。

まず、ターミナルを使用してlangchain hubをインストールします。

pip install langchainhub

langchain-openaiパッケージをインストールしてください。

pip install langchain-openai

次に、llmをAIエージェントとして動作させるのに役立つ、プロンプトハブから定義済みのプロンプトを取得します。

from langchain import hub
prompt = hub.pull("hwchase17/openai-functions-agent")

このプロンプトについてもっと学びましょう、それはllmをAIエージェントとして動作させます。

プロンプトは、AIエージェントを作成するために特別に設計されたプロンプトのハブから引き出されます。

それは、llmが可能なアクションについて考え、目標に向かって進行するアクションを決定するために使用するエージェントスクラッチパッドで構成されています。

次の記事では、AIエージェントがどのように考えるかについての興味深い詳細をカバーします。

さて、llmを準備しましょう。

from langchain_openai import ChatOpenAI
llm = ChatOpenAI(api_key="Your API Key here")

次に、LangChainからいくつかのライブラリをインポートしてエージェントを作成し、エージェントを実行しましょう。

from langchain.agents import create\_openai\_functions_agent
from langchain.agents import AgentExecutor

AIエージェントを作成する準備ができています。 AIエージェントにはllm、ツール、およびプロンプトが必要です。

agent = create\_openai\_functions_agent(llm,tools,prompt)
agent_executor=AgentExecutor(agent=agent,tools=tools,verbose=True)

AIエージェントを呼び出す

すべての必要な作業は、AIエージェントを呼び出すことだけです。

agent_executor.invoke({"input":"What is the mission of DASA"})

出力は次のとおりです:

Entering new AgentExecutor chain…

Invoking: DASA_search with {‘query’: ‘mission of DASA’}

{'input': 'What is the mission of DASA',
'output': 'The mission of DASA (DevOps Agile Skills Association) is to facilitate the journey towards flow, business agility, and value maximization. DASA aims to help organizations transform into high-performance digital organizations by prioritizing customer-focused innovation, fostering a culture of agility and teamwork, and emphasizing key principles crucial for effective adoption and transition to a DevOps-centric approach. DASA offers a portfolio of talent and guidance products to boost enterprise transformation success and provides a collaborative space for leaders and professionals to share ideas and adopt best practices in the field.'}

ユーザーの入力に基づき、AIエージェントはリトリーバツールを使用することにしました。

DASAに関連しない他の質問をしましょう。

agent_executor.invoke({"input":"What is weather in Kuala Lumpur?"})

アウトプットは次の通り:

Entering new AgentExecutor chain…

Invoking: tavily_search_results_json with {‘query’: ‘weather in Kuala Lumpur’}

{'input': 'What is weather in Kuala Lumpur?',
'output': 'The current weather in Kuala Lumpur is partly cloudy with a temperature of 29.0°C (84.2°F). The humidity is at 84% and the wind speed is 3.6 km/h coming from the east-southeast direction. The visibility is 10.0 km and the UV index is 7.0.'}

今回、AIエージェントはリトリーバーツールの代わりにインターネットを検索するためにTavily Searchツールを使用することにしました。

おめでとうございます!自分で次に何をするべきかを決定できる思考AIエージェントを作成しました。

複合AIシステムのデザインパターン(対話型AI、CoPilots、RAG)

複合AIシステムのデザインパターン(対話型AI、CoPilots、RAG)

Design Patterns for Compound AI Systems (Conversational AI, CoPilots & RAG)

https://medium.com/@raunak-jain/design-patterns-for-compound-ai-systems-copilot-rag-fa911c7a62e0

オープンソースツールを使用して設定可能なフローと複合AIシステムを構築する方法。

複合AIシステムの理解

最近の記事である モデルから複合AIシステムへのシフト において、バークレーの研究者たちはAIが単一のモデルの使用から複数のコンポーネントの複雑なシステムへと移行していることについて話しました。基本モデルが同じ(例えばGPT4)であっても、その使用方法により、それがより大きなシステムの異なる部分のように見せる事ができます。

以下は、これらのシステムが一般的にどのように使用されているかのいくつかの方法です:

  1. RAG(理解が鍵) - これらのシステムは、思考生成、推論、コンテキストを使用してユーザーの質問を理解し、それに対応します。これらはエージェントアシスト設定に最適です。ダイアログモデルのようなユーザー向けモデルと一緒に使用すると、RAGシステムは会話型AIまたはCoPilotシステムの一部になることができます。
  2. マルチエージェント問題解決者(チームワークが鍵) - これらのシステムは、異なるエージェントが協力して働く結果に基づいたソリューションを構築します。各エージェントは独自のツールを持ち、推論と行動計画において特定の役割を果たします。
  3. 会話型AI(チャットが鍵) - これらは、カスタマーサービスエージェントのように、人間とやり取りし、人間の入力に基づいて繰り返し行うタスクを自動化します。ここでの主な特徴は、過去の会話を記憶し、新しい会話を生成する能力で、あなたが人間と話しているかのように感じさせます。会話型AIは、基礎となるRAGシステムやマルチエージェント問題解決者を使用することができます。
  4. CoPilots(人間の関与が鍵) - これらのシステムは、ツール、データ、推論、計画を使用して人間と対話しながら問題を解決できます。システムがCoPilotである主な特徴は、人間の作業環境を理解していることです。例としては、MetaGPT Researcher: Webを検索しレポートを作成A measured take on DevinLet’s build something with CrewAIAutogen Studioがあります。
  5. 注:LLMを使用して多くのシステムを設定した後、それらが皆が望む完璧な解決策ではないことがわかりました。すべてのAIと同様に、LLMでさえ単純なタスクを実行するためには多くの作業が必要で、パフォーマンス保証があっても、信頼性や安定性が保証されるわけではありません。
  6. 潜在的な利点:LLMの最良の使用法は、製品やサービスがどこで改善できるかを理解し、その情報を使って時間とともに改善することで、機械学習を支援することです。これは人間のレビュアーの作業を減らすことを意味するかもしれません。LLMをテストし評価できる閉じたシステムでは、それらは多くのことを達成できますが、それは高価です。しかし、それはまた、より良いLLMを作るためのデータを生成します。この改善のサイクルこそが、LLMが本当に輝く場所です。

これらのシステムのコンポーネントとそれらがどのように相互作用して複雑なシステムを構築するか

複合AIシステムは通常、互いに依存して特定のタスクを行い、デザインパターンを実行するために連鎖する「モジュール」を使用してデプロイされます。

ここで、モジュールは、システム内の個々のコンポーネントを指し、それは検索エンジン、LLMなどの基礎となるシステムの助けを借りても借りなくても、よく定義されたタスクを行います。一般的なモジュールには、ジェネレーター、リトリーバー、ランカー、クラス分類器などがあり、これらは伝統的にNLPのタスクと呼ばれています。これらは、ドメイン固有の概念的な抽象化であり(例えば、NLPのモジュールはコンピュータビジョンや推奨システムとは異なる抽象化モジュールを持つかもしれませんが、それらはすべて同じ基本モデルの提供や検索プロバイダーに依存するかもしれません)。

https://miro.medium.com/v2/resize:fit:750/1*uNJw3fHBZID_1sYLpoJV2w.png

Key components of a module

https://miro.medium.com/v2/resize:fit:750/1*JgKXJhmui92kk6_JcZl5xQ.png

追加の標準モジュール

AIの領域では、ツールエージェントコンポーネントなどの用語によく出会います。これらはすべて実質的にモジュールです。

LLMベースの自律エージェント - 複合AIシステムの重要なモジュール

モジュールの一種に、LLMによって可能となる、独立した推論と計画を立てる能力を持つ自律エージェントがあります。自律エージェントは、環境との相互作用時に推論アプローチと行動計画を決定するための一連のサブモジュールに依存する可能性があります。

https://miro.medium.com/v2/resize:fit:525/1*_NZt68XlQNHWBv407MRNsg.png

source

Key capabilities or skills of a Autonomous Agent module:

https://miro.medium.com/v2/resize:fit:525/1*36lfyC7SBGfHVROLHZ4vQQ.png

推論能力は思考の連鎖を引き起こし、実際の行動に結びつきます。

  1. 推論 — 観察を行い、仮説を生成し、データに基づいて検証するなど、問題を解決するための論理的な方法。
  2. 思考 — 推論の適用と因果関係の一貫した生成。
  3. 思考の連鎖 — 解決策を論理的につながった推論の連鎖に分解する一連の思考。
  4. 計画 — サブゴールの形成を行い、現状から未来の状態への道筋を作るための決定力。これは通常、行動を起こし、学習するための基本的な環境にアクセスすることで利益を得る。LLM計画についてはここで詳しく読むことができます。
  5. ツール — エージェントがエージェントからの指示に基づいて外部世界と対話することを可能にするサブモジュール。
  6. アクション — 名前が示す通り、これはエージェントが計画を通じて目標を追求するための決定的なステップです。ツールがアクションをトリガーするために呼び出されることがあります。アクションは環境で行われます。
  7. 環境 — エージェントのアクションと報酬が発生する外部世界、例えばカスタムアプリ(Microsoft Word、コーディング環境など)やゲーム、シミュレーションなど。

「確率的なオウム」との作業

注:大規模言語モデル(LLM)の推論と計画における限界についての広範な理論的研究にもかかわらず、ここここで示されているように、LLMが解決方法を"オウム返し"できることは明らかです。問題と過去の解決例が提供されれば、LLMは論理的な思考過程を効果的に複製できます。それが一般化するかどうかは、ここでは焦点ではありません。ヤン・ル・クンが言うように、自己回帰モデルは失敗する運命にある

ビジネス環境では、信頼性の高いタスクの繰り返しと過去の経験からの学習を、過剰な創造性なしで目指すのが目標です。

これらの”思考過程の複製”は実際にどのように計画を立てるのでしょうか?

この調査に基づくと、LLMは以下のようにして自律的なエージェントを強化できるようです:

  1. タスクの分解 - 実生活でのタスクは通常複雑で多段階的であり、計画を立てるのが非常に難しくなります。このような方法は分割統治の考え方を採用し、複雑なタスクをいくつかのサブタスクに分解し、それぞれのサブタスクについて順序立てて計画を立てます。例えば、TDAG
  2. 複数の計画選択 - このような方法は、LLMに「もっと考える」ことに焦点を当て、タスクに対するさまざまな代替計画を生成します。その後、タスク関連の検索アルゴリズムが用いられて、実行する計画を一つ選びます。例えば、ReWoo
  3. 外部モジュールを利用した計画 - また、計画の取り出しとも言えます。
  4. 反省と改善 - この方法論は、反省と改善を通じて計画能力を向上させることを強調します。LLMに失敗について反省し、計画を改善することを奨励します。例えば、自己批評と改善ループ。
  5. メモリ強化型計画 - このようなアプローチは、付加的なメモリモジュールを用いて計画を強化します。このモジュールには、一般的な知識、過去の経験、ドメイン固有の知識など、価値のある情報が保存されます。この情報は計画を立てる際に取り出され、補助信号として機能します。

https://miro.medium.com/v2/resize:fit:525/1*Vmw2T2mjhFFZuhZNC2TZ8w.png

LLMエージェントプランニングの理解:ガイド

これらの特徴の訓練方法、特にRAGのために知流ためには、企業向けRAGのためのLLM Fine-tuningの簡素化をチェックしてみてください。

これらのモジュールを理解したところで、会話型AI、RAG、およびCoPilotシステムの複雑な問題を解決するためにどのように異なる設計を作ることができるかを見てみましょう。

複合AIシステムデザインパターン

役立つ定義

現在のAIの話題性を考えると、特定の用語が誤解されたり、誤用されたりすることも多いので、まずは正確な定義を設定しましょう:

  1. "Agentic"パターンとは何ですか? 自律エージェントの主な利点は、自身の行動コースを決定する能力です。もし私たちが手動でフローや決定を定義しているなら、それは単にスマートなワークフローです。しかし、フローが事前に定義されていない場合や、決定過程が上記の能力とツール、行動を利用している場合、私たちは"Agentic"パターンを扱っています。例えば、Agentic RAGは、モジュールが検索ツールにアクセスを許可され、事前に定義されたステップなしで複雑な検索フローを自動的に生成できるパターンです。
  2. "ワークフロー"とは何ですか? 簡単に言うと、ワークフローとは、問題を一貫性のある、繰り返し可能な方法で解決するための事前エンコード、手動で宣言された計画です。
  3. "マルチエージェント"とは何ですか? これは、各々が自身の役割と責任を持つ異なるモジュールが、お互いの出力を共同で処理し、問題を協力して解決するシステムを指します。

エージェントを作成する際には、以下に注目してください:

  1. エージェントのプロファイリング — エージェントの役割に密接に関連したプロンプトに基づいて、エージェントの行動を定義します。
  2. エージェントのコミュニケーション — これらの部分がお互いにどのように交流するかを特定し、下の画像で示されているように描き出します。
  3. エージェント環境のインターフェース — 環境からのフィードバックを収集して、エージェントが学習、適応、そしてより具体的な反応を作り出すのを助けます。
  4. エージェントの学習と開発 — エージェントは、環境との交流(特にコーディングアシスタントの場合)、他のエージェント、自己評価、人間からのフィードバック、ツールから学びます。各設計がリアルタイムで問題解決にどのように取り組むかを見ていきましょう。

パターンを選ぶ前に考えるべきこと

RAG、会話型AI、CoPilots、複雑な問題解決者などのデザインパターンを作成する際には、以下のことを考慮する必要があります:

  1. モジュール間の相互作用の方法は固定されているのか、それともそれらは独立して動作することができるのか? エンジニアリングフロー対エージェントシステム。
  2. 情報は一方向に流れるのか、それともメッセージを渡すようなものなのか? 彼らは協力して働くのか、それとも反対に働くのか? エージェントモジュロ.*
  3. システムは自己学習できるのか? 自己修正が重要なのか?
  4. 推論と行動をループさせることができるのか?
  5. モジュールは互いに学習することができるのか?
  6. 各モジュールの結果は実世界でテストすることができるのか?
  7. システムの動作方法はユーザーの入力に基づいて変化するのか?

パターン1 - RAG / 会話型RAG

以下の図は、RAG / 会話型RAGシステムのモジュールの主なタスクを示しています。これは情報検索(IR)分野から始まり、ニューラルサーチと知識グラフによって改善され、言語モデルを用いたループベースの形に進化しました。IRと対話システムが結合し、会話中にクエリが変わると、これを会話型IRと呼びます。

RAGシステムを機能させるためには、ユーザーが何を尋ねているかを理解し、関連する知識(組織化されているかどうか)を見つけて、それをGenerator / Dialogue Managerに適切な指示で提供することが重要です。これは、よく計画されたワークフローを使用するか、次に何をすべきかを選択するAgentモジュールを使用して実行できます(次の部分で詳しく説明します)。

https://miro.medium.com/v2/resize:fit:525/1*T-DF9Gbw_g-K4nIZ9v9Weg.png

RAGシステムはダイアログマネージャーとペアにすることができます。ダイアログマネージャーがエージェントである場合、RAGはツールとして使用できます。

以下は、エージェントが複雑なRAGシステムを操作するのを助ける中間モジュール/ツールの一部です。

クエリの理解と変更

クエリの拡張 / 複数のクエリ

https://miro.medium.com/v2/resize:fit:767/1*TGcKK_GtL4f6XzAPbEHDUA.png

https://miro.medium.com/v2/resize:fit:1521/1*hy94U4CiUSQZQOWOJ6W_2A.png

LLMを使用して検索クエリをより詳細にすると、特定のタイプのリトリーバーを使用した場合の検索結果が向上します。

自己問い合わせリトリーバー

自己問い合わせリトリーバーは自己に質問をすることができます。自然言語での任意のクエリを取り、LLMチェーンを使用して構造化クエリを作成し、これを自身のVectorStoreに適用します。このようにして、初期のユーザークエリを保存されたドキュメントと比較し、ユーザークエリからの任意のフィルターをドキュメントのメタデータに適用することができます。

エンティティの識別

クエリの強化

情報の検索または意図の理解

複数のドキュメントの検索

会話の管理

レスポンスの作成

エージェント型RAG

エージェント型RAGは、LLMによって駆動されるモジュールが、使用可能なツールのセットに基づいて、質問にどのように答えるかを推理し計画するデザインパターンです。高度なシナリオでは、複数のエージェントを接続して、エージェントが情報を取得するだけでなく、確認、要約などを行うような創造的な方法でRAGを解決することもあります。これについては、マルチエージェントセクションを参照してください。

改善が必要な主要な手順とコンポーネントは次の通りです:

  1. 推理、サブタスクの形成、および体系的な配置に基づいた計画。
  2. 複数のパスの生成と推理、計画に基づくRAGアプローチ(ReWooとPlan+)による自己整合性に基づく自己修正は、単なる推理に基づくもの(ReAct)よりも優れています。
  3. 実行に基づいて適応する能力、より多エージェント型のパラダイム。

通常、これらは以下のパターンを使用して実行されます:

推理に基づいたエージェント型RAG

ReActhttps://blog.langchain.dev/planning-agents/

ReAct:言語モデルにおける推論と行動のシナジー

While large language models (LLMs) have demonstrated impressive capabilities across tasks in language understanding and…

https://miro.medium.com/v2/resize:fit:525/1*SkTt9vPLwzYII3ig3u8bGw.png

arxiv.org

検索ツールを使用して理由(Reason)と行動(Act) ⇒ ReAct

計画に基づくAgentic RAG

Untitled%2077bf2364b2f445d0b3e70ff2fc6d969a/Untitled.png)

https://blog.langchain.dev/planning-agents/

ReWOO:効率的な拡張言語モデルのための観察からの推論の分離

Untitled%2077bf2364b2f445d0b3e70ff2fc6d969a/Untitled%201.png)

https://arxiv.org/abs/2305.18323

Augmented Language Models (ALMs) blend the reasoning capabilities of Large Language Models (LLMs) with tools that allow…

https://miro.medium.com/v2/resize:fit:668/1*9IRQkDf-YcxCn7DXv8OmoA.png

https://miro.medium.com/v2/resize:fit:1362/1*eEz3IN5lpO0psZECdvd63A.png

ReWoo - ReActよりもはるかに少ないトークン生成につながります。

ReActがReWooよりもずっと劣っている理由についての詳細は、こちらをご覧ください。

PlanRAG

それは二つのコンポーネントで構成されています:まず、全体のタスクをより小さなサブタスクに分割する計画を立て、次にその計画に従ってサブタスクを実行する。

Untitled%2077bf2364b2f445d0b3e70ff2fc6d969a/Untitled%202.png)

https://openreview.net/forum?id=4sajV6NEnWE

Plan-and-Solve Prompting: Improving Zero-Shot Chain-of-Thought Reasoning by Large Language Models

デプロイメントパターン2 - 会話型AI

過去、チャットボットの会話は単純なパターンに従っていました:ボットが話し、ユーザーが反応し、その後ボットが返答します。このパターンは、Rasa開発者の「ストーリー」としても知られており、異なる現実世界の状況を表しています。各ユーザーの意図は、ユーザーの状態と相互作用に基づいて数百の「ストーリー」で示すことができます。その後、ボットはアクションを起こしてストーリーに従い、準備された反応で答えます。例えば、ユーザーがニュースレターにサインアップしたい場合、次の2つのシナリオが考えられます:

  1. ユーザーはすでにサインアップしています。
  2. ユーザーはまだサインアップしていません。

https://miro.medium.com/v2/resize:fit:525/1*RUxaRla7NtaG98KBs_844g.png

source

ユーザーが「ニュースレターを購読するにはどうすればいいですか」と尋ねた場合、ボットはユーザーがすでに購読しているかどうかを調べてから進める必要があります。このプロセスは現在ハードコーディングされています。ボットが理解できない場合、「すみません、まだ学習中で、xyzに関してはお手伝いできます」と言います。

ボットの作成と維持における課題は、これらのプロセスを管理することです。私たちはこれを行うことで、ボットがさまざまな実世界の状況に対応できるようにしています。しかし、これらのパスを作成することは、条件を確認し、アクションを実行し、会話の目標に到達するという複雑なプロセスを伴うため、複雑になることがあります。

私たちは、このプロセスを自動化するために言語モデル(LLMs)を使用しています。LLMsを使用すると、「推論」と「計画」の能力を使ってパスを作成することができます。これについてはこちらで詳しく学ぶことができます。

例えば、あなたがカスタマーサービスのエージェントだとします。ユーザーがあなたのサービスの購読方法を尋ねます。次のステップをどのように決定しますか?それは完全に自由な形式であることはできませんが、コストの考慮からあまりにもスクリプト化されすぎることもできません。しかし、以下のようなガイドラインがあったらどうでしょうか:

条件 - メールが存在する場合、ユーザーは購読できますツール - check_subscription、add_subscription

この場合、次のようなプランを作成することができます:

  1. ユーザーは購読を希望している、という声明に基づく - 「どうやって購読しますか?」
  2. ユーザーにメールを聞く - 「あなたのメールアドレスは何ですか?」
  3. 彼が有効なメールを提供した場合、ツールをトリガー - check_subscription
  4. ユーザーがまだ購読していない場合、トリガー add_subscription
  5. 成功または失敗を返答

これがLLMが行いたいことです - 参照し、行動に移すことができる「プラン」を作成すること。このプロセスについてはこちらで詳しく学ぶことができます。

では、モジュールテンプレートでのプランナーがどのように見えるか見てみましょう。

https://miro.medium.com/v2/resize:fit:525/1*zr1GwtkatJLacabou3TMEQ.png

上記のプランナーは、ツールや条件を使用して、設計時または実行時にプランやストーリーを作成することができます。これについての実例を研究で見てみましょう:

Untitled%2077bf2364b2f445d0b3e70ff2fc6d969a/Untitled%203.png)

KnowAgent: Knowledge-Augmented Planning for LLM-Based Agents

大規模な言語モデル(LLMs)は複雑な推論タスクにおいて大きな可能性を示していますが、それでも不足しているときには…

arxiv.org

https://miro.medium.com/v2/resize:fit:750/1*0fzrq1pycvs5i24e260RNw.png

KnowAgent: Knowledge-Augmented Planning for LLM-Based Agents

プランナーが信頼性のある推論でパスを決定するためのツールは何がありますか?

  1. 同様の発言によって引き起こされた過去のパス。
  2. 行動の企業グラフ、および行動間の依存関係。これにより、プランナーはある行動が正しい結果につながるかどうかを決定し、次にそれが次の行動につながり、再帰的に問題を解決するまで進むことができます。その関連のある実世界の統合については、こちらこちらを参照してください。これは、Neo4JとLangchainを使用した知識グラフと計画の統合であり、必ずしも計画パスに関連しているわけではありません。
  3. ユーザー/会話の現在の状態。

デプロイメントパターン3 - 複数のエージェント

多数のエージェントが存在する設定では、LLM(Large Language Models)ベースのジェネレーターに役割とタスクを割り当てることが目指されています。これらのジェネレーターは、特定のツールを装備しており、スマートな答えや解決策を提案するために協力して働きます。

明確に割り当てられた役割とサポートモデルのおかげで、各エージェントは "プラン" の一部または小さな目標を "エキスパート"に引き渡すことができます。彼らは次にこの出力を使用して次のステップを決定します。詳細については、最後にあるGPTPilotの例をご覧ください。

大規模言語モデルに基づくインテリジェントエージェントの探求:定義、方法、展望

Untitled%2077bf2364b2f445d0b3e70ff2fc6d969a/Untitled%204.png)

Intelligent agents could be a step towards artificial general intelligence (AGI). Therefore, researchers have…

このようなパターンは、実行チェーンの次のステップを定義する権限を制御する以下の通信パターンを使用して実行されます。これについての詳細は Orchestrating Agentic Systemsとしての詳しい情報はこちらをご覧ください。

https://miro.medium.com/v2/resize:fit:525/1*1_x-pFbfY5_o9OqES1BpgQ.png

エージェント/モジュールがどのようにコミュニケーションを取り、現実世界のCoPilotsを構築するかhttps://arxiv.org/pdf/2402.01680v1.pdf

マルチエージェントデザインの利点

  • 関心の分離:各エージェントは、それぞれの指示とフューショットの例を持つことができ、別々の微調整された言語モデルによって支えられ、さまざまなツールによって支援されます。タスクをエージェント間で分割すると、結果が向上します。各エージェントは、多数のツールから選択するのではなく、特定のタスクに集中できます。
  • モジュラリティ:マルチエージェントデザインでは、複雑な問題を管理可能な作業単位に分割し、それを専門のエージェントと言語モデルで対象とすることができます。マルチエージェントデザインでは、全体のアプリケーションを混乱させることなく、各エージェントを独立して評価し、改善することができます。ツールと責任をグループ化すると、より良い結果が得られます。エージェントは、特定のタスクに集中しているときに成功する可能性が高くなります。
  • 多様性:エージェントチームに強い多様性を持ち込むことで、異なる視点を取り入れ、出力を洗練させ、ホールシネーションとバイアスを避けます。(典型的な人間のチームのように)。
  • 再利用性:エージェントが構築されたら、これらのエージェントを異なるユースケースで再利用する機会があり、エージェントのエコシステムを考え、適切なコレオグラフィー/オーケストレーションフレームワーク(AutoGen、Crew.aiなど)を用いて問題を解決することができます。

デプロイメントパターン4 - CoPilot

CoPilotシステムで私が見る唯一の違いは、ユーザーとテスト機能とのインタラクションによって得られる学習です。

続きは後ほど...

フレームワークと実装

これらのCoPilotsを構築するフレームワークと、実際のCoPilotsの実装(GPT Pilotやaiderなど)を区別することは重要です。ほとんどのシナリオでは、オープンソースのCoPilotsはフレームワーク上に開発されておらず、すべての実装はゼロから開発されています。

レビューする人気のある実装:OpenDevinGPT Pilot

レビューする人気のある研究論文:AutoDevAgentCoder

人気のあるフレームワーク - FabricLangGraphDSPyCrew AIAutoGen、Meta GPT、Super AGIなど。

可能な限り、LLMベースのマルチエージェントについて以下の定義に従おうと試みます。

Deep Dive — アプリ

GPT Pilot

GPT Pilot プロジェクトは、創造的なプロンプトエンジニアリングとLLMのレスポンスを「レイヤー化」した流れで連鎖させることで、複雑に見えるタスクを実行する優れた例です。

レイヤー化されたコミュニケーション方式で働くいくつかのプロファイルがあります。下の緑のボックスをご覧ください:

https://miro.medium.com/v2/resize:fit:525/0*dDPEruR-hgVjnDrA

https://www.reddit.com/r/MachineLearning/comments/165gqam/p_i_created_gpt_pilot_a_research_project_for_a/

個々のエージェントは、階層的な方法で相互作用し、エージェントは一つのノードから次のノードにトリガーされ、決定を下すエージェントは存在しません。

https://miro.medium.com/v2/resize:fit:525/0*PzC0XCylWtjr3uxi

この製品は、効果的に動作するためのいくつかの素晴らしい戦略を使用しています:

  1. LLMがコードを作成できるように、タスクを小さく、管理しやすい部分に分割します。
  2. テスト駆動開発を使用し、ユーザーから有用な例を収集して正確で効果的な更新を保証します。
  3. コンテキストの巻き戻しとコードの要約を使用します。

設計プロセスは複雑であることがありますが、各エージェントを調整してコストを抑え、すべてが正確に動作するようにすることが非常に重要です。

Function Calling(機能)を用いて自律的なAIエージェントを構築する

Function Calling(機能)を用いて自律的なAIエージェントを構築する

https://towardsdatascience.com/build-autonomous-ai-agents-with-function-calling-0bb483753975

OpenAIは2023年7月からGPTモデルにFunction Callingを使用し始めました。現在、GoogleのGemini APIやAnthropicのClaudeなどもこれを使用しています。このツールは大規模言語モデル(LLM)に非常に役立ち、それをどのように使用するかを知ることは重要です。

Function Callingを実際にどのように使用するか、完全に自己機能するAIエージェントを作成する方法、さらに、Streamlitと接続してChatGPTのようなチャットインターフェースを作る方法も紹介します。このガイドはOpenAIに基づいていますが、GeminiのようなFunction Callingを使用する他のLLMでも使用できます。

Function Callingは何のために使うのか?

Function Callingは、開発者が関数(ツールとも呼ばれますが、これはモデルが行うアクション、つまり計算を行ったり、注文を行ったりすることを考えることができます)を記述し、モデルがそれらの関数を呼び出すための引数を含むJSONオブジェクトを出力することを知的に選択することを可能にします。より簡単な言葉で言えば、次のことが可能になります:

  • 自律的な意思決定:モデルは知的にツールを選択して質問に応答することができます。
  • 信頼性のあるパーシング:レスポンスはJSON形式で、より一般的な対話型のレスポンスではなく。初めて見た時には大したことがないように思えますが、これがLLMを、例えば構造化された入力を持つAPIなどの外部システムに接続することを可能にしています。

これにより、多くの可能性が開かれます:

  • 自律的なAIアシスタント:ボットは、問い合わせに対する回答を提供するだけでなく、顧客の注文や返品などの内部システムとのタスクを交換することができます。
  • 個人の研究アシスタント:旅行の計画を立てている場合など、アシスタントはWebを検索し、コンテンツをクロールし、オプションを比較し、結果をExcelでまとめることができます。
  • IoT音声コマンド:モデルは、ACの温度を調整するなど、検出された意図に基づいてデバイスを制御したり、アクションを提案したりすることができます。

Function Callingの構造

GeminiのFunction Callingドキュメンテーションから借りて、関数呼び出しには以下の構造があり、これはOpenAIでも同様に機能します。

https://miro.medium.com/v2/resize:fit:413/0*rrgnwWr7Hif3TfH_

GeminiのFunction Callingドキュメンテーションからの画像

  1. ユーザーがアプリケーションにプロンプトを発行します
  2. アプリケーションは、ユーザーが提供したプロンプトとFunction Declaration(モデルが使用可能なツールの説明)を渡します
  3. Function Declarationに基づいて、モデルは使用するツールと関連するリクエストパラメータを示します。モデルが関数を実際に呼び出すことなく、提案されたツールとパラメータのみを出力することに注意してください
  4. & 5. レスポンスに基づいて、アプリケーションは関連するAPIを呼び出します
  5. & 7. APIからのレスポンスは再度モデルにフィードされ、人間が読むことができるレスポンスを出力します
  6. アプリケーションは最終的なレスポンスをユーザーに返し、1から繰り返します。

これは複雑に見えるかもしれませんが、例を用いて詳細に説明される概念です。

アーキテクチャ

コードに深く入る前に、デモアプリケーションのアーキテクチャについて少し説明します。

解決策

ここでは、ホテルを訪れる観光客のためのアシスタントを構築します。アシスタントは次のツールにアクセスでき、これによりアシスタントは外部アプリケーションにアクセスできます。

  • get_items, purchase_item:APIを介してデータベースに保存された商品カタログに接続し、商品リストの取得と購入をそれぞれ行います。
  • rag_pipeline_func:検索強化生成(RAG)を備えたドキュメントストアに接続し、構造化されていないテキストから情報を取得します。例えば、ホテルのパンフレットなど。

https://miro.medium.com/v2/resize:fit:560/1*2aXhxSCJKyOVzkC0IJofiQ.png

技術スタック

  • Embedding モデル: all-MiniLM-L6-v2
  • ベクトルデータベース: HaystackのInMemoryDocumentStore
  • LLM: OpenRouter経由でアクセス可能なGPT-4 Turbo。OpenRouterを使用すると、VPNなしで香港から異なるLLM APIにアクセスできます。他のLLMを使用するためには、Function Callingをサポートしていれば、コードを少し変更して流れを適応させることが可能です、例えばGemini
  • LLMフレームワーク: Haystack。使いやすさ、素晴らしいドキュメンテーション、パイプライン構築の透明性を提供しています。このチュートリアルは実際には、同じトピックの彼らの素晴らしいチュートリアルの拡張版です。

サンプルアプリケーション

準備

Githubに移動して私のコードをクローンしてください。以下の内容はfunction_calling_demoノートブックにあります。

また、仮想環境を作成して有効化し、pip install -r requirements.txtを実行して必要なパッケージをインストールしてください。

初期化

まず、OpenRouterに接続します。あるいは、api_base_urlを上書きせずにオリジナルのOpenAIChatGeneratorを使用することも可能ですが、その場合はOpenAI APIキーが必要です。

import os
from dotenv import load_dotenv
from haystack.components.generators.chat import OpenAIChatGenerator
from haystack.utils import Secret
from haystack.dataclasses import ChatMessage
from haystack.components.generators.utils import print\_streaming\_chunk

load_dotenv()
OPENROUTER\_API\_KEY = os.environ.get('OPENROUTER\_API\_KEY')

chat\_generator = OpenAIChatGenerator(api\_key=Secret.from\_env\_var("OPENROUTER\_API\_KEY"),
  api\_base\_url="https://openrouter.ai/api/v1",
  model="openai/gpt-4-turbo-preview",
        streaming\_callback=print\_streaming_chunk)

次に、chat_generatorが正常に呼び出されるかどうかをテストします

chat\_generator.run(messages=\[ChatMessage.from\_user("Return this text: 'test'")\])
\-\-\-\-\-\-\-\-\-\- The response should look like this ----------
{'replies': \[ChatMessage(content="'test'", role=<ChatRole.ASSISTANT: 'assistant'>, name=None, meta={'model': 'openai/gpt-4-turbo-preview', 'index': 0, 'finish_reason': 'stop', 'usage': {}})\]}

ステップ1:データストアの構築

ここでは、アプリケーションと二つのデータソース:非構造化テキストのための ドキュメントストアと、API経由のアプリケーションデータベースとの間の接続を確立します。

パイプラインでドキュメントをインデックス化

documentsには、モデルがRetrival Augmented Generation (RAG)を実行するためのサンプルテキストを提供します。これらのテキストはエンベディングに変換され、インメモリのドキュメントストアに保存されます。

from haystack import Pipeline, Document
from haystack.document\_stores.in\_memory import InMemoryDocumentStore
from haystack.components.writers import DocumentWriter
from haystack.components.embedders import SentenceTransformersDocumentEmbedder

documents = \[
    Document(content="Coffee shop opens at 9am and closes at 5pm."),
    Document(content="Gym room opens at 6am and closes at 10pm.")
\]

document_store = InMemoryDocumentStore()

indexing_pipeline = Pipeline()
indexing\_pipeline.add\_component(
    "doc_embedder", SentenceTransformersDocumentEmbedder(model="sentence-transformers/all-MiniLM-L6-v2")
)
indexing\_pipeline.add\_component("doc_writer", DocumentWriter(document\_store=document\_store))

indexing_pipeline.connect("doc_embedder.documents", "doc_writer.documents")

indexing_pipeline.run({"doc_embedder": {"documents": documents}})

これは、作成したサンプルとしての documents に対応する出力です

{'doc_writer': {'documents_written': 2}}

APIサーバーの起動

Flaskを使用したAPIサーバーは、SQLiteに接続するために db_api.pyの下に作成されます。ターミナルでpython db_api.pyを実行して起動してください。

https://miro.medium.com/v2/resize:fit:560/1*S4Ty6XitWFrOHY5wWENaXg.png

これは、正常に実行された場合にターミナルに表示されます

また、db_api.pyに初期データが追加されたことにも注意してください

https://miro.medium.com/v2/resize:fit:486/1*tASIXxNUJThtf0-HuPtISw.png

データベースのサンプルデータ

ステップ2:関数の定義

ここでは、モデルが関数呼び出し(関数呼び出しの構造で説明されているステップ4-5)の後に**呼び出すための実際の関数を準備します。

RAG関数

具体的には、rag_pipeline_funcです。これはモデルがドキュメントストアに格納されたテキストを検索して答えを提供するためのものです。まず、RAGの検索をHaystackパイプラインとして定義します

from haystack.components.embedders import SentenceTransformersTextEmbedder
from haystack.components.retrievers.in_memory import InMemoryEmbeddingRetriever
from haystack.components.builders import PromptBuilder
from haystack.components.generators import OpenAIGenerator

template = """
Answer the questions based on the given context.

Context:
{% for document in documents %}
    {{ document.content }}
{% endfor %}
Question: {{ question }}
Answer:
"""

rag_pipe = Pipeline()
rag\_pipe.add\_component("embedder", SentenceTransformersTextEmbedder(model="sentence-transformers/all-MiniLM-L6-v2"))
rag\_pipe.add\_component("retriever", InMemoryEmbeddingRetriever(document\_store=document\_store))
rag\_pipe.add\_component("prompt_builder", PromptBuilder(template=template))

rag\_pipe.add\_component("llm", OpenAIGenerator(api\_key=Secret.from\_env_var("OPENROUTER\_API\_KEY"),
  api\_base\_url="https://openrouter.ai/api/v1",
  model="openai/gpt-4-turbo-preview"))

rag_pipe.connect("embedder.embedding", "retriever.query_embedding")
rag_pipe.connect("retriever", "prompt_builder.documents")
rag_pipe.connect("prompt_builder", "llm")

関数が機能するかテストしてください

query = “When does the coffee shop open?”
rag_pipe.run({"embedder": {"text": query}, "prompt_builder": {"question": query}})

これにより、次の出力が得られます。モデルが提供したrepliesは、以前に提供したサンプルドキュメントからのものであることに注意してください。

{'llm': {'replies': \['The coffee shop opens at 9am.'\],
  'meta': \[{'model': 'openai/gpt-4-turbo-preview',
    'index': 0,
    'finish_reason': 'stop',
    'usage': {'completion_tokens': 9,
     'prompt_tokens': 60,
     'total_tokens': 69,
     'total_cost': 0.00087}}\]}}

その後、rag_pipeを関数に変換することができます。これにより、他の詳細を追加せずにrepliesのみが提供されます。

def rag\_pipeline\_func(query: str):
    result = rag_pipe.run({"embedder": {"text": query}, "prompt_builder": {"question": query}})

    return {"reply": result\["llm"\]\["replies"\]\[0\]}

APIの呼び出し

データベースとの対話のために、 get_items および purchase_item 関数を定義します

db\_base\_url = 'http://127.0.0.1:5000'

import requests
import json

def get_categories():
    response = requests.get(f'{db\_base\_url}/category')
    data = response.json()
    return data

def get_items(ids=None,categories=None):
    params = {
        'id': ids,
        'category': categories,
    }
    response = requests.get(f'{db\_base\_url}/item', params=params)
    data = response.json()
    return data

def purchase_item(id,quantity):

    headers = {
    'Content-type':'application/json',
    'Accept':'application/json'
    }

    data = {
        'id': id,
        'quantity': quantity,
    }
    response = requests.post(f'{db\_base\_url}/item/purchase', json=data, headers=headers)
    return response.json()

ツールリストを定義する

関数が定義されたので、モデルがこれらの関数を認識し、それらがどのように使用されるかを指示するために、それらの説明を提供する必要があります。

ここではOpenAIを使用しているため、toolsは以下のようにフォーマットされています。これはOpen AIによって必要とされる形式に従っています。

tools = \[
    {
        "type": "function",
        "function": {
            "name": "get_items",
            "description": "Get a list of items from the database",
            "parameters": {
                "type": "object",
                "properties": {
                    "ids": {
                        "type": "string",
                        "description": "Comma separated list of item ids to fetch",
                    },
                    "categories": {
                        "type": "string",
                        "description": "Comma separated list of item categories to fetch",
                    },
                },
                "required": \[\],
            },
        }
    },
    {
        "type": "function",
        "function": {
            "name": "purchase_item",
            "description": "Purchase a particular item",
            "parameters": {
                "type": "object",
                "properties": {
                    "id": {
                        "type": "string",
                        "description": "The given product ID, product name is not accepted here. Please obtain the product ID from the database first.",
                    },
                    "quantity": {
                        "type": "integer",
                        "description": "Number of items to purchase",
                    },
                },
                "required": \[\],
            },
        }
    },
    {
        "type": "function",
        "function": {
            "name": "rag\_pipeline\_func",
            "description": "Get information from hotel brochure",
            "parameters": {
                "type": "object",
                "properties": {
                    "query": {
                        "type": "string",
                        "description": "The query to use in the search. Infer this from the user's message. It should be a question or a statement",
                    }
                },
                "required": \["query"\],
            },
        },
    }
\]

ステップ3:すべてをまとめる

これでFunction Callingのテストに必要な入力が揃いました!ここではいくつかのことを行います:

  1. モデルに初期のプロンプトを提供し、一部のコンテキストを与えます
  2. ユーザーが生成したメッセージのサンプルを提供します
  3. 最も重要なのは、tools内のチャットジェネレータにツールリストを渡すことです
context = f"""You are an assistant to tourists visiting a hotel.
You have access to a database of items (which includes {get_categories()}) that tourists can buy, you also have access to the hotel's brochure.
If the tourist's question cannot be answered from the database, you can refer to the brochure.
If the tourist's question cannot be answered from the brochure, you can ask the tourist to ask the hotel staff.
"""
messages = \[
    ChatMessage.from_system(context),

    ChatMessage.from_user("Can I buy a coffee?"),
    \]

response = chat\_generator.run(messages=messages, generation\_kwargs= {"tools": tools})
response
\-\-\-\-\-\-\-\-\-\- Response ----------
{'replies': \[ChatMessage(content='\[{"index": 0, "id": "call\_AkTWoiJzx5uJSgKW0WAI1yBB", "function": {"arguments": "{\\\"categories\\\":\\\"Food and beverages\\\"}", "name": "get\_items"}, "type": "function"}\]', role=<ChatRole.ASSISTANT: 'assistant'>, name=None, meta={'model': 'openai/gpt-4-turbo-preview', 'index': 0, 'finish\_reason': 'tool\_calls', 'usage': {}})\]}

さあ、レスポンスを調査してみましょう。モデルが選択した関数と、選択した関数を呼び出すための引数の両方を、関数呼び出しが返すことに注目してください。

function_call = json.loads(response\["replies"\]\[0\].content)\[0\]
function\_name = function\_call\["function"\]\["name"\]
function\_args = json.loads(function\_call\["function"\]\["arguments"\])
print("Function Name:", function_name)
print("Function Arguments:", function_args)
\-\-\-\-\-\-\-\-\-\- Response ----------
Function Name: get_items
Function Arguments: {‘categories’: ‘Food and beverages’}

別の質問が提示されたとき、モデルはより関連性の高い別のツールを使用します

messages.append(ChatMessage.from_user("Where's the coffee shop?"))

response = chat\_generator.run(messages=messages, generation\_kwargs= {"tools": tools})
function_call = json.loads(response\["replies"\]\[0\].content)\[0\]
function\_name = function\_call\["function"\]\["name"\]
function\_args = json.loads(function\_call\["function"\]\["arguments"\])
print("Function Name:", function_name)
print("Function Arguments:", function_args)
\-\-\-\-\-\-\-\-\-\- Response ----------
Function Name: rag\_pipeline\_func
Function Arguments: {'query': "Where's the coffee shop?"}

再度、ここでは実際の関数が呼び出されていないことに注意してください、これは次に行うことです!

関数の呼び出し

その後、選択した関数に引数をフィードできます

available_functions = {"get_items": get_items, "purchase_item": purchase_item,"rag\_pipeline\_func": rag\_pipeline\_func}
function\_to\_call = available\_functions\[function\_name\]
function\_response = function\_to\_call(**function\_args)
print("Function Response:", function_response)
\-\-\-\-\-\-\-\-\-\- Response ----------
Function Response: {'reply': 'The provided context does not specify a physical location for the coffee shop, only its operating hours. Therefore, I cannot determine where the coffee shop is located based on the given information.'}

rag_pipeline_funcからの応答は、それをmessagesの下に追加することでチャットのコンテキストとして渡すことができ、モデルは最終的な答えを提供します。

messages.append(ChatMessage.from\_function(content=json.dumps(function\_response), name=function_name))
response = chat_generator.run(messages=messages)
response_msg = response\["replies"\]\[0\]

print(response_msg.content)
\-\-\-\-\-\-\-\-\-\- Response ----------
For the location of the coffee shop within the hotel, I recommend asking the hotel staff directly. They will be able to guide you to it accurately.

以上でチャットサイクルが完了です。

ステップ4:対話型チャットに変換する

上記のコードは関数呼び出しがどのように行われるかを示していますが、これをさらに一歩進めて対話型のチャットに変えたいと思います。

ここでは、ノートブック自体にダイアログを表示するよりも原始的な input() から、それをStreamlit を通じてレンダリングしてChatGPTのようなUIを提供するまで、それを行うための2つの方法を紹介します。

input()** ループ

このコードは Haystackのチュートリアル からコピーされており、モデルを素早くテストすることができます。注:このアプリケーションは関数呼び出しの考え方を示すために作られたものであり、同時に複数のアイテムの順序をサポートしたり、幻覚を起こさないなど、完全に堅牢であることを意味していません。

import json
from haystack.dataclasses import ChatMessage, ChatRole

response = None
messages = \[
    ChatMessage.from_system(context)
\]

while True:

    if response and response\["replies"\]\[0\].meta\["finish_reason"\] == "tool_calls":
        function_calls = json.loads(response\["replies"\]\[0\].content)

        for function_call in function_calls:

            function\_name = function\_call\["function"\]\["name"\]
            function\_args = json.loads(function\_call\["function"\]\["arguments"\])

            function\_to\_call = available\_functions\[function\_name\]
            function\_response = function\_to\_call(**function\_args)

            messages.append(ChatMessage.from\_function(content=json.dumps(function\_response), name=function_name))

    else:

        if not messages\[-1\].is_from(ChatRole.SYSTEM):
            messages.append(response\["replies"\]\[0\])

        user_input = input("ENTER YOUR MESSAGE 👇 INFO: Type 'exit' or 'quit' to stop\\n")
        if user_input.lower() == "exit" or user_input.lower() == "quit":
            break
        else:
            messages.append(ChatMessage.from\_user(user\_input))

    response = chat\_generator.run(messages=messages, generation\_kwargs={"tools": tools})

https://miro.medium.com/v2/resize:fit:560/1*A5nwZCw3JO_553WiBEGaDg.png

IDEでの対話型チャットの実行

それが機能している間、もっと見栄えのいいものを持つことを望むかもしれません。

Streamlit インターフェース

Streamlitはデータスクリプトを共有可能なWebアプリに変換し、私たちのアプリケーションに対してきちんとしたUIを提供します。上記に示したコードは、私のリポジトリのstreamlitフォルダの中にあるStreamlitアプリケーションに適応されています。

実行するには:

  1. まだ行っていない場合、python db_api.pyでAPIサーバーを起動します。
  2. 環境変数としてOPENROUTER_API_KEYを設定します。例:export OPENROUTER_API_KEY = ‘@YOUR API KEYに置き換えてください’ Linux / git bashで実行する場合を仮定しています。
  3. ターミナルでstreamlitフォルダに移動します。cd streamlitを使用します。
  4. streamlit run app.pyでStreamlitを実行します。新しいタブが自動的にブラウザで開かれ、アプリケーションが実行されるはずです。

Neo4j GDSでのセマンティック検索を向上させるトピックの抽出技術

Neo4j GDSでのセマンティック検索を向上させるトピックの抽出技術

https://medium.com/neo4j/topic-extraction-with-neo4j-graph-data-science-for-better-semantic-search-c5b7f56c7715

セマンティック検索は、ドキュメントに正確なキーワードが含まれていなくても、クエリの意味に一致するドキュメントを見つけるのに役立ちます。これは、特にRetrieval Augmented Generation (RAG)アプリケーションでの生成型AIに非常に有用です。

RAGアプリケーションは、セマンティック検索を使用して関連するドキュメントを見つけ、それらのドキュメントに基づいて大規模な言語モデルを使用して質問に答えます。

セマンティック検索は、テキストドキュメントの要約を数字、またはベクトルに変換して使用します。これらのベクトルは、Neo4jのようなベクトルストアに保存されます。ユーザーがクエリを作成すると、それはベクトルに変換されます。最も似ているベクトルを持つドキュメントが返されます。

長いドキュメントをベクトルの要約のためのより小さなチャンクに分解することは難しいです。チャンクが大きすぎると、一部の詳細が見逃されるかもしれません。チャンクが小さすぎると、重要な文脈が多くのチャンクに散らばる可能性があります。

この問題を解決する良い方法は、検索のためにドキュメントのトピックを使用することです。ユーザーの質問に一致するトピックを見つけ、それらのトピックを言及しているすべてのドキュメントを見つけます。

Neo4jはこれに強力なツールです。ドキュメントとそれらのトピックの知識グラフを作成できます。Neo4jはベクトル(数学的なオブジェクト)を使用してトピックとドキュメントを検索できます。Neo4j Graph Data Science (GDS)機能を使用すると、より良い検索結果のために重複するトピックを見つけて組み合わせることができます。

映画のプロットのデータベースでテストを行い、グラフベースのトピッククラスタを検索に使用すると、通常の検索よりも27%多くの関連結果を得られることがわかりました。

最近の映画のデータセット

テストでは、TMDB.orgから得た映画情報を使用し、Neo4j AuraDSグラフデータベースにロードしました。私は2023年9月1日以降に公開された映画のみを使用しました。これは、私が使用した大規模な言語モデルが映画について事前に何も知らないようにするためです。使用した映画は、大きなオスカー受賞作から学生の短編映画まで様々でした。

テストには16,156の映画ノードのデータセットを使用しました。各ノードにはタイトルとプロットの概要がありました。私は映画をDowload_TMDB_movies.ipynbノートブックのコードを使用してNeo4jにロードしました。これは私のプロジェクトリポジトリにあります。

https://miro.medium.com/v2/resize:fit:525/1*Mdb4j-qw71woKiOK6HJGRQ.png

Neo4j Bloomには、タイトルと概要のあるMovieノードが表示されます。

LLMで映画のテーマを抽出

私は映画のデータをNeo4jにロードし、LLMを使用して映画のタイトルと概要における主要なテーマを特定しました。これらは特定のオブジェクト、設定、またはアイデアに関連する可能性があります。これらは、人々が映画を検索するときに思い浮かぶ要素かもしれません。このタスクは、伝統的な名前エンティティ認識(ER)よりも少し簡単でした。なぜなら、私は見つかったテーマのタイプをカテゴライズしなかったからです。ERでは、アルゴリズムが日付、人、または組織などの特定のタイプのエンティティを見つけようとします。

こちらが私が使用した指示です:

You are a movie expert.
You are given the tile and overview of the plot of a movie.
Summarize the most memorable themes, settings, and public figures in the movie
into a list of up to eight one-to-two word phrases.
Only include the names of people if the person is a famous public figure.
Prioritize any phrases that appear in the movie's title.
You can provide fewer than eight phrases.
Return the phrases as a pipe separated list.
Return only the list without a heading.

このタスクのためにAnthropicのClaude 3 Sonnetモデルを選びました。理由は、彼らの新しいモデルをテストしたかったからです。他のLLMも良いかもしれません。

下記がインプットのサンプルです。

title: Maestro
overview: A towering and fearless love story chronicling the lifelong
relationship between Leonard Bernstein and Felicia Montealegre Cohn Bernstein.
A love letter to life and art, Maestro at its core is an emotionally epic
portrayal of family and love.

下記がLLMからの回答です。

meastro|family bonds|Emotional epic|Fearless passion|Lifelong relationship|
Towering love|Art devition

これらのLLMからの応答を、Neo4jのHAS_THEME関係によってMovieノードに接続されたThemeノードに変換しました。

https://miro.medium.com/v2/resize:fit:525/1*tTA9fGLipzFp1xhfbyGzOg.png

テーマ(青いノード)は、HAS_THEME関係で映画(黄色いノード)に接続します。

プロジェクトリポジトリ内のノートブックExtract themes.ipynbには、このプロセスのこのステップのコードが含まれています。

テーマの整理とテキスト埋め込みの生成

LLMはパイプで区切られたテーマのリストだけを完璧に返すわけではありませんでした。いくつかのケースでは、リストの前に「この映画の記憶に残るテーマ、設定、公的人物は:...」のような余分なテキストが付けられていました。場合によっては、LLMがテーマを見つけられなかったため、空のリストの代わりにそのことを伝える文を返しました。いくつかのケースでは、LLMは概要で説明された内容があまりにも過敏または露骨であると判断しました。これらの応答を整理するために使用したコードは、プロジェクトリポジトリのノートブックClean up themes and get embeddings.ipynbにあります。LLMの予測不能な性質のため、コードを実行する場合、テーマを整理するために少し異なる手順を取る必要があるかもしれません。

テーマを整理した後、私はOpenAIのtext-embedding-3-smallモデルを使用してテーマの埋め込みベクトルを生成しました。これらのベクトルはNeo4jの Theme ノードのプロパティとして保存しました。また、映画のタイトルと映画の概要を連結した文字列の埋め込みも生成しました。これらの埋め込みはNeo4jの Movie ノードのプロパティとして保存されました。

私は Theme ベクトルと Movie ベクトルのNeo4jベクトルインデックスを作成しました。これらのインデックスにより、私が提供するクエリベクトルに対するコサイン類似性に基づいて、最も類似した埋め込みベクトルを持つノードを効率的に見つけることができました。

Neo4jグラフデータサイエンスを使用したクラスタテーマ

LLMは言語を操作するのに驚くべき仕事をしますが、その出力を標準化するのは難しいです。私はLLMが近い同義語となるテーマをいくつか特定したことに気づきました。私はテーマのセマンティック検索をより効率的にするために、重複したテーマや非常に密接に関連したテーマを組み合わせることができることを望んでいました。テーマのクラスタリングと重複排除のすべてのコードは、プロジェクトリポジトリのノートブックCluster themes.ipynbに含まれています。

ステムを共有するテーマを見つけるための伝統的なNLPテクニックを使用する

私は伝統的な自然言語処理手法を使用して、同じ語幹に基づく単語を特定することから始めました。これは、語幹と呼ばれます。私はNLTK Python packageからのWordNet lemmatizerを使用して、共通の語幹を見つけるためにテーマから接頭辞と接尾辞を削除しました。私はグラフ内に Stem ノードを作成し、それらを HAS_STEM 関係でテーマにリンクしました。私は最も多くの Movie ノードに接続されている語幹グループ内の Theme ノードからの埋め込みベクトルを Stem ノードの埋め込みベクトルとして割り当てました。

https://miro.medium.com/v2/resize:fit:525/1*HUkXkvmIZ8W0z_pILbKI0Q.png

例としてステム(緑色のノード)と関連するテーマ(青色のノード)があります。

ステムを共有しない同様のテーマを探索する

グラフの中には、ステムを共有していないにもかかわらず、非常に似た意味を持つ他のグループのテーマがありました。それらを特定し始めるために、グラフからいくつかのテーマノードを選択し、その他のテーマノードと最も類似したエンベッディングを見つけるためにベクトルインデックスに対してクエリを実行しました。私は、下記のコサイン類似性の妥当なカットオフを見つけようとしていましたが、これはおそらく二つのテーマの同義語ではありません。また、データセット内でテーマが持つ可能性のある近い同義語の数のカットオフを見つけようとしていました。

ここにテーマ「水中」の例があります:

https://miro.medium.com/v2/resize:fit:277/1*WQgBz09nYTrEiAX0g7EtZg.png

「underwater」に最も類似したテーマを示す表。

私は「undersea」、「sub aquatic」、「underwater world」、「undersea world」はすべて基本的に「underwater」と同じものだと思いました。 「underwater music」テーマは、私が別のテーマとして保持したい新しいアイデアを導入し始めます。 0.880904以上の類似性のカットオフまたは4以下のトップkは、「underwater」と一緒にまとめるべきでないテーマを除外します。

ここに「fast food」のテーブルの最初の部分があります。

https://miro.medium.com/v2/resize:fit:275/1*KnT2g3kezhIec-nnxnz4Gg.png

「fast food restaurant」と「Fast-food burger」の最初の2つのテーマは、1つの概念として十分に関連していると思いました。「street food」のテーマは、異なるグループにするに値するように思えます。0.804882以上の類似性カットオフまたは2以下のトップkを維持すれば、street foodとfast foodの違いを保つことができます。

「Africa」に最も似ているテーマは「Asia」でした。これはまったく別の大陸です。これら二つのテーマがクラスタに結合されることがないようにするには、0.829958以上の類似性カットオフが必要となります。

https://miro.medium.com/v2/resize:fit:261/1*jipax5B-Hba_A1Mxnb1csA.png

「Africa」に関する類似したテーマを示す表。

K Nearest Neighborsアルゴリズムを使用してIS_SIMILAR関係を作成する

いくつかの他のテーマの類似性を見てみた後、類似度のカットオフ値を0.83、トップkを2にすることにしました。Stemノードと関連性のないすべてのThemeノードを含むグラフの投影を作成しました。その後、選択した類似度のカットオフ値とトップkの閾値を超えるノード間にIS_SIMILAR関係を追加するために、K Nearest Neighborsアルゴリズムを使用してグラフの投影を変更しました。

連結の弱いコンポーネントコミュニティをテストする

Weakly Connected Componentのコミュニティ検出アルゴリズムは、無向パスによって接続されているノードを同じコンポーネントに割り当てます。IS_SIMILAR関係を作成したときに非常に厳格な基準を選んだ場合、WCCは類義語のクラスターを特定するための実行可能なアプローチであったかもしれません。AがBの類義語で、BがCの類義語であるという推移的な仮定を立てることができます。つまり、AはCの類義語です。

WCCを実行したところ、結果は理想的ではありませんでした。WCCの類似度の閾値を0.875に設定してみました。これは、私がKNN用に使用したカットオフ値よりも高い値です。非常に緊密に関連しているテーマだけがまとめられるようにしたかったのです。最大のWCCコミュニティには29のテーマが含まれていました。それらすべてにはChristmasに関する何かが含まれていましたが、「Christmas Terror」と「Christmas Magic」は、おそらく非常に異なる雰囲気の映画に関連するでしょう。

https://miro.medium.com/v2/resize:fit:302/1*JpYoQXkWCVksSf7paIkGIw.png

0.875のカットオフを持つ最大のWCCコミュニティのテーマ。

高い類似性のカットオフ、例えば0.875を設定すると、「乾燥した風景」や「荒廃した風景」のようなテーマが別々のコミュニティに分かれてしまうという問題がありました。これらは私が考えるに一緒にあるべきテーマです。そこで、WCCの代わりにLeidenコミュニティ検出アルゴリズムを試すことにしました。

Leidenコミュニティは大きなまたは小さなコミュニティに対して調整可能です

Leidenコミュニティ検出アルゴリズムは、コミュニティ内の関係がランダムに分布していると想定した場合よりも、コミュニティ内で始まりと終わりが高い割合を持つコミュニティを識別します。

ガンマというパラメータを調整することで、Leidenが生成するコミュニティの数を大きくしたり小さくしたりすることができます。私はガンマを、「コミュニティとしてラベル付けされたノード群が、関係がランダムに分布していると想定した場合よりもどれだけ相互接続されているか」を指定するものと考えています。ガンマが増加すると、クラスタ定義の基準がより厳格になります。高いガンマ値では、大規模で疎に接続されたコミュニティは基準をクリアできず、小規模で密に接続されたコミュニティが残ります。

Leidenを実行する前に、グラフプロジェクションを修正する必要がありました。Leidenは無向グラフで実行する必要がありますが、KNNは有向関係を生み出します。私はgds.graph.relationships.toUndirected()手順を使用して、グラフプロジェクション中のIS_SIMILAR関係をUNDIRECTED_SIMILAR関係に変換しました。

Leidenは重み付きの関係で実行することができます。K最近傍用に選んだ類似性カットオフのため、UNDIRECTED_SIMILAR関係上のすべての類似性スコアは0.83から1.0の間でした。私はmin-maxスケーリング式を使用して、これらの重みを0.0から1.0の範囲に変換し、近い接続を遠い接続よりも相対的に影響力があるようにしました。

私はアルファ値が1.0、2.0、4.0、8.0、16.0、32.0、64.0、128.0、256.0、512.0、および1024.0のLeidenを実行するテストを行いました。

https://miro.medium.com/v2/resize:fit:525/1*XelqPiYCAJcdBjO73tudVw.png

ガンマの増加値におけるコミュニティサイズの表。

この表から、ガンマを増加させると最大のコミュニティのサイズが93ノードから9ノードへと減少することがわかります。私は、小さなコミュニティの方がテーマ間の微妙な違いを捉える可能性が高いと考えました。

私はいくつかのテーマを選び、ガンマの様々なレベルでそのコミュニティに含まれる他のテーマを見てみました。

https://miro.medium.com/v2/resize:fit:525/1*B8S5B8fsg1TgMa0f03oYjQ.png

ガンマ値が32.0の場合、Christmasに関連するすべてのテーマは何らかの形で休日と関連しています。しかし、「Christmas Terro」と「Christmas Miracle」は、私がWCCを試したときと同様にまだ一緒にいました。ガンマを128以上に上げると、他のテーマは消えましたが、「Xmas」および「Christmas」は一緒に残りました。

さまざまなガンマレベルでいくつかの異なるテーマを見ることに基づいて、私は同じライデンコミュニティ内のテーマをガンマレベル256.0で同じテーマグループに収集することを選びました。各コミュニティに対して、ThemeGroupノードを作成しました。コミュニティのThemeノードをThemeGroupに関連付けるIN_GROUP関係を作成しました。

https://miro.medium.com/v2/resize:fit:525/1*qZ8u3fxuEUW9N3uwqbSEaQ.png

失恋に関連するテーマ(青いノード)を持つ例のテーマグループ(ピンクのノード)。

テーマグループが整えられたことで、私は同じか類似のテーマを共有する映画をグラフから検索し始めることができました。以下の例では、2つの映画が「Opulent neighborhood」というテーマを共有しています。また、両方のテーマが同じテーマグループ内にあるため、「opulent home」というテーマを持つ第3の映画とも関連しています。

https://miro.medium.com/v2/resize:fit:525/1*nmezXilD3m5q058HBN8fJA.png

映画(黄色のノード)の視覚化とテーマ(青色のノード)がテーマグループ(ピンクのノード)内にあります。

Theme Groupのサマリー

一旦テーマグループが決まったら、私はOpenAIのChatGPT-3.5-turboにテーマグループの短い説明を書いてもらいました。このタスクのコードは、Summarize theme groups.ipynbノートブックにあります。私は「これらの映画はテーマ...を扱っています」というパターンに従って説明の最初の文を提供しました。スターターの文と一緒に、私はLLMにテーマを含む最大20のタイトルと概要のサンプルを提供しました。これが私が使用したプロンプトです。

You are a movie expert.
You will be given a list of information about movies and the first
sentence of a short paragraph that summarizes themes in the movies.
Write one or two additional sentences to complete the paragraph.
Do not repeat the first sentence in your answer.
Use the example movie information to guide your description of the
themes but do not include the titles of any movies in your sentences.

「locals vs visitors」、「guest」、「guests」、「visitor」、「visitors」というテーマグループを含むLLMは、次のような要約を作り出しました:

これらの映画は、「locals vs visitors」、「guest」、「guests」、「visitor」、「visitors」というテーマを扱っています。これらの映画は、地元の人々と訪問者との間のダイナミクスを探求し、異なる背景を持つ個々の人々が交流する際に生じる緊張と興奮をしばしば強調します。物語は、もてなし、関係性、そしてゲストとホスト、訪問者と地元の人々との間に形成される予想外のつながりの複雑さに深く踏み込みます。「locals vs visitors」や「guest」のテーマが物語の中に巧妙に織り込まれており、人間の経験と交流の豊かな織物を提供しています。

「scamming」、「Swindling」、「scam artist」、「swindle」というテーマグループは次のような要約を作り出しました:

これらの映画は、「Swindling」、「scam artist」、「scamming」、「swindle」というテーマを扱っています。これらの映画は、登場人物が自身の目標を達成するために詐欺や詐欺行為に訴える、欺瞞と操作の世界に深く踏み込みます。物語は、これらの行動の結果を探求し、人間の性質の複雑さと個人的な利得の追求における正と不正のぼやけた境界線を明らかにします。欺瞞を通じた自己発見の旅は、社会の暗い側面と個々が望みを叶えるためにどこまで行くかを明らかにします。

各要約は、スターターセンテンスに関連するすべてのテーマを含んでいたので、要約からキーワードが漏れることはありませんでした。LLMは、映画の例から引き出して1つまたは2つの単語のテーマを周りの文脈を提供するのに良い仕事をしたようです。

このLLMが生成したテーマグループの長い説明に加えて、私は「~についての映画」というパターンに従った短い説明を作成しました。上記のテーマグループの短い要約は「詐欺、詐欺師、詐欺行為、ねずみ講についての映画」でした。これにより、LLMによって提供される追加の文脈がより良い検索結果をもたらすかどうかをテストすることができました。

私は各テーマグループに関連した3つのベクトルプロパティを作成しました。OpenAIのtext-embedding-3-smallモデルを使用して、短いサマリーと長いサマリーの埋め込みを生成しました。3つ目の埋め込みは、テーマグループに関連するテーマキーワードの埋め込みの平均でした。

異なるベクトルインデックスに基づいてリトリーバーを比較する

この段階で、映画コンテンツに関連する5つのベクトルインデックスを作成しました:

  • タイトルと概要をカバーするMovieノードのインデックス
  • テーマワードをカバーするThemeノードのインデックス
  • テーマの長いLLM生成サマリーをカバーするThemeGroupノードのインデックス
  • *テーマの短いサマリ”Movies about …”をカバーするThemeGroupノードのインデックス
  • ThemeGroupに関連するThemeノードからのテーマベクトルの平均をカバーするThemeGroupノードのインデックス

すべてのインデックスを同じ一連の質問でテストし、どのインデックスが関連する映画を最もよく取り出すことができるかを見ました。各質問について、各インデックスが最大50本の映画を見つけることを許しました。私は、各インデックスの質問に一致する結果の映画の数を数えることによってリコールに焦点を当てました。私はその指標を選んだのは、取得の下流のプロセスが誤検出をフィルタリングし、ドキュメントをランク付けすることができるからです。これらの比較のためのコードは、Compare retrievers.ipynbノートブックにあります。

私がテストした質問は以下の通りです:

  • 画家についてのドキュメンタリーは何がありますか?
  • クラシック音楽についての映画は何がありますか?
  • アイスホッケーについての映画は何がありますか?
  • 野球についての映画は何がありますか?
  • どの映画が犯人ですか?
  • ダークコメディーは何がありますか?
  • 1960年代のヨーロッパを舞台にしたものは何がありますか?
  • 先コロンブス時代のアメリカについての映画は何がありますか?
  • 鳥についての映画は何がありますか?
  • 犬についての映画は何がありますか?

Neo4j知識グラフからのデータの取得は、私がクエリに似たベクトルをセマンティックに検索し、グラフの関係をたどって探していた映画を見つけるための柔軟性を与えてくれました。

映画のインデックスについては、クエリベクトルに最も近いベクトルを持つ50本の映画を取得しました。これは最も基本的な取得でした。以下は私が使用したCypherクエリです。

CALL db.index.vector.queryNodes("movie\_text\_vectors", 50, $query_vector)
YIELD node, score
RETURN $queryString AS query,
"movie" AS index,
score, node.tmdbId AS tmdbId, node.title AS title, node.overview AS overview,
node{question: $queryString, .title, .overview} AS map
ORDER BY score DESC

テーマインデックスのために、最も近いベクトルを持つ25のテーマノードを取得し、グラフ内のHAS_THEME関連性を使用してそれらのテーマに関連するすべての映画を見つけました。クエリとのテーマの類似性によってソートされ、次にクエリとの映画の類似性によってソートされたテーマに関連するトップ50の映画を返しました。このCypherクエリを使用しました。

CALL db.index.vector.queryNodes("theme_vectors", 50, $query_vector)
YIELD node, score
MATCH (node)<-\[:HAS_THEME\]-(m)
RETURN $queryString AS query,
"theme" AS index,
collect(node.description) AS theme,
gds.similarity.cosine(m.embedding, $query_vector) AS score,
m.tmdbId AS tmdbId, m.title AS title, m.overview AS overview,
m{question: $queryString, .title, .overview} AS map
ORDER BY score DESC, gds.similarity.cosine(m.embedding, $query_vector) DESC
LIMIT 50

テーマグループに関連するインデックスについて、クエリベクトルに最も近い25のテーマグループを見つけました。IN GROUPの関係を使用して、それらのテーマグループに関連するすべてのテーマを見つけました。次に、HAS_THEMEの関係を使用して、それらのテーマに関連するすべての映画を見つけました。クエリに対するテーマグループの類似性、そして映画の類似性によってソートされた上位50の映画を返しました。以下は、テーマグループの長いサマリーインデックスに基づいて映画を取得するために使用したCypherクエリです。短いサマリーと平均インデックスのクエリは、インデックス名を除いて同じでした。

CALL db.index.vector.queryNodes("theme\_group\_long\_summary\_vectors",
  25, $query_vector) YIELD node, score
MATCH (node)<-\[:IN_GROUP\]-()<-\[:HAS_THEME\]-(m)
RETURN $queryString AS query,
"theme\_group\_long" AS index,
collect(node.descriptions) AS theme,
gds.similarity.cosine(m.embedding, $query_vector) AS score,
m.tmdbId AS tmdbId, m.title AS title, m.overview AS overview,
m{question: $queryString, .title, .overview} AS map
ORDER BY score DESC,
gds.similarity.cosine(m.embedding, $query_vector) DESC
LIMIT 50

私はChatGPT-3.5-turboに、取得した映画が質問にマッチするかどうかを判断してもらいました。また、私自身も映画を判断して、それが私の質問の意図に合っているかどうかを見ました。場合によっては、微妙な判断が求められました。野球の質問に対してソフトボールの映画はカウントすべきでしょうか?ホラー映画はどの程度ダークコメディとしてカウントされるべきでしょうか?私は一貫性を持って答えを出すように努め、映画の答えを評価した際にどのインデックスが映画を返したかを知らないようにしました。私が映画が質問にマッチするかどうかについてChatGPTと74%の時間で一致するという結果が出ました。全体として、私はChatGPTよりも取得した映画の多くを質問に関連があると分類しました。

すべての問いに関連すると私が判断した映画の総数を合計すると、テーマグループインデックスが他を明らかに上回り、映画インデックスよりも27%多くの関連映画を見つけ出しました。また、Graph Data Scienceを使用してThemeGroupノードを作成すると、LLMによって生成された生のThemeノードを使用するよりも良い結果を得られることがわかりました。

https://miro.medium.com/v2/resize:fit:489/1*jbGlHhNbvvNvixdzsKGFEA.png

インデックスによる検索結果の全体結果。

以下のチャートは、クエリごとの結果の内訳を示しています。長いサマリーインデックスは常に良好なパフォーマンスを示し、常に基本的な映画インデックスを上回りましたが、すべての質問でトップのインデックスではありませんでした。

テーマインデックスはダークコメディを見つけるのに非常に優れていました。それは「ホラーコメディ」のテーマを独自に見つけ、ダークネスについてのテーマを優先する長いサマリーインデックスをパスしました。

短いサマリーインデックスは、クラシック音楽の質問で他のインデックスを上回りました。それは「作曲家」という言葉を含むテーマグループを他のインデックスが見逃したのを見つけました。

https://miro.medium.com/v2/resize:fit:515/1*n1VttniTUrO6zKvWqvn_7w.png

各インデックスに対する質問ごとの結果。

ChatGPT-3.5-turboが関連性があると考えた映画の総数を見ると、長い要約インデックスが他を上回っていましたが、映画インデックスを13%しか上回りませんでした。これは、LLMが取得したドキュメントを分析し、ユーザーに結果を返すときに何を言い換えるかを決定するRetrieval Augmented Generationアプリケーションで見ることができるより現実的な期待値かもしれません。

https://miro.medium.com/v2/resize:fit:489/1*vpWNwJTWMD5lUL3B66NOEA.png

結論

私は、意味的検索のトピックモデリングにNeo4j Graph Data Scienceを使用する3つの主要な利点を見つけました。

  1. Neo4j Graph Data Scienceで作成された長いサマリーテーマグループインデックスは、他のインデックス戦略よりも多くの関連検索結果を提供しました。
  2. テーマグループを作成することで、非構造化テキストをデータの分析と視覚化に使用できる知識グラフに変えました。
  3. Neo4jでトピックモデリングを実行することは、トピックの抽出、語幹化、トピッククラスタリングの各層を通じて私の作業を整理し、表示するための素晴らしい方法を提供しました。データの取り込みとクリーニング、アルゴリズム分析、ベクトルベースの取得がすべて同じグラフプラットフォームで行われました。

OpenDevinの紹介:AIによるソフトウェア開発の可能性

Introduction to OpenDevin: The Aspiring AI-Powered Software Development Platform | by Elmo | May, 2024 | AI Advances

OpenDevin logo

OpenDevin is an innovative, open-source project that aims to revolutionize software development by introducing an autonomous AI software engineer. This AI assistant has the mission to tackle complex engineering tasks and actively collaborate with human users on various software projects. It’s a work in progress, but the alpha version, already released, offers a clear glimpse into the exciting future of collaborative AI development.

Break. End of the introduction. More details in:

  1. OpenDevin’s Core Functionalities: What it Does (or at least What it Aspires to Do)
  2. Getting Started with OpenDevin
  3. Understanding OpenDevin’s Architecture
  4. OpenDevin’s Agents: Specialized AI Assistants
  5. OpenDevin’s Potential Applications
  6. Conclusion

Imagine having a tireless teammate who can tackle complex coding tasks, understand your intent, and offer suggestions and explanations alongside the way. That’s the potential future of OpenDevin. This project aspires to create a comprehensive AI assistant that can:

  • Automate Repetitive Tasks: OpenDevin aims to handle various coding chores, including generating code, fixing bugs, and refactoring existing code, freeing up developers to focus on more strategic aspects of the project.
  • Collaborate Like a Partner: OpenDevin isn’t just an automated tool; it strives to be a collaborative partner. It will understand your intent through natural language processing and provide intelligent suggestions, explanations, and code examples tailored to your specific needs.
  • Continuously Learn and Adapt: OpenDevin aspires to be a fast learner: by interacting with users and analyzing past projects, it’s designed to continuously improve its performance and adapt to different coding styles and project requirements.

OpenDevin primarily operates within a Docker container, providing a controlled environment for its operations. Here’s a basic guide to get started:

  1. Set up your workspace: Choose a directory where OpenDevin can access and modify your code.
  2. Configure your LLM: Select and configure your desired Large Language Model (LLM) by setting relevant environment variables like LLM_API_KEY and LLM_MODEL. OpenDevin supports various LLMs, including GPT-4, Claude, Azure OpenAI, Google Gemini/Vertex, and local models like the ones provided by Ollama.
  3. Run OpenDevin: Use the provided Docker command with appropriate environment variables to launch OpenDevin.
  4. Access the interface: Once running, OpenDevin is accessible through a web interface at http://localhost:3000.

As shown in the documentation, to start you just need to use these lines of code:

export WORKSPACE_BASE=$(pwd)/workspace;
docker run \
    --pull=always \
    -e SANDBOX\_USER\_ID=$(id -u) \
    -e WORKSPACE\_MOUNT\_PATH=$WORKSPACE_BASE \
    -v $WORKSPACE\_BASE:/opt/workspace\_base \
    -v /var/run/docker.sock:/var/run/docker.sock \
    -p 3000:3000 \
    --add-host host.docker.internal=host-gateway \
    ghcr.io/opendevin/opendevin:0.5

An important note: while OpenDevin operates within a Docker sandbox for isolation, ensure your chosen workspace directory is backed up as files might be modified or deleted during operation!

Also, it is important to note that OpenDevin will issue many prompts to the configured LLM, which may incur costs. Therefore, setting spending limits and monitoring usage is essential.

OpenDevin’s system architecture consists of two primary components:

Frontend: This is the user interface where developers interact with OpenDevin. It allows users to input tasks, view code suggestions, and manage project settings.

Backend: This component handles the core functionalities of OpenDevin, including:

  • LLM interaction: Sending prompts to the chosen LLM and receiving responses.
  • Agent execution: Utilizing various agents to process information and perform actions.
  • Workspace management: Interacting with the code within the designated workspace directory.

Their interconnection and their building blocks are shown in the following image.

Architecture of OpenDevin

The key components of OpenDevin’s system architecture are:

  • Chat Interface: User interface for interacting with the chat application
  • App: Main component that houses various sub-components for user experience
  • settingsService: Manages user preferences and personalization options
  • chatService: Handles core chat functionalities (message transmission, encryption, storage)
  • socket: Enables real-time communication between frontend and backend
  • Client WS: WebSocket on the client-side for real-time data exchange
  • Server WS: WebSocket on the server-side for real-time data exchange
  • VITE_TERMINAL_WS_URL: Configuration element specifying the web address for WebSocket connection
  • AgentController: Manages automated agents or chatbots for intelligent chat functionalities

OpenDevin utilizes different agents, each with unique capabilities to tackle specific tasks:

  • CodeAct Agent: The CodeAct Agent embodies the concept of consolidating LLM agents’ actions into a unified code action space. This agent can converse with users, execute Linux bash commands, and run Python code through an interactive interpreter. It leverages OpenDevin’s plugin system, including the Jupyter plugin for IPython execution and the SWE-agent tool plugin for software development tasks. This agent is shown in action in the following image.

CodeAct Agent

  • Monologue Agent: The Monologue Agent harnesses the power of long-term and short-term memory to complete tasks efficiently. It stores long-term memory as a LongTermMemory object, allowing the model to search for relevant examples from the past. Short-term memory is maintained as a Monologue object, which the model can condense as needed. This agent supports a wide range of actions, including running commands, reading/writing files, recalling information, browsing URLs, and pushing to GitHub.
  • Planner Agent: The Planner Agent employs a unique prompting strategy to create long-term plans for solving problems. It receives previous action-observation pairs, the current task, and hints based on the last action taken at every step. This agent checks if the current step is completed and either returns an AgentFinishAction or creates a plan prompt to send to the model for inference.

OpenDevin’s capabilities (and similar projects) open doors for various applications within the software development lifecycle:

  • Rapid Prototyping: Quickly generate and iterate on code prototypes based on user specifications and feedback.
  • Automated Code Generation: Automate repetitive coding tasks, such as creating boilerplate code or implementing standard algorithms.
  • Intelligent Code Completion: Receive context-aware code suggestions and completions to improve coding efficiency and accuracy.
  • Bug Detection and Fixing: Identify and fix bugs in existing code with AI-powered analysis and suggestions.
  • Code Refactoring: Improve code quality and maintainability by automatically refactoring existing code.
  • Learning and Education: Tools like OpenDevin can serve as a valuable aid for learning new programming languages and concepts by providing interactive explanations and code examples.

OpenDevin represents a nice challenge in AI-assisted software development and it’s splendidly done in an open-source way. As OpenDevin continues to evolve, it promises to give super power to developers, accelerating development cycles, and ultimately shaping the future of software development. When will this juicy fruit be ripe enough to be eaten, coff, used?

( text taken from this page from https://didyouknowbg8.wordpress.com/ )