Skip to content

Commit f81509c

Browse files
qazbnm456claude
andcommitted
docs(examples): use discovery="inject" skills manifest; fix max_retries semantics
harness_run.py: switch the skills demo from the default discovery="list" (a pre-manifest pattern that told the model to call list_skills) to the recommended discovery="inject" + render_skills_manifest — the catalog is injected into the system prompt at startup and read_skill pulls bodies JIT, mirroring the reference consumer. mini_run.py: max_retries is the whole-RLM-retry knob (default 1, no re-run), not a loop bound — drop the misleading max_retries=2 "tiny/cheap" override and clarify that max_iterations bounds the in-run loop. No other API drift: intercept_sub_lm/export_rl/TraceRecorder/configure usage is already current. rlm-kit suite: 161 passed. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
1 parent a5f9bf8 commit f81509c

2 files changed

Lines changed: 25 additions & 9 deletions

File tree

examples/harness_run.py

Lines changed: 22 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,8 @@
44
a sandbox, so it is NOT imported by the test suite):
55
66
- a local/base model wrapped via intercept_sub_lm (validate + post-process),
7-
- a Skills directory exposed to the main LM as tools (LM-decided),
7+
- a Skills directory whose catalog is injected into the prompt (discovery="inject") with
8+
read_skill for just-in-time bodies,
89
- the whole run recorded to JSONL, then exported as an RL dataset.
910
1011
Run as a script after exporting RLM_* env vars and pointing SKILLS_DIR at a
@@ -29,6 +30,7 @@
2930
intercept_sub_lm,
3031
load_events,
3132
load_skills_as_tools,
33+
render_skills_manifest,
3234
)
3335

3436

@@ -41,18 +43,31 @@ def _non_empty(text: str):
4143
return None if text.strip() else "empty response"
4244

4345

46+
_INSTRUCTIONS = (
47+
"You are a research assistant. The <available_skills> catalog above lists the reference "
48+
"notes; pull the relevant one with read_skill(name), then emit a Note JSON."
49+
)
50+
51+
4452
class Research(RLMTask):
4553
signature = "topic: str -> note: Note"
4654
output_field = "note"
4755
output_model = Note
48-
instructions = (
49-
"You are a research assistant. Use list_skills/read_skill to consult "
50-
"reference notes, then emit a Note JSON."
51-
)
56+
instructions = _INSTRUCTIONS
5257

5358
def __init__(self, skills_dir: str, **kw):
54-
# Skills become RLM tools; the LM decides when to read them.
55-
self.tools = load_skills_as_tools(skills_dir)
59+
# discovery="inject": the skill CATALOG (name + description) is injected into the system
60+
# prompt via render_skills_manifest, so the LM sees every skill at startup with NO
61+
# `list_skills` discovery round-trip; `read_skill(name)` pulls a skill's full body JIT.
62+
self.tools = load_skills_as_tools(skills_dir, discovery="inject")
63+
self.instructions = (
64+
render_skills_manifest(
65+
skills_dir,
66+
header="<available_skills> — reference notes; `read_skill(name)` loads one:",
67+
)
68+
+ "\n\n"
69+
+ _INSTRUCTIONS
70+
)
5671
super().__init__(**kw)
5772

5873

examples/mini_run.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -46,8 +46,9 @@ async def main() -> None:
4646
cfg = configure(RLMConfig.from_env())
4747
print(f"main={cfg.main_model} sub={cfg.sub_model} interpreter={cfg.interpreter}")
4848

49-
# Keep the loop tiny/cheap.
50-
task = Summarize(max_retries=2)
49+
# A single RLM attempt (max_retries defaults to 1 — no whole-RLM re-run). The in-run REPL
50+
# loop is bounded by max_iterations, not by max_retries.
51+
task = Summarize()
5152

5253
trace_path = "./traces/mini_run.jsonl"
5354
document = (

0 commit comments

Comments
 (0)