クラウドもGPUもなし、100%ローカルのエージェントのみ!!!
8,678 文字
マルチエージェントシステムをllamaエージェントを使用して実装します。5 + 3は8、8 + 2は10となり、計算機からその答えが返ってきました。私たちは2つの異なるモデルを使用します。1つ目はml、2つ目はRCエージェントです。RCエージェントは関数呼び出しに適していると言われているので、RCエージェントとmistlを使って2つのツールを使用します。1つは計算ツール、もう1つは自然言語処理ツールです。
正直に言って、これは現時点で100%完璧なソリューションではありませんが、このビデオで強調したい主なポイントは、このモデルを完全にローカルで実行できるということです。GPT-4のような有料APIやクラウドは必要なく、ローカルマシンで実行できます。十分なスペックのマシンと言っても主観的ですが、専用のNvidia GPUがないコンピュータでも、このコードはYouTubeチュートリアルで見られるように正確に動作します。コードはYouTubeの説明欄にリンクを貼っておきますので、苦労せずに済むようにしています。
このコードには多くの異なる要素が含まれているので、いくつかの項目に馴染みがない場合は、今後のチュートリアルで別の方向に分岐できるように教えていただければと思います。
まずは、これが実際に動作することを知った時に衝撃を受けたので、デモを簡単に紹介させていただきます。まず、このエージェントに単純な質問をしました。「5 + 3 + 2は何ですか?」。私には2つのエージェントがあります。1つはNLPエージェント、もう1つは計算機エージェントです。ご覧のように、これが計算タスクだと理解し、質問を計算機に転送しました。
計算機は、オペレーションが加算で、引数のaは5、bは3という応答を得ました。そして、3つ目の引数があるため、再度戻って5 + 3は8、8 + 2は10と計算し、計算機から答えを受け取り、結果として10を表示しました。これがローカルで動作するllamaエージェントの実行例です。
では、実際に動作することがわかったので、最初から始めましょう。ここで私たちが行っているのは、独自のllamaエージェントを構築することです。そのためには、llama index core、llama agents、llama index embeddings、hugging faceなど、特定のアイテムを完全に更新しておく必要があります。これらは、完全に動作させるために絶対に必要なものです。
私はllamaとllama indexについての別のチュートリアルを持っており、それをYouTubeの説明欄にリンクしていますので、試してみたい方はそちらをご覧ください。oLamaをインストールし、llama agentsを最新版にアップデートする必要があります。
その後、背後で何が起きているかを理解するために、シンプルなpythonロギングをセットアップします。これは非常に重要です。次に、私はVisual Studio codeのノートブックで実行しているため、async Ioを有効にしています。pythonスクリプトとして実行する場合は、おそらくこれを有効にする必要はありません。
次に、llama agentsからagent service、agent orchestrator、control plane server、local launcher、simple mqをインポートします。これらの個々の要素に詳しくない場合は、私の最初のllama agentビデオをご覧になることを強くお勧めします。そこでこれらのポイントについて簡単に触れています。
次に重要なのは、reactエージェントを作成することです。通常、人々は関数呼び出しエージェントワーカーを作成しますが、llama indexは実際にモデルの関数呼び出し機能に基づいてモデルをフィルタリングします。たとえモデルが優れた関数呼び出し機能を持っていても、llama indexはすべてのローカルモデルに対して、このモデルは関数呼び出しに適していないため実行させないと言います。
そのため、私たちは実際にreactエージェントを作成しています。reactエージェントは、LLMが思考プロセスを経て答えを返し、再び考えて答えを返すというシステムです。reactに馴染みがない場合、これは全く異なる概念ですが、これがreactエージェントだということだけ知っておいてください。
次に、関数をツールとして作成する関数ツールがあります。そして、oLamaがあります。これはoLamaモデルにアクセスする必要があるからで、これは単にLLMを有効にするための設定です。また、ローカルメモリにアクセスするためにローカル埋め込みが必要な場合があるため、hugging face埋め込みも使用します。
これらはすべてローカルで行われます。pythonライブラリを正常にインストールした後です。これが必要なすべてのインポート文です。主なものはllama agentsで、関数ツールとreactエージェントを取得するllama index coreも必要です。そして、大規模言語モデルを定義するoLamaモデルがあります。
すべての入力が完了したので、このビデオの冒頭で説明した2つのツール、計算機ツールと基本的なNLPツールを定義する必要があります。計算機ツールには3つの引数があります。最初の引数は操作で、文字列型です。次にfloat型のa、float型のbがあり、文字列を返します。つまり、3つの入力を受け取り、文字列を返します。
何をするのかというと、基本的な算術演算を実行します。引数に関する詳細と、操作の結果が文字列として返されます。操作がADDなら加算、subtractなら減算、multiplyなら乗算、divideなら除算を行いますが、除算の前にゼロで割れるかどうかも検証します。最後に、これら4つの基本計算以外の無効な操作があれば、操作が無効であることを示し、最後に結果を出力として返します。これが私たちの計算機です。
計算機を定義した後、このマルチエージェントシステムで使用する2番目のツールを定義しましょう。この場合はテキスト分析ツールです。入力として文字列を受け取り、出力として文字列を返します。基本的なテキスト分析を実行します。引数は分析するテキストで、分析結果を文字列として返します。
何をするかというと、単語数、文字数、文章数をカウントします。それだけです。洗練されたNLPツールではありませんが、基本的なものです。ここでもいくつかのtry-catchブロックを設けて、処理していないバグに陥らないようにしています。
作成した関数、計算機とテキスト分析器の関数からツールを作成します。function_tool.from_defaultsを使用して、関数は計算機、function_tool.from_defaultsを使用して関数はテキスト分析器とします。最初のツールは計算機ツール、2番目のツールはテキストツールと呼ばれます。
この時点で2つのツールの準備ができました。これらのツールはエージェントにマッピングされ、それを使って遊び始めることができます。次にLLMを定義します。oLamaを使用してmistlモデルを定義します。これを動作させるには、すでにmistlがローカルのコンピュータにインストールされている必要があります。
最も簡単な確認方法の1つは、コマンドプロンプトに行って「olama list」と入力することです。「olama list」と入力すると、コンピュータにローカルで利用可能なモデルがわかります。例えば、私の場合、このビデオで使用するmistlがあり、おそらく使用できるllama 3があり、RCエージェントなど他のモデルもあります。
これらのモデルがすでにコンピュータにダウンロードされていることを確認することが重要です。ダウンロードされていない場合は、「olama pull」のように入力するだけで、使用したいモデルのダウンロードが始まります。それが完了すると、使用したいLLMを正常に指定したことになり、ここでLLM設定も指定しています。LLMを定義する際のLLMとは何かを示しているだけです。
次に、前述のように2つのエージェントを定義します。これは関数呼び出しエージェントではありません。なぜなら、関数呼び出しエージェントは現時点でllama indexではローカルモデル、lamaモデルでは動作しないからです。そこで2つのreactエージェントを定義します。最初のreactエージェントは計算機をツールとして使用します。
私の知る限り、この引数はツールだと思います。そうですね。これはツールです。2つ目はLLM、verosはこれらのメッセージ、veros メッセージを実際に表示するかどうかを指定します。2つ目のエージェントを定義します。最初のエージェントはAgent 1、2つ目のエージェントはAgent 2です。もっと良い名前を付けられたかもしれません。
2つ目のエージェントはテキストツールを持ち、この場合はRCエージェントをモデルとして使用します。ビデオの途中で、これを変更して出力がどのように変化するかを示します。前述のように、これは堅牢なシステムではありませんが、このモデル、ローカルモデルで遊んで、ローカルのマルチエージェントシステムがどれほど有用で効率的に構築できるかを見ていただきたいと思いました。
さて、Agent 1とAgent 2ができました。Agent 1は同じLLM、つまりmistlを使用し、2つ目はRCエージェントをエージェントとして使用します。ここでRCエージェントを選んだ理由の1つは、これがNPツールだからです。多くの問題を避けたかったのですが、この特定のケースではとてもよく合っているとは言えませんが、仕事はこなします。
次に埋め込みモデルがあります。この場合は非常に小さなBG埋め込みです。その後、4つの重要なものを定義する必要があります。メッセージキューが必要です。これはメッセージがどのように送信されるかを示します。例えば、ユーザーからの質問があれば、その質問はメッセージキューに送られ、そこからコントロールパネルにも送られます。コントロールパネルのメッセージはメッセージキューに戻ってきます。
メッセージキューはパイプラインのようなもので、非常に重要な部分です。ソフトウェアシステムの設計に詳しい方なら、AWSシステムのkafkaなどで人々が行っていることと同じです。メッセージキューがあり、コントロールプレーンサーバーがあります。これはメッセージキューを受け取り、オーケストレーター、エージェントオーケストレーター、物事を処理するLLMがあります。これがコントロールパネル、プレーン、コントロールパネル、コントロールプレーンです。
次に最初のエージェントサービスを設計します。最初のエージェントサービスは最初のエージェントを取り、メッセージキューを持ち、エージェントの説明を持ちます。基本的な算術演算、計算に役立つ、サービス名は計算機エージェント、ポートは80002で実行されます。ご存じない方のために説明すると、llamaエージェントの各部分はマイクロサービスです。
これにより、マシン間に分散デプロイメントが可能になり、ソフトウェアエンジニアが時には好み、時には嫌うマイクロサービスアーキテクチャも提供されます。最初のエージェント、エージェントサーバー1にはエージェント1、メッセージキュー、同じメッセージキュー、説明、サービス名があります。
2つ目のエージェントサーバー2には2つ目のエージェント、メッセージキュー、説明(NLPテキスト分析、テキスト処理の実行に役立つ)があり、サービス名はNLPエージェントです。ローンチャーがあります。ローカルローンチャーです。2つの方法でローンチできます。1つはローカルローンチャーを使用する方法、もう1つはサーバーローンチャーを使用する方法です。
私の場合、少なくとも現在のチュートリアルでは、サーバーローンチャーは使用せず、ローカルローンチャーを使用します。サーバーローンチャーとしてローンチすると、すべてがマイクロサービスコールである必要があります。このような呼び出しをして答えを得ることはできず、コントロールプレーンに送信し、HTTPリクエストとして応答を受け取る必要があります。
それを避けるため、ローカルローンチャーとしてローンチします。ローカルローンチャーには2つのエージェント、エージェント1とエージェント2、またはエージェントサーバー1とエージェントサーバー2、コントロールプレーン、メッセージキューがあります。ローンチャーの準備ができたので、あとはlauncher.launch_singleを実行し、質問をします。「5 + 3 + 2は何ですか?」
別の質問をしてみましょう。「10 + 3 + 2」で実行してみます。うまく動作するか見てみましょう。reactエージェントの問題の1つは、モデルがあまり優れていない場合、またはreactプロンプトに慣れていない場合、ループに陥る可能性があることです。これはビデオの途中で見られる可能性のある問題の1つです。
ループに陥るため、最終的に終了せず、時には停止して確認する必要があります。また、非常に興味深いことも見られます。正直に言うと、それを見せたいと思います。例えば、最初にメッセージを送信すると、計算機エージェントが登録され、NLPエージェントが登録され、人間が登録されます。「私を認識してくれてありがとう、Lamaエージェンツ、本当に感謝します」。コントロールプレーンが登録されました。
計算機エージェントはローカルでローンチされ、NLPエージェントもローカルでローンチされます。これはすべてメッセージキューにあり、ここで見ることができます。そしてサービスエージェントがあります。サービスエージェントは、新しいアクション、新しいタスクでメッセージキューに新しいメッセージを持っています。
アクションは新しいタスクなので、コントロールプレーンに新しいタスクがあることを伝えています。メッセージキューをローカルでローンチし、新しいタスクのアクションで計算機エージェントにメッセージを送信しています。この時点で、私たちが与えたタスクが計算タスクであると判断し、計算機エージェントが適切なエージェントであると判断したので、新しいタスクで計算機エージェントにメッセージを送信しています。
メッセージが送信され、新しいタスクが作成され、計算機エージェントからコンシューマーにメッセージが正常に送信されました。何が起きているのでしょうか?思考があります。思考は「ユーザーの現在の言語は英語です。質問に答えるためにツールを使用する必要があります。ツールはありますか?すでにツールがあります。ツールは何ですか?ツールは計算機です」。
アクション入力は、私たちが与えたプロンプトを関数呼び出しのように変換しました。この場合、操作はADDで、値はa=10、b=3です。ここで私たちが与えたのは10 + 3 + 2です。10 + 3は13で、技術的には13 + 2は15ですが、この場合reactエージェントはそれを行いませんでした。
ご覧のように、ここでは行われませんでした。reactから抜け出して2番目のLに行き、「ツールなしでこの質問に答えることができます。ユーザーの言語を使って答えます。10 + 3は13です」と言って、間違いを犯しました。うまく動作しませんでした。
では、この場合は別の質問をしてみましょう。「テキストを分析してください:やあ、元気?」と送信してみます。時々、試行中に、正しい答えを得た後に停止するように指示すると、時には停止しますが、時にはループに陥り続けることがわかりました。
さて、何が起こるでしょうか。ご覧のように、計算機エージェントとNLPエージェントがあり、コントロールプレーンに新しいメッセージが送信されましたが、今回はNLPタスクだと判断したため、メッセージはNLPエージェントに送られました。NLPエージェントが新しいタスクで呼び出され、メッセージが正常にJSONレスポンスまたは関数呼び出しに変換されました。
この場合、入力テキストは「やあ、元気?」で、テキスト分析結果は4つの単語(1、2、3、4)、文字数、およその文章数が得られました。しかし、前述のように、reactエージェントが私たちが行っていることにあまり慣れていないため、ループに陥り続けています。
ご覧のように、ループに陥り、最終的には中間で答えを見つけたにもかかわらず、答えがないと判断してしまいました。前述のように、これは完璧に動作するソリューションではありません。問題がどこにあるかがわかります。変更できることがいくつかあります。異なるLLMを試してみて、また、プロンプトにもっとテンプレート化されたアプローチを取って、実際に動作するかどうかを確認できます。
今回は別のことをやってみましょう。LLMを交換して、答えに違いがあるかどうかを見てみます。例えば、エージェント2のモデルとしてRCエージェントを使用する代わりに、文字通りLLMとしてRCエージェントを使用してみます。
ここに行って、これをマイルとして使用します。ここに行き、エージェント1のLLMとしてRCエージェントを使用し、コントロールプレーンのLLMとしてもRCエージェントを使用します。エージェント1のLLM RCエージェントを選択します。この時点ですべてが設定されています。
エージェントオーケストレーターとLLMを持つコントロールプレーンがあり、ここでLLMを変更することもできます。例えば、エージェント1に異なるLLM、エージェント2に異なるLLMを持つことができ、これがマイクロサービスであることで、制御できる要素がより細かくなります。
同じ質問で実行してみましょう。違う質問ではなく、まったく同じ質問です。最初の勝利は、タスクを正しく識別し、正しいエージェントに送信したときに得られます。ご覧のように、まだ考え中です。この場合、RCエージェントは少し重いです。少なくとも私のマシンでは、RCエージェントは5GBモデルです。
私のRCエージェントは5GBモデル、Lama 3は4.7GB、mlは4.1GBです。したがって、RCエージェントは自然とここで時間がかかります。メッセージが正しいエージェントにルーティングされたことを正しく識別しましたが、再びご覧のように、ループに陥り続けます。これは、特定のプロンプトエンジニアリングで解決する必要があるか、どうすべきか考える必要があることです。
これは1つの問題です。この時点で停止します。すでに答えを得ているので、今度は計算の質問をしてみましょう。もう一度行って、「100を20で割ることができますか?」と聞いてみましょう。おそらくこれは最も簡単な除算計算で、100÷20は5です。はい、5です。
再び、新しいメッセージがあり、メッセージは計算機エージェントに送信されました。仕事は完了し、「ツールなしで答えることができます」と言います。過信していますが、答えを出すのは良い仕事をしました。しかし、これの全体的なポイントは、ツールを使って答えることです。これは再びreactエージェントの問題です。
関数エージェントを使用する場合、この問題は存在しないはずですが、いずれにせよ、この特定のケースでは「ツールなしで答えることができます。ユーザーの言語を使用し」、100を20で割ると5.0という正しい答えが得られました。
この時点で、これはかなりプロトタイプで、多くの実験があります。私も結果に影響を与える様々な方法を学んでいます。llamaエージェントは新しいものなので、このメッセージを発信し、人々がどのように使用しているかを見るのに良い時期だと思いました。
また、少しより洗練された関数を試してみたいと思っています。現時点では、関数自体がAPIを呼び出さないシンプルなチュートリアルを作成し、スケルトン全体を説明したいと思いました。ご覧のように、現在の関数は文字通り関数ですが、将来的には外部APIを呼び出すことができるツールを作成し、これがどのように効率的に動作するかを見てみたいと思います。
また、サーバーローンチを作成し、異なるサービスを持ち、これらと通信する方法を見てみたいと思います。これらは私が計画している事柄ですが、質問があればコメント欄で教えてください。それ以外の場合、このノートブックはYouTubeの説明欄にありますので、試してみてください。この新しいllamaエージェントシリーズについてどう思うか教えてください。私はこれについてとてもワクワクしています。また別のビデオでお会いしましょう。ハッピーBR day。