# Best Practices for Organizing Agent Code in Python: A Prime Agent Guide

> Master Python agent code organization with best practices. Learn to structure async modules, CLI helpers, and config for seamless agent integration.

- Repository: [Prime Intellect/prime-agent](https://github.com/PrimeIntellect-ai/prime-agent)
- Tags: best-practices
- Published: 2026-08-10

---

**Organize Python agent skills as self-contained async modules with a standard `run` entry point, shared CLI helpers, and environment-aware configuration to ensure seamless integration with the agent runtime.**

PrimeIntellect-ai/prime-agent demonstrates a scalable approach to organizing agent code in Python by treating each capability as an isolated, importable package. This architecture separates concerns between the runtime infrastructure and individual skills, making it straightforward to add new tools without modifying the core agent logic. By following these conventions, developers can build modular, testable components that integrate cleanly with the RLM REPL.

## One-Module Skill Layout

Each skill in Prime Agent lives as an independent Python package following a strict directory convention.

### Directory Structure Convention

Place skill code under `packages/coding-agent/skills/<skill-name>/src/<skill-name>/`. This nested structure ensures the package name matches the import path expected by the runtime. For example, the `websearch` skill resides at `packages/coding-agent/skills/websearch/src/websearch/`, allowing the runtime to import it predictably.

### The Run Entry Point

Every skill must expose an **async coroutine named `run`** that serves as the entry point for the RLM REPL. This function receives parameters parsed from the CLI and returns a value to the agent. The minimal implementation in [`packages/coding-agent/test/fixtures/skills/python-skill/src/python_skill/__init__.py`](https://github.com/PrimeIntellect-ai/prime-agent/blob/main/packages/coding-agent/test/fixtures/skills/python-skill/src/python_skill/__init__.py) demonstrates this pattern with a four-line function:

```python
async def run(message: str = "hello") -> str:
    """Return the provided message."""
    return message

```

## Async-First Architecture

Skills should perform I/O without blocking the agent’s event loop.

### Non-Blocking I/O Patterns

Write all skills as `async def run(...)` coroutines. The `websearch` skill in [`packages/coding-agent/skills/websearch/src/websearch/websearch.py`](https://github.com/PrimeIntellect-ai/prime-agent/blob/main/packages/coding-agent/skills/websearch/src/websearch/websearch.py) uses `httpx.AsyncClient` for HTTP requests, allowing concurrent network operations:

```python
import httpx

async def run(query: str, *, max_output: int = 8192) -> str:
    async with httpx.AsyncClient() as client:
        resp = await client.post(
            "https://google.serper.dev/search",
            json={"q": query},
            headers={"X-API-KEY": api_key},
        )
        resp.raise_for_status()
        data = resp.json()
    return data

```

### Cancellation and Timeouts

Respect the agent’s lifecycle by handling cancellation gracefully. The `websearch` implementation configures `httpx.AsyncClient` with appropriate timeouts, ensuring that slow network calls do not hang the REPL indefinitely.

## Shared Infrastructure and CLI Helpers

Centralize command-line plumbing to reduce boilerplate in individual skills.

### Centralized CLI Parsing

The runtime provides shared CLI helpers in [`prime-agent-runtime/src/rlm/skill.py`](https://github.com/PrimeIntellect-ai/prime-agent/blob/main/prime-agent-runtime/src/rlm/skill.py). The `cli()` function discovers the skill module by matching the console-script name to the import name, then invokes `run_cli` which parses arguments using **tyro** and prints any non-`None` result.

### Entry Point Registration

Register skills as console scripts in [`pyproject.toml`](https://github.com/PrimeIntellect-ai/prime-agent/blob/main/pyproject.toml) or [`setup.cfg`](https://github.com/PrimeIntellect-ai/prime-agent/blob/main/setup.cfg), pointing to the shared CLI handler:

```ini
[options.entry_points]
console_scripts =
    echo = echo:cli

```

Inside the skill package, create a minimal [`cli.py`](https://github.com/PrimeIntellect-ai/prime-agent/blob/main/cli.py) that delegates to the runtime:

```python
from prime_agent_runtime.rlm.skill import cli

if __name__ == "__main__":
    cli()

```

## Environment-Aware Configuration

Handle credentials and settings without hardcoding sensitive values.

### Credential Resolution

Implement helper functions like `_resolve_api_key` to check environment variables before falling back to persisted storage. The `websearch` skill first checks `SERPER_API_KEY`, then consults the agent’s [`auth.json`](https://github.com/PrimeIntellect-ai/prime-agent/blob/main/auth.json) file, enabling seamless operation after a live `/login` command.

```python
def _resolve_api_key():
    import os
    return os.getenv("SERPER_API_KEY") or _load_from_auth_json()

```

### Graceful Degradation

When configuration is missing, return explicit, user-focused messages instead of raising cryptic exceptions. This allows the agent to report actionable feedback:

```python
api_key = _resolve_api_key()
if not api_key:
    return "Web search not configured – see the skill doc for setup."

```

## Robust Output Handling

Manage response sizes to prevent context window overflow.

### Truncation Strategies

Accept a ** `max_output` parameter** in the `run` signature to limit response length. The `websearch` skill truncates results safely, preserving the most relevant content while respecting the boundary:

```python
return formatted_results[:max_output]

```

### Error Message Best Practices

Structure error messages to indicate exactly what resource is missing and how to configure it. This convention appears throughout the codebase, ensuring users receive clear guidance rather than stack traces.

## Testing Isolation

Maintain test fixtures under `packages/coding-agent/test/fixtures/skills/`, mirroring the production layout. This structure allows unit tests to import skills directly without initializing the entire agent runtime, providing fast, isolated feedback during development.

## Summary

- **Organize agent code in Python** as self-contained packages under `packages/coding-agent/skills/<name>/src/<name>/` to ensure predictable imports.
- Implement an **async `run` coroutine** as the universal entry point for all skills.
- Leverage **shared CLI helpers** in [`prime-agent-runtime/src/rlm/skill.py`](https://github.com/PrimeIntellect-ai/prime-agent/blob/main/prime-agent-runtime/src/rlm/skill.py) to handle argument parsing with `tyro`.
- Configure skills to read **environment variables first**, then fall back to persisted [`auth.json`](https://github.com/PrimeIntellect-ai/prime-agent/blob/main/auth.json) credentials.
- **Truncate output** using a `max_output` parameter to respect context limits.
- Place **test fixtures** in `packages/coding-agent/test/fixtures/skills/` to enable isolated testing.

## Frequently Asked Questions

### What is the required function signature for a Prime Agent skill?

Every skill must define an async coroutine named `run` that accepts typed parameters and returns a value. The signature `async def run(message: str = "hello") -> str` in [`packages/coding-agent/test/fixtures/skills/python-skill/src/python_skill/__init__.py`](https://github.com/PrimeIntellect-ai/prime-agent/blob/main/packages/coding-agent/test/fixtures/skills/python-skill/src/python_skill/__init__.py) demonstrates the minimal viable implementation expected by the runtime.

### How does Prime Agent handle asynchronous operations in skills?

Skills must be declared as `async def` functions. The runtime executes these coroutines within the agent’s event loop, allowing non-blocking I/O. As shown in [`packages/coding-agent/skills/websearch/src/websearch/websearch.py`](https://github.com/PrimeIntellect-ai/prime-agent/blob/main/packages/coding-agent/skills/websearch/src/websearch/websearch.py), use `httpx.AsyncClient` for network requests and implement timeouts to respect cancellation signals.

### Where should API keys and secrets be stored for agent skills?

Store sensitive configuration in environment variables (e.g., `SERPER_API_KEY`) or the agent’s persisted [`auth.json`](https://github.com/PrimeIntellect-ai/prime-agent/blob/main/auth.json) file. Helper functions like `_resolve_api_key` check these sources in order, keeping credentials out of source code while maintaining usability after authentication commands.

### How can I test individual skills without loading the entire agent?

Place test fixtures under `packages/coding-agent/test/fixtures/skills/` using the same directory structure as production skills. This allows you to import and unit test the `run` function directly without initializing the full Prime Agent runtime, enabling fast, isolated development cycles.