How to Build an Agentic Hotel PMS: Multi-Agent Architecture Explained
A technical guide to designing a multi-agent hotel PMS from scratch — agent boundaries, tool design, handoff patterns, and PMS integration.
TL;DR
Building an agentic hotel PMS requires careful agent decomposition, tool design, handoff logic, and PMS integration. Here is the architecture blueprint, drawn from CallSphere's production 11-agent stack.
Why Multi-Agent?
A monolithic "super agent" trying to handle every hotel workflow fails in production. Problems:
flowchart TD
START(["How to Build an Agentic Hotel PMS:<br/>Multi-Agent Architecture Explained"])
S0["TL;DR"]
START --> S0
S1["Why Multi-Agent?"]
S0 --> S1
S2["Agent Decomposition Principles"]
S1 --> S2
S3["Tool Design"]
S2 --> S3
S4["Handoff Contracts"]
S3 --> S4
S5["PMS Integration Layer"]
S4 --> S5
S6["Guardrails"]
S5 --> S6
S7["Observability"]
S6 --> S7
DONE(["Key Takeaways"])
S7 --> DONE
style START fill:#4f46e5,stroke:#4338ca,color:#fff
style DONE fill:#059669,stroke:#047857,color:#fff
- Tool call explosion (40+ tools in one context)
- Policy drift across domains
- Handoff confusion
- Hallucinations on rarely-used tools
- Debugging nightmare
Multi-agent decomposition solves these by giving each agent a narrow domain.
Agent Decomposition Principles
- One agent per primary business domain (reservation, check-in, housekeeping, etc.)
- Shared context via typed state (not just conversation history)
- Explicit handoff contracts (each handoff includes required context)
- Tool specialization (tools live with the agent that owns them)
- Clear escalation paths (every agent can escalate to human)
Tool Design
Tools should be:
- Idempotent where possible (safe to retry)
- Strongly typed (JSON schema enforcement)
- Observable (all tool calls logged)
- Rate-limited per tenant
Example tool schema for create_reservation:
{
name: "create_reservation",
description: "Create a confirmed reservation in the PMS",
parameters: {
guest_id: "string",
check_in: "ISO 8601 date",
check_out: "ISO 8601 date",
room_type: "enum: standard|deluxe|suite",
rate_plan: "string",
payment_token: "string (Stripe token)"
},
returns: {
reservation_id: "string",
confirmation_number: "string"
}
}
Handoff Contracts
Each handoff includes:
flowchart LR
S0["TL;DR"]
S1["Why Multi-Agent?"]
S0 --> S1
S2["Agent Decomposition<br/>Principles"]
S1 --> S2
S3["Tool Design"]
S2 --> S3
S4["Handoff Contracts"]
S3 --> S4
S5["PMS Integration Layer"]
S4 --> S5
DONE(["Done"])
S5 --> DONE
style S0 fill:#4f46e5,stroke:#4338ca,color:#fff
style DONE fill:#059669,stroke:#047857,color:#fff
- Current agent's summary of conversation
- Required context for receiving agent
- Open tool calls to complete
- Guest profile state
Example handoff from Concierge to Reservation:
{
"from": "concierge",
"to": "reservation",
"context": {
"guest_phone": "+15551234567",
"guest_name": "John Smith",
"loyalty_tier": "Gold",
"intent": "book_room",
"dates_mentioned": ["2026-05-15", "2026-05-17"],
"language": "en"
}
}
PMS Integration Layer
Build a PMS abstraction layer so agent code is PMS-agnostic:
See AI Voice Agents Handle Real Calls
Book a free demo or calculate how much you can save with AI voice automation.
[Agents] -> [PMS Abstraction] -> [Opera|Mews|Cloudbeds|ASI adapters]
Each adapter implements the same interface (create_reservation, update_folio, get_room_status, etc.) but translates to the specific PMS API.
Guardrails
Multi-layer guardrails:
- Input guardrails: language validation, intent confidence threshold
- Tool guardrails: schema enforcement, rate limiting, policy checks
- Output guardrails: hallucination detection, policy compliance
- Human escalation: when any guardrail fails
Observability
Log every:
flowchart TD
HUB(("How to Build an<br/>Agentic"))
HUB --> L0["TL;DR"]
style L0 fill:#e0e7ff,stroke:#6366f1,color:#1e293b
HUB --> L1["Why Multi-Agent?"]
style L1 fill:#e0e7ff,stroke:#6366f1,color:#1e293b
HUB --> L2["Agent Decomposition<br/>Principles"]
style L2 fill:#e0e7ff,stroke:#6366f1,color:#1e293b
HUB --> L3["Tool Design"]
style L3 fill:#e0e7ff,stroke:#6366f1,color:#1e293b
HUB --> L4["Handoff Contracts"]
style L4 fill:#e0e7ff,stroke:#6366f1,color:#1e293b
HUB --> L5["PMS Integration Layer"]
style L5 fill:#e0e7ff,stroke:#6366f1,color:#1e293b
HUB --> L6["Guardrails"]
style L6 fill:#e0e7ff,stroke:#6366f1,color:#1e293b
style HUB fill:#4f46e5,stroke:#4338ca,color:#fff
- Agent activation
- Tool call (with parameters and result)
- Handoff (with context payload)
- User utterance + agent response
- Guardrail trigger
Feed into LangSmith, Langfuse, or a custom observability stack.
Deployment
Production deployment uses:
- Containerized agents (Docker/Kubernetes)
- Stateless message-queue orchestration (NATS or Kafka)
- Persistent conversation state (PostgreSQL)
- Redis for low-latency state cache
- ChromaDB / Pinecone for RAG
FAQ
Q: How many agents is too many? A: Depends on domain. Hotels benefit from ~10–12 agents. Fewer = monolithic, more = handoff chaos.
Q: Can I use LangGraph instead of OpenAI Agents SDK? A: Yes. LangGraph, CrewAI, AutoGen all work.
Q: What's the biggest production pitfall? A: Handoff context loss. Invest in typed context contracts.
Related: CallSphere hotel stack | Hotel industry
#Architecture #MultiAgent #Design #CallSphere
Try CallSphere AI Voice Agents
See how AI voice agents work for your industry. Live demo available -- no signup required.