Files
derek.holloway 7502bf64a4
CodeQL / Analyze (actions) (push) Canceled after 0s
CodeQL / Analyze (python) (push) Canceled after 0s
pre-commit / pre-commit (push) Canceled after 0s
Multi-Arch CI / setup (push) Canceled after 0s
Publish build_manylinux_x86_64 images / publish_build_manylinux_x86_64 (push) Canceled after 0s
Setup (Multi-Arch) / setup (push) Canceled after 0s
Multi-Arch CI / Linux::${{ fromJSON(needs.setup.outputs.linux_build_config || '{}').build_variant_label || 'skip' }} (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish no_rocm_image_ubi10 image / publish_no_rocm_image_ubi10 (push) Canceled after 0s
Multi-Arch CI / Windows::${{ fromJSON(needs.setup.outputs.windows_build_config || '{}').build_variant_label || 'skip' }} (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Multi-Arch CI / Manifest Diff (push) Canceled after 0s
TheRock Manifest Diff Report / Generate Manifest Diff Report (push) Canceled after 0s
Multi-Arch CI / CI Summary (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04 (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04_ocl_rt images / publish_no_rocm_image_ubuntu24_04_ocl_rt (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_rocgdb (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04_rocgdb images / publish_no_rocm_image_ubuntu24_04_rocgdb (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_ocl_rt (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Unit Tests / Unit Tests :: ubuntu-24.04 (push) Canceled after 0s
Unit Tests / Unit Tests :: windows-2022 (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_media (push) Canceled after 0s
Unit Tests / Unit Tests Summary (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_openmpi (push) Canceled after 0s
Flatten subprojects into a single base monorepo
2026-09-02 16:34:47 -07:00

210 lines
9.2 KiB
Markdown

# Agent Hierarchy
PerfXpert's agentic runtime (v0.2.0+) is a three-tier hierarchy of
OpenAI Agents SDK agents plus deterministic middleware. This document
is the authoritative reference for how the agents relate, how the
fence-slice pattern keeps each agent's system prompt narrow, and where
to look in source.
**Each of the 8 agents is callable from two surfaces:**
- **MCP:** `perfxpert_agent_root`, `perfxpert_agent_analysis`,
`perfxpert_agent_recommendation`, `perfxpert_agent_correctness`,
`perfxpert_agent_compute_specialist`,
`perfxpert_agent_memory_specialist`,
`perfxpert_agent_latency_specialist`,
`perfxpert_agent_diff_specialist` (READ_ONLY, auto-registered
from `perfxpert.tools.agents.*`).
- **Python API:** `perfxpert.api.agent_root(...)`,
`perfxpert.api.agent_analysis(...)`, etc. — **1:1 mirror** of the
MCP tools (same function, same schema).
The two surfaces resolve to the same underlying Python function; the
MCP registration is a thin wrapper around the `perfxpert.api.*`
callable. Agents are reachable from any entry point — the Root is NOT
the only way into the hierarchy. Backend TUIs (Claude Code, Gemini
CLI, Codex CLI, opencode) pick whichever agent matches the user's
intent based on the `AGENTS.md` reference.
Cross-links:
- [Gate cascade](gate-cascade.md) — the 5 deterministic correctness
gates that sit between agents
- [MCP server](../integration/mcp-server.md) — how READ_ONLY tools are
re-exposed to external clients
- [Python API](../guides/python-api.md) — in-process embedding with
the same schemas as the MCP tools
- [Agentic mode guide](../guides/agentic-mode.md) — end-user provider
ladder and air-gap behavior
## Three tiers
```mermaid
flowchart TD
classDef root fill:#e8f3ff,stroke:#1664ad,color:#0f2f4a,stroke-width:1px
classDef tier1 fill:#fff4d8,stroke:#a66a00,color:#4a3100,stroke-width:1px
classDef tier2 fill:#eaf8ef,stroke:#227343,color:#143b26,stroke-width:1px
classDef brain fill:#fff8c7,stroke:#9a6b00,color:#3d2b00,stroke-width:2px
subgraph brainSection["🧠 PerfXpert agent brain"]
root["Root<br/>Tier 0: intent classify"]
analysis["Analysis<br/>Tier 1: read traces + artifacts"]
correctness["Correctness<br/>Tier 1: verdicts and gate summaries"]
recommendation["Recommendation<br/>Tier 1: optimization strategy"]
end
compute["Compute specialist<br/>Tier 2"]
memory["Memory specialist<br/>Tier 2"]
latency["Latency specialist<br/>Tier 2"]
diff["Diff specialist<br/>Tier 2"]
root --> analysis
root --> correctness
root --> recommendation
analysis --> compute
analysis --> memory
analysis --> latency
analysis --> diff
recommendation --> compute
recommendation --> memory
recommendation --> latency
recommendation --> diff
class root,analysis,correctness,recommendation brain
class compute,memory,latency,diff tier2
```
- **Tier 0 (Root)** — classifies the user's natural-language query
into a routing decision (profile, analyze, recommend, diagnose).
Owns no tools; its only job is handoff selection.
- **Tier 1 (Layer-1 agents)** — three siblings:
- **Analysis** — reads trace/source artifacts via READ_ONLY tools,
emits a structured finding (primary bottleneck, metrics,
kernel_runtimes).
- **Correctness** — receives a `GateVerdict` from the gate-cascade
middleware and narrates it (never runs gates itself). The tier-0
diagram above shows Correctness as a sibling of the other two
tier-1 agents, but the data flow is: Recommendation proposes an
edit → middleware runs the gate cascade → the resulting
`GateVerdict` is handed to Correctness. See
[gate-cascade.md](gate-cascade.md).
- **Recommendation** — converts findings into proposed code changes,
delegates to specialists when needed.
- **Tier 2 (Specialists)** — four narrow experts invoked by
Recommendation (or directly from a TUI backend) when the user's
intent falls in their domain:
- `compute_specialist` — VALU occupancy, waves-per-EU, VGPR pressure.
Also consumes `kernel_fusion.find_fusion_candidates` to surface
adjacent-short-kernel fusion recipes (elementwise+elementwise,
GEMM+bias+act, ...) drawn from `knowledge/fusion_patterns.yaml`.
MFMA vs VALU ratio classifier (`mfma_vs_valu_ratio_classification`
in `knowledge/sol_metrics.yaml`) derived from existing `metrics.*`
helpers. Attention-scope patterns (Flash / naive SDPA / KV-cache
amplification) from `knowledge/attention_patterns.yaml`. Pragma
suggestions (allowlisted LLVM loop hints) gated behind `--advanced`.
- `memory_specialist` — HBM bandwidth, cache miss rate, LDS conflicts.
Binds `unified_memory.analyze_paging` for MI300X cross-die + paging
detection. Multi-level bandwidth chain (HBM → L2 → L1 → LDS) with
per-level classifier + recommendation in
`knowledge/memory_patterns.yaml`. Attaches change-impact
predictions to each surfaced technique via
`predict_impact.predict_change_impact`.
- `latency_specialist` — dependency chains, kernel launch overhead,
async-stream gaps.
Binds `dependency_graph.reconstruct_dag` for critical-path +
GPU-bubble attribution. Binds `rccl_analysis.analyze_collectives`
+ `interconnect.lookup_peaks` for per-collective bus-bandwidth +
NIC efficiency ratios. Reads `gpu_runtime_monitor.*` outputs from
the user-supplied `PERFXPERT_GPU_MONITOR_LOG` to flag thermal /
power throttle (MCP surface only — not in the cap-5 allowlist
because thermal analysis is diagnostic / out-of-band).
- `diff_specialist` — run-to-run comparison; wraps
`trace_diff.diff_runs` + `regression.compare_runs` +
`roofline.classify` and returns an
`improved` / `regressed` / `neutral` verdict with per-kernel deltas.
## Fence-slice pattern
Each agent's system prompt lives in `perfxpert/agents/fence/<agent>.md`
and is loaded verbatim at runtime — no runtime string concatenation of
prose. Slices are enforced at ≤ 400 lines by CI.
Slice files (one per agent, plus `always.md` loaded into every agent):
```
perfxpert/agents/fence/
├── always.md # safety preamble loaded into every agent
├── root.md # tier 0
├── analysis.md # tier 1
├── correctness.md # tier 1
├── recommendation.md # tier 1
├── compute_specialist.md # tier 2
├── memory_specialist.md # tier 2
├── latency_specialist.md # tier 2
└── diff_specialist.md # tier 2
```
Why fence-slicing:
1. **Scope containment** — each agent only sees rules relevant to
its job. Cross-agent leakage is impossible because the other slices
are never loaded into that agent's context.
2. **Length bound** — the 400-line cap forces focused guidance. Content
that grows past the cap is a signal to split agents or move facts
into `perfxpert/knowledge/*.yaml`.
3. **Reviewability** — every slice change shows as a small diff. The
prior monolithic reference guide (removed in Phase 7.1) made
cross-agent behavior hard to reason about in a single review pass.
## Invoking the hierarchy
From Python, you interact with the hierarchy through the session handle
returned by `build_session()`:
```python
from perfxpert.agents.runtime import build_session
from perfxpert.agents.schemas import RootInput
session = build_session(airgap=True) # or provider='anthropic'
output = session.run_root(RootInput(
user_query="Identify the hot kernel and suggest a first fix.",
airgap=True,
))
print(output.primary_bottleneck)
print(output.recommendations)
```
The session also exposes `run_analysis`, `run_correctness`, and
`run_recommendation` for direct tier-1 invocation — useful for
integrations that already know the routing decision.
## Where to find each piece in source
| Concern | Path |
|---------|------|
| Session handle + agent runner | `perfxpert/agents/runtime.py` |
| Schemas (Root/Analysis/Correctness/Recommendation I/O) | `perfxpert/agents/schemas.py` |
| Per-agent definitions | `perfxpert/agents/{root,analysis,correctness,recommendation}.py` |
| Specialists | `perfxpert/agents/{compute,memory,latency,diff}_specialist.py` |
| Fence slices (system prompts) | `perfxpert/agents/fence/*.md` |
| Agent framework + framework-level helpers | `perfxpert/agents/framework.py` |
| Gate cascade (middleware between agents) | `perfxpert/runtime/gate_cascade.py` |
| Recursion guard (prevents opencode→opencode loops) | `perfxpert/runtime/recursion_guard.py` — `ensure_not_recursive` is also re-exported from `perfxpert.runtime` and imported from there by `agents/runtime.py` |
| Intent classifier (deterministic pre-route) | `perfxpert/runtime/intent_classifier.py` |
## Adding a new agent
The contributor walkthrough is in
[contributing/agents.md](../contributing/agents.md). In brief:
1. Create `perfxpert/agents/<name>.py` with an `AgentSpec` + handoff
dataclass.
2. Add the fence slice `perfxpert/agents/fence/<name>.md` (≤ 400 lines).
3. Wire it into the parent agent's tools list (Recommendation →
specialist allowlist; Root → tier-1 allowlist).
4. Add tests under `tests/test_agents/test_<name>.py`.
5. Update this page's diagram.
Every agent addition is a small diff: one Python module, one fence
slice, two tests. No architectural review required for agents that fit
within an existing tier.