Skip to content

feat(evaluator-sdk): agent-skill A/B evaluation for Fabric agent-eval - #625

Merged
SandyChapman merged 1 commit into
mainfrom
agent-skill-eval/schapman
Jul 15, 2026
Merged

feat(evaluator-sdk): agent-skill A/B evaluation for Fabric agent-eval#625
SandyChapman merged 1 commit into
mainfrom
agent-skill-eval/schapman

Conversation

@SandyChapman

@SandyChapman SandyChapman commented Jul 9, 2026

Copy link
Copy Markdown
Contributor

What

Adds agent-skill evaluation to the Fabric agent-eval runtime: inject an
agentskills.io skill into an eval and A/B the same
taskset with vs. without it, to measure the skill's effect.

  • AgentSkill + install_skill (runtimes/fabric/skills.py) — a
    directory-backed agentskills bundle, staged per task and wired to the harness.
    Namespaced under <name>/ so it can't collide with task-seeded workspace files.
    SkillProvenance (name, content hash, mode, adapter, location) is stamped into
    trial metadata for an auditable A/B diff.

  • How the skill reaches the harness is decided by querying Fabric's own
    capability planner at runtime
    , not a hardcoded adapter list. The runtime plans
    a copy of the config with a sentinel skill path attached and reads
    RunPlan.capability_plan routes:

    • a skills route targeting harness_native (the adapter accepts the native
      Fabric skills config, e.g. Hermes/Claude) → native skills.paths overlay;
    • otherwise a codex harness → .agents/skills/<name>/ placement, which the
      Codex CLI self-discovers;
    • otherwise → fail fast rather than run a skill-free trial mislabeled "with
      skill" (which would corrupt the A/B).

    Driving the decision from Fabric means it tracks whatever the installed adapters
    declare — including end-user adapters we don't ship (e.g. the claude
    adapter, which a static allow-list would miss) — instead of a list that silently
    goes stale.

  • FabricAgentRuntime gains a skill= param and a with_skill() clone for
    confound-free A/B: baseline (with_skill(None)) vs. treated (with_skill(skill))
    differ in exactly the skill and nothing else.

  • SkillUsedMetricskill_present / skill_used booleans, to flag a failure
    to engage an injected skill (best-effort trajectory detection; strongest for
    Codex filesystem discovery).

  • run_id is folded into the Fabric evidence path (<root>/<run_id>/<task>) so
    an A/B baseline and skilled variant sharing a work_root don't collide.

  • examples/skill_eval/ — a runnable baseline-vs-treated A/B where the skill
    (the "Supercool Coding Guidelines": supercool_ prefix + French enieme param)
    is required to pass follows_guidelines.

Notes

  • Rebased onto the merged FabricClientFabric SDK migration (refactor(evaluator-sdk): migrate Fabric agent-eval runtime to the updated Fabric SDK #648), so this is
    built on the current config-first Fabric run model (Fabric().run(...) /
    Fabric().plan(...)). No longer blocked on that migration.
  • The runtime-query decision (resolve_skill_mode / native_skills_route) is pure
    and unit-testable without the native SDK; the actual client.plan(...) probe was
    verified live against a NeMo-Fabric checkout (hermes→native, codex→unsupported,
    claude→native).

Verification

  • test_fabric_skills.py, test_fabric_runtime.py, test_skill_used_metric.py
    and the surrounding agent-eval suite — 160 passed, 2 skipped.
  • ruff, ty (only the expected unused-ignore warnings CI relies on),
    lint-sdk-vendored, and lint-cli all clean; vendored SDK mirror regenerated
    via make vendor.

🤖 Generated with Claude Code

Summary by CodeRabbit

  • New Features
    • Added agent-skill injection for Fabric evaluations with with_skill(...), including per-run evidence/run isolation and skill provenance metadata.
    • Added skill_present/skill_used reporting via a new metric.
    • Added a complete A/B skill evaluation example, including a sample supercool-guidelines skill bundle.
  • Bug Fixes
    • Unsupported skill-injection configurations now fail fast with a clear message.
    • Failed trials retain the relevant skill metadata for easier diagnosis.
  • Documentation
    • Updated example documentation and skill instructions.

@github-actions github-actions Bot added the feat label Jul 9, 2026
@github-actions

github-actions Bot commented Jul 9, 2026

Copy link
Copy Markdown
Contributor
Suite Lines Covered Line Rate Branch Rate
Unit Tests 25436/32661 77.9% 62.5%
Integration Tests 14703/31310 47.0% 19.3%

@SandyChapman
SandyChapman force-pushed the agent-skill-eval/schapman branch from 8d57c62 to b74828a Compare July 14, 2026 11:41
@SandyChapman
SandyChapman changed the base branch from main to fabric-client-to-fabric/schapman July 14, 2026 11:41
@SandyChapman
SandyChapman force-pushed the agent-skill-eval/schapman branch from b74828a to ae72018 Compare July 14, 2026 11:42
Base automatically changed from fabric-client-to-fabric/schapman to main July 14, 2026 11:47
@SandyChapman
SandyChapman force-pushed the agent-skill-eval/schapman branch 2 times, most recently from b79565c to d7401b3 Compare July 14, 2026 13:27
@SandyChapman SandyChapman changed the title feat(evaluator-sdk): agent-skill injection + SkillUsedMetric for Fabric agent-eval feat(evaluator-sdk): agent-skill A/B evaluation for Fabric agent-eval Jul 14, 2026
@SandyChapman
SandyChapman force-pushed the agent-skill-eval/schapman branch from d7401b3 to f681e57 Compare July 14, 2026 15:47
@SandyChapman
SandyChapman marked this pull request as ready for review July 14, 2026 15:47
@SandyChapman
SandyChapman requested review from a team as code owners July 14, 2026 15:47
@coderabbitai

coderabbitai Bot commented Jul 14, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Enterprise

Run ID: 4db7e68d-bae1-41a8-817e-058ea0d1d8f2

📥 Commits

Reviewing files that changed from the base of the PR and between 4a69366 and 93f637c.

⛔ Files ignored due to path filters (3)
  • sdk/python/nemo-platform/src/nemo_platform/beta/evaluator/agent_eval/metrics.py is excluded by !sdk/**
  • sdk/python/nemo-platform/src/nemo_platform/beta/evaluator/agent_eval/runtimes/fabric/runtime.py is excluded by !sdk/**
  • sdk/python/nemo-platform/src/nemo_platform/beta/evaluator/agent_eval/runtimes/fabric/skills.py is excluded by !sdk/**
📒 Files selected for processing (10)
  • packages/nemo_evaluator_sdk/examples/skill_eval/.gitignore
  • packages/nemo_evaluator_sdk/examples/skill_eval/README.md
  • packages/nemo_evaluator_sdk/examples/skill_eval/run_skill_eval.py
  • packages/nemo_evaluator_sdk/examples/skill_eval/skills/supercool-guidelines/SKILL.md
  • packages/nemo_evaluator_sdk/src/nemo_evaluator_sdk/agent_eval/metrics.py
  • packages/nemo_evaluator_sdk/src/nemo_evaluator_sdk/agent_eval/runtimes/fabric/runtime.py
  • packages/nemo_evaluator_sdk/src/nemo_evaluator_sdk/agent_eval/runtimes/fabric/skills.py
  • packages/nemo_evaluator_sdk/tests/agent_eval/test_fabric_runtime.py
  • packages/nemo_evaluator_sdk/tests/agent_eval/test_fabric_skills.py
  • packages/nemo_evaluator_sdk/tests/agent_eval/test_skill_used_metric.py
🚧 Files skipped from review as they are similar to previous changes (6)
  • packages/nemo_evaluator_sdk/examples/skill_eval/.gitignore
  • packages/nemo_evaluator_sdk/examples/skill_eval/skills/supercool-guidelines/SKILL.md
  • packages/nemo_evaluator_sdk/examples/skill_eval/README.md
  • packages/nemo_evaluator_sdk/src/nemo_evaluator_sdk/agent_eval/runtimes/fabric/skills.py
  • packages/nemo_evaluator_sdk/tests/agent_eval/test_fabric_skills.py
  • packages/nemo_evaluator_sdk/src/nemo_evaluator_sdk/agent_eval/runtimes/fabric/runtime.py

📝 Walkthrough

Walkthrough

Adds Fabric agent-skill injection with native and Codex modes, provenance tracking, usage metrics, run-scoped evidence isolation, and an A/B evaluation example using the bundled supercool-guidelines skill.

Changes

Agent skill evaluation

Layer / File(s) Summary
Skill validation and installation
packages/nemo_evaluator_sdk/src/nemo_evaluator_sdk/agent_eval/runtimes/fabric/skills.py, packages/nemo_evaluator_sdk/tests/agent_eval/test_fabric_skills.py
Validates skill bundles, resolves injection modes, stages native or Codex skills, and records content-sensitive provenance.
Runtime skill injection and isolation
packages/nemo_evaluator_sdk/src/nemo_evaluator_sdk/agent_eval/runtimes/fabric/runtime.py, packages/nemo_evaluator_sdk/tests/agent_eval/test_fabric_runtime.py
Probes Fabric routing, injects skills into task profiles or workspace directories, attaches provenance to trials, and scopes evidence paths by run ID.
Skill usage measurement
packages/nemo_evaluator_sdk/src/nemo_evaluator_sdk/agent_eval/metrics.py, packages/nemo_evaluator_sdk/tests/agent_eval/test_skill_used_metric.py
Adds SkillUsedMetric outputs for skill presence and evidence-based skill usage.
A/B evaluation example
packages/nemo_evaluator_sdk/examples/skill_eval/*
Runs baseline and treated evaluations, scores guideline adherence, reports metric rates and failed trials, and documents setup and output behavior.

Sequence Diagram(s)

sequenceDiagram
  participant EvaluationExample
  participant FabricAgentRuntime
  participant FabricPlanner
  participant SkillInstaller
  participant FabricClient
  participant SkillUsedMetric
  EvaluationExample->>FabricAgentRuntime: create baseline and treated runs
  FabricAgentRuntime->>FabricPlanner: probe skill capability
  FabricPlanner-->>FabricAgentRuntime: return injection mode
  FabricAgentRuntime->>SkillInstaller: stage and install skill
  SkillInstaller-->>FabricAgentRuntime: return profiles and provenance
  FabricAgentRuntime->>FabricClient: run evaluation task
  FabricClient-->>SkillUsedMetric: provide trial metadata and evidence
  SkillUsedMetric-->>EvaluationExample: return presence and usage results
Loading

Possibly related PRs

Suggested reviewers: arpitsardhana, ngoncharenko

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 17.24% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly summarizes the main change: adding agent-skill A/B evaluation for Fabric agent-eval.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch agent-skill-eval/schapman

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
packages/nemo_evaluator_sdk/examples/skill_eval/README.md (1)

1-95: 📐 Maintainability & Code Quality | 🟠 Major | ⚡ Quick win

Split this into a HOW-TO and an EXPLANATION.

Move causal rationale and metric caveats to an explanation page. Start the HOW-TO with prerequisites, provide Python SDK and CLI examples in tab sets, use configured product substitutions, and end with Next Steps.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/nemo_evaluator_sdk/examples/skill_eval/README.md` around lines 1 -
95, Split the skill_eval README content into separate HOW-TO and EXPLANATION
documentation pages. Make the HOW-TO begin with prerequisites, include Python
SDK and CLI examples in tab sets, replace hard-coded product references with
configured product substitutions, and end with a Next Steps section; move the
causal rationale, metric caveats, and other explanatory material into the
EXPLANATION page.

Source: Coding guidelines

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@packages/nemo_evaluator_sdk/examples/skill_eval/README.md`:
- Around line 34-52: Update the “Run it” prerequisites in the skill evaluation
README to establish the import path for nemo_evaluator_sdk before the shown
module command. Document the supported workspace install or dependency-sync
step, or provide an invocation that sets the package path, while preserving the
existing NVIDIA_API_KEY and ADAPTER_PYTHON guidance.

In `@packages/nemo_evaluator_sdk/examples/skill_eval/run_skill_eval.py`:
- Around line 68-90: The guideline metric currently searches the entire response
and applies the same parameter rule to every task. In
packages/nemo_evaluator_sdk/examples/skill_eval/run_skill_eval.py lines 68-90,
update compute_scores and its regex logic to extract the returned function
signature and validate parameters there; in lines 112-115, make the second task
index-based or provide task-specific expected-parameter rules so gcd does not
require enieme while positional-index tasks do.

---

Outside diff comments:
In `@packages/nemo_evaluator_sdk/examples/skill_eval/README.md`:
- Around line 1-95: Split the skill_eval README content into separate HOW-TO and
EXPLANATION documentation pages. Make the HOW-TO begin with prerequisites,
include Python SDK and CLI examples in tab sets, replace hard-coded product
references with configured product substitutions, and end with a Next Steps
section; move the causal rationale, metric caveats, and other explanatory
material into the EXPLANATION page.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Enterprise

Run ID: 1726fadf-56b3-4856-a67b-fa3070d1f2e4

📥 Commits

Reviewing files that changed from the base of the PR and between b62a72e and f681e57.

⛔ Files ignored due to path filters (3)
  • sdk/python/nemo-platform/src/nemo_platform/beta/evaluator/agent_eval/metrics.py is excluded by !sdk/**
  • sdk/python/nemo-platform/src/nemo_platform/beta/evaluator/agent_eval/runtimes/fabric/runtime.py is excluded by !sdk/**
  • sdk/python/nemo-platform/src/nemo_platform/beta/evaluator/agent_eval/runtimes/fabric/skills.py is excluded by !sdk/**
📒 Files selected for processing (10)
  • packages/nemo_evaluator_sdk/examples/skill_eval/.gitignore
  • packages/nemo_evaluator_sdk/examples/skill_eval/README.md
  • packages/nemo_evaluator_sdk/examples/skill_eval/run_skill_eval.py
  • packages/nemo_evaluator_sdk/examples/skill_eval/skills/supercool-guidelines/SKILL.md
  • packages/nemo_evaluator_sdk/src/nemo_evaluator_sdk/agent_eval/metrics.py
  • packages/nemo_evaluator_sdk/src/nemo_evaluator_sdk/agent_eval/runtimes/fabric/runtime.py
  • packages/nemo_evaluator_sdk/src/nemo_evaluator_sdk/agent_eval/runtimes/fabric/skills.py
  • packages/nemo_evaluator_sdk/tests/agent_eval/test_fabric_runtime.py
  • packages/nemo_evaluator_sdk/tests/agent_eval/test_fabric_skills.py
  • packages/nemo_evaluator_sdk/tests/agent_eval/test_skill_used_metric.py

Comment thread packages/nemo_evaluator_sdk/examples/skill_eval/README.md Outdated
Comment thread packages/nemo_evaluator_sdk/examples/skill_eval/run_skill_eval.py Outdated

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@packages/nemo_evaluator_sdk/examples/skill_eval/run_skill_eval.py`:
- Around line 240-271: Move the AgentSkill.from_directory call into the existing
try block, or extend the exception handling to include SkillInjectionError, so
missing bundled skills follow the same friendly error path as runtime failures.
Preserve the existing message and return behavior in the run_skill_eval flow.

In `@packages/nemo_evaluator_sdk/src/nemo_evaluator_sdk/agent_eval/metrics.py`:
- Around line 167-181: Update the exception handling in _skill_used to catch
trace validation failures from Trajectory.model_validate and file-read errors in
addition to the existing KeyError and ValueError cases. Preserve the warning log
and return False best-effort fallback for all expected trace-reading failures.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Enterprise

Run ID: adcebd6e-e668-4a38-bf7d-d03d3bf6e1e2

📥 Commits

Reviewing files that changed from the base of the PR and between f681e57 and 4a69366.

⛔ Files ignored due to path filters (3)
  • sdk/python/nemo-platform/src/nemo_platform/beta/evaluator/agent_eval/metrics.py is excluded by !sdk/**
  • sdk/python/nemo-platform/src/nemo_platform/beta/evaluator/agent_eval/runtimes/fabric/runtime.py is excluded by !sdk/**
  • sdk/python/nemo-platform/src/nemo_platform/beta/evaluator/agent_eval/runtimes/fabric/skills.py is excluded by !sdk/**
📒 Files selected for processing (10)
  • packages/nemo_evaluator_sdk/examples/skill_eval/.gitignore
  • packages/nemo_evaluator_sdk/examples/skill_eval/README.md
  • packages/nemo_evaluator_sdk/examples/skill_eval/run_skill_eval.py
  • packages/nemo_evaluator_sdk/examples/skill_eval/skills/supercool-guidelines/SKILL.md
  • packages/nemo_evaluator_sdk/src/nemo_evaluator_sdk/agent_eval/metrics.py
  • packages/nemo_evaluator_sdk/src/nemo_evaluator_sdk/agent_eval/runtimes/fabric/runtime.py
  • packages/nemo_evaluator_sdk/src/nemo_evaluator_sdk/agent_eval/runtimes/fabric/skills.py
  • packages/nemo_evaluator_sdk/tests/agent_eval/test_fabric_runtime.py
  • packages/nemo_evaluator_sdk/tests/agent_eval/test_fabric_skills.py
  • packages/nemo_evaluator_sdk/tests/agent_eval/test_skill_used_metric.py
🚧 Files skipped from review as they are similar to previous changes (7)
  • packages/nemo_evaluator_sdk/examples/skill_eval/.gitignore
  • packages/nemo_evaluator_sdk/examples/skill_eval/skills/supercool-guidelines/SKILL.md
  • packages/nemo_evaluator_sdk/tests/agent_eval/test_fabric_skills.py
  • packages/nemo_evaluator_sdk/examples/skill_eval/README.md
  • packages/nemo_evaluator_sdk/src/nemo_evaluator_sdk/agent_eval/runtimes/fabric/skills.py
  • packages/nemo_evaluator_sdk/tests/agent_eval/test_skill_used_metric.py
  • packages/nemo_evaluator_sdk/src/nemo_evaluator_sdk/agent_eval/runtimes/fabric/runtime.py

Comment thread packages/nemo_evaluator_sdk/examples/skill_eval/run_skill_eval.py Outdated
Add agent-skill (agentskills.io) injection to FabricAgentRuntime so an A/B
eval can score the same taskset with and without a skill: build one runtime
with `skill=None` and one via `with_skill(skill)` over the same tasks, then
diff the scores. Each run gets its own run-id evidence subtree so a baseline
and a skilled variant sharing a work_root don't collide, and a SkillUsedMetric
scores whether the agent actually engaged the injected skill.

How the skill reaches the harness is decided by querying Fabric's own
capability planner at runtime rather than a hardcoded adapter list: the
runtime plans a copy of the config with a sentinel skill path attached and
reads the resulting RunPlan.capability_plan routes. A `skills` route targeting
`harness_native` means the adapter accepts the native Fabric `skills` config,
so the bundle is handed over natively; otherwise a codex harness falls back to
the `.agents/skills/` self-discovery convention, and anything else fails fast
rather than run a skill-free trial mislabeled "with skill". Driving the
decision from Fabric means it tracks whatever the installed adapters declare —
including end-user adapters the platform doesn't ship (e.g. the `claude`
adapter) — instead of a list that silently goes stale.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Signed-off-by: Sandy Chapman <schapman@nvidia.com>
@SandyChapman
SandyChapman force-pushed the agent-skill-eval/schapman branch from 4a69366 to 93f637c Compare July 15, 2026 11:20
@SandyChapman
SandyChapman enabled auto-merge July 15, 2026 11:26
@SandyChapman
SandyChapman added this pull request to the merge queue Jul 15, 2026
Merged via the queue into main with commit 48614f1 Jul 15, 2026
57 checks passed
@SandyChapman
SandyChapman deleted the agent-skill-eval/schapman branch July 15, 2026 11:43
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants