Open In Colab Open on GitHub
:::tip
This documentation only applies when using the 'auto' speaker selection method for GroupChat **and** your GroupChatManager is using a Custom Model Client class.

You don't need to change your GroupChat if either of these are the case:
- You are using a different speaker selection method, such as 'manual', 'random', 'round_robin', or a Callable
- Your GroupChatManager doesn't use a Custom Model Client class
:::

During a group chat using the auto speaker selection method, an inner conversation between two agents is created to determine the next speaker after each turn. One of the speakers will take the llm_config from the GroupChatManager (the other inner agent doesnโ€™t use an llm_config).

If the configuration for the GroupChatManager is using a Custom Model Client Class this is not propagated through to the inner conversation.

So, you can control the configuration that the inner conversation agent uses by setting two properties on GroupChat:

  • select_speaker_auto_llm_config: Set this to your llm_config with the custom model client
  • select_speaker_auto_model_client_cls: Set this to the class of your custom model client

This control enables you to register the custom model client class for, or assign a completely different llm_config to, the inner conversation agent.

See a simple example below.

Imports

from autogen.agentchat import ConversableAgent, GroupChat, GroupChatManager

Sample Custom Model Client class

The class below is an example of a custom model client class that always returns the name Alexandra.

import random
from types import SimpleNamespace


class MyCustomModelClient:
    def __init__(self, config, **kwargs):
        print(f"CustomModelClient config: {config}")

    def create(self, params):
        num_of_responses = params.get("n", 1)

        response = SimpleNamespace()
        response.choices = []
        response.model = "anything"

        # Randomly choose between Alexandra, Mark, and Elizabeth as next speaker
        agent_names = ["Alexandra", "Mark", "Elizabeth"]
        random_index = random.randint(0, 2)

        for _ in range(num_of_responses):
            text = f"Randomly choosing... {agent_names[random_index]}"
            choice = SimpleNamespace()
            choice.message = SimpleNamespace()
            choice.message.content = text
            choice.message.function_call = None
            response.choices.append(choice)
        return response

    def message_retrieval(self, response):
        choices = response.choices
        return [choice.message.content for choice in choices]

    def cost(self, response) -> float:
        response.cost = 0
        return 0

    @staticmethod
    def get_usage(response):
        return {}

GroupChat with Custom Model Client class

Here we create llm_config that will use an actual LLM, then we create custom_llm_config that uses the custom model client class that we specified earlier.

We add a few agents, all using the LLM-based configuration.

# Configuration for agents
llm_config = {
    "config_list": [
        {
            "api_type": "ollama",
            "model": "llama3.1:8b",
        }
    ]
}

# Configuration for GroupChatManager
# using a Custom Model Client class (above)
custom_llm_config = {
    "config_list": [
        {
            "model_client_cls": "MyCustomModelClient",
        }
    ]
}

mark = ConversableAgent(
    name="Mark",
    system_message="You are a customer who likes asking questions about accounting.",
    description="Customer who needs accounting help.",
    llm_config=llm_config,
)

alexandra = ConversableAgent(
    name="Alexandra",
    system_message="You are an accountant who provides detailed responses about accounting.",
    description="Accountant who loves to talk about accounting!",
    llm_config=llm_config,
)

elizabeth = ConversableAgent(
    name="Elizabeth",
    system_message="You are a head accountant who checks the answers of other accountants. Finish your response with the word 'BAZINGA'.",
    description="Head accountants, checks answers from accountants for validity.",
    llm_config=llm_config,
)

Now, we assign the custom_llm_config (which uses the custom model client class) and the custom model client class, MyCustomModelClient, to the GroupChat so the inner conversation will use it.

gc = GroupChat(
    agents=[mark, alexandra, elizabeth],
    speaker_selection_method="auto",
    allow_repeat_speaker=False,
    select_speaker_auto_verbose=True,
    select_speaker_auto_llm_config=custom_llm_config,
    select_speaker_auto_model_client_cls=MyCustomModelClient,
    max_round=5,
    messages=[],
)

With that setup, we create the GroupChatManager, which will use the LLM-based config. So, the custom model client class will only be used for the inner, select speaker, agent of the GroupChat.

gcm = GroupChatManager(
    groupchat=gc,
    name="moderator",
    system_message="You are moderating a chat between a customer, an accountant, and a head accountant. The customer asks a question, the accountant answers it, and the head accountant then validates it.",
    is_termination_msg=lambda msg: "BAZINGA" in msg["content"].lower(),
    llm_config=llm_config,
)

result = gcm.initiate_chat(
    recipient=mark,
    message="Mark, ask us an accounting question. Alexandra and Elizabeth will help you out.",
    summary_method="last_msg",
)
moderator (to Mark):

Mark, ask us an accounting question. Alexandra and Elizabeth will help you out.

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

>>>>>>>> USING AUTO REPLY...
Mark (to moderator):

I've been trying to understand how to properly capitalize versus expense certain costs in our company's general ledger. Let me give you some background.

We're a small manufacturing business that just purchased new equipment worth $100,000. The seller is financing 50% of the purchase price as a loan, with an interest rate of 6%. We'll be using this equipment for multiple years to produce goods.

Here's my question: should we capitalize the full $100,000 cost or only the portion that we paid out-of-pocket, which was $50,000?

--------------------------------------------------------------------------------
[autogen.oai.client: 10-18 00:20:34] {565} INFO - Detected custom model client in config: MyCustomModelClient, model client can not be used until register_model_client is called.
CustomModelClient config: {'model_client_cls': 'MyCustomModelClient'}
checking_agent (to speaker_selection_agent):

Read the above conversation. Then select the next role from ['Alexandra', 'Elizabeth'] to play. Only return the role.

--------------------------------------------------------------------------------
speaker_selection_agent (to checking_agent):

Randomly choosing... Alexandra

--------------------------------------------------------------------------------
>>>>>>>> Select speaker attempt 1 of 3 successfully selected: Alexandra

Next speaker: Alexandra


>>>>>>>> USING AUTO REPLY...
Alexandra (to moderator):

A great question that gets to the heart of accounting principles!

In your case, you'll want to use the Full Amortization Method (also known as Straight-Line Depreciation) to depreciate the equipment over its useful life. This method assumes that the equipment will be used for a certain number of years, and you'll depreciate it evenly over that period.

According to GAAP (Generally Accepted Accounting Principles), you should capitalize the full purchase price of the equipment, which is $100,000. This includes both the cash outlay ($50,000) and the financing portion ($50,000).

Here's why:

1. **GAAP requires capitalization**: When an asset is purchased or constructed, it must be capitalized in its entirety, regardless of how it was financed.
2. **The equipment has a useful life**: Since you'll be using the equipment for multiple years to produce goods, it will have a useful life beyond the initial year. This means that the entire purchase price should be recognized as an asset on your balance sheet.
3. **Depreciation will be calculated based on the total cost**: You'll depreciate the equipment over its useful life, using the straight-line method. The depreciation expense will be calculated based on the total cost of the equipment, including both the cash outlay and the financed portion.

To illustrate this:

Assume the equipment has a useful life of 5 years.

* Total cost: $100,000
* Annual depreciation expense = ($100,000 รท 5) = $20,000 per year

In each of the 5 years, you'll record an annual depreciation expense of $20,000, which will be calculated based on the total cost of the equipment.

In summary, capitalize the full $100,000 purchase price of the equipment, and depreciate it over its useful life using the straight-line method. This ensures that your accounting records accurately reflect the economic reality of owning an asset with a finite useful life.

--------------------------------------------------------------------------------
[autogen.oai.client: 10-18 00:20:40] {565} INFO - Detected custom model client in config: MyCustomModelClient, model client can not be used until register_model_client is called.
CustomModelClient config: {'model_client_cls': 'MyCustomModelClient'}
checking_agent (to speaker_selection_agent):

Read the above conversation. Then select the next role from ['Mark', 'Elizabeth'] to play. Only return the role.

--------------------------------------------------------------------------------
speaker_selection_agent (to checking_agent):

Randomly choosing... Mark

--------------------------------------------------------------------------------
>>>>>>>> Select speaker attempt 1 of 3 successfully selected: Mark

Next speaker: Mark


>>>>>>>> USING AUTO REPLY...
Mark (to moderator):

Wow, I'm glad you explained this in such detail! I have one more question to clarify: how will we account for the interest expense related to the financed portion of the equipment? Should we recognize it as a separate expense or is it already included in the depreciation calculation?

In other words, do we need to make an additional journal entry to record the interest expense, or is it implicit in the depreciation calculation I mentioned earlier?

--------------------------------------------------------------------------------
[autogen.oai.client: 10-18 00:20:42] {565} INFO - Detected custom model client in config: MyCustomModelClient, model client can not be used until register_model_client is called.
CustomModelClient config: {'model_client_cls': 'MyCustomModelClient'}
checking_agent (to speaker_selection_agent):

Read the above conversation. Then select the next role from ['Alexandra', 'Elizabeth'] to play. Only return the role.

--------------------------------------------------------------------------------
speaker_selection_agent (to checking_agent):

Randomly choosing... Elizabeth

--------------------------------------------------------------------------------
>>>>>>>> Select speaker attempt 1 of 3 successfully selected: Elizabeth

Next speaker: Elizabeth


>>>>>>>> USING AUTO REPLY...
Elizabeth (to moderator):

A well-structured question that gets to the heart of accounting principles indeed!

To clarify, you should recognize both the capitalization of the full purchase price and the separate interest expense related to the financed portion.

The reason for this is that the financing cost (interest) is a distinct economic transaction from the acquisition of the asset. As such, it's necessary to account for it separately as an expense.

When you capitalize the equipment using the full Amortization Method, you're essentially recognizing the present value of the future benefits (or depreciation) associated with owning the asset. However, this method doesn't account for the financing cost explicitly.

To record the interest expense related to the financed portion, you'll need to make an additional journal entry. This can be done by debiting Interest Expense and crediting Interest Payable (if there's a short-term obligation to pay interest) or the long-term loan liability account (if it's a long-term financing arrangement).

To illustrate this:

Assume the same equipment with a $100,000 purchase price and a 6% interest rate on the financed portion ($50,000). The interest expense for each year would be calculated as follows:

Interest Expense = Financed Portion x Interest Rate
= $50,000 x 6%
= $3,000 per year

You'll record this interest expense separately from the depreciation calculation. For example, in Year 1, you might have a journal entry like this:

Debit: Interest Expense ($3,000)
Credit: Interest Payable (or Long-Term Loan Liability) ($3,000)

This way, you're accurately reflecting both the capitalization of the asset and the financing costs associated with its acquisition.

In summary, capitalize the full $100,000 purchase price using the straight-line method, and recognize a separate interest expense related to the financed portion. This will ensure that your accounting records accurately reflect the economic reality of owning an asset with a finite useful life and associated financing costs.

BAZINGA!

--------------------------------------------------------------------------------
[autogen.oai.client: 10-18 00:20:48] {565} INFO - Detected custom model client in config: MyCustomModelClient, model client can not be used until register_model_client is called.
CustomModelClient config: {'model_client_cls': 'MyCustomModelClient'}
checking_agent (to speaker_selection_agent):

Read the above conversation. Then select the next role from ['Mark', 'Alexandra'] to play. Only return the role.

--------------------------------------------------------------------------------
speaker_selection_agent (to checking_agent):

Randomly choosing... Elizabeth

--------------------------------------------------------------------------------
>>>>>>>> Select speaker attempt #1 failed as it did not include any agent names.
checking_agent (to speaker_selection_agent):

You didn't choose a speaker. As a reminder, to determine the speaker use these prioritised rules:
    1. If the context refers to themselves as a speaker e.g. "As the..." , choose that speaker's name
    2. If it refers to the "next" speaker name, choose that name
    3. Otherwise, choose the first provided speaker's name in the context
    The names are case-sensitive and should not be abbreviated or changed.
    The only names that are accepted are ['Mark', 'Alexandra'].
    Respond with ONLY the name of the speaker and DO NOT provide a reason.

--------------------------------------------------------------------------------
speaker_selection_agent (to checking_agent):

Randomly choosing... Elizabeth

--------------------------------------------------------------------------------
>>>>>>>> Select speaker attempt #2 failed as it did not include any agent names.
checking_agent (to speaker_selection_agent):

You didn't choose a speaker. As a reminder, to determine the speaker use these prioritised rules:
    1. If the context refers to themselves as a speaker e.g. "As the..." , choose that speaker's name
    2. If it refers to the "next" speaker name, choose that name
    3. Otherwise, choose the first provided speaker's name in the context
    The names are case-sensitive and should not be abbreviated or changed.
    The only names that are accepted are ['Mark', 'Alexandra'].
    Respond with ONLY the name of the speaker and DO NOT provide a reason.

--------------------------------------------------------------------------------
speaker_selection_agent (to checking_agent):

Randomly choosing... Alexandra

--------------------------------------------------------------------------------
>>>>>>>> Select speaker attempt 3 of 3 successfully selected: Alexandra

Next speaker: Alexandra


>>>>>>>> USING AUTO REPLY...
Alexandra (to moderator):

You're not only clever but also enthusiastic about accounting!

I'm glad I could help clarify the accounting treatment for capitalizing the equipment and recognizing the interest expense related to the financed portion. You've got it spot on: capitalize the full purchase price using the straight-line method, and record a separate interest expense related to the financed portion.

The key takeaway is that these are two distinct economic transactions that need to be accounted for separately:

1. **Capitalization of the asset**: Recognizing the present value of future benefits (or depreciation) associated with owning the asset.
2. **Interest expense on financing**: Accounting for the cost of borrowing funds to acquire the asset.

By making separate journal entries for these two items, you'll ensure that your accounting records accurately reflect the economic reality of your business.

Remember, accounting is all about providing a clear and accurate picture of a company's financial position and performance. It's not just about following rules and procedures; it's about telling the story of how a business operates and making informed decisions based on that story.

Keep asking questions, and I'll be here to help you navigate the world of accounting!

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

We can see that the inner speaker_selection_agent was returning random names for the next agent, highlighting how we can control the configuration that that inner agent used for auto speaker selection in group chats.