3. Agent Overview#
pycsamt.agents is the workflow layer of pyCSAMT. It packages common
MT, AMT, and CSAMT tasks into small executable agents: one agent loads a
survey, another checks data quality, another corrects static shift, another
prepares inversion files, another runs AI inversion, and another assembles a
report. The value is not that every operation becomes automatic; the value is
that each operation has the same execution shape, so a workflow can be
previewed, run, inspected, checkpointed, and repeated.
The agent layer is broader than LLM usage. Many agents are deterministic and run without an API key. LLM support is added where text understanding or narrative drafting is useful: parsing natural-language requests, choosing a workflow route, generating draft interpretation text, or writing report prose. The scientific data products remain structured outputs inside AgentResult, and those outputs should be reviewed directly.
3.1. Core ideas#
The package is built around four concepts:
Concept |
Role |
|---|---|
Abstract base class for every agent. It provides LLM access, cost tracking, JSON extraction, plotting helpers, and common validation helpers. |
|
Standard return object with |
|
Ordered workflow executor. It chains agents, maps outputs between steps, supports dry run previews, and checkpoints workflow state. |
|
High-level entry point for natural-language workflow requests. It classifies the request and builds the matching agent chain. |
Imports are lazy. Importing pycsamt.agents exposes public names without
importing optional provider libraries such as anthropic, openai,
google-generativeai, torch, or gradio until a feature needs them.
This keeps basic processing and no-LLM workflows lightweight.
3.2. How the pieces fit#
At the lowest level, an agent is just a class with one execute method:
where \(I\) is the input dictionary, \(A\) is the agent, and \(R\) is the returned AgentResult. A coordinated workflow repeats that pattern:
config
-> MTLoaderAgent
-> DataQCAgent
-> StaticShiftAgent
-> PhaseAnalysisAgent
-> ReportAgent
The step boundary matters. Each step should make clear which object it consumes: raw loaded sites, corrected sites, selected periods, an inversion model, a QC table, or a dictionary of previous results. That explicit data flow is what makes an agent chain easier to audit than a long notebook cell.
3.3. When to use agents#
Use agents when you want a workflow-oriented interface rather than individual low-level function calls.
Task |
Recommended entry point |
|---|---|
Parse a plain-English request into a structured config |
|
Load EDI, AVG, or J files and inspect station completeness |
|
Run a reproducible multi-step processing chain |
|
Let pyCSAMT choose the workflow from a request |
|
Prepare inversion inputs |
|
Run AI inversion or model-zoo workflows |
|
Generate final products |
|
Use lower-level pyCSAMT APIs when you need full control of an algorithm’s internal arrays, solver configuration, training loop, or plotting object. Use agents when the built-in input and output contracts match the workflow you want to run.
3.4. Installation#
The base package can be installed without LLM, GPU, or web-interface dependencies:
pip install pycsamt
Install optional provider clients only when you plan to use them:
pip install anthropic
pip install openai
pip install google-generativeai
Install optional AI or web dependencies only for those features:
pip install torch
pip install gradio
Optional dependencies are intentionally lazy. A user can run loading, QC, classical preparation, and many previews without installing a neural backend or an LLM client.
3.5. The AgentResult contract#
Every agent returns AgentResult. The object exposes structured fields
and also supports dict-like access to data.
1>>> from pycsamt.agents import AgentResult
2>>> result = AgentResult(
3... status="needs_review",
4... summary="QC finished with warnings.",
5... data={"n_stations": 28},
6... warnings=["2 stations need review"],
7... )
8>>> bool(result)
9True
10>>> result.status
11'needs_review'
12>>> result.get("n_stations")
1328
14>>> result.warnings[0]
15'2 stations need review'
Only "failed" is false in a boolean test. That means
if result: ... allows both "success" and "needs_review" to pass.
Use exact status checks when a review state should stop a production workflow.
Important fields:
Field |
Meaning |
|---|---|
|
|
|
Short human-readable description of the run. |
|
Agent-specific structured outputs, such as |
|
Non-fatal issues encountered during execution. |
|
Optional LLM-generated interpretation text. |
|
Wall-clock runtime measured by the agent. |
|
Estimated LLM cost for that agent run. |
|
Failure details and suggested remediation. |
3.6. No-LLM request parsing#
ContextInputAgent converts a plain-English request into a structured
workflow configuration. With LLM credentials it can ask the configured model;
without credentials it uses deterministic request parsing for common workflow
phrases, paths, period ranges, components, output directories, and inversion
codes.
1>>> from pycsamt.agents import AGENT_CONFIG, ContextInputAgent
2>>> with AGENT_CONFIG.offline():
3... result = ContextInputAgent().execute({
4... "request": (
5... "Run phase tensor analysis on /data/WILLY_EDIs, "
6... "period 0.001 to 10 s, save to /out/willy_phase"
7... )
8... })
9>>> print(result.status)
10success
11>>> print(result["config"]["workflow"])
12phase_analysis
13>>> print(result["config"]["data_path"])
14/data/WILLY_EDIs
15>>> print(result["config"]["period_range"])
16[0.001, 10.0]
17>>> print(result["config"]["output_dir"])
18/out/willy_phase
19>>> print(result.cost_estimate_usd)
200.0
This result is not yet a processed survey; it is a plan-ready configuration. The warnings list should still be checked, especially when the referenced path does not exist on the current machine or the request lacks an output directory.
3.7. Dry-run workflow preview#
A dry run lets the coordinator describe the chain before executing any step. It is useful before long runs, file-writing steps, AI training, or operations that depend on external executables.
1>>> from pycsamt.agents import AgentCoordinator, AgentResult, BaseAgent
2>>>
3>>> class MiniAgent(BaseAgent):
4... def __init__(self, name, payload):
5... super().__init__(name)
6... self.payload = payload
7...
8... def execute(self, input_data):
9... return AgentResult(
10... status="success",
11... summary=f"{self.name} complete",
12... data={**self.payload, "input": input_data},
13... )
14>>>
15>>> coord = AgentCoordinator(
16... "overview_demo",
17... checkpoint_dir="outputs/docs/overview_demo",
18... verbose=False,
19... )
20>>> coord.add_step(
21... "load",
22... MiniAgent("load", {"sites": "SITES:28"}),
23... description="Load survey",
24... )
25>>> coord.add_step(
26... "qc",
27... MiniAgent("qc", {"qc_score": 0.91}),
28... input_fn=lambda r: {"sites": r["load"]["sites"]},
29... description="Run QC",
30... )
31>>> preview = coord.execute({"path": "/data/WILLY_EDIs"}, dry_run=True)
32>>> print(preview.status)
33success
34>>> print(preview.summary)
35Workflow preview: 2 steps.
36>>> [(s["name"], s["agent"], s["required"]) for s in preview["steps"]]
37[('load', 'MiniAgent', True), ('qc', 'MiniAgent', True)]
The preview result contains a formatted plan string and a structured
steps list. No registered agent’s execute method is called.
3.8. Direct agent execution#
Agents can also be used individually. This is the clearest pattern when you already know which operation you want and want to inspect each intermediate object before moving on.
1>>> from pycsamt.agents import MTLoaderAgent, DataQCAgent
2>>> load = MTLoaderAgent().execute({
3... "path": "data/AMT/WILLY_DATA/L18PLT",
4... })
5>>> if load.status == "success":
6... qc = DataQCAgent().execute({
7... "sites": load["sites"],
8... "output_dir": "outputs/willy_qc",
9... })
10... print(qc.status)
11... print(qc.summary)
This style is especially useful in notebooks. The Sites object returned by
the loader can be inspected, plotted, filtered, or passed to a different
agent before any larger workflow is committed.
3.9. Coordinated workflows#
Use pycsamt.agents.AgentCoordinator when several agents should run as
a named workflow. Each step can receive either the original configuration or a
mapped view of earlier step results.
1>>> from pycsamt.agents import (
2... AgentCoordinator,
3... MTLoaderAgent,
4... DataQCAgent,
5... StaticShiftAgent,
6... ReportAgent,
7... )
8>>> config = {
9... "path": "data/AMT/WILLY_DATA/L18PLT",
10... "output_dir": "outputs/willy_static_shift",
11... }
12>>> coord = AgentCoordinator(
13... "static_shift_report",
14... checkpoint_dir=f"{config['output_dir']}/checkpoints",
15... )
16>>> coord.add_step("load", MTLoaderAgent(), description="Load survey files")
17>>> coord.add_step(
18... "qc",
19... DataQCAgent(),
20... input_fn=lambda r: {
21... "sites": r["load"]["sites"],
22... "output_dir": f"{config['output_dir']}/qc",
23... },
24... description="Run quality control",
25... )
26>>> coord.add_step(
27... "static_shift",
28... StaticShiftAgent(),
29... input_fn=lambda r: {
30... "sites": r["load"]["sites"],
31... "qc_table": r["qc"].get("qc_table"),
32... "output_dir": f"{config['output_dir']}/static_shift",
33... },
34... description="Detect and correct static shift",
35... )
36>>> coord.add_step(
37... "report",
38... ReportAgent(),
39... input_fn=lambda r: {
40... "workflow_results": r,
41... "output_dir": f"{config['output_dir']}/report",
42... },
43... description="Assemble the workflow report",
44... required=False,
45... )
46>>> preview = coord.execute(config, dry_run=True)
47>>> print([step["name"] for step in preview["steps"]])
48['load', 'qc', 'static_shift', 'report']
The key idea is the input_fn boundary. The QC step consumes loaded sites.
The static-shift step consumes loaded sites plus any QC table the QC agent
returned. The report step consumes the dictionary of previous step results.
See Agent Coordinator for the full workflow contract.
3.10. Natural-language orchestration#
Use pycsamt.agents.WorkflowOrchestratorAgent when a user request
should determine the workflow. The orchestrator can classify requests such as
quality control, phase-tensor analysis, Occam2D preparation, ModEM
preparation, AI inversion, 2-D inversion, 3-D inversion, ensemble inversion,
joint inversion, and full workflows.
1>>> from pycsamt.agents import AGENT_CONFIG, WorkflowOrchestratorAgent
2>>> with AGENT_CONFIG.offline():
3... result = WorkflowOrchestratorAgent().execute({
4... "request": "Run phase tensor and strike analysis",
5... "data_path": "data/AMT/WILLY_DATA/L18PLT",
6... "output_dir": "outputs/willy_phase",
7... "dry_run": True,
8... })
9>>> print(result["workflow_type"])
10phase_analysis
11>>> print([step["name"] for step in result["steps"]])
12['load', 'qc', 'static_shift', 'phase_analysis', 'report']
Remove dry_run when the chain should execute. In executed mode, the
orchestrator returns both the built coordinator and the coordinator result so
the workflow can still be inspected step by step.
3.11. LLM-assisted interpretation#
Agents inherit provider settings from pycsamt.agents.AGENT_CONFIG
unless an explicit per-agent key is supplied.
1>>> from pycsamt.agents import configure_agents, PhaseAnalysisAgent
2>>> configure_agents(
3... provider="claude",
4... api_key="sk-ant-...",
5... model="claude-sonnet-4-6",
6... )
7>>> result = PhaseAnalysisAgent().execute({
8... "path": "data/AMT/WILLY_DATA/L18PLT",
9... "output_dir": "outputs/willy_phase",
10... })
11>>> print(result.summary)
12>>> print(result.llm_interpretation)
13>>> print(result.cost_estimate_usd)
llm_interpretation is narrative assistance, not a substitute for the
structured result fields, diagnostic figures, or a geophysicist’s review. For
provider selection, environment variables, budgets, and custom pricing, see
Agent And LLM Configuration.
3.12. AI and model-zoo entry points#
AI inversion agents are available as first-class workflow steps and direct interfaces. They are intended for workflows where a neural inverse model, synthetic training configuration, or model-zoo checkpoint is part of the analysis.
1>>> from pycsamt.agents import ModelZooAgent
2>>> zoo = ModelZooAgent()
3>>> models = zoo.execute({"action": "list"})
4>>> print(models.status)
5success
6>>> print(models.summary)
75 pre-trained models in zoo.
8>>> [item["name"] for item in models["details"][:2]]
9['mt1d-resnet-5layer-v1', 'mt1d-cnn-5layer-v1']
Use Inv2DAgent, Inv3DAgent, EnsembleAgent, and
JointInversionAgent for specialized deep-learning workflows. See
AI And Model-Zoo Agents for the agent catalogue view and
AI inversion agents for the detailed AI inversion workflow guide.
3.13. CLI and web interface#
The agent package also exposes a module CLI:
python -m pycsamt.agents preview "Load /data/WILLY EDIs, QC, PT analysis"
python -m pycsamt.agents list
python -m pycsamt.agents pricing
python -m pycsamt.agents zoo
python -m pycsamt.agents web --port=7860
The web interface requires gradio and can also be started from Python:
1>>> from pycsamt.agents.web import launch
2>>> launch()
The CLI is useful for quick previews, catalogue checks, pricing checks, and model-zoo inspection. The Python API remains the preferred interface for auditable project workflows because it keeps structured results in memory and lets the caller archive them explicitly.
3.14. Outputs and reproducibility#
Agent workflows are designed to be inspectable. A robust workflow should:
Keep the original input path and output directory in the workflow config.
Preserve intermediate AgentResult objects while debugging.
Use
dry_run=Truebefore expensive or file-writing runs.Inspect
warningsanderror_fix_hintbefore trusting final products.Track
cost_estimate_usdper agent and session-wide spend throughAGENT_CONFIG.Record checkpoint directories for coordinated workflows.
Use
CodeGenerationAgentwhen a workflow should be converted into a reproducible standalone Python script.
For scientific results, reproducibility also means recording which object a step consumed: raw survey, corrected survey, selected-period survey, AI prediction, conventional inversion output, or full previous-step dictionary. That record is what lets another user distinguish “the report was generated” from “the report was generated from the reviewed corrected data.”
3.15. Where to go next#
Page |
Use it for |
|---|---|
Choosing the right agent for each task. |
|
Building explicit multi-agent workflows. |
|
Natural-language workflow classification and execution. |
|
Provider setup, key resolution, budgets, and pricing. |
|
BaseAgent, AgentResult, ContextInputAgent, MTLoaderAgent, and AgentCoordinator basics. |
|
QC, static shift, phase analysis, tensor rotation, tipper analysis, frequency decimation, and denoising. |
|
Forward modelling and classical inversion preparation. |
|
AI inversion, model-zoo, ensemble, joint inversion, and anomaly agents. |