Skip to content

Experts & routing

An expert is a teammate who can answer questions — the routing target when the knowledge base comes up empty. Each expert has roles, skills, and an availability state. When an agent calls ask_expert and the question misses the knowledge base, Halyard uses those attributes plus the person’s Slack identity to pick someone and deliver the question. Slack is the human side of the loop.

AttributeWhat it isExample values
rolesWhat the person does, stored as lowercase free text"engineer", "pm", "architect", "product manager"
skillsDomains they’re strong in, stored as Title-Case names"React", "System Design", "Product Strategy"
availabilityWhether they can take a question nowONLINE, AWAY, DND

list_team(role?, skill?, available_only?) returns the roster:

{
"status": "success",
"count": 8,
"match_type": "unfiltered",
"members": [
{
"id": "4fbca6b9-…",
"name": "Priya Sharma",
"roles": ["pm", "product manager"],
"skills": ["Product Strategy", "Roadmapping", "Analytics"],
"availability": "ONLINE"
},
{
"id": "1ed79467-…",
"name": "David Kim",
"roles": ["engineer"],
"skills": ["React", "TypeScript", "Accessibility"],
"availability": "ONLINE"
},
{
"id": "779ac70a-…",
"name": "James Okonkwo",
"roles": ["architect", "engineer"],
"skills": ["System Design", "Cloud Architecture", "Security"],
"availability": "ONLINE"
}
]
}

When ask_expert misses the knowledge base, it selects an expert by combining:

  1. Role / skill match — narrow to people who fit the question. An agent steers this by passing role or skill to ask_expert.
  2. Availability — prefer people who can answer now over those who are AWAY or DND.
  3. Slack identity — the chosen expert must have a linked Slack account so the question can be delivered.

Over-constraining is the usual failure: ask for a role and a skill that no one online matches, and routing finds no one. Loosen the filters or drop to a single attribute.

ask_expert(prompt, role?, skill?) [knowledge base misses]
-> Halyard DMs a matching expert in Slack
-> agent polls check_response(conversation_id, wait?) [wait blocks ≤ 55s]
-> expert replies in Slack
-> reply_to_expert / get_conversation as needed
-> summarize_conversation(conversation_id, question, answer) [captured to knowledge]

The expert answers in Slack — the place they already work — and the agent captures the reply back into the knowledge base, so the next agent that asks the same thing resolves it from memory instead of interrupting the person again.

Every member also has an accessRoleADMIN or MEMBER. This governs permissions in Halyard (for example, get_delivery_metrics is admin-only), not who answers questions. A MEMBER can be an expert; an ADMIN may never be routed a single question. Keep the two axes separate: accessRole is about what you can do, roles / skills are about what you can answer.