Skip to content
🎓 Find your path Subscribe

Inter-Agent Messaging: ask_agent

Tier 3 · Everything Built 6 min read

In a multi-agent system, agents need to ask each other things. A build agent needs to know if the CEO wants a Tauri or Electron approach. A domain agent needs the health status from the health agent. The executive assistant needs to know what the family agent has on the calendar.

ask_agent is the mechanism. One call, one response, any target.


From Python:

from agents.shared.ask_agent import ask
response = ask("health", "What's JD's average resting HR this week?")
response = ask("ceo", "Should we prioritize nexus-desktop or ai-foundry this sprint?")
response = ask("project/leland-coaching", "What's the current blocker?")

From the command line:

Terminal window
python3.12 -m agents.shared.ask_agent health "What's JD's resting HR this week?"
python3.12 -m agents.shared.ask_agent ceo "Review my plan and tell me if I'm missing anything"

The caller passes a target name and a question. It gets a text response back. That’s the full interface.


health, family, growth, ai-foundry, siemens, consulting,
school, life-ops, mba-office ← domain agents (bridge-routed)
ceo ← Opus-context CEO agent (bridge-routed)
project/<slug> ← e.g. "project/leland-coaching" (bridge-routed)
health-expert ← KB-backed health agent (in-process)
merch-expert ← KB-backed merch consultant (in-process)

The target list grows as new agents are registered. The caller doesn’t need to know where the target lives — the router handles it.


Bridge-routed targets (domains, ceo, projects)

Section titled “Bridge-routed targets (domains, ceo, projects)”

ask_agent calls the bridge’s /api/chat/turn endpoint — the same path the cockpit UI uses. It builds a fresh thread per call, injects the target domain’s context as a system prompt (so the health agent “knows it’s the health agent”), and returns the LLM response.

This means ask_agent does not share memory with the live cockpit session for that domain. It spins up a parallel context-aware instance. The file at agents/shared/ask_agent.py is explicit about this:

“For simple factual queries (‘what’s the health status?’, ‘does the CEO want X?’) this is fine. For tasks that need the brain’s accumulated conversation history, use the cockpit UI directly.”

This is the right trade. Sharing live session state across parallel agents would cause the same race conditions that forced worktree isolation for git operations. A separate context, pre-loaded with the domain’s file-based state, handles the common case correctly.

In-process targets (health-expert, merch-expert)

Section titled “In-process targets (health-expert, merch-expert)”

Some targets are KB-backed specialist agents — not domain cockpit sessions but Python packages with their own ask() function. These are dispatched in-process rather than through the bridge:

# Under the hood for ask("health-expert", "...")
from agents.health_expert import ask as health_ask
result = health_ask(question, files=[])

The health expert and merch expert both work this way. They load a knowledge base from ~/clawd/domains/<domain>/state/expert-kb/, inject JD’s goal file, retrieve the most relevant KB sections, and call the LLM with that context. No bridge required, no cockpit session to contend with.


Without ask_agent, inter-agent communication means either:

  1. Files — one agent writes a request file, another polls for it, one reads the response. Workable but asynchronous and requires each pair of agents to agree on a schema.
  2. Shared state — both agents read from the same Supabase table or yaml. Fine for broadcast state (domain reports), awkward for request/response.
  3. Spawning a subprocess — the caller runs python3.12 -m agents.health_expert "question" and reads stdout. Works but doesn’t carry domain context.

ask_agent handles the request/response case cleanly and handles domain context injection automatically. The caller doesn’t manage system prompts or context windows. It asks a question and gets an answer.


The CLAUDE.md rule: agents communicate up or down their chain. Lateral communication (a specialist in the school domain asking a specialist in the health domain directly) should be rare and should go through the orchestrator, not through direct ask_agent calls that skip the chain of command.

In practice, this rule is mostly observed for writes — actions that change state. For reads — “what’s the current status of X?” — direct cross-domain queries via ask_agent are common and cause no harm. The distinction: a question doesn’t change anything; an instruction can.


Next: Fleet of Claudes: Parallel Build Agents — the first parallel-spawn engine: 6 PRs, 48/48 tests, shipped 2026-04-30.