Engineering perspectives
From AI Copilots to Autonomous Agents: How to Architect, Deploy and Govern Agentic AI in Enterprise Environments
Reference architecture and implementation patterns for multi-agent systems integrated with enterprise APIs.
26 February 2026 · 28 min read
Enterprise agentic AI moves beyond single-shot chat completions toward systems that plan, call tools, retrieve context, and coordinate human approvals across bounded workflows. For European CTOs and platform leads, the design question is no longer whether to use a large language model, but how to embed agents into existing identity, data, and change-management boundaries without creating ungoverned automation. This guide explains reference architectures, orchestration patterns, Model Context Protocol (MCP) integration, observability, and rollout checklists suitable for regulated and multi-team environments. Damascode, Digital Agency, Lda supports clients through IT consulting and nearshore software development when agentic capabilities must ship on production-grade platforms.
Table of contents
- Why agentic systems differ from chatbots
- Capability tiers and maturity model
- Reference architecture (logical view)
- Control plane vs data plane
- Orchestration patterns
- Tooling and MCP servers
- Memory, state, and retrieval boundaries
- Human-in-the-loop and approval gates
- Identity, authorization, and tenancy
- Observability and evaluation
- Deployment topologies on Kubernetes
- Implementation sketches (Python and TypeScript)
- Security and governance cross-links
- Rollout checklist
- FAQ
- References
Why agentic systems differ from chatbots
A chatbot optimizes for conversational UX. An agentic system optimizes for task completion under policy: it decomposes goals, selects tools, handles partial failures, and leaves an audit trail. That shift introduces new failure modes: unbounded tool loops, credential leakage through prompts, stale retrieval, and ambiguous accountability when multiple agents collaborate.
| Dimension | Chatbot | Agentic workflow |
|---|---|---|
| Primary output | Natural language | State change + narrative |
| External effects | Usually none | APIs, tickets, infra, data writes |
| Latency profile | Single round trip | Multi-step, seconds to minutes |
| Governance | Content moderation | Tool ACLs, approvals, FinOps caps |
| Testing | Prompt regression | Trajectory + outcome evaluation |
Teams that treat agents as "LLM with plugins" often skip orchestration contracts (timeouts, budgets, idempotency keys) and discover cost and security issues in production. Pair agent design with enterprise AI security and AI-ready data governance from day one.
Capability tiers and maturity model
Use a tier model to set expectations with the board and auditors.
| Tier | Behavior | Typical enterprise fit |
|---|---|---|
| T0 | Retrieval-augmented Q&A, no tools | Internal knowledge, low risk |
| T1 | Read-only tools (search, metrics, CRM read) | Analyst copilots |
| T2 | Constrained writes (create draft, open ticket) | Operations with HITL |
| T3 | Multi-agent coordination, scheduled jobs | Platform automation (strict gates) |
Promotion between tiers requires explicit sign-off: threat modeling, data classification review, and runbooks. Damascode recommends documenting tier per use case in an internal AI register linked from your internal developer platform.
Reference architecture (logical view)
+---------------------+
| Identity / SSO |
+----------+----------+
|
+--------------------+--------------------+
| | |
+------v------+ +------v------+ +------v------+
| Web / API | | Agent | | Admin / |
| Gateway | | Orchestrator| | Policy UI |
+------+------+ +------+------+ +-------------+
| |
| +--------v---------+
| | Planner / Router |
| +--------+---------+
| |
| +-------------+-------------+
| | | |
| +----v----+ +----v----+ +----v----+
| | Worker | | Worker | | Worker |
| | Agent A | | Agent B | | Agent C |
| +----+----+ +----+----+ +----+----+
| | | |
+--------v-------------v-------------v--------+
| Tool Gateway (MCP / HTTP) |
+--------+------+------+--------+
| | |
+------v--+ +-v----+ +v------+
| Vector | | SaaS | | K8s |
| Store | | APIs | | API |
+---------+ +------+ +-------+Agent orchestrator owns session lifecycle, policy enforcement, and correlation IDs. Workers are stateless executors that run one bounded step. Tool gateway centralizes authentication to MCP servers and REST integrations so agents never hold long-lived secrets in prompts.
Control plane vs data plane
Separate concerns early:
| Plane | Responsibilities | Stores |
|---|---|---|
| Control | Policies, tool registry, model routing, feature flags | Config DB, GitOps |
| Data | Prompts, retrieved chunks, tool I/O, embeddings | Ephemeral + encrypted logs |
| Evidence | Traces, evaluations, cost attribution | Observability backend |
The control plane should be GitOps-friendly: tool allow lists, model versions, and max spend per tenant versioned like application code. The data plane must respect retention limits aligned with GDPR and sector rules.
Orchestration patterns
Single orchestrator, multiple workers
One orchestrator delegates to specialized workers (research, coding, approval packaging). Pros: clear audit root. Cons: orchestrator can become a bottleneck; mitigate with horizontal scaling and queue-backed steps.
Supervisor with critic
A supervisor agent assigns tasks; a lightweight critic checks outputs against JSON schema or business rules before commit. Useful for T2 writes where LLM creativity must not bypass validation.
Event-driven agents
Messages on a bus (Kafka, SNS, CloudEvents) trigger agents. Fits ITSM and FinOps automation. Requires idempotent consumers and dead-letter queues.
Human-in-the-loop checkpoints
Mandatory for financial approvals, production changes, and personal data export. Model the checkpoint as a workflow state, not an informal chat message.
START --> PLAN --> [policy check] --> EXECUTE_TOOL
|
fail v
ESCALATE --> HUMAN_APPROVAL --> RESUMETooling and MCP servers
The Model Context Protocol standardizes how applications expose tools, resources, and prompts to models. In enterprise settings, run MCP servers as sidecars or cluster services behind the tool gateway, not on developer laptops only.
| Integration style | When to use | Risk note |
|---|---|---|
| MCP over stdio | Local dev only | Never expose stdio to untrusted users |
| MCP over SSE/HTTP | Shared platform | mTLS, OAuth, network policies |
| Direct REST tools | Legacy systems | Wrap with schema validation |
Register each tool with: owner team, data classification, rate limits, and required scopes. Deny by default; agents receive capability tokens scoped to session and tenant.
Example tool registry entry (illustrative YAML):
tools:
- id: jira.create_issue
mcp_server: mcp-jira-prod
classification: internal
allowed_tiers: [T2]
scopes: [jira:issue:create]
rate_limit_rpm: 30
requires_hitl: true
- id: metrics.query
mcp_server: mcp-observability
classification: operational
allowed_tiers: [T1, T2]
scopes: [prometheus:query:read]
rate_limit_rpm: 120
requires_hitl: falseMemory, state, and retrieval boundaries
Agents need three memory types with different lifetimes:
- Working memory: current plan, tool results (session TTL, hours).
- Organizational memory: embeddings in vector stores with ACL mirroring source systems.
- User preference memory: opt-in, deletable, minimized.
Never pass entire conversation history to every tool call. Summarize with structured state objects:
from dataclasses import dataclass, field
from typing import Any
import json
@dataclass
class AgentSessionState:
goal: str
plan_steps: list[str] = field(default_factory=list)
completed: list[str] = field(default_factory=list)
artifacts: dict[str, Any] = field(default_factory=dict)
token_budget_remaining: int = 8000
def to_context_block(self) -> str:
return json.dumps(
{
"goal": self.goal,
"plan": self.plan_steps,
"done": self.completed,
"artifact_keys": list(self.artifacts.keys()),
},
ensure_ascii=False,
)Retrieval must enforce document-level ACLs at query time, not post-filter in the model. See enterprise data governance for AI-ready data for catalog and lineage patterns.
Human-in-the-loop and approval gates
Define approval types:
| Gate | Trigger | Implementation |
|---|---|---|
| Soft review | Low-risk draft | UI diff, one-click accept |
| Hard approval | Production change | Two-person rule, ticket ID |
| Legal hold | Regulated content | Static workflow, no auto-send |
Store approver identity, timestamp, and input hash with the agent trace. Regulators and customers increasingly ask for decision provenance, not only model version.
Identity, authorization, and tenancy
Agents act on behalf of a user or service principal. Patterns:
- On-behalf-of (OBO): propagate user OAuth token with downscoped scopes.
- Workload identity: agent uses federated identity; human approval binds action to user.
- Break-glass: emergency roles with enhanced logging.
Multi-tenant SaaS must isolate: vector namespaces, tool credentials, prompt templates, and spend quotas per tenant.
Observability and evaluation
Minimum observability stack:
| Signal | Purpose |
|---|---|
| Trace per agent run | Debug multi-step failures |
| Tool latency and errors | SLO for platform team |
| Token and GPU cost | Chargeback, FinOps |
| Outcome labels | Quality regression tests |
Log prompt hashes and retrieved document IDs, not raw secrets. Evaluate with golden trajectories: given goal G and mock tools, expect tool sequence S within tolerance.
Example OpenTelemetry span attributes (conceptual):
span.setAttributes({
"ai.agent.id": "ops-runbook-v2",
"ai.session.id": sessionId,
"ai.model": "gpt-4.1-mini",
"ai.tier": "T2",
"ai.tool.calls": toolCallCount,
"ai.cost.usd_estimate": costUsd,
});Deployment topologies on Kubernetes
Common production layout:
Namespace: ai-platform
+--------------------------------------------------+
| Ingress (WAF) --> API Gateway --> Orchestrator |
| | |
| +---------v----------+ |
| | Agent Worker HPA | |
| +---------+----------+ |
| | |
| +---------v----------+ |
| | MCP Tool Gateway | |
| +----+-----------+---+ |
| | | |
| mcp-jira mcp-k8s mcp-git |
+--------------------------------------------------+
| GPU node pool (optional, inference) |
+--------------------------------------------------+Use dedicated node pools for inference when latency SLOs require it; coordinate capacity with FinOps. NetworkPolicy: workers talk only to gateway and approved MCP hosts.
Helm values fragment (illustrative):
orchestrator:
replicas: 3
resources:
requests: { cpu: "500m", memory: 1Gi }
env:
MAX_STEPS_PER_RUN: "12"
SESSION_TTL_MINUTES: "60"
toolGateway:
mtls:
enabled: true
allowedServers:
- mcp-jira.ai-platform.svc
- mcp-kubernetes.ai-platform.svcImplementation sketches (Python and TypeScript)
Bounded tool loop (Python)
import time
from typing import Callable
ToolFn = Callable[[dict], dict]
def run_agent_loop(
goal: str,
tools: dict[str, ToolFn],
planner,
*,
max_steps: int = 10,
deadline_sec: float = 120.0,
) -> dict:
state = {"goal": goal, "steps": []}
start = time.monotonic()
for step in range(max_steps):
if time.monotonic() - start > deadline_sec:
raise TimeoutError("agent deadline exceeded")
action = planner(state) # returns {"tool": name, "input": {...}}
tool_name = action.get("tool")
if tool_name == "finish":
return action.get("result", state)
if tool_name not in tools:
raise ValueError(f"tool not allowed: {tool_name}")
output = tools[tool_name](action["input"])
state["steps"].append({"tool": tool_name, "output": output})
raise RuntimeError("max steps exceeded")MCP client guardrails (TypeScript)
type ToolCall = { name: string; arguments: Record<string, unknown> };
export async function invokeTool(
registry: Set<string>,
call: ToolCall,
client: { callTool: (n: string, a: Record<string, unknown>) => Promise<unknown> },
): Promise<unknown> {
if (!registry.has(call.name)) {
throw new Error(`Tool ${call.name} is not registered for this agent tier`);
}
const argsJson = JSON.stringify(call.arguments);
if (argsJson.length > 32_000) {
throw new Error("Tool arguments exceed size limit");
}
return client.callTool(call.name, call.arguments);
}These sketches omit vendor SDK details; bind them to your orchestrator's retry, idempotency, and circuit breaker policies.
Security and governance cross-links
Agentic architectures amplify classic AI risks: prompt injection via retrieved content, tool misuse, and excessive agency. Implement defensive controls only: input sanitization, tool allow lists, output filtering, and separation of instruction vs data channels. Detailed mitigations live in enterprise AI security and prompt injection.
Align change management: agent behavior changes when models, tools, or prompts update. Treat prompt and tool registry changes as release artifacts with rollback.
Multi-region and residency
European deployments often require data and inference within specific regions. Agentic systems complicate residency because a single run may touch a model endpoint, vector index, ticket system, and logging backend in different jurisdictions. Document a data flow map per agent tier and block tool calls that would move personal data across non-approved borders.
| Component | Residency decision |
|---|---|
| Model inference | EU region endpoint or on-prem GPU |
| Vector index | Same region as source PII |
| Traces/logs | Redact PII; short retention in EU |
| MCP tools | SaaS vendor DPA and region |
Use geo-DNS or global load balancing only for stateless orchestrators; pin session affinity when conversation state must stay local. Fail closed if a tool returns data from a region outside the tenant allow list.
Model routing and fallback
Production agent platforms rarely bind to one model. Implement a routing table by task type, language, and sensitivity:
routing:
plan_step:
primary: { provider: azure, model: gpt-4.1-mini, region: westeurope }
fallback: { provider: azure, model: gpt-4o-mini, region: northeurope }
synthesis:
primary: { provider: azure, model: gpt-4.1, region: westeurope }
fallback: { provider: none } # queue for human rather than cross-border fallback
embedding:
primary: { provider: internal, model: bge-m3, region: onprem-gpu-1 }Fallback logic must be deterministic code, not model choice. When primary fails (429, timeout), retry with exponential backoff, then degrade to cached retrieval-only answers for T0/T1, never silently switch to a non-compliant region.
Testing agent trajectories
Unit tests alone are insufficient. Maintain a trajectory suite:
| Test type | Input | Assertion |
|---|---|---|
| Happy path | Goal + mock tools | Exact tool sequence and args |
| Injection | Poisoned RAG fixture | No write tools invoked |
| Budget | Long plan | Stops at max_steps |
| Authz | User without role | Tool gateway 403 |
Mock tools record calls without side effects. Run suite on every change to planner prompts, tool registry, or model version. Store traces of failing runs for regression comparison.
def test_support_agent_escalates_on_unknown_refund(mock_tools):
mock_tools.register("crm.lookup", lambda _: {"status": "unknown"})
result = run_agent("process refund for order 991", tools=mock_tools, user_role="support")
assert "escalate" in result["steps"][-1]["tool"]Operational runbooks
Platform on-call needs runbooks distinct from classic microservices:
- Model provider outage: switch to fallback table, enable read-only banner in UI, pause T2 agents.
- Tool gateway degradation: circuit-break per MCP server; queue writes.
- Cost anomaly: identify tenant label, disable feature flag for agent tier, notify FinOps.
- Retrieval lag: switch to keyword-only mode if vector DB unhealthy.
Link runbooks from the internal developer platform catalog so application teams know escalation paths.
Vendor and contract considerations
Enterprise agreements should cover: subprocessors, training opt-out, logging retention, availability SLOs, and security incident notification. For agents, clarify whether tool outputs sent back to the model become logging on vendor side. Legal review pairs with technical minimization (strip PII before model call where possible).
When combining Damascode delivery with your internal platform, define shared responsibility: client owns identity and data classification; delivery squad owns application code and agent policies; platform team owns cluster and gateway SLOs. See software development outsourcing for engagement models.
Rollout checklist
Foundation
- AI use case register with tier (T0-T3) and data classification
- Tool gateway with OAuth/mTLS and centralized secrets
- Identity pattern chosen (OBO vs workload) documented
- Retrieval ACL tests automated
Engineering
- Max steps, deadlines, and token budgets enforced in code
- Structured logging and distributed tracing enabled
- Golden trajectory tests in CI
- HITL flows for all T2+ writes
Operations
- On-call runbook for agent platform
- Cost dashboards and alerts (FinOps guide)
- Incident response includes prompt/tool rollback
- Vendor DPAs and subprocessors reviewed for model APIs
Organization
- Training for product owners on agent limits
- Legal/privacy review for new data sources
- Partner model defined if extending team via software development outsourcing
When internal platform capacity is constrained, contact Damascode or read about our delivery model for architecture reviews and squad augmentation.
FAQ
Should we build one super-agent or many small agents?
Prefer small agents with narrow tools. Compose with an orchestrator. Super-agents are harder to test and secure.
Do we need MCP if we already have REST integrations?
MCP reduces integration drift for AI-native tools but is not mandatory. A gateway with uniform auth and schema validation matters more than the wire format.
How do we prevent runaway costs?
Per-session token caps, model routing (small model for planning, large for synthesis), caching retrieval, and hard stop on step count. Attribute cost by team label in Kubernetes and cloud billing.
Can agents run fully autonomously in production?
Only for low-tier, read-only, or reversible actions with strong monitoring. Production changes and customer-facing commitments need HITL or deterministic automation outside the LLM.
How does this relate to RAG?
Retrieval feeds context; agents decide actions. Governance for embeddings and documents is shared. See the data governance article.
What about multi-cloud?
Keep orchestration portable (Kubernetes, open telemetry). Pin model inference to regions with data residency requirements. Abstract tool gateway endpoints per environment.
How do we version agent behavior for auditors?
Ship immutable bundles: {planner_prompt_hash, tool_registry_version, model_id}. Log that tuple on every completed run. Roll forward and backward as a unit.
Should planners and executors use different models?
Often yes. Smaller models handle routing and tool selection; larger models handle customer-facing synthesis. Measure quality and cost per tier before standardizing.
What is the minimum team to operate agent platform v1?
Typically one platform engineer plus one product engineer part-time, with security review hours booked monthly. Scale with number of tools and tiers, not number of chat users alone.
How do agents interact with existing ITSM change control?
T2+ actions should open or reference change tickets. Tool gateway validates ticket state (approved window) before executing mutating calls.
Adoption patterns by industry
| Industry | High-value agent pattern | Guardrail emphasis |
|---|---|---|
| Financial services | Research copilot, compliance checklist assist | Audit trails, no unapproved trades |
| Healthcare | Clinical admin drafting (non-diagnostic) | Special category data ban in general agents |
| Retail | Returns and order status with read-only ERP | PII minimization, fraud monitoring |
| Manufacturing | Maintenance runbooks with IoT read tools | Safety interlocks, OT network isolation |
| Public sector | Policy Q&A on published corpora only | Transparency, language accessibility |
Start with read-only patterns in regulated sectors; promote to T2 only after legal sign-off and successful eval period.
References
- Model Context Protocol documentation: https://modelcontextprotocol.io/
- NIST AI Risk Management Framework: https://www.nist.gov/itl/ai-risk-management-framework
- OWASP Top 10 for LLM Applications: https://owasp.org/www-project-top-10-for-large-language-model-applications/
- Kubernetes documentation (workloads, NetworkPolicy): https://kubernetes.io/docs/home/
- OpenTelemetry semantic conventions for generative AI (evolving): https://opentelemetry.io/docs/specs/semconv/gen-ai/
- Google Cloud Architecture Center (ML ops patterns): https://cloud.google.com/architecture
- Azure OpenAI / AI architecture guides: https://learn.microsoft.com/en-us/azure/architecture/ai-ml/
- CNCF Cloud Native AI Whitepaper: https://www.cncf.io/reports/
- Related Damascode insights: AI security, data governance, FinOps for AI on Kubernetes, platform engineering IDP
Planning a project in Portugal?
Tell us about your stack, timeline and team setup. We respond on business days.
