Agents in userdata: best practice

I started from the restaurant example here, where the `agents` are included in the userdata. Same for the medical office triage here. This all worked fine for many months, but today I wanted to have another LLM for one of the agents.

The session works just fine, but for tests, I have something like this

async def test_greeter_...(
    base_userdata,
    setup...,
) -> None:

and

@pytest.fixture
def base_userdata(mock_dtmf_handler, mock_room, backend_client) -> UserData:
    ...
    return UserData(
        room=mock_room,
        dtmf_handler=mock_dtmf_handler,
        ...
        agents=get_agents(),
    )

When running the tests, pytest complains about not being able to pickle the agent if it includes a custom LLM, which makes sense.

Questions:

  1. What’s the best practice for having agents globally available?
  2. If they should be in userdata, how to make the agent still pickable and avoid problems when running tests

Thanks!

Hi @Marc_Torrellas_Socastro.

My 2 cents here:

You can use a factory pattern. You don’t need to stre the agent object, and the factory should be fully pickable. That said, I think UserData should reflect what the session actually needs, not be shaped around pytest’s constraints related to pickle, you can simply instantiate the agent inline per test, something like:

def test_greeter(mock_room):
    mocked_llm  = MagicMock()
    agent = YourAgent(llm=mocked_llm)

And if you truly need agents globally available across the session, a class-level registry initialized at session start is worth considering, register agents at the top of your entrypoint, clear on teardown, and look them up by name wherever needed. Nothing to pickle, nothing in UserData.

yeah, I think I will go with the latter: agent init per session. Thanks for your answer!

1 Like