Aptible AI のエンジニアリング チームは、SRE チームが本番環境の問題を調査して解決できるように、過去約 4 か月かけて AI エージェントを構築してきました。私たちは、同様の目的で独自のエージェントを構築中の非常に多くの初期テスターや設計パートナーと話をしたため、独自のエージェントで何を行ったか、そしてどのように構築できるかを説明するガイドをまとめることにしました。あなた自身もひとつ。
次のステップバイステップのチュートリアルでは、次の方法を説明します。
その前に、考慮事項と専門的なヒントをいくつか説明します。
? 考慮事項: 新しいものを構築する必要がない場合は、構築すべきではありません。ありますよ。多くの。市販のツール。特定の使用例に応じて、最適なものが見つかるかもしれません。
Aptible が検索し、最終的に独自のインシデント対応を開発するきっかけとなったのは、私たちが知識のサイロ化に悩まされ、特定のシステムで問題が発生するたびに 3 人か 4 人の対象分野の専門家に頼る傾向があったことでした。
そこで私たちは、情報検索を改善するために Danswer と呼ばれるオープンソース ツールの開発を開始しました (人気のある商用競合会社である Glean と同様)。これは Slack に直接接続され、さまざまな情報ソースから自然言語の質問に対する回答を取得できました。問題は、インデックス付けされたデータのみ (つまり、ドキュメントとチャット履歴のみ) に限定されていたことでした。
⚒️ 私たちが構築したもの: 私たちが必要としていたのは、他のすべてのシステム (ドキュメントや Slack だけでなく) と統合できるツールでした。インシデントの終了後には、ログとメトリクス、アプリケーションの健全性ステータスを取得し、レポートと事後検証を生成する必要がありました。そこで私たちは、基本的にリアルタイム データとインデックス付きデータの両方に接続できる一連の統合に基づいて構築された AI エージェントを設計しました。詳細については後ほど!
? プロのヒント: 独自の製品を構築することを決定する前に、すでに利用可能なものを調べてください。まず始めに、Reddit からアイデアをクラウドソーシングする (このスレッドをチェックしてください) か、オープンソース ツールをいくつかチェックしてみるとよいでしょう (特にインシデント対応ツールを探している場合は、github から始めるのが良いでしょう) )。明日から使い始められるオープンソース AI エージェントの長いリストもあります。
? 考慮事項: 上で述べたように、ここでの最大の考慮事項は、エージェントがどのような種類の情報にアクセスできるようにする必要があるかということです。 API を介してサードパーティのプロバイダーと統合するだけで済むかもしれませんが、よりニーズに合わせた統合が必要な場合は、統合の仕組みをより慎重に検討する必要があります。
構築を開始する前に何を統合する必要があるかを慎重に検討することで、後で頭を悩ませる必要がなくなります。データベースにクエリを実行するカスタム スクリプトをエージェントが実行できるようにする必要がありますか?ログとメトリクスをリアルタイムで取得する必要がありますか?その情報を取得するようにエージェントをどのように設計しますか?ソースへのリンクを返しますか?手動で選別する必要があるログの行の塊が返されるのでしょうか? それとも、異常がどこにあるのかを推測できるのでしょうか?
⚒️ 私たちが構築したもの: その中核として、Aptible AI は一連の統合に基づいて構築されています。統合は、サードパーティプロバイダーへの単なる接続ではなく、チームがそのプロバイダーを使用する方法に特有の構成のコレクションでもあります。たとえば、Aptible AI は、同じプロバイダーをさまざまな方法で使用する必要があるため、同じプロバイダーの複数の統合をサポートします。チームごとに Datadog の使用方法が異なり、考慮するメトリクスやタグも異なるため、各チームが必要な方法で同じツールへの統合を使用できます。
Aptible AI は、以下を含むさまざまな一般的な SRE ツールをサポートします。
これらの統合の実際の実装は、カスタマイズ可能性の 3 つのカテゴリのいずれかに当てはまります。
まず、カスタマイズを必要としない基本的な統合があります (PagerDuty はその一例です)。 PagerDuty からデータを取得して AI のコンテキストに追加するだけなので、PagerDuty 統合を利用するすべてのチームが同じ方法でそれを使用します。
次に、よりカスタマイズ可能な統合 (前述の Datadog の例など) があります。これらは、汎用の InfluxDB 統合の上に構築されていますが、コンテナーのメトリクスの検索や再起動アクティビティの検索の特定のユースケースに合わせてカスタマイズされています。
最後に、Aptible 以外の人には意味がないと思われる完全にカスタムのツールがあります (ここでの例は、アプリケーションのコンテナを取得する統合です)。これらはインフラストラクチャの実行方法に完全に固有であり、軽量の PubSub インターフェイスまたは WebSocket ベースの「安全な」プロキシのいずれかによって実装できます。
? プロのヒント: 少ないほど効果的です。モデルに選択できるツールが多すぎると、モデルが間違ったツールを選択し始めて混乱する可能性があります。詳細については次のセクションで説明します
? 考慮事項: モデルに関する問題は次のとおりです…新しいモデルが毎日登場しており、モデルを選択する際には留意すべき考慮事項がいくつかあります (主に特定の使用例に関係します)。セルフホストする必要がありますか?エージェントは会話ベースかタスクベースか、あるいはその両方が必要ですか?単純なタスクを実行するのでしょうか、それとも複雑なタスクを実行するのでしょうか?リアルタイムのパフォーマンスが必要ですか?
そのコンテンツはすでにあちこちにあるため、存在するすべてのモデルを検討する必要はありません (詳しく知りたい場合は、これが素晴らしいリソースです)。しかし、私たちが下した決定を順を追って確認することはできます。 Aptible AI を構築するときに行うべきことと、私たちが検討したオプション。
トレードオフを避けることはできないため、これは難しいプロセスです。エージェントに複雑なタスクを実行してもらう必要がある場合は、速度とコストを少し犠牲にする必要があります。
モデルのサイズ、機能、アーキテクチャは、タスクに単純な分類が必要か、それとも非常に複雑な推論と対話が必要かによって大きく異なります。単純であれば、デシジョン ツリー、ランダム フォレスト、または単純なニューラル ネットワークのような、より小さく軽量なモデルで十分です。より複雑な場合は、GPT-4、BERT、または同様のトランスフォーマーベースのアーキテクチャのような、より強力なモデルを検討できます。
セキュリティの問題を回避するためにセルフホストを選択した場合、セルフホスト型バージョンはホスト型オプションよりも遅れるため、機能を犠牲にする必要がある可能性があります。
エージェントにドメイン固有の知識のトレーニングを受ける必要がある場合は、微調整用に独自のデータセットを厳選または作成する必要があります。データ品質の問題を回避するために、大規模なデータセットですでにトレーニングされている事前トレーニング済みモデルを使用して回避できるかどうかを確認してください (ただし、エージェントがアクセスする必要があるデータによっては不可能な場合があります)。
⚒️ 私たちが構築したもの: 私たちは現在、Aptible AI に GPT-4o を使用しています。これは、GPT-4o が最も質の高い回答を提供してくれると考えているためです。ただし、Aptible AI を使用しているお客様が独自のモデル (自己ホスト型モデルを含む) の使用を希望する可能性があることを私たちは認識しています。そのため、私たちは構築する際にそのことを念頭に置いています。
? プロのヒント: エージェントは、提供した情報によってのみ賢くなります。 LLM は、与えられた情報をいつどのように使用するかを理解するための支援を必要としています。情報を解釈する方法についての指示を与えないと、LLM は単に何かをでっち上げてしまいます。 LLM にフィードする情報を厳選するために、事前に多大な労力を費やしてください!
? 考慮事項: できるだけ多くのデータ (ドキュメント、Slack の会話、コード リポジトリ、問題トラッカーなど) を取得して、すべてを RAG アプリケーションに投げたいと思うかもしれません*、 *そして質問してください。しかし、私たちの経験では、ノイズが多すぎて役に立たないことがほとんどです。そこでプロンプトエンジニアリングの出番です。
これについてはすでに触れましたが、プロンプト エンジニアリングはここでのパズルの重要な部分です (プロンプト テクニックの概要については、これを確認してください)。迅速なエンジニアリングが優れているほど、エージェントの能力も向上します。
コンテキストとして、Aptible AI を構築する際に (時間をかけて) 検討したいくつかの点を以下に示します。
ゼロショット プロンプト: これは、ほとんどの人が ChatGPT と話すときに行うことです。彼らはただ質問するだけで、答えが得られます。反応が悪ければ、質問の仕方を変えるだけです。
少数のプロンプト: これは、ChatGPT と話すときに少し経験豊富な人が行うことです。彼らは質問をし、必要な出力の例を含めます。基盤となるモデルがすでにその方法を知っている非常に単純なタスクには、ゼロショットまたは少数ショット、あるいはその両方のプロンプトを使用できます。
取得拡張生成 (RAG): これは、モデルが追加のコンテキストを取得し、それを使用して質問に答えることを可能にする手法です。これは、AI を利用したドキュメント検索に特に役立ちます (Glean と Danswer も参照)。
ReAct: この技術により、エージェントは、人間の推論に最も似た、反復的な方法で「思考」を生成し、「アクション」を実行して問題を解決できます。 ReAct は、リアルタイムでドキュメントやツールを参照して回答を作成するなど、ある程度複雑な問題に最適です。
覚えておくべき重要な点は、これらのテクニックを組み合わせて使用できるということです (マルチエージェント アプローチについては次に説明します)。私たちがやったことは次のとおりです…
⚒️ 私たちが構築したもの: Aptible AI はマルチエージェント構造であるため (詳細は後述)、タスク/質問の複雑さに応じて ReAct と RAG を組み合わせて実装しました。
つまり、AI に質問すると、すべての統合 (使用方法の指示付き) が AI に引き渡されます。次に、AI は利用可能な情報に基づいて、どのツールを呼び出すかを決定します。各統合呼び出しの後、AI には、回答を提供するのに十分な情報があると判断するか、追加の統合が関連しており追加情報が得られる可能性があると判断するかのオプションがあります。
プロセス全体を通じて、私たちはいくつかの異なるメカニズムを介して、AI がどの統合を活用するかについてより適切な決定を下せるよう支援しようとしています。
各統合をいつどのように使用するか、出力の解釈方法を明確にするための、統合のための広範なプロンプト エンジニアリング。
私たちは、AI に統合からの応答の価値を自己評価するよう求める自己評価システムを構築しました。 AI が統合を呼び出す際に愚かな決定を下した場合 (または不適切な入力を提供した場合) であっても、統合の出力が役に立ったかどうかを自己評価するよう AI に依頼すると、通常は事後的にそれを認識できます。その後、それを使用して、特定の出力が応答にどの程度影響を与えるかに影響を与えることができます。 AI が一貫して間違った決定を下している場合、AI の処理をブロックすることもできます。
私たちは過去の経験に基づいて Naïve Bayes を実装しました。たとえば、ほとんどの場合、統合 A を呼び出してから B を呼び出し、それによって有益な結果が得られる場合は、そうし続けることがおそらく有益です。エージェントは、以前の同様のインシデントとの比較などを使用して、特定のシナリオでどの統合がいつ役立つかをさらに絞り込むこともできます。
? プロのヒント: 正しいように見えて実はそうではない、ナンセンスな答えを避けるために、必ず一歩下がって、AI で解決しようとしている問題に対して、最も有用な情報が通常どこから得られるのかを検討してください。 – 次に、それに基づいてエージェントを設計します。
? 考慮事項: マルチエージェントのアプローチはますます一般的になってきていますが、ユースケースによっては複雑になり、不要になる可能性があります。複雑な問題を解決するために、エージェントのチームがさまざまな手法で協力することは非常に便利です。
たとえば、特定のインフラストラクチャとは関係のない質問を Slack でボットに行う場合 (1995 年のワールド シリーズ優勝者を知りたいだけかもしれません)、ゼロショットでエージェントを構築することができます。 Slack (または Slack がある場所) に統合された ChatGPT として単に機能するように求められます。
しかし、質問やニーズが複雑な場合は、基本的に小さな調査チームとして機能し、異なるソースからインテリジェントな方法でデータを収集して分析するエージェントのチームを用意すると便利です。
⚒️ 私たちが構築したもの: Aptible AI は、どのタイプの質問やタスクに対処する必要があるかを決定するブローカー エージェントから始まる、マルチエージェント アプローチを使用します。
? プロのヒント: マルチエージェント アプローチからリファクタリングするよりも、マルチエージェント アプローチにリファクタリングする方が簡単です。したがって、この方法でエージェントの構築を開始する前に、それが必要であることを確認してください。
? 考慮事項: これは、Aptible AI の初期ユーザーとチャットするときによく話題になるトピックです。ほとんどのエンジニアリング チームは、新しいツールの実装に関しては最終的にセキュリティ チームと対峙する必要があり、データの安全性を確保することが重要です (特に規制の厳しい業界で働いている場合)。したがって、最初に行う必要があるのは、組織の AI セキュリティ ポリシーを知ることです。その後、潜在的なデータ漏洩や外部の脅威から保護するためにできることがいくつかあります。
⚒️ 構築したもの: まず、データでトレーニングしないモデルを使用します。私たちは、セルフホスティングであろうと他のものであろうと、セキュリティに関してお客様が何を必要としているのかについて、現在も多くの発見を行っています。ご期待ください。
? プロのヒント: AI にアクセスを許可するデータ、またはプロンプトに含めるデータには注意してください。特に、そのデータがエンド ユーザーと共有されるべきでない場合は注意してください。ログなどの予測不可能なデータを含める必要がある場合は、LLM とエンドユーザーに渡される内容が確実にサニタイズされるように、Nightfall などの at ツールの使用を検討してください。
ああ、もちろん、使用できる必要があります!
? 考慮事項: エージェントをどのように使用する予定ですか? UIが必要なのでしょうか?組織全体で使用されますか?
ボット周りの UX に関しては、車輪の再発明に時間を費やす必要はおそらくありません。 Chainlit、Gradio、Streamlit などのフレームワークは、ユーザー インターフェイスを構築したり、Slack などの他のワークフロー ツールと統合したりするための、すぐに使えるツールを提供します。まずはこれらのツールのいずれかを使用して、エージェントから適切な回答を得ることに集中できるようにしてください。
⚒️ 構築したもの: 当社のエージェントはインシデント対応専用に構築されているため、また Slack 内でインシデントを処理しているため、主に UI として Slack を使用しています。ただし、それには制限があるため、私たちはそれらを回避するために最善を尽くします (つまり、ChatGPT で見られるようにエージェントが入力を模倣して応答していることを示す代わりに、ボットは代わりに Slack の質問に ? 絵文字で反応します)。また、構成、レポート、監査、分析のための Web UI も設計しました。
? プロのヒント: 必要に応じて別の UX に簡単にリファクタリングできるように、LLM コードはできる限り分離しておいてください。
さて、モデル、テクニック、フレームワークについての理論的な話から始めましょう!早速、独自のエージェントの構築を始めましょう。
AI の構築という終わりのないウサギの穴を掘り下げる前に、会話型アシスタント インターフェイスを構築するための人気のあるフレームワークである Chainlit をセットアップして、成功に向けて準備を整えていきます。
Chainlit は、スレッド、メッセージ、ステップなどの会話型対話をモデル化するための独自の構築ブロックのセットと、LLM と対話するための ChatGPT のようなユーザー インターフェイスを提供します。
また、Slack や Teams などの人気のあるチャット ツールとのすぐに使える統合や、React や FastAPI などの人気のあるツールとインターフェースするためのライブラリも提供しているため、必要に応じてより大きなアプリケーションに組み込むことができます。 .
簡単に言うと、Chainlit は多くの足場や単調な作業を排除してくれるので、UI や設定をいじるのではなく、AI アシスタントの開発とユーザーからのフィードバックに集中できるようになります。
このラボが終了するまでに、ユーザーの発言をエコーバックするだけの動作する Chainlit アプリケーションが完成します。次の記事では AI の統合について説明します。
始める前に、いくつかのことを設定する必要があります:
セットアップが完了したら、次に進みます。
まず、プロジェクトをセットアップし、chainlit を依存関係として追加します。
mkdir roger cd roger poetry init --no-interaction poetry add chainlit
次に、次の内容を含む app.py ファイルをプロジェクトのルートに作成します。
import chainlit as cl @cl.on_message async def handle_message(message: cl.Message) -> None: # Echo the message back to the user. await cl.Message( content=f"Received: {message.content}", ).send()
上記のコードは、handle_message 関数を Chainlit に登録しているため、メッセージが受信されるたびにこの関数が実行されます。
現時点では、この関数は単に「Received: 」という接頭辞を付けてメッセージをユーザーにエコーバックします。
最後に回転させます!変更を加えるときに、 --watch を使用してコードをホットリロードできます。
poetry run chainlit run app.py --watch
このコマンドを実行すると、Chainlit アプリが起動し、ブラウザーでその UI が開き、メッセージを送信して応答を受け取ることができます。
Chainlit アプリをスキャフォールディングすると、LLM に接続して、話しかけて人間のような応答を得ることができます。
簡単にするために OpenAI のホストされた gpt-4o モデルを使用しますが、別のプロバイダーを使用するかどうかは単に構文の問題です。
この記事を終えるまでに、ChatGPT を操作する場合と同様に、gpt-4o モデルにプロンプトを出し、応答を取得できるようになります。また、ボットが会話のコンテキストを維持して、フォローアップの質問ができるようにします。
始める前に以下が必要です:
OpenAI アカウントと API キー
まず、OpenAI の API と連携するように API クライアントを構成します。次のコードを app.py の先頭に追加します:
mkdir roger cd roger poetry init --no-interaction poetry add chainlit
次に、ユーザーのメッセージを OpenAI に送信し、単にエコーバックするのではなく応答を取得できるように、handle_message 関数を更新する必要があります。 handle_message 関数を次の関数に置き換えます:
import chainlit as cl @cl.on_message async def handle_message(message: cl.Message) -> None: # Echo the message back to the user. await cl.Message( content=f"Received: {message.content}", ).send()
これで、アプリケーションを実行すると (または --watch フラグを指定して実行したままにした場合)、質問して応答を得ることができます。
少し遊んでフォローアップの質問をしたことがある方は、ボットがあなたが話した内容を「覚えていない」ことに気づいたかもしれません。例:
これは、メッセージを送信するたびに、その 1 つのメッセージだけを LLM に送信するため、デフォルトでは「会話」という概念が存在しないために発生します。
この記憶喪失を治すには、新しいメッセージを送信するたびに会話内のすべてのメッセージを送信する必要があります。
Chainlit は cl.chat_context.to_openai() ヘルパーを提供することでこれを容易にします。これにより、これまでに交換されたすべてのメッセージが、OpenAI (および他のほとんどのプロバイダー) が期待する形式で便利に提供されます。
handle_message 関数を更新して、最新のメッセージの前に履歴メッセージを追加します。
poetry run chainlit run app.py --watch
フォローアップの質問ができるようになりました!
パート 1 の最初のいくつかのステップを完了した後、長い回答が必要な質問をすると、何も表示されないまでに時間がかかることに気づいたかもしれません。
これにより、ユーザー エクスペリエンスが低下する可能性があります (特にパート 3 の後半で、長時間実行されるツール呼び出しを追加し始めるとき) ので、これを修正しましょう。
このステップの最後には、ChatGPT と同様に、ボットの「タイプ」をリアルタイムで確認できるようになります。
リアルタイムのメッセージ更新を取得するには、「ストリーム」を使用するように実装を更新する必要があります。基本的に、メッセージを受信するとすぐに空のメッセージで応答し、LLM でストリームを開始し、ストリームから応答の新しいチャンクを受信するたびに空のメッセージを更新します。
これは複雑に聞こえるかもしれませんが、驚くほど簡単です。 handle_message 関数を次のように更新します:
mkdir roger cd roger poetry init --no-interaction poetry add chainlit
?? これまでの完全なコードは次のとおりです:
import chainlit as cl @cl.on_message async def handle_message(message: cl.Message) -> None: # Echo the message back to the user. await cl.Message( content=f"Received: {message.content}", ).send()
これで、質問すると、ボットがリアルタイムで「入力」しているのが表示されるはずです!
この時点までに、ChatGPT の軽量クローンを構築しました。それはそれで素晴らしいことですが、私たちが本当に必要としているのは、特定のタスクの実行を支援してくれるアシスタントです。この場合、SRE のようにインシデントのトラブルシューティングを行ってもらいたいのです。
そこに到達するには、まずエージェントをカスタム OpenAI アシスタントにリファクタリングします。これにより、システム プロンプトを制御できるようになります (また、LLM にファイル検索や関数呼び出しなどのツールへのアクセスを許可する機能も提供します)。これについては後で説明します)。
このステップが終わるまでに、ボットをカスタムの「アシスタント」にリファクタリングし、システム プロンプトをカスタマイズして独自の「個性」を与えることができます。コードでは、新しいメッセージを受信するたびにすべてのメッセージを送信する代わりに、OpenAI API を使用してメッセージを永続化する「スレッド」も使用します。
アシスタントの作成は簡単です。OpenAI Assistants API を呼び出すだけです。ただし、これをアプリケーションの起動時に一度だけ実行したいため、その API 呼び出しを handle_message 関数に含めることはできません。
代わりに、別の Chainlit フック、on_chat_start を使用します。これはアプリケーションの最初の起動時に 1 回だけ実行され、アシスタントを設定します。
これを app.py に追加します:
poetry run chainlit run app.py --watch
注: handle_message のメッセージ履歴に最初のシステム タイプのメッセージを提供することで、アシスタントにカスタム システム プロンプトを提供することが技術的に可能です。ただし、近い将来に使用する他のいくつかの機能が解放されるため、カスタム命令を備えたアシスタントにリファクタリングしています。
会話用のアシスタントとスレッドができたので、それらを使用するようにメッセージ ハンドラーをリファクタリングできます。
まず、会話中に発生するさまざまなイベントの処理方法を新しいアシスタント オブジェクトに伝えるために、AssistantEventHandler が必要です。
以下を app.py に追加します:
import os from openai import AsyncOpenAI ## # Settings # try: OPENAI_API_KEY = os.environ["OPENAI_API_KEY"] except KeyError as ex: raise LookupError(f"Missing required environment variable: {ex}") client = AsyncOpenAI(api_key=OPENAI_API_KEY) # ...
ここで、新しいおもちゃをすべて使用できるように handle_message 関数を調整するだけです。 handle_message 関数を次のように更新します:
# ... @cl.on_message async def handle_message(message: cl.Message) -> None: # Retrieve the response from the LLM response = await client.chat.completions.create( messages=[{"content": message.content, "role": "user"}], model="gpt-4o", ) await cl.Message(content=response.choices[0].message.content).send()
?? これまでの完全なコードは次のとおりです:
mkdir roger cd roger poetry init --no-interaction poetry add chainlit
アシスタントとスレッドを使用したので、動作のカスタマイズを開始できます。まず、アシスタントが内部ドキュメントの一部にアクセスできるようにして、ユースケースに合わせた応答を提供できるようにします。
このセクションの終わりまでに、プロンプトに応答するときにファイルのコレクション (SRE Runbook やその他の内部ドキュメントなど) を検索する機能をボットに提供できるようになります。
簡単にするために、ベクター ストアにアップロードされてアシスタントに提供されるファイルが詰まったフォルダーとしてこれを実装します。
最初に行う必要があるのは、ベクター ストアを作成し、アシスタントに提供することです。
まず、handle_chat_start 関数の先頭を更新して以下を含めます:
import chainlit as cl @cl.on_message async def handle_message(message: cl.Message) -> None: # Echo the message back to the user. await cl.Message( content=f"Received: {message.content}", ).send()
次に、client.beta.assistants.update() への呼び出しを更新して、アシスタントにベクター ストアへのアクセスを許可し、file_search ツールを有効にします。
poetry run chainlit run app.py --watch
最後に、アシスタントがプロンプトに答えるときに参照するドキュメントをアップロードする必要があります。
まず、ドキュメントを入れるフォルダーを作成する必要があります。
import os from openai import AsyncOpenAI ## # Settings # try: OPENAI_API_KEY = os.environ["OPENAI_API_KEY"] except KeyError as ex: raise LookupError(f"Missing required environment variable: {ex}") client = AsyncOpenAI(api_key=OPENAI_API_KEY) # ...
次に、ドキュメントを収集してそのフォルダーに置きます。テスト目的で、次の偽のドキュメントをフォルダーに追加しました:
# ... @cl.on_message async def handle_message(message: cl.Message) -> None: # Retrieve the response from the LLM response = await client.chat.completions.create( messages=[{"content": message.content, "role": "user"}], model="gpt-4o", ) await cl.Message(content=response.choices[0].message.content).send()
最後に、handle_chat_start 関数を更新して、前に作成したベクター ストアにドキュメントを自動的にアップロードします。ベクター ストアを作成する場所の直後に次のコードを追加します:
# ... @cl.on_message async def handle_message(message: cl.Message) -> None: # Retrieve the response from the LLM response = await client.chat.completions.create( messages=[ # Prepend all previous messages to maintain the conversation. *cl.chat_context.to_openai(), {"content": message.content, "role": "user"} ], model="gpt-4o", ) await cl.Message(content=response.choices[0].message.content).send()
ℹ️ 注: 現時点では、.md ファイルのみをサポートしますが、OpenAI はさまざまなファイル タイプをサポートしているため、ユースケースに適したものに自由に glob パターンを更新してください。
これにより、./docs フォルダー内のすべてのファイルが自動的にアップロードされ、ベクター ストアに追加されます。
特に大規模なデータセットの場合、ファイルの検索に時間がかかることがあります。そのような場合、ユーザーがイライラしないように、何が起こっているのかをユーザーに知らせた方がよいでしょう。
幸いなことに、Chainlit は、バックグラウンドで何かが起こっていることをユーザーに伝えるために使用できる Step クラスを提供することで、これを簡単にします。 Step クラスを以前に構築した MessageEventHandler と組み合わせて使用し、ツールが呼び出されるたびにインジケーターを追加できます。
MessageEventHandler に以下を追加します:
# ... @cl.on_message async def handle_message(message: cl.Message) -> None: # Send an empty initial message that we can update with a streaming # response. message = cl.Message(content="") await message.send() # Stream the response from the LLM stream = await client.chat.completions.create( messages=[ # Prepend all previous messages to maintain the conversation. *cl.chat_context.to_openai(), {"content": message.content, "role": "user"} ], model="gpt-4o", stream=True, ) # Update the existing (initially-empty) message with new content # from each "chunk" in the stream. async for chunk in stream: if token := chunk.choices[0].delta.content: await message.stream_token(token) # Send a final update to let the message know it's complete. await message.update()
独自のドキュメントの一部をアップロードしたので、ユースケースにさらに具体的な質問をいくつかしてみて、何が得られるかを確認してください。
このテスト ケースでは、顧客データベースの高い CPU 使用率について尋ねられたときに、ランブックが正しく参照されました。
?? 参考までに、これまでの完全なコードを次に示します:
mkdir roger cd roger poetry init --no-interaction poetry add chainlit
当社のエージェントは、厳選された内部ドキュメントからデータを取得できるようになりました。これは、適切なドキュメントがある場合に役立ちます。ただし、インシデント管理では、アラートのスキャン、ログの読み取り、指標の解釈など、ドキュメントでカバーされていない事柄の調査に多くの時間が費やされることがよくあります。
これらの目的のために、アシスタントに外部 API を呼び出す機能 (より広義には、定義した関数を実行する機能) を提供して、必要に応じてより多くのコンテキストを収集できるようにしたいと考えています。
これを行うには、モデルの「関数呼び出し」機能を活用して、定義した関数を実行します。
このセクションが終わるまでに、プロンプトに答えるときに外部ツール (偽の PagerDuty ツール) を使用して情報を取得できる機能をボットに与えたことになります。
まず、get_pagerduty_alert_details という新しい関数を app.py に追加しましょう。
import chainlit as cl @cl.on_message async def handle_message(message: cl.Message) -> None: # Echo the message back to the user. await cl.Message( content=f"Received: {message.content}", ).send()
次に、LLM にツールを呼び出す方法を指示する必要があります。 OpenAI は、JSONSchema 形式のツール定義を必要とします。
client.beta.assistants.update() の呼び出しを更新して、すでにある file_search ツールの後に新しいツール定義を含めます。
poetry run chainlit run app.py --watch
現在、MessageEventHandler は往復メッセージ イベントを処理しますが、ツールの呼び出しには特別な処理が必要です。
プロンプトに応答するとき、LLM は、(存在する場合) どのツールを呼び出す必要があるかを決定し、応答ペイロードで 1 つ以上の「ツール呼び出し」定義を返し、応答には「アクションが必要」であることを伝えます。実際に関数を実行するには、これらの「アクションが必要」応答を処理する必要があります。
これを行うには、MessageEventHandler クラスを更新して on_event メソッドを実装し、さらに関数呼び出しを実行して結果を実行中のスレッドに追加するための新しい handle_requires_action メソッドを実装します。
import os from openai import AsyncOpenAI ## # Settings # try: OPENAI_API_KEY = os.environ["OPENAI_API_KEY"] except KeyError as ex: raise LookupError(f"Missing required environment variable: {ex}") client = AsyncOpenAI(api_key=OPENAI_API_KEY) # ...
必要に応じて、提供されたツールの使用を試行する必要があることを LLM に思い出させると役立つ場合があります。プロンプトの最後に次のような行を追加します:
該当する場合は、提供されたツールを使用して、インシデントに関する追加のコンテキストを収集します。
ツールを設定すると、プロンプトに PagerDuty リンクを含めることができ、LLM はそれらのツールを使用して、応答する前にコンテキストを収集します。
?? 完全なコードは次のとおりです:
mkdir roger cd roger poetry init --no-interaction poetry add chainlit
これで、SRE チームにとって便利な AI エージェントを構築する準備が整いました。このガイドで説明した内容についてご質問がございましたら、お気軽にお問い合わせください。喜んでお手伝いいたします。それまでの間、不足しているものや、その他 AI エージェント関連で知りたいことがあれば、お知らせください。
独自のエージェントを構築するのではなく、Aptible AI を自分で試してみたい場合は、www.aptible.ai にアクセスしてサインアップできます。
以上がガイド: SRE チーム用の AI エージェントを構築する方法の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。