2024.07.08

AIエージェントのためのLangroidフレームワーク紹介

こんにちは、次世代システム研究室のN.M.です。

Langroidフレームワークは、自然言語の理解と生成が可能なAIエージェントを構築するための包括的なツールセットを提供する新しいオープンソースプロジェクトです。
このフレームワークは柔軟で拡張可能に設計されており、開発者は簡単に自身のプロジェクトに統合し、必要に応じてカスタマイズすることができます。

公式ウェブサイトからの引用:

Langroid is the first Python LLM-application framework that was explicitly designed with Agents as first-class citizens, and Multi-Agent Programming as the core design principle.
The framework is inspired by ideas from the Actor Framework.

フレームワークを選択する際には、フレームワークの価値提案とアプローチに感銘を受けるべきです。
ドキュメントと例を確認した後でも、感銘を受けない場合は、別のフレームワークを探すべきです。
正直に言って、自分自身のエージェントを書こうと考えた最初は、ゼロから自分で書くことに魅力を感じました。
しかし、Langroidを見つけたら、その洗練されたデザインと強力な機能にすぐに感銘を受けました。
セットアップは簡単で、ドキュメントは明確で簡潔です:https://langroid.github.io/langroid/quick-start/setup/

主な特徴

シンプルさと柔軟性。
次の例は、要件に応じてより強力なLLM駆動プログラムを段階的に構築する方法を示しています。

 

import langroid as lr
import langroid.language_models as lm
from langroid.language_models import Role, LLMMessage

# LLMの設定
llm_cfg = lm.OpenAIGPTConfig(
  # OpenAIAssistantを使用するとAssistant APIを使用
  chat_model=lm.OpenAIChatModel.GPT4o, # 例: "ollama/mistral"
)
# LLMを直接使用
mdl = lm.OpenAIGPT(llm_cfg)
messages = [
    LLMMessage(content="You are a helpful assistant", role=Role.SYSTEM), 
    LLMMessage(content="What is the capital of Japan?", role=Role.USER), 
]

response = mdl.chat(messages, max_tokens=200)

 

このシンプルなプログラムでは、モデルオブジェクトを作成し、LLMとチャットする方法が示されています。
ここではOpenAI GPT-4oモデルを使用していますが、他のモデルについてはこちらを参照してください:
https://github.com/langroid/langroid/blob/7e69f541ea5d26c855ff6ef003b6902ddfc20afd/langroid/language_models/openai_gpt.py#L67-L74
また、OpenAI互換のAPIを介して提供されるOllamaモデルも使用可能です。
注意すべきは、”ollama/mistral”など他のモデルも指定できることです。

システムメッセージとユーザーメッセージを作成し、それらをLLMに渡して処理する方法も見ています。

以下は出力です:

REDIS_PASSWORD, REDIS_HOST, REDIS_PORT not set in .env file,
                    using fake redis client
2024-07-07 12:19:57 - WARNING - REDIS_PASSWORD, REDIS_HOST, REDIS_PORT not set in .env file,
                    using fake redis client
The capital of Japan is Tokyo.

この例ではRedis設定に関するいくつかの警告が表示されていますが、この例ではRedisは設定されていません。
フレームワークはLLMの応答のキャッシュにRedisを使用します。設定されていない場合は、メモリ内キャッシュを使用します。
フレームワークで使用する環境変数は警告メッセージおよび以下に示されている名前を使用して設定できます:

OPENAI_API_KEY=your-key-here-without-quotes
REDIS_PASSWORD=your-redis-password-no-quotes
REDIS_HOST=your-redis-hostname-no-quotes
REDIS_PORT=your-redis-port-no-quotes

 

通常、これらから始めることができますが、オプションの設定についてはドキュメントを参照してください:https://langroid.github.io/langroid/quick-start/setup/

RedisコンテナとRedis設定を設定しましょう:

docker run --name redis-container -d redis
# データを永続化したい場合:
# docker run -d --name redis-container -v ~/.redis/langroid:/data redis:latest redis-server --appendonly yes
# sudo chmod -R 755 ~/.redis/langroid
export REDIS_HOST=localhost
export REDIS_PORT=6379
export REDIS_PASSWORD=

より有用なチャットは、ユーザーがLLMと対話できるようにループすることができます:
前述のモデルを設定した場合、簡単なチャットループを作成できます:

messages = [
    LLMMessage(role=Role.SYSTEM, content="You are a helpful assitant"),
]

while True:
    message = Prompt.ask("[blue]Human")
    if message in ["x", "q"]:
        print("[magenta]Bye!")
        break
    messages.append(LLMMessage(role=Role.USER, content=message))

    response = mdl.chat(messages=messages, max_tokens=200)
    messages.append(response.to_LLMMessage())
    print("[green]Bot: " + response.message)

これで、ループ内でLLMとチャットし、質問に対する応答を得ることができます。また、会話中に以前の応答を参照することもできます。

もちろん、エージェントフレームワークがチャットループを処理することも期待されますが、これを行います。

import langroid as lr

config = lr.ChatAgentConfig( 
    name="MyAgent", # 名前にはスペースを入れないでください!
    llm = lr.language_models.OpenAIGPTConfig(
        chat_model=lr.language_models.OpenAIChatModel.GPT4o,
    )
)

agent = lr.ChatAgent(config)
task = lr.Task(
    agent, name="Bot", 
    system_message="You are a helpful assistant", 
)

task.run()

 

Taskクラスを使用してエージェントを実行し、チャットループを処理します。

説明:

– ユーザーはエージェントと初期メッセージを使用してタスクを初期化します。
– タスクはinit()を呼び出し、その中でpending_messageを初期化します。
– タスクはdone()がtrueを返すまでstep()を繰り返し呼び出します。
– 各ステップ中に:
– タスクはエージェントのレスポンダメソッドを呼び出して現在のpending_messageに対する応答を取得します。
– エージェントは応答を返します。
– タスクはこの応答でpending_messageを更新します。
– タスクが完了すると、結果をユーザーに返します。

マルチエージェントの例

これまでにLLMとチャットできる単一のエージェントを簡単に作成する方法を見てきましたが、マルチエージェントシステムを作成する方法を見てみましょう。

以下はドキュメントからのマルチエージェントの例です: https://langroid.github.io/langroid/quick-start/two-agent-chat-num/

import langroid as lr

config = lr.ChatAgentConfig(
    llm = lr.language_models.OpenAIGPTConfig(
        chat_model=lr.language_models.OpenAIChatModel.GPT4,
    ),
    vecdb = None, 
)

student_agent = lr.ChatAgent(config)
student_task = lr.Task(
    student_agent,
    name = "Student",
    system_message="""
        You will receive a list of numbers from me (the User),
        and your goal is to calculate their sum.
        However you do not know how to add numbers.
        I can help you add numbers, two at a time, since
        I only know how to add pairs of numbers.
        Send me a pair of numbers to add, one at a time, 
        and I will tell you their sum.
        For each question, simply ask me the sum in math notation, 
        e.g., simply say "1 + 2", etc, and say nothing else.
        Once you have added all the numbers in the list, 
        say DONE and give me the final sum. 
        Start by asking me for the list of numbers.
    """,
    llm_delegate = True, 
    single_round=False,  
)

adder_agent = lr.ChatAgent(config)
adder_task = lr.Task(
    adder_agent,
    name = "Adder", 
    system_message="""
        You are an expert on addition of numbers. 
        When given numbers to add, simply return their sum, say nothing else
        """,
    single_round=True,  
)

student_task.add_sub_task(adder_task) 
student_task.run()

 

この例では、学生と加算者の2つのエージェントがあります。adder_taskはstudent_taskのサブタスクです。
student_taskはメインのタスクであり、学生と加算者の間の会話を管理する責任があります。
これはループで行われ、学生が加算者に数値のペアを追加するように要求し、加算者がその合計を返します。
student_taskのstep()メソッド内で、student_agentのすべてのレスポンダを呼び出し、adder_taskが有効な応答を返します。
次に、adder_agentのレスポンダが呼び出され、adder_agentのLLMDelgateResponderが有効な応答を返し、これが上位のstudent_taskに返されます。

>>> Starting Agent Student (1) gpt-4
Please provide me with the list of numbers.
Stats: N_MSG=1, TOKENS: in=154, out=9, max=1024, ctx=8192, COST: now=$0.0052, cumul=$0.0052, tot=$0.0052
(gpt-4)
Human (respond or q, x to exit current level, or hit enter to continue)
: 2 4
2 + 4
Stats: N_MSG=3, TOKENS: in=166, out=4, max=1024, ctx=8192, COST: now=$0.0052, cumul=$0.0104, tot=$0.0104
(gpt-4)
Human (respond or q, x to exit current level, or hit enter to continue)
:
...|>>> Starting Agent Adder (1) gpt-4
...|6
...|Stats: N_MSG=2, TOKENS: in=29, out=1, max=1024, ctx=8192, COST: now=$0.0009, cumul=$0.0009,
tot=$0.0113 (gpt-4)
...|<<< Finished Agent Adder (3)
Human (respond or q, x to exit current level, or hit enter to continue)

 

学生が加算者に2と4を加算するように要求し、加算者が6を返すことがわかります。
各ステップでhumanが応答する必要がありますが、これはステップがデフォルトでインタラクティブモードになっているためです。
これを変更するには、student_taskのinteractive属性をFalseに設定することができますが、その場合は数値を対話的に入力することができなくなります:

student_task = lr.Task(
    student_agent,
    name = "Student",
    system_message="""
        You will receive a list of numbers ...
    """,
    llm_delegate = True, 
    single_round=False,  
    interactive=False,
)

 

これを試してみると、次のような出力が得られます:

>>> Starting Agent Student (1) gpt-4
(cached)Please provide me with the list of numbers.
Stats: N_MSG=1, TOKENS: in=0, out=0, max=1024, ctx=8192, COST: now=$0.0000, cumul=$0.0000, tot=$0.0000 (gpt-4)
...|>>> Starting Agent Adder (1) gpt-4
...|As an AI, I don't have the ability to provide you with a list of numbers. However, you can provide me with a list of numbers and I can add them for you.
...|Stats: N_MSG=2, TOKENS: in=34, out=38, max=1024, ctx=8192, COST: now=$0.0033, cumul=$0.0033, tot=$0.0033 (gpt-4)
...|<<< Finished Agent Adder (3)
Apologies for the confusion. Here are the numbers: 5, 7, 2, 4, 6.
Stats: N_MSG=3, TOKENS: in=201, out=26, max=1024, ctx=8192, COST: now=$0.0076, cumul=$0.0076, tot=$0.0109 (gpt-4)
...|>>> Starting Agent Adder (3) gpt-4
...|24
...|Stats: N_MSG=4, TOKENS: in=98, out=1, max=1024, ctx=8192, COST: now=$0.0030, cumul=$0.0063, tot=$0.0139 (gpt-4)
...|<<< Finished Agent Adder (5)
5 + 7
Stats: N_MSG=5, TOKENS: in=228, out=4, max=1024, ctx=8192, COST: now=$0.0071, cumul=$0.0147, tot=$0.0210 (gpt-4)
...|>>> Starting Agent Adder (5) gpt-4
...|12
...|Stats: N_MSG=6, TOKENS: in=103, out=1, max=1024, ctx=8192, COST: now=$0.0032, cumul=$0.0095, tot=$0.0241 (gpt-4)
...|<<< Finished Agent Adder (7)

 

結論

Langroidの始め方、そのコア機能、そしてシンプルなチャットボットやマルチエージェントシステムの構築方法を見てきました。
このフレームワークには、ツールやRAGバインディングなど、より複雑なエージェントやマルチエージェントシステムを構築するためのさまざまな機能があります。
Langroidを使用してエージェントを構築することは直感的で楽しいと思います。

詳細についてはドキュメントを参照してください: https://langroid.github.io/langroid/quick-start/chat-agent-tool/
ドキュメントやGitHubリポジトリ(https://github.com/langroid/langroid-examples)には多くの有用な例があります。

 

次世代システム研究室では、グループ全体のインテグレーションを支援してくれるアーキテクトを募集しています。インフラ設計、構築経験者の方、次世代システム研究室にご興味を持って頂ける方がいらっしゃいましたら、ぜひ募集職種一覧からご応募をお願いします。

  • Twitter
  • Facebook
  • はてなブックマークに追加

グループ研究開発本部の最新情報をTwitterで配信中です。ぜひフォローください。

 
  • AI研究開発室
  • 大阪研究開発グループ

関連記事