Use when creating or revising a custom agent type, when an experiment needs an agent class that does not yet exist in the workspace, or when the agent design must be sized against a simulation budget.
73
91%
Does it follow best practices?
Run evals on this skill
Adds up to 20 points to the overall score
View guide
Passed
No findings from the security scan
Add Python modules under custom/agents/ relative to the workspace root (the directory that contains custom/). The backend scanner loads every *.py under that tree except paths under an examples/ segment.
custom/agents/research/lab_agent.py).AgentBase subclasses in the same file if you define them.Do NOT use when:
Use the Python interpreter from .env. See CLAUDE.md for setup.
Collect the simulation scale budget before locking the agent design:
If the budget is still open, ask a single round of clarifying questions. Present 2-3 approaches with trade-offs and a recommendation, then choose the option that keeps per-agent logic proportional to the simulation size.
| Action | Command |
|---|---|
| Validate agent file | $PYTHON_PATH .agentsociety/bin/ags.py create-agent --file /path/to/workspace/custom/agents/my_agent.py |
| Validate (JSON output) | $PYTHON_PATH .agentsociety/bin/ags.py create-agent --file ... --json |
| Register | VS Code: Scan Custom Modules (and Test Custom Modules if needed) |
digraph create_agent_flow {
rankdir=LR;
node [shape=box, style=filled, fillcolor="#E8F4FD"];
intake [label="gather requirements"];
design [label="choose base class\nand state model"];
generate [label="implement code\nfrom templates"];
validate [label="run validator\nand self-check"];
register [label="scan custom modules"];
intake -> design -> generate -> validate -> register;
}stages/intake.md: gather requirements and clarify open questionsstages/design.md: choose base class, workspace, profile, and state shapestages/generate.md: implement code with artifacts/templates.mdstages/validate.md and checklists/compatibility.md: final validation| Class | When to use |
|---|---|
AgentBase | Simple behavior, games/benchmarks, you manage state yourself |
PersonAgent | Skills, tool loops, workspace, checkpoint/WAL, heavier runtime |
Inherit ONLY from AgentBase or PersonAgent. Never subclass an existing agent — neither a contrib agent (e.g. PublicGoodsAgent) nor another custom agent in custom/agents/. If a similar agent already exists, read it as a reference and re-implement the methods (ask, step, restore, to_workspace, build_react_messages, …) yourself in the new file. The validator rejects anything that is not a direct AgentBase/PersonAgent subclass, but more importantly: env @tool discovery and the agent's own registration treat each class by its own namespace, so an agent that "inherits to reuse" behaviour silently loses the inherited contract. Rewrite from scratch.
Required and optional methods, LLM/env APIs, config: use references/agent-base-interface.md as the single detailed source (avoids duplicating it here).
references/environment-interaction.mdask_env code): references/pitfalls.mdreferences/profile-design.mdreferences/examples.mdBy default an agent loads skills from <workspace>/custom/skills/ plus any
environment-module skill dirs. You can also point an agent at skills stored
anywhere on disk — useful for sharing a skill library across agents or
mounting skills from outside the workspace:
extra_skill_paths to the agent's
init_config.json (written verbatim to config.json, read back on restore):
{ "extra_skill_paths": ["/shared/skills", "research/skills"] }agent.discover_skill_sources(env, extra_skill_paths=[...])Each entry is a root of skill subdirectories (same layout as custom/skills);
relative paths resolve against the workspace root. The default scan is unchanged
when omitted. Full details: references/agent-base-interface.md → Skill sources.
Each skill is a subdirectory containing a SKILL.md file. SKILL.md must
start with a YAML frontmatter block delimited by --- and declare at least
name and description:
custom/skills/
└─ my-skill/
└─ SKILL.md---
name: my-skill
description: One-line summary the agent sees in the skill catalog before activation. Keep it specific.
---
# My Skill
Body — only injected into the prompt AFTER the agent activates this skill.The name/description are the only catalog fields the model sees at
selection time. A SKILL.md without frontmatter is silently registered with an
empty description, so the agent effectively never discovers or selects it.
Rules:
name: stable skill id; lowercase kebab-case is conventional.description: concise, action-oriented; mention what it does and that env
tools are reached via ask_env when the skill drives an environment.script / hooks are optional frontmatter keys.ask_env instructions stable (template + variables) so env
router cache hits across agents.$PYTHON_PATH .agentsociety/bin/ags.py create-agent --file /path/to/workspace/custom/agents/my_agent.py
$PYTHON_PATH .agentsociety/bin/ags.py create-agent --file ... --jsonThe script checks: AST shows a direct base named AgentBase or PersonAgent,
the three required abstracts (to_workspace, ask, step) are async def,
the module imports, and the class is not abstract. That is stricter
than Scan Custom Modules: the scanner now verifies real overrides of
to_workspace/ask/step, arg-less construction, and non-empty
description()/init_description() (via build_agent_scan_diagnostic), but it
does not enforce async def or a direct base class — this validator does.
AgentBase already defines default description() and init_description() methods;
overriding both is still recommended for real modules.
For the full human checklist see stages/validate.md and checklists/compatibility.md.
| Mistake | Fix |
|---|---|
| Subclassing an existing agent (contrib or another custom agent) to reuse behaviour | Don't. The validator requires a direct AgentBase/PersonAgent base, and inherited contracts (e.g. env @tool interaction setup) are not carried over reliably through subclassing. Rewrite the methods yourself in the new file, inheriting ONLY from AgentBase or PersonAgent |
| Putting runtime state in construction code | Put state setup in restore(self, workspace_path, service_proxy) and persist state through to_workspace |
Reusing run_react_loop without overriding build_react_messages | The base raises NotImplementedError. Always override build_react_messages when you call run_react_loop |
| Using intermediate base classes that fail the AST validation rule | Ensure direct inheritance from AgentBase or PersonAgent, or follow the MRO note in stages/validate.md |
| Forgetting to make required methods async | to_workspace / ask / step must all be async def |
| Not running the validator after creating the agent | Always run .agentsociety/bin/ags.py create-agent --file ... as the final step |
Adding files under an examples/ path | The scanner skips any path containing an examples/ segment; place files directly under custom/agents/ |
Phrasing ask_env message as a Python call literal ("tool(arg=val)") | Use natural language "Please call tool_name() using <args> from ctx['variables'] ..." — see references/pitfalls.md P2 |
Using template_mode=True for readonly=False writes without checking idempotency / argument-name collisions | Default to template_mode=False for writes; only enable when the env tool is verified idempotent AND argument names don't collide with other writes — see references/pitfalls.md P3 |
Calling the same write tool more than once per step() "to be safe" | Trust the status return; retry only on fail/error — see references/pitfalls.md P4 |
Shipping a SKILL.md without YAML frontmatter (or with empty description) | Always start SKILL.md with --- frontmatter declaring name + description; without it the skill registers with an empty description and is never selected — see Custom Skills above |
Stages 2-3 (design + code generation) can consume significant context. Delegate to subagents when:
How to delegate (planner → generator → reviewer):
subagent-prompts/planner.md and follow it. The planner produces a structured DesignSpec JSON — what methods to implement, what state to track, what persistence is needed, all tied to the hypothesis.subagent-prompts/implementer.md and follow it. The generator writes code from the spec.subagent-prompts/reviewer.md and follow it. The reviewer checks the code against the spec with fresh context.$PYTHON_PATH .agentsociety/bin/ags.py create-agent --file ... yourself and fix any remaining issues from the reviewer report.Do NOT delegate: simple agents that inherit from AgentBase with trivial ask/step overrides. For those, do Stages 1-4 yourself.
Optional helpers: scan-modules (to check existing agents before creating a new one) Successors: experiment-config (when custom agents are needed) Required Sub-Skills: None
Called by experiment-config as an optional branch when the required agent class does not already exist.
1832bcb
If you maintain this skill, you can claim it as your own. Once claimed, you can manage eval scenarios, bundle related skills, attach documentation or rules, and ensure cross-agent compatibility.