Explorer
/proc/2012/task/2095/root/tmp/skill-router-benchmark-hard.py
← Zurück ↓ Download
import json,re,time
from hermes_constants import set_hermes_home_override, reset_hermes_home_override
from tools.skills_tool import _find_all_skills
from agent.auxiliary_client import call_llm
HOME='/home/hermes/.hermes/profiles/redakteur'
CASES=[
 ('H1','Aus einem langen Besprechungsprotokoll sollen nur konkrete Verantwortlichkeiten und nächste Schritte herausgezogen werden.', ['meeting-action-items']),
 ('H2','Der Text klingt stark nach KI. Überarbeite ihn so, dass er natürlich und menschlich geschrieben wirkt, ohne die Aussage zu ändern.', ['humanizer']),
 ('H3','Wir brauchen eine visuelle Übersicht unserer Server, Dienste und Datenflüsse als technische Architekturzeichnung.', ['architecture-diagram']),
 ('H4','Beobachte den Preis eines konkreten Produkts und melde relevante Preisänderungen.', ['product-price-monitor']),
 ('H5','Eine wissenschaftliche Aussage soll gegen Originalpublikationen und Preprints geprüft werden.', ['arxiv','grounded-citations']),
 ('H6','Aus einem bestehenden Dokument sollen ausführbare Aufgaben mit Zuständigkeiten abgeleitet werden.', ['document-to-action-items']),
 ('H7','Überprüfe einen Pull Request fachlich auf Codequalität und problematische Änderungen.', ['github-code-review']),
 ('H8','Schreibe einen Songtext und plane anschließend die Umsetzung mit einem KI-Musikwerkzeug.', ['songwriting-and-ai-music']),
 ('H9','Erkläre mir in zwei Sätzen, was eine API ist. Keine Dateien, Recherche oder Spezialwerkzeuge.', []),
 ('H10','Ordne nur diese drei Zahlen der Größe nach: 8, 3, 5.', []),
]
def text_of(r):
 m=r.choices[0].message; return getattr(m,'content',None) or getattr(m,'reasoning_content',None) or ''
def parse(s):
 try:return json.loads(s)
 except Exception:
  m=re.search(r'\{.*\}',s,re.S); return json.loads(m.group(0)) if m else {}
t=set_hermes_home_override(HOME)
try:
 skills=sorted(_find_all_skills(),key=lambda x:x['name']); allowed={x['name'] for x in skills}
 skill_text='\n'.join(f"- {x['name']}: {x.get('description','')} [category: {x.get('category') or 'general'}]" for x in skills)
 cases='\n'.join(f'{qid}: {q}' for qid,q,_ in CASES)
 prompt=f'''Du bist ein konservativer Skill-Router. Ordne jeder Aufgabe 0-5 Skills aus der exakten Liste zu. Semantik zählt, auch Deutsch↔Englisch. Nimm keinen Skill nur wegen loser Themenähnlichkeit. Keine erfundenen Namen. Wenn kein Spezial-Skill nötig ist, gib [].\n\nSKILLS:\n{skill_text}\n\nAUFGABEN:\n{cases}\n\nNur JSON: {{"H1":["skill"],...,"H10":[]}}'''
 print('VISIBLE',len(skills),'CHARS',len(prompt))
 for effort in ('low','medium'):
  st=time.time(); r=call_llm(provider='openai-codex',model='gpt-5.6-luna',messages=[{'role':'user','content':prompt}],temperature=0,max_tokens=1400,timeout=60,reasoning_config={'enabled':True,'effort':effort})
  raw=text_of(r); o=parse(raw); score=0; invented=[]
  print('\nEFFORT',effort.upper(),'SEC',round(time.time()-st,2))
  for qid,_,req in CASES:
   ch=o.get(qid,[]) if isinstance(o,dict) else []; ch=ch if isinstance(ch,list) else []
   invented += [x for x in ch if x not in allowed]
   hit=(all(x in ch for x in req) if req else len(ch)==0); score+=hit
   print(qid,'REQ',req,'GOT',ch,'OK',bool(hit))
  u=getattr(r,'usage',None); print('SCORE',f'{score}/{len(CASES)}','INVENTED',invented,'USAGE',getattr(u,'prompt_tokens',None),getattr(u,'completion_tokens',None),getattr(u,'total_tokens',None))
  print('RAW',raw[:4000])
finally: reset_hermes_home_override(t)