Skip to content

Connect an agent

ChemWorld agents choose one typed operation at a time from public task state. The environment keeps hidden world state evaluator-owned, validates every request, records resource use and writes an exact replay trajectory. Start offline before introducing an external model.

Capability matrix

Path Network or key Intended use Public status
Custom Python agent No Your own planner or policy Stable protocol
Built-in classic agents No Smoke tests and reproducible baselines Stable
Replay agent No Re-run a previously captured model trace Stable
DeepSeek LiveLLMAgent DEEPSEEK_API_KEY Operation-level online model experiments Optional adapter
Codex subscription client Existing codex login Audited structured calls through a ChatGPT subscription Optional adapter
Interactive Codex experiment Existing codex login One persistent model context per complete experiment Advanced API
Frozen SB3 policy Local checkpoint and .[rl] Evaluation of an already trained RL policy Optional extra

The command-line --agent flag intentionally exposes only constructor-free built-ins. Agents that need credentials, model selection, replay paths, checkpoints or workspaces are created in Python and passed to run_agent explicitly.

Minimal custom agent

Subclassing BaseAgent supplies a zero-external-resource manifest. Use only public task information and public history when choosing an action.

from chemworld.agents.base import BaseAgent, HistoryRecord
from chemworld.eval.runner import run_agent


class TutorialAgent(BaseAgent):
    name = "tutorial"

    recipe = (
        {"operation": "add_solvent", "volume_L": 0.030, "solvent": 1},
        {"operation": "add_reagent", "amount_mol": 0.012},
        {"operation": "add_catalyst", "catalyst": 2, "catalyst_amount_mol": 0.0004},
        {"operation": "heat", "target_temperature_K": 350.0, "duration_s": 1200.0,
         "stirring_speed_rpm": 800.0},
        {"operation": "measure", "instrument": "hplc"},
        {"operation": "quench"},
        {"operation": "terminate"},
        {"operation": "measure", "instrument": "final_assay"},
    )

    def act(self, history: list[HistoryRecord]) -> dict[str, object]:
        return dict(self.recipe[len(history)])


run_agent(
    env_id="ChemWorld",
    agent=TutorialAgent(),
    world_split="public-dev",
    budget=8,
    objective="balanced",
    seed=0,
    task_id="reaction-to-assay",
    output_path="runs/tutorial-agent.jsonl",
)

For a capable agent, prefer act_with_context(context) or act_with_public_view(context, public_view). The official runner detects these methods and provides the current legal operations, resource state, observation summaries and lifecycle status without exposing hidden truth.

Built-in offline agents

List tasks and run a deterministic connectivity check:

chemworld tasks list
chemworld run --task reaction-to-assay --agent scripted_chemistry --seed 0

Other constructor-free names include random, lhs, greedy, gp_bo, rf_ei, safe_gp_bo, tool_using_llm_stub and llm_replay. Use make_agent(name) from chemworld.eval.runner when composing runs in Python.

Inspect policies in the browser

Run chemworld lab and open http://127.0.0.1:8876/agent/. The Agent Observatory exposes a deliberately provider-free subset of the built-ins. It calls the same official run_agent() path as the CLI and presents, step by step:

  • the public legal-operation context available before the choice;
  • the submitted typed action and transaction result;
  • public lab reports, processed estimates and spectra;
  • decision-audit fields and any declared Agent trace;
  • environment and method-resource accounting.

You can pause at a step boundary, replay completed records, download the public run JSON, or launch two to four policies on the same task and seed. That comparison is a behavioral inspection aid, not a benchmark: formal claims require multiple registered seeds, fixed resource limits and the public evaluation protocol.

Read the Agent Observatory guide →

Live DeepSeek adapter

Keep the key out of source files and shell history:

export DEEPSEEK_API_KEY="..."
from chemworld.agents.live_llm import LiveLLMAgent
from chemworld.eval.runner import run_agent
from chemworld.providers.deepseek import DeepSeekClient

client = DeepSeekClient(model="deepseek-v4-pro", thinking=True)
agent = LiveLLMAgent(client, role_id="public-example")

run_agent(
    env_id="ChemWorld",
    agent=agent,
    world_split="public-dev",
    budget=18,
    objective="balanced",
    seed=0,
    task_id="reaction-to-assay",
    output_path="runs/deepseek-reaction-to-assay.jsonl",
)

Model identity, retries, token use and estimated cost are recorded separately. Provider failure is not silently replaced with another model or a host-generated action.

Codex subscription adapter

Install the Codex CLI, complete codex login with a ChatGPT subscription, and construct CodexSubscriptionClient from chemworld.providers.codex_subscription. Pass that client to LiveLLMAgent using the same runner pattern above. Subscription usage has no per-run USD price, so the accounting receipt reports that limitation rather than inventing a cost.

InteractiveCodexExperimentAgent is the advanced path for keeping one Codex context alive across a complete experiment. It requires an explicit isolated workspace and role identifier; see the class docstring and focused tests before using it in a formal comparison.

Reproducibility and safety boundary

  • Never commit API keys, provider response dumps or private reasoning.
  • Do not compare live-agent scores unless task, seed, model identity, prompt contract and resource limits are fixed.
  • Validate and replay every submitted trajectory before reporting a score.
  • ChemWorld is a software-model environment, not a generator of physical laboratory procedures.
  • The checked-in live-agent evidence is finite qualification evidence, not a claim that one provider or agent is generally superior.