Pattern 03 — Basic Agent vs. Governed Agent
Uncontrolled agents are the prototype trap at its worst: they work in demos and cause incidents in production. This pattern shows how to add governance, observability, and hop limits without changing the agent logic.
❌ Before — The Ungoverned Agent
flowchart TD
User["User Request"]
LLM["LLM\n(planning + reasoning)"]
T1["Tool: send_email()"]
T2["Tool: query_database()"]
T3["Tool: call_external_api()"]
Resp["Response\n(unaudited)"]
User --> LLM
LLM -->|"unbounded tool calls\nno hop limit\nno policy check"| T1
LLM --> T2
LLM --> T3
T1 --> LLM
T2 --> LLM
T3 --> LLM
LLM --> Resp
style User fill:#1e1e2e,stroke:#585b70,color:#cdd6f4
style LLM fill:#313244,stroke:#585b70,color:#cdd6f4
style T1 fill:#3b1219,stroke:#f38ba8,color:#cdd6f4
style T2 fill:#3b1219,stroke:#f38ba8,color:#cdd6f4
style T3 fill:#3b1219,stroke:#f38ba8,color:#cdd6f4
style Resp fill:#313244,stroke:#585b70,color:#cdd6f4
What fails:
- Infinite loops — no hop limit stops recursive tool calls
- No policy on tool calls —
send_email()fires without approval - No audit trail — you can't explain what the agent did
- No observability — failures are opaque
- State leaks across sessions with no boundary
✅ After — The Governed Agent
flowchart TD
User["User Request"]
subgraph Governance["🟣 L01 Governance"]
POL["PolicyEngine\nsubject · resource · action rules"]
PG["PolicyGateway\ntool_call stage"]
AUDIT["Audit Trail\ndecision logging"]
end
subgraph Orchestration["🔵 L08 Orchestration"]
AC["AgentCollaboration\nhop_limit=5\npolicy integration"]
RT["Realtime\nsession lifecycle"]
end
subgraph Tools["🔵 L05 Tool Integration"]
TR["ToolRegistry\ndeclarative definitions"]
T1["send_email()\n→ REQUIRE_APPROVAL"]
T2["query_database()\n→ ALLOW"]
T3["call_external_api()\n→ SANITIZE params"]
end
subgraph Observability["🔵 L02 Observability"]
OBS["ObservabilityService\nagent_span · tool_span\nper-hop tracing"]
end
User --> AC
AC -->|"hop 1"| PG
PG -->|"check: authorize_tool_call()"| POL
POL --> AUDIT
POL -->|"ALLOW"| T2
POL -->|"REQUIRE_APPROVAL"| T1
POL -->|"SANITIZE"| T3
T1 & T2 & T3 -->|"results"| OBS
OBS -->|"traces + audit"| AC
AC -->|"hop limit enforced\nmax 5 iterations"| User
style Governance fill:#1a0d2e,stroke:#cba6f7,color:#cdd6f4
style Orchestration fill:#0d152e,stroke:#89b4fa,color:#cdd6f4
style Tools fill:#0d152e,stroke:#89b4fa,color:#cdd6f4
style Observability fill:#0d1a2e,stroke:#89dceb,color:#cdd6f4
Key additions:
| Component | What it prevents |
|---|---|
AgentCollaboration hop limit |
Infinite recursion and runaway cost |
PolicyGateway tool stage |
Unauthorized tool invocations |
PolicyEngine approval workflow |
send_email firing without human confirmation |
Audit Trail |
Inability to explain agent decisions post-incident |
ObservabilityService |
Invisible tool calls — every hop is a traced span |
ToolRegistry |
Undocumented tool surfaces with no schema validation |
from electripy.ai.agent_collaboration import AgentCollaborationService, CollaborationConfig
from electripy.ai.policy_gateway import PolicyGateway, PolicyStage
gateway = PolicyGateway(rules=tool_policy_rules)
svc = AgentCollaborationService(
config=CollaborationConfig(max_hops=5, policy_gateway=gateway),
)
# Every tool call goes through the policy gateway.
# Every hop is a traced span. Hop limit enforced automatically.
result = svc.run(task=user_request, agents=[planner, executor, reviewer])