Software Architecture and the Age of Agentic AI
Dashboards and reports
Analysts bring context from experience
Batch-friendly — nightly refreshes are fine
Forgives ambiguity — humans interpret
Humans smell bad data
Autonomous action — not just display
Context must be explicit and encoded
Real-time — stale data causes wrong actions
Zero ambiguity — agents take everything literally
Errors cascade silently
"The bottleneck is no longer the model — it's the architecture of your data."
Agents can't smell bad data
Trusted
Auditing autonomous agents
Traceable Governed
Teaching agents what your data means
Contextual
Agent-ready data access patterns
Operational
"What's the current price for Product X?"
"This price doesn't look right — didn't we update it last week?"
Humans have a smell test. They notice when data feels stale, when numbers look off, when something doesn't add up.
Agents have no smell test. They act on stale data with the same confidence as fresh data.
Every step was "correct." The data was the problem.
apiVersion: v3.1.0
kind: DataContract
id: product-pricing
name: Product Pricing
version: 1.0.0
status: active
schema:
- name: product_pricing
physicalType: TABLE
properties:
- name: product_id
logicalType: string
required: true
primaryKey: true
- name: price
logicalType: decimal
required: true
quality:
- type: custom
expression: "price > 0"
- name: currency
logicalType: string
required: true
quality:
- type: library
metric: invalidValues
arguments:
validValues: [USD, EUR, GBP]
mustBe: 0
- name: updated_at
logicalType: timestamp
required: true
slaProperties:
- property: freshness
value: "24"
unit: hours # Must be < 24h for agents
Types, nullability, constraints — no guessing
Max staleness per dataset — nightly batch ≠ real-time agent
Validated in CI/CD — deployment blocked on failure
For agents, schema IS law — null values corrupt vector embeddings, stale data causes wrong actions.
Circuit breaker for data — bad data never reaches the agent
Better for an agent to say "I don't know" than to act on bad data.
The agent gets silence instead of poison. That's a feature, not a bug.
Raw → validated → certified → agent-optimized
Immutable ingestion. Full audit trail and lineage preserved.
Deduplicated, schema-applied. Contract-validated for agent retrieval.
Semantic layer applied. Governed access, trusted metrics.
Agents monitor queries, materialize optimized datasets.
Agents as active participants in data curation, not just consumers. They monitor frequent query patterns and materialize optimized views.
Agents should only access Gold or above. Bronze and Silver exist for lineage and debugging — never for agent consumption.
Price data is 3 days stale.
Freshness SLA: 24 hours → violated.
Confidence drops below threshold.
"I'm not confident this price is current. Routing to a human for verification."
Key insight: Thresholds should be based on data quality signals (freshness, completeness, consistency) — not just model confidence.
Not every decision needs a human. Not every decision should skip one.
For every dataset agents touch, specify max staleness. Nightly batch ≠ real-time agent. A pricing dataset that's fine at 24h for dashboards may need <1h for a quoting agent.
Validate before ingestion. Dead letter queue for violations. Never feed bad data to agents. Start with your highest-risk datasets.
Define contracts as code. Validate in CI/CD. Block deployments on contract violations. Version your contracts alongside your schemas.
When data quality signals are low, defer to human review instead of autonomous action. Start with a high threshold (90%) and adjust down as trust builds.
Next up: Agents act on quality data — but who's watching? → Traceability & Governance
Agent processes letter of credit: checks customer KYC, verifies compliance rules, approves $2.4M transaction — all in 30 seconds.
A regulator asks: "Why was this approved?"
Can you answer with full reasoning chains? Or just timestamps and table names?
"What" happened — which tables were accessed, timestamps, user IDs
"Why" — which sources did the agent consult, what reasoning chain led to the decision, what alternatives were considered and rejected
The gap between these two is where regulatory risk lives.
Not just "what was accessed" — but "WHY the agent decided to access it"
End-to-end agent workflow, like a distributed request
Individual steps — data access, reasoning, decisions
Confidence scores, reasoning chains, sources consulted
Automatically log events (Art. 12) — traceable, not just timestamps
Retain 6+ months (Art. 19) — full audit trail with decision context
Explain "why" — which data sources, what logic, what alternatives were considered
Not just EU — similar regulations emerging in US (NIST AI RMF), UK, Singapore
Trust is earned, not assumed
Agent recommends, human decides. Full logging of what agent would have done.
Agent acts, human approves before execution. Full audit trail.
Agent acts within defined boundaries. Alerts on exceptions.
Agent acts independently. Continuous monitoring, spot-check audits.
Like onboarding a new employee. You don't give them the corporate credit card on day one.
New hire starts with supervision, earns autonomy as trust builds. Same principle for agents.
• More trust — proven reliability at the previous level
• More observability — increasing monitoring scope
• More governance — stronger audit trails and controls
Agent uses shared credentials
Accesses all customer data
Persistent tokens — never expire
"Who did this?" — no attribution
Agent inherits user's permissions
Scoped access — only Alice's data
Short-lived token — expires after task
Full attribution — who, what, why
Agents inherit invoking user's permissions, not broad service accounts
Short-lived tokens issued per task, expire on completion
Minimum access needed for the specific task — nothing more
Add traces and spans to every agent workflow. Use Langfuse, Arize, or OpenTelemetry. Retrofitting observability is 10x harder than building it in.
Deploy agents that recommend but don't act. Build the audit trail before you need it. Measure accuracy before granting autonomy.
Agents inherit user permissions, not service accounts. Issue JIT credentials for every task. No persistent tokens.
Design audit trails to answer "why did the agent do this?" not just "what did the agent do?" Think EU AI Act Article 12.
Next up: Now that data is trusted and governed, agents need context. → Semantic Layers
"What was Q3 revenue for Product X?"
→ Which table to query
→ Gross sales or net of returns?
→ What "Q3" maps to in your fiscal calendar
→ Which joins connect products → orders → revenue
Two years of institutional knowledge, absorbed through osmosis, tribal docs, and Slack threads.
Your agent has none of it.
A declarative translation layer between business language and data
How "revenue" is calculated — order_amount - discount_amount
How customers → orders → products connect — join paths, foreign keys, cardinality
Fiscal calendars, access controls, valid dimensions per metric, time grains
Version-controlled Peer-reviewed CI/CD testable
Change "revenue" once → propagates everywhere
semantic_models:
- name: orders
entities:
- name: order_id
type: primary
- name: customer_id
type: foreign
measures:
- name: revenue
agg: sum
expr: order_amount - discount_amount
dimensions:
- name: order_date
type: time
type_params:
time_granularity: day
"What was Q3 revenue for Product X?"
SELECT SUM(order_amount - discount_amount)
FROM orders o
JOIN products p ON o.product_id = p.id
WHERE p.name = 'Product X'
AND o.order_date
BETWEEN '2025-07-01'
AND '2025-09-30'
dbt MetricFlow — similar patterns in Cube.js, Snowflake Semantic Views, Databricks Metric Views
"What was Q3 revenue for Product X?"
-- Agent guesses table names
SELECT SUM(amount)
FROM sales_data
WHERE product = 'Product X'
AND quarter = 'Q3'
Wrong table · Uses gross amount not net · No fiscal calendar mapping · Missing join to products
-- Constrained by metric definition
SELECT SUM(order_amount
- discount_amount)
FROM orders o
JOIN products p
ON o.product_id = p.id
WHERE p.name = 'Product X'
AND o.order_date
BETWEEN '2025-07-01'
AND '2025-09-30'
Correct table · Net revenue formula · Fiscal Q3 resolved · Valid join path
The semantic layer constrains the LLM — only valid dimensions appear for selected metrics. That's a feature, not a bug.
Identify your top 10-15 business metrics. Document how they're actually calculated today. You'll find 2-3 conflicting definitions for the important ones.
Pick a tool that fits your stack:
dbt → MetricFlow
Standalone → Cube.js
Snowflake → Semantic Views
Connect via MCP server or API. The agent queries the semantic layer, never the raw schema.
Ask ambiguous terms, edge cases, cross-domain joins. Every hallucination = a gap in your semantic definitions.
Anti-pattern: Don't boil the ocean — start with the metrics your first use case needs, not a full warehouse model.
When relationships matter more than metrics
"Which customers bought Product X but churned after we changed the pricing in Q2?"
Multi-hop reasoning across entities, events, and time — flat tables can't answer this.
3 entities · 2 relationships · multi-hop traversal
Semantic layers → structured metrics | Knowledge graphs → relationship reasoning | Together → institutional memory
Next up: Agents understand your data — but can they act on it? → From Searchable to Actionable
"I see that all the payments for the PO's are not yet received for Party Foo."
RAG can search documents — it retrieves the right troubleshooting guide.
But it can't query live systems to check if the PO's are actually received for Party Foo right now.
And it can't take action — no ticket creation, no status update, no workflow trigger.
Agentic AI needs data that's not just searchable — it's actionable.
Three tiers — most organizations are stuck at Tier 1
RAG, vector search, document lookup
PO System: retrieve troubleshooting guide
Live APIs, database reads, service status
PO System: check payment status NOW
Create records, trigger workflows, update state
PO System: create helpdesk ticket
Most orgs are stuck at Tier 1. Agentic AI requires all three.
"One protocol to connect any AI model to any data source or tool."
Official MCP SDKs, early 2026 (from ~2M/mo at launch)
Community and vendor-built integrations
Joined Dec 2025 (hosted by Linux Foundation) — open governance
Adopted by:
Anthropic OpenAI AWS Google MicrosoftExpose data for agents to read. Structured, discoverable, schema-described.
PO System: troubleshooting docs, config data
Reusable interaction patterns. Shape how agents approach tasks.
PO System: IT triage workflow template
Functions agents can invoke. Real-world side effects.
check_po_payment_status()create_ticket()
Risk escalates left to right: safe → shapes behavior → real-world consequences
Thoughtworks Technology Radar Vol. 33 — HOLD · Design capabilities, not endpoints.
# 50 REST endpoints = 50 MCP tools
@tool def get_po_payment_status_chicago(): ...
@tool def get_po_payment_status_nyc(): ...
@tool def get_po_payment_status_london(): ...
@tool def create_po_payment_ticket(): ...
@tool def create_po_payment_ticket_network(): ...
# ... 44 more tools
50 tools → agent can't choose correctly
No business context · Tool sprawl kills accuracy
# 3 capabilities with rich descriptions
@tool
def check_service_status(
service: str, location: str
) -> ServiceStatus:
"""Check real-time health of any
infra service by name & location."""
@tool
def create_support_ticket(
category: str, priority: str
) -> Ticket: ...
3 tools → clear agent decisions
Rich descriptions · Parameterized · Composable
LLMs are bad at choosing from large tool sets. 5-10 well-described capabilities beat 50 thin wrappers.
"Build with any framework. Equip with MCP. Communicate with A2A."
MCP = vertical (agent ↔ tools) | A2A = horizontal (agent ↔ agents)
check_po_payment_status()create_po_payment_ticket()3 data tiers. 2 MCP primitives. 1 coherent action. ~30s vs ~45min manual.
Pick your top 3 agent use cases. For each, classify what's needed: read-only retrieval, real-time structured access, or write-back actions. Most gaps are in Tiers 2 and 3.
Group your APIs into 5-10 business capabilities with rich descriptions. Think "what can this agent do?" not "what endpoints exist?"
Read-only first — lowest risk, immediate value. Expose knowledge bases and configuration data. Graduate to Tools only after governance is in place.
Log every tool invocation: who triggered it, what was called, when, and on behalf of whom. You'll need this for audit and debugging.
We've covered all four pillars. Next → The reference architecture that ties it all together.
Every layer depends on the one below it
Semantic layers are the highest-ROI investment. The <20% → 95%+ accuracy gap isn't about the model — it's about the context you give it.
Start with MCP Resources (read-only), graduate to Tools (write) with governance. Staged autonomy, not all-or-nothing.
Freshness SLAs, schema enforcement, quarantine bad data. Agents can't smell bad data — your architecture has to.
Traces and spans in every agent workflow. Retrofitting observability is 10x harder. Build for the regulator before they ask.
"When agents become your primary data consumers, the architecture of your data IS the architecture of your AI."