Central bottleneck) | Critical |
| Protolink Mesh Architecture | Low (Modular plugins) | High (Any LLM/Local/Cloud) | High (HTTP/gRPC/Custom) | Low (Direct A2A routing) | None |
Key Findings:
- Zero Vendor Lock-in: Swap LLMs, transports, or storage backends without rewriting agent logic.
- Native A2A Extension: Agents can leverage each other's reasoning capabilities and tools directly, bypassing unnecessary serialization overhead.
- Built-in Observability: Automatic HTTP/CSS/JS status cards expose runtime metrics, agent registration states, and mesh topology without external monitoring stacks.
- Deterministic + Generative Hybridization: Pure reasoning agents (LLM-only) and deterministic agents (Tool-only) coexist seamlessly in the same mesh.
Core Solution
The vacation booking system implements a four-agent mesh coordinated by a central Registry. Agents communicate via Protolink's standard agent_call protocol over HTTP, enabling local or distributed deployment.
1. Architecture Overview
- Coordinator Agent: User-facing orchestrator (LLM + Tools). Decomposes requests and delegates tasks.
- Holiday Advisor: Pure reasoning agent (LLM). Evaluates destinations and travel preferences.
- Weather Agent: Deterministic agent (Tools). Fetches and processes weather forecasts.
- Hotel Agent: Deterministic agent (Tools). Executes booking logic and availability checks.
- Registry: Central discovery service. Agents register and query the mesh via HTTP transport.
2. Environment & Dependency Setup
Install Protolink (Python β₯ 3.11 required):
pip install protolink
3. Execution Context & Async Handling
Protolink relies on asynchronous execution. When running all agents in a single file, wrap the logic in an async def block:
import asyncio
from dotenv import load_dotenv
load_dotenv(".env")
async def main():
<PUT CODE HERE>
...
if __name__ == "__main__":
asyncio.run(main())
For distributed deployments (separate scripts per agent), use .start(blocking=True) to maintain the runtime lifecycle:
# In separate agent scripts
agent.start(blocking=True)
4. LLM Configuration & API Management
Configure credentials via .env or pass directly to the LLM constructor. Protolink supports multiple providers out-of-the-box:
OPENAI_API_KEY=
ANTHROPIC_API_KEY=
GEMINI_API_KEY=
HF_API_TOKEN=
OLLAMA_URL=
OLLAMA_MODEL=
Direct instantiation example:
from protolink.llms.api import AnthropicLLM
llm = AnthropicLLM(api_key="<YOUR_API_KEY>")
Supported LLM modules:
protolink.llms.api: OpenAILLM, AnthropicLLM, GeminiLLM, DeepSeekLLM, GrokLLM
protolink.llms.server: OllamaLLM
protolink.llms.local: TBD
Custom LLM wrappers can be implemented by overriding call and call_stream methods. Base class reference: protolink/llms/base.py.
5. Registry Initialization & Mesh Discovery
Start the Registry to enable agent discovery and network mapping:
from protolink.discovery import Registry
registry = Registry(transport="http", url="http://localhost:9000")
# Start the Registry simply by using .start()
await registry.start()
Built-in Observability: Starting the Registry or any agent with HTTP transport automatically exposes a monitoring card at /status. Access http://localhost:9000/status in your browser to view real-time mesh topology, agent registration states, and communication health.
6. Agent Communication Flow
All agents register with the Registry and expose an Agent Card containing capability metadata, available tools, and LLM configurations. The Coordinator routes requests using the agent_call protocol, allowing direct tool invocation or LLM delegation across the mesh without intermediate orchestration layers.
(Note: The original guide references a flowchart illustrating the agent_call protocol routing. The mesh operates on direct peer-to-peer HTTP calls after initial Registry discovery.)
Pitfall Guide
- Async Context Misalignment: Using
await outside an async def block or mixing synchronous and asynchronous runtimes will cause RuntimeError. Always wrap Protolink initialization and agent calls in an async context or use asyncio.run().
- Blocking vs Non-Blocking Runtime Management: Running agents in separate scripts without
.start(blocking=True) causes the process to exit immediately after initialization. Use blocking mode for standalone services; omit it for Jupyter notebooks or single-file orchestrations.
- Environment Variable Resolution Failures: Protolink's LLM constructors fall back to
.env variables. If keys are missing or misnamed, initialization fails silently or throws authentication errors. Validate .env placement in the script's working directory or explicitly pass keys via constructor arguments.
- Registry Port Conflicts: The default Registry URL (
http://localhost:9000) may clash with existing services. Always verify port availability or override the url parameter during Registry instantiation.
- Over-Engineering Agent Communication: Attempting to implement custom HTTP routing or message serialization bypasses Protolink's native
agent_call protocol. Rely on the built-in discovery and routing mechanisms; only extend communication schemes when base A2A limitations are encountered.
- Ignoring Built-in Observability: Deploying without monitoring the
/status endpoint leads to blind failures during agent registration or tool invocation. Use the auto-generated HTTP/CSS/JS cards to validate mesh topology and agent health before routing production traffic.
Deliverables
π Architecture Blueprint
- Mesh topology diagram mapping Coordinator β Advisor/Weather/Hotel agents
- Registry discovery flow and Agent Card schema structure
- A2A protocol extension points for custom tool/LLM delegation
β
Deployment Checklist
βοΈ Configuration Templates
.env credential mapping (OpenAI, Anthropic, Gemini, Ollama, HF)
- LLM constructor patterns (API key injection vs environment fallback)
- Registry & Agent startup snippets (single-file async vs distributed blocking)
- Custom LLM wrapper skeleton (
call/call_stream override template)