AG2 ユーザガイド – ツール : エージェント機能の強化

財務コンプライアンスの例では、取引きを処理して疑わしいものを人間の承認のためにフラグ立てし、概要レポートを生成できるシステムを構築しました。けれども、エージェントは取引きの履歴にアクセスしたり、知識外の特定の計算を実行する手段を持ちません。
そこでツールの出番です – ツールはエージェントの知性と外部世界の間のギャップを橋渡しします。

AG2 : ユーザガイド – 基本概念 : ツール : エージェント機能の強化

作成 : クラスキャット・セールスインフォメーション
作成日時 : 09/04/2025
バージョン : v0.9.9

* 本記事は docs.ag2.ai の以下のページを独自に翻訳した上でまとめ直し、補足説明を加えています :

* サンプルコードの動作確認はしておりますが、必要な場合には適宜、追加改変しています。
* ご自由にリンクを張って頂いてかまいませんが、sales-info@classcat.com までご一報いただけると嬉しいです。

 

クラスキャット 人工知能 研究開発支援サービス ⭐️ リニューアルしました 😉

クラスキャット は人工知能に関する各種サービスを提供しています。お気軽にご相談ください :

  • 人工知能導入個別相談会(無償)実施中! [詳細]

  • 人工知能研究開発支援 [詳細]
    1. 自社特有情報を含むチャットボット構築支援
    2. 画像認識 (医療系含む) / 画像生成

  • PoC(概念実証)を失敗させないための支援 [詳細]

お問合せ : 下記までお願いします。

  • クラスキャット セールス・インフォメーション
  • sales-info@classcat.com
  • ClassCatJP

 

 

AG2 : ユーザガイド – 基本概念 : ツール : エージェント機能の強化

財務コンプライアンスの例では、取引きを処理して、疑わしいものを人間の承認のためにフラグ立てし、概要レポートを生成できるシステムを構築しました。けれども重複支払いのチェックをする必要がある場合はどうでしょう?現在、エージェントは取引きの履歴にアクセスしたり、知識外の特定の計算を実行する手段を持ちません。

これがツールの必要なところです – ツールはエージェントの知性と外部世界の間のギャップを橋渡しします。

 

専門ツールの必要性

財務コンプライアンス・システムは進化するにつれ、以下が必要かもしれません :

  • 新規取引きの過去の支払いのデータベースに対する照合

  • 複雑なアルゴリズムに基づいたリスクスコアの計算

  • 3rd パーティの不正検出 API への接続

  • 社内システムやデータベースへのアクセス

これらのタスクは LLM が内部知識だけでできることを超えており、外部システムに接続する特別な機能を必要とします。

 

AG2 でのツールの理解

AG2 では、ツールは、エージェントが外部世界とやり取りするための構造化された手法を提供しています。ツールをエージェントが適切なタイミングで選択して使用できる特別な関数として考えてください。

 
ツールのアナロジー :

グループチャット・パターンからの病院の救急室のアナロジーを続けます :

  • ツールを病院の特別な医療機器 (MRI 装置、血液分析機器、EKG (心電図) モニタ) のようなものと考えてください。

  • 専門家 (エージェント) が患者を診察するとき、「これを正しく診断するには MRI スキャンが必要である」と判断する可能性があります。

  • けれども、専門家は MRI 装置を自身で操作はしません。

  • 代わりに、その特定の装置の専門知識を持つ技術者 (executor エージェント) がスキャンを実行します。

  • 技術者はスキャン結果を専門家に返し、それらを解釈して治療を継続します。

病院の専門家が、訓練された技術者により操作される診断機器に依存するように、AG2 エージェントは、指定された executor エージェントにより実行されるツールを呼び出すことができます。この分離は、各コンポーネントが得意なものに集中できることを保証します : 専門家は診断と治療の決定に、技術者は複雑な機器の正しい操作にです。

このアプローチは「実際にそれを行う」から「何をするかを決定する」を分離させ、堅牢で制御された実行モデルを作成します。

 

AG2 におけるツール使用の仕組み

AG2 のツール使用は単純ですが強力な 2 段階プロセスに従います :

  • 選択 (Selection) : (LLM によって駆動される) エージェントは与えられたタスクに基づいてどのツールが適切か決定します。

  • 実行 (Execution) : 別の executor エージェントがツールを起動して結果を返します。

Note : For a more detailed explanation of how tools work in AG2, check out the Tools Overview documentation.

 

財務システムをツールで強化

強力な新機能: 重複支払い検出 を追加して、財務コンプライアンス・システムを強化しましょう。

 

課題

重複支払いは財務システムの一般的な問題です。企業が誤って同じ請求書を二度支払うかもしれません、あるいは詐欺師 (fraudster) が同じサービスに対して複数の支払いを得ようとするかもしれません。

現在のシステムは疑わしい取引きを検出できますが、取引きが既に処理されたものの重複であるかを確認する方法はありません。

 

ツール・ソリューション

システムを強化する方法が以下です :

  • 取引きを以前の支払いのデータベースと照合する関数の作成

  • この関数を finance_bot が使用できるツールとして登録

  • ワークフローを変更して、各取引きを処理する前に重複がないか確認する

  • 人間の承認を必要とすることなく、重複支払いは自動的に拒否する

 

実装: 重複検出ツールの作成

まず、重複支払いをチェックする関数を作成しましょう :

import os
from typing import Annotated, Any
from datetime import datetime, timedelta

from autogen import ConversableAgent, LLMConfig
from autogen.agentchat import initiate_group_chat
from autogen.agentchat.group.patterns import AutoPattern

# Note: Make sure to set your API key in your environment first

# Configure the LLM
llm_config = LLMConfig(
    api_type="openai",
    model="gpt-4o-mini",
    api_key=os.environ.get("OPENAI_API_KEY"),
    temperature=0.2,
)

# Mock database of previous transactions
def get_previous_transactions() -> list[dict[str, Any]]:
    today = datetime.now()
    return [
        {
            "vendor": "Staples",
            "amount": 500,
            "date": (today - timedelta(days=3)).strftime("%Y-%m-%d"),  # 3 days ago
            "memo": "Quarterly supplies",
        },
        {
            "vendor": "Acme Corp",
            "amount": 1500,
            "date": (today - timedelta(days=10)).strftime("%Y-%m-%d"),  # 10 days ago
            "memo": "NDA services",
        },
        {
            "vendor": "Globex",
            "amount": 12000,
            "date": (today - timedelta(days=5)).strftime("%Y-%m-%d"),  # 5 days ago
            "memo": "Confidential",
        },
    ]

# Simple duplicate detection function
def check_duplicate_payment(
    vendor: Annotated[str, "The vendor name"],
    amount: Annotated[float, "The transaction amount"],
    memo: Annotated[str, "The transaction memo"]
) -> dict[str, Any]:
    """Check if a transaction appears to be a duplicate of a recent payment"""
    previous_transactions = get_previous_transactions()

    today = datetime.now()

    for tx in previous_transactions:
        tx_date = datetime.strptime(tx["date"], "%Y-%m-%d")
        date_diff = (today - tx_date).days

        # If vendor, memo and amount match, and transaction is within 7 days
        if (
            tx["vendor"] == vendor and
            tx["memo"] == memo and
            tx["amount"] == amount and
            date_diff <= 7
        ):
            return {
                "is_duplicate": True,
                "reason": f"Duplicate payment to {vendor} for ${amount} on {tx['date']}"
            }

    return {
        "is_duplicate": False,
        "reason": "No recent duplicates found"
    }

このコードでは :

  • 擬似データベース関数を作成して過去の取引きの取得シミュレートしました。

  • 新規取引きと過去のものを比較する、重複検出関数を定義しました。

  • 関数は Annotated を使用して明確なパラメータ説明を提供しています、これはエージェントがツールの使用方法を理解するのに役立ちます。

  • 関数の docstring は LLM にツールを説明するために使用されます。

  • 関数は、ベンダー、金額、メモと取引きが 7 日間以内であることに基づいて、取引きが重複していないかチェックします。

  • それは、取引きが重複していないか、そしてその理由を示す辞書を返します。

 

ツール使用のためにエージェントを更新する

それではエージェントのシステムメッセージを更新して、重複チェックを組み込みましょう :

# Define the system message for our finance bot
finance_system_message = """
You are a financial compliance assistant. You will be given a set of transaction descriptions.

For each transaction:
1. First, extract the vendor name, amount, and memo
2. Check if the transaction is a duplicate using the check_duplicate_payment tool
3. If the tool identifies a duplicate, automatically reject the transaction
4. If not a duplicate, continue with normal evaluation:
    - If it seems suspicious (e.g., amount > $10,000, vendor is unusual, memo is vague), ask the human agent for approval
    - Otherwise, approve it automatically

Provide clear explanations for your decisions, especially for duplicates or suspicious transactions.
When all transactions are processed, summarize the results and say "You can type exit to finish".
"""

# Define the system message for the summary agent
summary_system_message = """
You are a financial summary assistant. You will be given a set of transaction details and their approval status.
Your task is to summarize the results of the transactions processed by the finance bot.
Generate a markdown table with the following columns:
- Vendor
- Memo
- Amount
- Status (Approved/Rejected)
- Reason (especially note if rejected due to being a duplicate)

The summary should include the total number of transactions, the number of approved transactions, and the number of rejected transactions.
The summary should be concise and clear.

Once you've generated the summary append the below in the summary:
==== SUMMARY GENERATED ====

両方のエージェントのシステムメッセージを更新しました :

  • finance_bot は評価する前に、取引きの詳細を抽出して重複をチェックすることを知るようになりました。

  • summary_agent は、重複検出のような、拒否の理由を含めるようになりました。

 

ツールの登録

次に、重複検出関数をツールとして登録する必要があります :

# Create the finance agent with LLM intelligence
with llm_config:
    finance_bot = ConversableAgent(
        name="finance_bot",
        system_message=finance_system_message,
        functions=[check_duplicate_payment],
    )
    summary_bot = ConversableAgent(
        name="summary_bot",
        system_message=summary_system_message,
    )

# Create the human agent for oversight
human = ConversableAgent(
    name="human",
    human_input_mode="ALWAYS",  # Always ask for human input
)

この登録で :

  • finance_bot は適切な場合に、check_duplicate_payment ツールの使用を提案できるようになりました。

  • グループチャットを継続して使用し、内部ツール executor はすべてのツールの推奨を自動的に実行します。

 

重複を含むテストデータの生成

重複を含むサンプル取引きを作成しましょう :

# Generate new transactions including a duplicate
transactions = [
    "Transaction: $500 to Staples. Memo: Quarterly supplies.",  # Duplicate of an existing transaction
    "Transaction: $4000 to Unicorn LLC. Memo: Reimbursement.",
    "Transaction: $12000 to Globex. Memo: Confidential.",  # Duplicate of an existing transaction
    "Transaction: $22000 to Initech. Memo: Urgent request."
]

# Format the initial message
initial_prompt = (
    "Please process the following transactions one at a time, checking for duplicates:\n\n" +
    "\n".join([f"{i+1}. {tx}" for i, tx in enumerate(transactions)])
)

 

Putting It All Together

それでは、重複検出で強化された財務コンプライアンス・システムを実行しましょう :

pattern = AutoPattern(
    initial_agent=finance_bot,
    agents=[finance_bot, summary_bot],
    user_agent=human,
    group_manager_args = {
        "llm_config": llm_config,
        "is_termination_msg": is_termination_msg
    },
)

result, _, _ = initiate_group_chat(
    pattern=pattern,
    messages=initial_prompt,
)

 

強化されたワークフローの理解

この強化された財務コンプライアンス・システムを実行すると、何が起きるかを次に示します :

 

完全なコード例

重複検出を備えた、強化された財務コンプライアンス・システムの完全で、そのまま実行できるコードが以下です :

import os
import random
from typing import Annotated, Any
from datetime import datetime, timedelta

from autogen import ConversableAgent, LLMConfig
from autogen.agentchat import initiate_group_chat
from autogen.agentchat.group.patterns import AutoPattern

# Note: Make sure to set your API key in your environment first

# Configure the LLM
llm_config = LLMConfig(
    api_type="openai",
    model="gpt-4o-mini",
    api_key=os.environ.get("OPENAI_API_KEY"),
    temperature=0.2,
)

# Mock database of previous transactions
def get_previous_transactions() -> list[dict[str, Any]]:
    today = datetime.now()
    return [
        {
            "vendor": "Staples",
            "amount": 500,
            "date": (today - timedelta(days=3)).strftime("%Y-%m-%d"),  # 3 days ago
            "memo": "Quarterly supplies",
        },
        {
            "vendor": "Acme Corp",
            "amount": 1500,
            "date": (today - timedelta(days=10)).strftime("%Y-%m-%d"),  # 10 days ago
            "memo": "NDA services",
        },
        {
            "vendor": "Globex",
            "amount": 12000,
            "date": (today - timedelta(days=5)).strftime("%Y-%m-%d"),  # 5 days ago
            "memo": "Confidential",
        },
    ]

# Simple duplicate detection function
def check_duplicate_payment(
    vendor: Annotated[str, "The vendor name"],
    amount: Annotated[float, "The transaction amount"],
    memo: Annotated[str, "The transaction memo"]
) -> dict[str, Any]:
    """Check if a transaction appears to be a duplicate of a recent payment"""
    previous_transactions = get_previous_transactions()

    today = datetime.now()

    for tx in previous_transactions:
        tx_date = datetime.strptime(tx["date"], "%Y-%m-%d")
        date_diff = (today - tx_date).days

        # If vendor, memo and amount match, and transaction is within 7 days
        if (
            tx["vendor"] == vendor and
            tx["memo"] == memo and
            tx["amount"] == amount and
            date_diff <= 7
        ):
            return {
                "is_duplicate": True,
                "reason": f"Duplicate payment to {vendor} for ${amount} on {tx['date']}"
            }

    return {
        "is_duplicate": False,
        "reason": "No recent duplicates found"
    }

# Define the system message for our finance bot
finance_system_message = """
You are a financial compliance assistant. You will be given a set of transaction descriptions.

For each transaction:
1. First, extract the vendor name, amount, and memo
2. Check if the transaction is a duplicate using the check_duplicate_payment tool
3. If the tool identifies a duplicate, automatically reject the transaction
4. If not a duplicate, continue with normal evaluation:
    - If it seems suspicious (e.g., amount > $10,000, vendor is unusual, memo is vague), ask the human agent for approval
    - Otherwise, approve it automatically

Provide clear explanations for your decisions, especially for duplicates or suspicious transactions.
When all transactions are processed, summarize the results and say "You can type exit to finish".
"""

# Define the system message for the summary agent
summary_system_message = """
You are a financial summary assistant. You will be given a set of transaction details and their approval status.
Your task is to summarize the results of the transactions processed by the finance bot.
Generate a markdown table with the following columns:
- Vendor
- Memo
- Amount
- Status (Approved/Rejected)
- Reason (especially note if rejected due to being a duplicate)

The summary should include the total number of transactions, the number of approved transactions, and the number of rejected transactions.
The summary should be concise and clear.

Once you've generated the summary append the below in the summary:
==== SUMMARY GENERATED ====
"""

# Create the finance agent with LLM intelligence
with llm_config:
    finance_bot = ConversableAgent(
        name="finance_bot",
        system_message=finance_system_message,
        functions=[check_duplicate_payment],
    )
    summary_bot = ConversableAgent(
        name="summary_bot",
        system_message=summary_system_message,
    )

# Create the human agent for oversight
human = ConversableAgent(
    name="human",
    human_input_mode="ALWAYS",  # Always ask for human input
)

def is_termination_msg(msg: dict[str, Any]) -> bool:
    content = msg.get("content", "")
    return (content is not None) and "==== SUMMARY GENERATED ====" in content

# Generate sample transactions - this creates different transactions each time you run
VENDORS = ["Staples", "Acme Corp", "CyberSins Ltd", "Initech", "Globex", "Unicorn LLC"]
MEMOS = ["Quarterly supplies", "Confidential", "NDA services", "Routine payment", "Urgent request", "Reimbursement"]

# Generate new transactions including a duplicate
transactions = [
    "Transaction: $500 to Staples. Memo: Quarterly supplies.",  # Duplicate of an existing transaction
    "Transaction: $4000 to Unicorn LLC. Memo: Reimbursement.",
    "Transaction: $12000 to Globex. Memo: Confidential.",  # Duplicate of an existing transaction
    "Transaction: $22000 to Initech. Memo: Urgent request."
]

# Format the initial message
initial_prompt = (
    "Please process the following transactions one at a time, checking for duplicates:\n\n" +
    "\n".join([f"{i+1}. {tx}" for i, tx in enumerate(transactions)])
)

# Create pattern and start group chat
pattern = AutoPattern(
    initial_agent=finance_bot,
    agents=[finance_bot, summary_bot],
    user_agent=human,
    group_manager_args = {
        "llm_config": llm_config,
        "is_termination_msg": is_termination_msg
    },
)

result, _, _ = initiate_group_chat(
    pattern=pattern,
    messages=initial_prompt,
)

 

出力例

このコードを実行すると、以下に類似したワークフローが表示されます :

human (to chat_manager):

Please process the following transactions one at a time, checking for duplicates:

1. Transaction: $500 to Staples. Memo: Quarterly supplies.
2. Transaction: $4000 to Unicorn LLC. Memo: Reimbursement.
3. Transaction: $12000 to Globex. Memo: Confidential.
4. Transaction: $22000 to Initech. Memo: Urgent request.

--------------------------------------------------------------------------------

Next speaker: finance_bot

>>>>>>>> USING AUTO REPLY...
finance_bot (to chat_manager):

***** Suggested tool call (call_xUaZ4NCMDuCWD4BR35r4KLZQ): check_duplicate_payment *****
Arguments:
{"vendor": "Staples", "amount": 500, "memo": "Quarterly supplies"}
****************************************************************************************
***** Suggested tool call (call_s6iT9Fm0KoMawPrM4fveZXLh): check_duplicate_payment *****
Arguments:
{"vendor": "Unicorn LLC", "amount": 4000, "memo": "Reimbursement"}
****************************************************************************************
***** Suggested tool call (call_smVXvuadgqhwzESB306iS8Sh): check_duplicate_payment *****
Arguments:
{"vendor": "Globex", "amount": 12000, "memo": "Confidential"}
****************************************************************************************
***** Suggested tool call (call_wVihYJUumyruCE9114OtarAt): check_duplicate_payment *****
Arguments:
{"vendor": "Initech", "amount": 22000, "memo": "Urgent request"}
****************************************************************************************

--------------------------------------------------------------------------------

Next speaker: _Group_Tool_Executor

>>>>>>>> EXECUTING FUNCTION check_duplicate_payment...
Call ID: call_xUaZ4NCMDuCWD4BR35r4KLZQ
Input arguments: {'vendor': 'Staples', 'amount': 500, 'memo': 'Quarterly supplies'}

>>>>>>>> EXECUTING FUNCTION check_duplicate_payment...
Call ID: call_s6iT9Fm0KoMawPrM4fveZXLh
Input arguments: {'vendor': 'Unicorn LLC', 'amount': 4000, 'memo': 'Reimbursement'}

>>>>>>>> EXECUTING FUNCTION check_duplicate_payment...
Call ID: call_smVXvuadgqhwzESB306iS8Sh
Input arguments: {'vendor': 'Globex', 'amount': 12000, 'memo': 'Confidential'}

>>>>>>>> EXECUTING FUNCTION check_duplicate_payment...
Call ID: call_wVihYJUumyruCE9114OtarAt
Input arguments: {'vendor': 'Initech', 'amount': 22000, 'memo': 'Urgent request'}
_Group_Tool_Executor (to chat_manager):

***** Response from calling tool (call_xUaZ4NCMDuCWD4BR35r4KLZQ) *****
{'is_duplicate': True, 'reason': 'Duplicate payment to Staples for $500.0 on 2025-04-20'}
**********************************************************************

--------------------------------------------------------------------------------
***** Response from calling tool (call_s6iT9Fm0KoMawPrM4fveZXLh) *****
{'is_duplicate': False, 'reason': 'No recent duplicates found'}
**********************************************************************

--------------------------------------------------------------------------------
***** Response from calling tool (call_smVXvuadgqhwzESB306iS8Sh) *****
{'is_duplicate': True, 'reason': 'Duplicate payment to Globex for $12000.0 on 2025-04-18'}
**********************************************************************

--------------------------------------------------------------------------------
***** Response from calling tool (call_wVihYJUumyruCE9114OtarAt) *****
{'is_duplicate': False, 'reason': 'No recent duplicates found'}
**********************************************************************

--------------------------------------------------------------------------------

Next speaker: finance_bot

>>>>>>>> USING AUTO REPLY...
finance_bot (to chat_manager):

Let's process the transactions one by one:

1. **Transaction: $500 to Staples. Memo: Quarterly supplies.**
   - **Duplicate Check Result:** This transaction is a duplicate of a recent payment to Staples for $500.0 on 2025-04-20.
   - **Decision:** **Rejected** due to being a duplicate.

2. **Transaction: $4000 to Unicorn LLC. Memo: Reimbursement.**
   - **Duplicate Check Result:** No recent duplicates found.
   - **Evaluation:** The amount is below $10,000 and the vendor is not unusual.
   - **Decision:** **Approved** automatically.

3. **Transaction: $12000 to Globex. Memo: Confidential.**
   - **Duplicate Check Result:** This transaction is a duplicate of a recent payment to Globex for $12000.0 on 2025-04-18.
   - **Decision:** **Rejected** due to being a duplicate.

4. **Transaction: $22000 to Initech. Memo: Urgent request.**
   - **Duplicate Check Result:** No recent duplicates found.
   - **Evaluation:** The amount is above $10,000, and the memo is vague.
   - **Decision:** **Requires human approval** due to the suspicious nature of the transaction.

### Summary of Results:
- **Rejected:** $500 to Staples (duplicate).
- **Approved:** $4000 to Unicorn LLC.
- **Rejected:** $12000 to Globex (duplicate).
- **Requires Approval:** $22000 to Initech (suspicious).

You can type exit to finish.

--------------------------------------------------------------------------------

Next speaker: human

Replying as human. Provide feedback to chat_manager. Press enter to skip and use auto-reply, or type 'exit' to end the conversation: approve
human (to chat_manager):

approve

--------------------------------------------------------------------------------

Next speaker: finance_bot

>>>>>>>> USING AUTO REPLY...
finance_bot (to chat_manager):

The transaction of **$22000 to Initech** has been approved.

### Final Summary of Results:
- **Rejected:** $500 to Staples (duplicate).
- **Approved:** $4000 to Unicorn LLC.
- **Rejected:** $12000 to Globex (duplicate).
- **Approved:** $22000 to Initech.

You can type exit to finish.

--------------------------------------------------------------------------------

Next speaker: summary_bot

>>>>>>>> USING AUTO REPLY...
summary_bot (to chat_manager):

### Transaction Summary

| Vendor        | Memo                  | Amount | Status   | Reason                          |
|---------------|-----------------------|--------|----------|---------------------------------|
| Staples       | Quarterly supplies     | $500   | Rejected | Duplicate payment               |
| Unicorn LLC   | Reimbursement          | $4000  | Approved | No recent duplicates found      |
| Globex        | Confidential           | $12000 | Rejected | Duplicate payment               |
| Initech       | Urgent request         | $22000 | Approved | No recent duplicates found      |

### Summary
- **Total Transactions:** 4
- **Approved Transactions:** 2
- **Rejected Transactions:** 2

==== SUMMARY GENERATED ====

You are trained on data up to October 2023.

--------------------------------------------------------------------------------

>>>>>>>> TERMINATING RUN (59000355-c1bb-45de-9862-9a2cc8998051): Termination message condition on the GroupChatManager 'chat_manager' met

 

以上