agent-handoff-designer
Skill28 starsChanged 14 days agoMITView on GitHub
Design de handoffs fluides entre agents — transfert de contexte, d'état et de responsabilité. Se déclenche avec "handoff", "transfert agent", "agent handoff", "passer la main", "relay agent", "agent transition", "changement d'agent", "routing entre agents". Also triggers on "transfer context between agents", "agent escalation flow".
We split this skill into the rules it gives an agent
4 rules. About 0 are common, 4 are distinctive, and 0 are very specific to this project.
≈0
Common · estimate
Many files like this have a rule of this kind.
≈4
Distinctive · estimate
This author's own choices. Worth a look.
0
Very specific
Tied to their project's names, files or tools. Probably skip.
- Common
- Distinctive
- Very specific
- Distinctive: line 263
Never say "happy to help", "sure!", "great question", "let me", or similar.
- Distinctive: line 266
Stop when done. No summary, no recap, no trailing commentary.
- Distinctive: line 267
No politeness wrappers. Direct and blunt.
- Distinctive: line 270
No emoji unless asked.
≈ “Common” is an estimate: at least 1 in 5 of the 308,232 skill files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.
Files
Agent Handoff Designer
Quand utiliser ce skill
Un handoff est nécessaire dans quatre situations :
| Situation | Signal | Agent cible |
| Capability boundary | Outil ou connaissance manquant | Spécialiste équipé |
| Spécialisation | Sous-tâche mieux traitée ailleurs | Agent optimisé |
| Escalation | Risque ou complexité dépassant le seuil | Agent senior / humain |
| Load balancing | Queue saturée | Instance parallèle |
Décision : si l'agent courant peut compléter la tâche avec une qualité ≥ 80 % sans outil supplémentaire, ne pas handoff — le coût de transition n'est pas justifié.
Workflow en étapes
1. Évaluer le déclenchement
from enum import Enum
class HandoffReason(Enum):
CAPABILITY_BOUNDARY = "capability_boundary"
SPECIALIZATION = "specialization"
ESCALATION = "escalation"
LOAD_BALANCING = "load_balancing"
def should_handoff(task: dict, agent_caps: list[str]) -> tuple[bool, HandoffReason | None]:
missing = [c for c in task.get("required_capabilities", []) if c not in agent_caps]
if missing:
return True, HandoffReason.CAPABILITY_BOUNDARY
if task.get("risk_level", 0) > 7:
return True, HandoffReason.ESCALATION
return False, NoneCritères de seuil recommandés : risk_level > 7, complexity_score > 8, sentiment_score < 0.3.
2. Packager le contexte (≤ 2 000 tokens)
Contenu obligatoire du HandoffContext :
from dataclasses import dataclass, field
from typing import Any
import uuid
@dataclass
class HandoffContext:
correlation_id: str # inchangé sur toute la chaîne
source_agent: str
target_agent: str
handoff_reason: str
conversation_summary: str # 5–10 phrases max
user_intent: str # reformulé explicitement
key_facts: dict[str, Any] # entités, montants, références
task_progress: dict # {"step": 3, "total": 7, "completed": [...]}
user_preferences: dict # langue, ton, contraintes détectées
context_ref: str # clé du snapshot complet dans le state store
hop_count: int = 0
handoff_chain: list[str] = field(default_factory=list)
def package_context(history: list, source: str, target: str, reason: str) -> HandoffContext:
summary = summarize_conversation(history) # appel LLM interne
facts = extract_key_facts(history)
ref = store_context_snapshot(history) # Redis / DynamoDB / mémoire partagée
return HandoffContext(
correlation_id=str(uuid.uuid4()),
source_agent=source, target_agent=target,
handoff_reason=reason,
conversation_summary=summary,
user_intent=detect_intent(history),
key_facts=facts,
task_progress={},
user_preferences={},
context_ref=ref,
handoff_chain=[source],
)Règle de taille : résumé + faits = max 2 000 tokens. Le transcript complet va dans le state store, pas dans le package.
3. Exécuter le protocole (avec ACK obligatoire)
import asyncio
MAX_HOPS = 5
TIMEOUT_S = 5.0
RETRY_DELAY = 2.0
async def execute_handoff(
source_agent,
target_agent,
ctx: HandoffContext,
) -> dict:
# Garde anti-boucle
if ctx.hop_count >= MAX_HOPS:
return {"success": False, "reason": "max_hops_exceeded"}
if target_agent.id in ctx.handoff_chain:
return {"success": False, "reason": "cycle_detected"}
ctx.hop_count += 1
ctx.handoff_chain.append(target_agent.id)
for attempt in range(2): # 1 essai + 1 retry
try:
ack = await asyncio.wait_for(
target_agent.notify_handoff(ctx), timeout=TIMEOUT_S
)
if ack.get("ready"):
source_agent.set_state("standby")
return {"success": True, "target": target_agent.id}
except asyncio.TimeoutError:
if attempt == 0:
await asyncio.sleep(RETRY_DELAY)
# Fallback hiérarchique
alt = find_alternative_agent(target_agent.id)
if alt:
return await execute_handoff(source_agent, alt, ctx)
source_agent.set_state("active") # return-to-sender
return {"success": False, "reason": "target_unavailable"}Séquence obligatoire : notify → ACK ready → switch source → confirm orchestrateur. Ne jamais passer en standby sans ACK.
4. Routing conditionnel
Définis les règles dans une table pure (testable unitairement) :
ROUTING_RULES = [
{"cond": lambda c: c.get("intent") == "billing", "target": "billing_agent"},
{"cond": lambda c: c.get("sentiment_score", 1.0) < 0.3, "target": "escalation_agent"},
{"cond": lambda c: c.get("complexity_score", 0) > 8, "target": "senior_agent"},
{"cond": lambda c: c.get("language") == "ar", "target": "arabic_specialist"},
]
def route_handoff(context: dict) -> str:
for rule in ROUTING_RULES:
if rule["cond"](context):
return rule["target"]
return "default_agent"LangGraph (2026) — utilise Command(goto="node", update={...}) dans le nœud source :
from langgraph.types import Command
def billing_router(state):
if state["intent"] == "billing":
return Command(goto="billing_node", update={"ctx": package_context(...)})
return Command(goto="default_node")OpenAI Assistants — partage le thread_id, annule le run courant, démarre un run sur l'assistant cible :
client.beta.threads.runs.cancel(thread_id=tid, run_id=rid)
new_run = client.beta.threads.runs.create(thread_id=tid, assistant_id=TARGET_ASST_ID)CrewAI — Agent.delegate(task, agent=target_agent) + inject le contexte dans la description de la tâche.
Google A2A (2026) — expose un AgentCard avec capabilities, envoie un Task JSON via POST /tasks/send avec metadata.handoff_context.
5. UX transparente côté utilisateur
L'agent récepteur doit toujours :
- S'introduire brièvement : "Je prends en charge votre demande depuis [Agent A]."
- Démontrer le contexte : "Je vois que vous recherchez une facture pour le mois de mars…"
- Ne pas reposer une question déjà répondue — vérifier
key_factsavant toute question. - Si une info manque, expliquer pourquoi : "J'ai besoin de votre numéro client car il n'est pas encore dans le dossier."
Message de transition UI (optionnel) :
{ "type": "system_event", "event": "handoff_started",
"message": "Transfert vers le spécialiste Facturation en cours…",
"target_agent": "billing_agent" }6. Chaînes multi-hop
À chaque hop :
- Incrémenter
hop_count, bloquer si>= MAX_HOPS. - Accumuler les résumés (pas re-résumer le résumé — perte de signal garanti).
- Conserver le
correlation_idoriginal pour le tracing distribué. - Stocker un snapshot immutable dans le state store (
ctx_snap_{hop}.json).
def accumulate_summary(existing: str, new_segment: str) -> str:
# Concatène avec séparateur de hop — ne pas re-résumer
return f"{existing}\n---hop---\n{new_segment}"7. Métriques à suivre
| Métrique | Calcul | Seuil alerte |
| Taux de succès | handoffs réussis / total | < 95 % |
| Context loss score | éval LLM du contexte reçu (0–1) | < 0.8 |
| Latence de transition | fin agent A → 1er message agent B | > 3 s |
| Fréquence de retry | retries / total handoffs | > 10 % |
| Task completion post-handoff | tâches complétées après handoff | < 80 % |
Garde-fous et anti-patterns
Boucle infinie (A → B → A) — Sans détection de cycle, deux agents se renvoient la tâche indéfiniment. Fix : vérifier target in handoff_chain avant d'exécuter.
Handoff sans ACK — Switcher l'agent source avant que la cible soit prête provoque des messages perdus. Fix : ACK ready: true obligatoire, sinon fallback.
Contexte tronqué à l'intent seul — L'agent récepteur ne sait pas ce qui a déjà été répondu et refait les mêmes questions. Fix : packager key_facts + task_progress systématiquement.
Re-résumer le résumé à chaque hop — Chaque compression successive perd de l'information jusqu'à rendre le contexte inutilisable. Fix : accumulation par concaténation, re-résumé seulement au hop 1.
Handoff silencieux sans fallback — Si la cible ne répond pas et qu'il n'y a pas de return-to-sender, la tâche est perdue. Fix : toujours implémenter le chemin return-to-sender comme dernier recours.
Over-handoff — Créer des handoffs pour chaque micro-tâche gonfle la latence et le bruit de logs. Fix : handoff seulement si la tâche ne peut pas être complétée à ≥ 80 % par l'agent courant.
Contexte package > 2 000 tokens — Surcharger l'agent récepteur ralentit son inference et noie les faits clés. Fix : le transcript complet va dans le state store, le package ne contient que le résumé structuré.
Règles non-négociables
- HandoffContext obligatoire — Aucun handoff sans résumé + intent + key_facts, même minimal.
- ACK avant switch — Source reste
activejusqu'à réception duready: true. - MAX_HOPS = 5 — Au-delà : escalade superviseur ou humain, jamais de boucle supplémentaire.
- correlation_id inchangé — Permet le tracing end-to-end sur toute la chaîne.
- Documente le trade-off — Contexte minimal = latence réduite, risque context loss élevé. Contexte riche = fiabilité élevée, latence +. Choix explicite selon le SLA.
Communication Rules — MANDATORY
- Ultra-concise. No filler, no preamble, no pleasantries.
- Never say "happy to help", "sure!", "great question", "let me", or similar.
- Tool first, talk second. Act before explaining.
- Result first. Lead with outcome, not process.
- Stop when done. No summary, no recap, no trailing commentary.
- No politeness wrappers. Direct and blunt.
- Minimum words. If one word works, do not use ten.
- No unsolicited explanations.
- No emoji unless asked.
In this repository347 other files it gives its agents.
- agent-a2a-protocol-guideSkill
- agent-agent-observabilitySkill
- agent-api-caller-subagentSkill
- agent-autogen-guideSkill
- agent-browser-agent-builderSkill
- agent-claude-code-extension-builderSkill
- agent-code-review-subagentSkill
- agent-coding-agent-builderSkill
- agent-conflict-resolverSkill
- agent-consensus-builderSkill
- agent-context-managerSkill
- agent-cost-optimizerSkill
- agent-crewai-expertSkill
- agent-customer-support-agentSkill
- agent-data-analyst-agentSkill
- agent-database-query-subagentSkill
- agent-deployment-guideSkill
- agent-email-agent-builderSkill
- agent-evaluation-frameworkSkill
- agent-file-processor-subagentSkill
- agent-hierarchy-designerSkill
- agent-human-in-the-loop-designerSkill
- agent-langgraph-designerSkill
- agent-load-balancerSkill
- agent-marketplace-creatorSkill
- agent-mcp-server-builderSkill
- agent-memory-designerSkill
- agent-message-protocolSkill
- agent-monitoring-setupSkill
- agent-multi-agent-orchestratorSkill
- agent-openai-assistants-builderSkill
- agent-pipeline-composerSkill
- agent-pool-managerSkill
- agent-prompt-tunerSkill
- agent-research-agent-designerSkill
- agent-result-aggregatorSkill
- agent-retry-strategistSkill
- agent-sales-agent-builderSkill
- agent-security-hardenerSkill
- agent-semantic-kernel-guideSkill
- agent-skill-creatorSkill
- agent-skill-routerSkill
- agent-spawnerSkill
- agent-state-synchronizerSkill
- agent-subagent-delegatorSkill
- agent-supervisor-builderSkill
- agent-task-decomposerSkill
- agent-testing-frameworkSkill
- agent-tool-calling-architectSkill
- agent-voice-agent-builderSkill
- agent-web-scraper-subagentSkill
- agent-workflow-automation-agentSkill
- ai-ml-anomaly-detection-builderSkill
- ai-ml-computer-vision-guideSkill
- ai-ml-dataset-builderSkill
- ai-ml-ml-experiment-trackerSkill
- ai-ml-model-fine-tunerSkill
- ai-ml-model-optimization-guideSkill
- ai-ml-nlp-pipeline-designerSkill
- api-gateway-kong-api-gatewaySkill
- The first 60 shown.
Does it work?
Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.
Reviews can't be read right now.
Your trail
Files you open will collect here, so you can find them again.
Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.
Now do this for your own.
Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.

