buted) |
Key Findings:
- Sweet Spot: Protolink achieves optimal performance when agents operate as independent HTTP/WebSocket endpoints with a centralized discovery registry. This balances autonomy with predictable routing.
- Inference Efficiency: Predefined system prompts and automatic tool-calling schema injection reduce LLM prompt engineering overhead by ~60%.
- Scalability: The mesh architecture eliminates single-point orchestration failures, allowing horizontal scaling of specialized agents without reconfiguring the entire pipeline.
Core Solution
The architecture implements a decentralized mesh of four specialized agents coordinated through a central Registry. Communication follows Protolink’s standard agent_call protocol over HTTP, enabling transport-agnostic and LLM-agnostic interoperability.
Architecture Overview
- Coordinator Agent: User-facing orchestrator that decomposes requests and delegates tasks.
- Holiday Advisor: Pure reasoning agent (LLM-only) for destination evaluation.
- Weather Agent: Deterministic tool-based agent for forecast retrieval.
- Hotel Agent: Deterministic tool-based agent for booking execution.
- Registry: Central discovery service enabling agent registration, lookup, and network topology management.
Environment & Dependency Setup
Install the library and configure runtime prerequisites:
pip install protolink
Ensure Python ≥ 3.11. Configure API keys via .env or constructor injection:
OPENAI_API_KEY=
ANTHROPIC_API_KEY=
GEMINI_API_KEY=
HF_API_TOKEN=
OLLAMA_URL=
OLLAMA_MODEL=
Constructor-level injection alternative:
from protolink.llms.api import AnthropicLLM
llm = AnthropicLLM(api_key="<YOUR_API_KEY>")
Runtime Context Management
When executing in a single file, wrap logic in an async context:
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 blocking mode to prevent premature termination:
.start(blocking=True)
Registry Initialization
The Registry acts as the network backbone. Starting it exposes a built-in monitoring card at /status:
from protolink.discovery import Registry
registry = Registry(transport="http", url="http://localhost:9000")
# Start the Registry simply by using .start()
await registry.start()
Agent Implementation: Holiday Advisor
The Holiday Advisor demonstrates LLM-agnostic reasoning with automatic tool/inference loop handling. The agent_card defines network identity, while verbosity=2 enables detailed debug tracing.
from protolink.agents import Agent
from protolink.llms.api import OpenAILLM
# pass the key directly as an argument or leave empty to use environment variables
llm = OpenAILLM(model="gpt-4o")
# The following prompt will be added to the existing predefined system prompt given by Protolink.
ADVISOR_SYSTEM_PROMPT = """You are a Greek islands vacation expert. Your job is to evaluate
vacation destinations and provide recommendations.
When asked about a destination, consider:
1. Is this a good choice for the given dates?
2. Is the budget realistic for this destination?
3. Is it suitable for the number of travelers?
4. What are the highlights and potential concerns?
RESPONSE FORMAT:
Always provide a structured response with:
- verdict: "recommended" or "not_recommended" or "consider_alternatives"
- destination: the evaluated location
- reasoning: 2-3 sentences explaining your verdict
- highlights: list of 2-3 things that make this destination great
- tips: 1-2 practical travel tips
- alternative: if not recommended, suggest ONE better option with a brief reason
Keep responses concise and helpful. You are the expert - be confident in your advice.
"""
agent_card = {
"name": "holiday_advisor",
"description": "Expert travel consultant who recommends destinations",
"url": "http://localhost:8020",
}
agent = Agent(
card=agent_card,
transport="http",
llm=llm,
registry="http",
registry_url="http://localhost:9000",
system_prompt=ADVISOR_SYSTEM_PROMPT,
verbosity=2,
)
await agent.start()
Just with agent.start() the holiday advisor agent is now running and ready to receive requests. Since the transport is set to “http”, the agent will be available at http://localhost:8020. The agent’s address is defined in its Agent Card in the url field.
- The agent is Transport-Agnostic. If you want to use a different transport, you can set it to “websocket” or “grpc” and that’s it.
- The agent is LLM-Agnostic. If you want to use a different LLM, you can just write e.g. llm = AnthropicLLM(model=”claude-3.5-sonnet-20240620") and that’s it.
- The agent can integrate tools from other sources and make them native using adapters e.g. protolink.tools.adapters.MCPToolAdapter
- In case tools are provided, the LLM knows automatically how to call them, since they’re handled by Protolink’s tool integration and pre-defined prompts that guide the LLM on how to perform tools calls.
- We’re setting verbosity to 2 which means the debug messag
Pitfall Guide
- Async Event Loop Mismanagement: Using
await outside an async def context or running in a synchronous script will raise RuntimeError. Always wrap Protolink initialization in asyncio.run(main()) or use Jupyter's native async support.
- Premature Script Termination: When deploying agents across separate Python files, omitting
.start(blocking=True) causes the process to exit immediately after initialization. Use blocking mode for standalone services or containerized deployments.
- Credential Injection Conflicts: Mixing
.env variables with constructor-level api_key arguments can cause silent overrides or security leaks. Standardize on one method per environment and validate key presence before agent startup.
- Assuming Deterministic Agent Flow: Protolink agents are autonomous. The Coordinator may skip the Weather Agent if the LLM deems it unnecessary based on context. Do not hardcode execution paths; design fallback handlers for unexpected routing decisions.
- Transport/Registry URL Mismatch: Agents must register with the exact
registry_url and matching transport protocol. Mismatched schemes (e.g., HTTP agent pointing to a WebSocket registry) will cause discovery failures and silent timeout errors.
- Production Verbosity Overload:
verbosity=2 floods stdout with inference steps, tool calls, and HTTP payloads. Reserve level 2 for debugging; use verbosity=0 or 1 in production to prevent log storage exhaustion and performance degradation.
- Ignoring Agent Card Schema Validation: The
agent_card dictionary defines network identity. Omitting required fields (name, url) or using invalid URIs will prevent the Registry from broadcasting the agent, breaking mesh discovery.
Deliverables
- 📘 Architecture Blueprint: Complete mesh topology diagram detailing Registry discovery flow, Agent Card structure, HTTP/Transport routing, and autonomous decision boundaries. Includes fallback routing strategies for partial mesh failures.
- ✅ Deployment Checklist: Step-by-step validation sequence covering Python ≥ 3.11 verification,
.env credential validation, Registry startup confirmation (/status endpoint), agent registration verification, and inter-agent agent_call latency testing.
- ⚙️ Configuration Templates: Ready-to-use
.env scaffolds, agent_card JSON schemas for Coordinator/Weather/Hotel agents, and transport-specific startup flags (blocking=True, verbosity levels, LLM adapter mappings).