Skip to main content
📖 You are viewing: Copy-pasteable patterns for common agent scenariosSee also: Agent System Guide · Tools Guide · Registry Source
Every pattern below mirrors a production agent in src/gaia/agents/. When in doubt, open the referenced file and read the real implementation — it is the source of truth.

Pattern 1: Minimal Python agent

The shortest agent that exercises every required surface area: class attrs, system prompt, tool registration, console, config dataclass.
Why every line is there:
  • _TOOL_REGISTRY.clear() — resets state when the agent is re-instantiated (leaks are silent otherwise)
  • @tool inside _register_tools — the decorator needs self scope; module-top-level registration drops the binding
  • os.getenv("LEMONADE_BASE_URL", ...) — lets Docker/CI override without changing code
  • Config dataclass separate from __init__ — eval harness and CLI use dataclasses.fields to filter kwargs

Pattern 2: MCP-enabled agent

MCPClientMixin must be initialized before super().__init__() runs — the base Agent.__init__ calls _register_tools, which may reference self._mcp_manager.
Companion mcp_servers.json:

Pattern 3: Composing tool mixins

Pull in reusable capabilities instead of duplicating them. GAIA convention: Agent goes first in the base list, mixins follow. This matches ChatAgent, SDAgent, and MedicalIntakeAgent.
The convention is register_<tool_name>_tools(). Keep it consistent if you add a new mixin so existing agents can opt in by inheritance and a single method call.

Pattern 4: Custom tool decorated with @tool

Inside _register_tools, the @tool decorator captures self via closure. The docstring is what the LLM sees — write it for the LLM, not for Python readers.

Pattern 5: Registering a built-in agent

Add to AgentRegistry._register_builtin_agents in src/gaia/agents/registry.py. The factory must filter kwargs to valid dataclass fields so callers can pass extra kwargs without crashing.

Pattern 6: Testing with mocked Lemonade

Most unit tests should mock Lemonade. Real inference belongs in integration tests gated by require_lemonade.
Fixtures live in tests/conftest.py. See docs/sdk/testing.mdx for more.

Pattern 7: Lint your agent before opening a PR

The convention linter catches missing tests, missing docs, missing registry entries, and base-class violations.

Anti-patterns to avoid


  • Agent System — reasoning loop and base class reference
  • Tools — tool decorator, LLM contract, parameters
  • Testing — fixtures, mocking, integration patterns
  • Best Practices — when to extract a mixin, when to inline, naming
  • Registry sourceKNOWN_TOOLS map, Python agent loader