SkillOpt v0.1.0: initial release
- Skill optimization framework with training loop analogy - 11 benchmarks, 4 model backends (Azure OpenAI, Claude, Codex, Qwen) - WebUI for browser-based training control - Pluggable architecture for extending benchmarks and backends
This commit is contained in:
@@ -0,0 +1,109 @@
|
||||
"""ReflACT gradient clipping — LLM-driven edit ranking and selection.
|
||||
|
||||
Analogous to gradient clipping in neural network training: ranks candidate
|
||||
edits by importance and selects the top-L to apply, controlling the
|
||||
effective step size. Previously core/select.py.
|
||||
"""
|
||||
from __future__ import annotations
|
||||
|
||||
from skillopt.model import chat_teacher
|
||||
from skillopt.optimizer.meta_skill import format_meta_skill_context
|
||||
from skillopt.optimizer.update_modes import (
|
||||
describe_item,
|
||||
get_payload_items,
|
||||
is_rewrite_mode,
|
||||
normalize_update_mode,
|
||||
payload_key,
|
||||
payload_label,
|
||||
)
|
||||
from skillopt.prompts import load_prompt
|
||||
from skillopt.utils import extract_json
|
||||
|
||||
|
||||
# ── Public API ────────────────────────────────────────────────────────────────
|
||||
|
||||
def rank_and_select(
|
||||
skill_content: str,
|
||||
patch: dict,
|
||||
max_edits: int,
|
||||
meta_skill_context: str = "",
|
||||
update_mode: str = "patch",
|
||||
) -> dict:
|
||||
"""Use a teacher LLM to rank edits by importance, then keep top-L.
|
||||
|
||||
If the edit pool is within budget, returns the patch unchanged.
|
||||
Otherwise, calls the teacher to rank and select the most impactful edits.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
skill_content : str
|
||||
Current skill document.
|
||||
patch : dict
|
||||
Merged :class:`~skillopt.types.Patch` dict with ``edits`` list.
|
||||
max_edits : int
|
||||
Maximum number of edits to keep (the "edit budget").
|
||||
|
||||
Returns
|
||||
-------
|
||||
dict
|
||||
:class:`~skillopt.types.Patch` dict with selected edits and
|
||||
optional ``ranking_details``.
|
||||
"""
|
||||
update_mode = normalize_update_mode(update_mode)
|
||||
edits = get_payload_items(patch, update_mode)
|
||||
if len(edits) <= max_edits:
|
||||
return patch
|
||||
|
||||
# Build the edit pool description for the teacher
|
||||
edits_desc = []
|
||||
for i, edit in enumerate(edits):
|
||||
edits_desc.append(f"[{i}] {describe_item(edit, update_mode, max_chars=500)}")
|
||||
|
||||
user = (
|
||||
f"## Current Skill\n{skill_content}\n\n"
|
||||
f"## {payload_label(update_mode, title=True)} Pool ({len(edits)} {payload_label(update_mode)}, budget={max_edits})\n"
|
||||
+ "\n".join(edits_desc)
|
||||
+ f"\n\nSelect the {max_edits} most important {payload_label(update_mode)}. "
|
||||
f"Return their 0-based indices in priority order."
|
||||
)
|
||||
teacher_ctx = format_meta_skill_context(meta_skill_context)
|
||||
if teacher_ctx:
|
||||
user = f"{teacher_ctx}\n\n{user}"
|
||||
prompt_name = "ranking_rewrite" if is_rewrite_mode(update_mode) else "ranking"
|
||||
|
||||
try:
|
||||
response, _ = chat_teacher(
|
||||
system=load_prompt(prompt_name), user=user,
|
||||
max_completion_tokens=2048, retries=3, stage="ranking",
|
||||
)
|
||||
result = extract_json(response)
|
||||
if result and "selected_indices" in result:
|
||||
indices = result["selected_indices"]
|
||||
selected = []
|
||||
seen: set[int] = set()
|
||||
for idx in indices:
|
||||
if (
|
||||
isinstance(idx, int)
|
||||
and 0 <= idx < len(edits)
|
||||
and idx not in seen
|
||||
):
|
||||
selected.append(edits[idx])
|
||||
seen.add(idx)
|
||||
if len(selected) >= max_edits:
|
||||
break
|
||||
if selected:
|
||||
return {
|
||||
"reasoning": patch.get("reasoning", "")
|
||||
+ f" [teacher-ranked: selected {len(selected)}/{len(edits)} {payload_label(update_mode)}]",
|
||||
payload_key(update_mode): selected,
|
||||
"ranking_details": result,
|
||||
}
|
||||
except Exception: # noqa: BLE001
|
||||
pass
|
||||
|
||||
# Fallback: simple truncation
|
||||
return {
|
||||
"reasoning": patch.get("reasoning", "")
|
||||
+ f" [fallback truncated {len(edits)}->{max_edits} {payload_label(update_mode)}]",
|
||||
payload_key(update_mode): edits[:max_edits],
|
||||
}
|
||||
Reference in New Issue
Block a user