This is Part 3 of the Enterprise Intelligence Platform Playbook series. Part 1 made the case for building an AI platform before building agents and introduced the eight-layer architecture. Part 2 translated those layers into a deployable topology with open-source tooling. Part 3 answers the question: who builds and owns each layer?

The greatest misconception about enterprise AI is that it is an application problem. It is not. It is an operating model problem. You cannot bolt AI onto an organization designed to process transactions and expect it to produce intelligence. The organization itself must evolve.
Platform Engineering teams already exist in most mature organizations. They own Kubernetes, CI/CD, cloud infrastructure, observability, security, and developer experience. But enterprise AI introduces capabilities that do not fit neatly into any existing team. Model gateways are not infrastructure. Context pipelines are not data engineering. Decision logic is not application code.
Traditional Platform Engineering standardized software delivery. Enterprise AI however must standardize enterprise decision making.
For this, new disciplines are required. We will call the new role Enterprise Intelligence Engineering for the sake of the remainder of this article.
| Traditional Platform Engineering | Enterprise Intelligence Engineering |
|---|---|
| Infrastructure | Context |
| APIs | Decisions |
| Microservices | Actions |
| CI/CD | Intelligence Lifecycle |
| Monitoring | Evaluation |
| Runbooks | Decision Models |
Discipline 1: Context Engineering
Most organizations treat enterprise knowledge as documents. Documents optimized for storage. Intelligent organizations using AI must optimize for information retrieval, which is where context is paramount. Context Engineering must therefore be treated as managed infrastructure.
The difference is not cosmetic. Documents are created, stored, and retrieved by humans. Infrastructure is designed, versioned, tested, monitored, and continuously improved. When knowledge is infrastructure, it has SLOs. It has deployment pipelines. It has automated quality gates. It degrades gracefully and alerts when it cannot.
What Context Engineering Owns
The Context Engineering team owns Layers 2 and 3 of the reference architecture - Enterprise Memory and Context. Their remit includes:
Memory architecture. Working memory for active sessions, conversational memory for multi-turn interactions, task memory for long-running workflows, operational memory for system state, historical memory for patterns and trends, and organizational memory for institutional knowledge. Each has different durability, retrieval latency, and consistency requirements.
Data ingestion and sync pipelines. Real-time Change Data Capture from source systems, vector embedding synchronization that re-embeds only deltas, data deduplication and conflict resolution, and data freshness SLOs that tell consuming agents how current each piece of context is. The pipeline ensures the Context Fabric does not degrade into stale, conflicting information.
Retrieval infrastructure. Vector databases, hybrid search, embedding pipelines, chunking strategies, re-ranking models, and cache layers. The team decides how documents are ingested, chunked, embedded, and stored. They own the precision and recall of enterprise retrieval.
Context assembly. Dynamic retrieval that selects the right information for each request. Context ranking that prioritizes relevant over peripheral information. Policy filtering that excludes information the requester should not see. Identity-aware retrieval that tailors context to the user or agent. Temporal relevance that ensures stale information is demoted.
Context quality. This is the most important and most overlooked responsibility. Context quality determines AI output quality more than model selection does. The team measures retrieval precision, context grounding rates, hallucination reduction attributable to context, and context freshness. They treat context quality as an SLO.
Memory Architecture: A Deep Dive
The memory architecture is not a single store. It is a hierarchy of specialized stores, each optimized for a different access pattern:

Each memory tier has different characteristics:
| Memory Tier | Store | Latency | Durability | Access Pattern |
|---|---|---|---|---|
| Working | Redis | < 1ms | Ephemeral | Read/write per request |
| Conversational | Redis + PostgreSQL | < 5ms | 24 hours | Read-heavy, append-only |
| Task | PostgreSQL | < 10ms | Permanent | Read/write during workflow |
| Operational | PostgreSQL + Qdrant | < 20ms | Permanent | Read-heavy, periodic write |
| Historical | MinIO + Trino | < 500ms | Permanent | Write-once, read-rarely |
| Organizational | Neo4j + Qdrant | < 50ms | Permanent | Read-heavy, versioned |
The Context Assembly Pipeline
When an agent requests context, the Context Engineering infrastructure executes a multi-stage pipeline:
1. INTENT PARSING
1.1 Extract entities, intent, and scope from request
1.2 Determine which memory tiers to query
1.3 Apply identity-based access filters
2. PARALLEL RETRIEVAL
2.1 Vector search (Qdrant): semantic similarity
2.2 Graph traversal (Neo4j): relationship queries
2.3 Relational query (PostgreSQL): structured state
2.4 Cache check (Redis): recently retrieved context
3. RANKING AND SCORING
3.1 Relevance score (embedding similarity)
3.2 Freshness score (time since last update)
3.3 Authority score (source reliability)
3.4 Access score (permission level)
3.5 Composite score = weighted combination
4. COMPRESSION AND ASSEMBLY
4.1 Deduplicate across sources
4.2 Truncate to token budget
4.3 Preserve high-ranking items
4.4 Add freshness metadata
4.5 Format for consumption
5. POLICY FILTERING
5.1 Remove items requester cannot access
5.2 Apply data classification rules
5.3 Enforce regulatory constraints (GDPR, HIPAA)
5.4 Log access for audit trail
6. DELIVERY
6.1 Return Context Object with metadata
6.2 Include: sources, timestamps, confidence, freshness
6.3 Log retrieval metrics for quality monitoring
Code Example: Context Retrieval
Click to expand code
class ContextFabric:
def __init__(self, qdrant, neo4j, postgres, redis, trino):
self.vector_db = qdrant
self.graph_db = neo4j
self.relational_db = postgres
self.cache = redis
self.historical = trino
async def resolve_context(self, request: ContextRequest) -> ContextObject:
# Step 1: Check cache
cached = await self.cache.get(f"context:{request.hash}")
if not cached.is_stale():
return cached
# Step 2: Parallel retrieval
results = await asyncio.gather(
self.vector_db.search(
collection=request.collection,
query_vector=request.embedding,
filter=request.access_filter,
limit=20
),
self.graph_db.query(
"""
MATCH (n)-[r]->(m)
WHERE n.id IN $entity_ids
RETURN n, r, m
""",
entity_ids=request.entity_ids
),
self.relational_db.query(
"""
SELECT * FROM business_objects
WHERE id = ANY($ids)
AND classification <= $access_level
""",
ids=request.object_ids,
access_level=request.access_level
)
)
# Step 3: Rank and score
ranked = self.rank_results(
vector_results=results[0],
graph_results=results[1],
relational_results=results[2],
weights=request.ranking_weights
)
# Step 4: Compress to token budget
compressed = self.compress(
ranked_results=ranked,
max_tokens=request.max_tokens
)
# Step 5: Build context object
context = ContextObject(
items=compressed,
metadata={
"sources": [r.source for r in compressed],
"freshness": [r.timestamp for r in compressed],
"confidence": [r.score for r in compressed],
"token_count": sum(r.tokens for r in compressed)
}
)
# Step 6: Cache for future requests
await self.cache.set(
f"context:{request.hash}",
context,
ttl=300 # 5 minutes
)
return context
Business Objects by Industry
The business objects Context Engineering models vary by industry:
| Industry | Business Objects | Relationships | State Dimensions |
|---|---|---|---|
| Retail | Customer, Store, Cart, Inventory, Warehouse, Order, Shipment, Promotion | Customer→Order→Shipment, Store→Inventory→Warehouse | Cart: active/abandoned, Order: pending/fulfilled, Inventory: available/reserved |
| Telecom | Subscriber, SIM, MSISDN, Plan, Cell Tower, Network Slice, Region | Subscriber→SIM→Plan, Cell Tower→Region→Network Slice | SIM: active/suspended, Tower: healthy/degraded, Slice: provisioned/throttled |
| Banking | Customer, Account, Card, Loan, Mortgage, Transaction | Customer→Account→Card, Account→Loan→Transaction | Account: active/frozen, Loan: current/delinquent, Card: active/blocked |
| Manufacturing | Factory, Machine, Production Line, Material, Work Order | Factory→Line→Machine, Work Order→Material→Supplier | Machine: running/maintenance, Line: active/idle, Work Order: queued/in-progress |
| Healthcare | Patient, Doctor, Diagnosis, Medication, Appointment | Patient→Diagnosis→Medication, Doctor→Appointment→Patient | Patient: admitted/discharged, Medication: active/discontinued, Appointment: scheduled/completed |
A Context Engineer working in telecom models a Cell Tower as a single object connected to its region, affected subscribers, active tickets, and SLA exposure. A Context Engineer in retail models an Order connected to its customer, inventory reservations, shipment status, and payment state. The discipline is the same. The objects change.
Context Quality Metrics
Context quality determines AI output quality. The Context Engineering team tracks these metrics:
| Metric | Definition | Target | How to Measure |
|---|---|---|---|
| Retrieval Precision | Relevant items / Total retrieved items | > 80% | Human evaluation of sampled retrievals |
| Context Grounding | Agent outputs traceable to context | > 95% | Automated trace analysis |
| Freshness Compliance | Items within SLO freshness | > 99% | Timestamp comparison against SLO |
| Hallucination Reduction | Hallucinations prevented by context | > 70% | A/B testing with/without context |
| Access Violation Rate | Unauthorized context delivered | 0% | Policy violation logging |
| Retrieval Latency (p95) | Time to assemble context | < 200ms | Distributed tracing |
| Cost per Retrieval | Infrastructure cost per context request | < $0.001 | Cost allocation tracking |
Why Context Engineering Must Be a Dedicated Discipline
Without a dedicated team, context becomes everyone’s problem and no one’s responsibility. Every agent team builds its own retrieval pipeline, chunking strategy, and vector store. None of them interoperate. None of them share retrieval infrastructure. None of them invest in context quality because each team has only one or two agents.
A centralized Context Engineering team serves every agent in the organization. They invest in retrieval infrastructure once. They build evaluation pipelines for context quality. They create golden paths for agent teams to consume context without understanding vector databases.
The ratio that works: one Context Engineer supports four to six agent teams. The leverage comes from building retrieval infrastructure once and reusing it across every agent.
Common Context Engineering Mistakes
| Mistake | Symptom | Fix |
|---|---|---|
| No freshness SLOs | Agents make decisions on stale data | Define freshness per object type, enforce via metadata |
| No access filtering | Agents see data they should not | Add identity-aware retrieval, policy filtering |
| Oversized context | Token budget exceeded, latency high | Implement compression, ranking, truncation |
| No quality metrics | Cannot measure if context is good | Build evaluation pipeline, track precision/recall |
| Duplicate retrieval pipelines | Every team builds their own | Centralize Context Engineering, provide golden paths |
| Ignoring temporal relevance | Old data ranks equally with new | Add freshness scoring, time-decay weighting |
Discipline 2: Decision Engineering
Decision Engineering is the most overlooked discipline in enterprise AI. Most organizations embed business logic directly into prompts. This is the equivalent of writing business logic in HTML - it works until it needs to be tested, versioned, reused, or audited.
Decision Engineering treats reasoning as software. Business logic, policies, constraints, and decision models become versioned artifacts with tests, deployment pipelines, and monitoring.
What Decision Engineering Owns
The Decision Engineering team owns Layer 4 of the reference architecture - the Decision Fabric. Their remit includes:
Business reasoning models. Structured decision logic that separates what the organization knows from how it reasons. These models encode business rules, regulatory constraints, optimization objectives, and risk tolerances. They are versioned, tested, and deployed independently from any agent or model.
Policy evaluation. Decision-time enforcement of business policies. Not policies written in documents and audited quarterly, but policies encoded in software and enforced on every decision. Policy evaluation covers regulatory compliance, risk appetite, delegation rules, escalation thresholds, and approval requirements.
Constraint solving and optimization. When a decision involves tradeoffs - maximize revenue within risk tolerance, minimize cost within SLA requirements, optimize resource allocation under budget constraints - the decision fabric solves the optimization problem explicitly rather than relying on the model to approximate it.
Decision traceability. Every decision records who initiated it, what context was used, which policies were evaluated, which constraints applied, which model executed, which human approved, and what outcome occurred. Traceability is not optional. It is a prerequisite for audit, learning, and accountability.
Approval workflows. Decisions that exceed an agent’s authority escalate to humans. The decision fabric routes these to the right person with the right context, tracks the outcome, and feeds the result back into the learning loop.
The Decision Model Architecture
A decision model is not a single rule. It is a structured artifact with inputs, logic, outputs, and metadata:

Code Example: Decision Model
Click to expand code
class DecisionModel:
def __init__(self, version: str, rules: List[Rule], policies: List[Policy]):
self.version = version
self.rules = rules
self.policies = policies
self.trace = DecisionTrace()
def evaluate(self, context: ContextObject, objects: List[BusinessObject]) -> Decision:
self.trace = DecisionTrace()
# Step 1: Check pre-conditions
if not self.check_preconditions(context, objects):
return Decision(
status="NOT_APPLICABLE",
reason="Pre-conditions not met",
trace=self.trace
)
# Step 2: Evaluate business rules
rule_results = []
for rule in self.rules:
result = rule.evaluate(context, objects)
rule_results.append(result)
self.trace.add_rule(rule.id, result)
# Step 3: Check policies
policy_results = []
for policy in self.policies:
result = policy.evaluate(context, objects)
policy_results.append(result)
self.trace.add_policy(policy.id, result)
# Step 4: Aggregate results
decision = self.aggregate(rule_results, policy_results)
# Step 5: Check confidence threshold
if decision.confidence < self.confidence_threshold:
decision = Decision(
status="ESCALATE",
reason=f"Confidence {decision.confidence} below threshold",
confidence=decision.confidence,
trace=self.trace
)
# Step 6: Log for traceability
self.log_decision(context, objects, decision)
return decision
def aggregate(self, rule_results, policy_results) -> Decision:
# Any policy violation = REJECT
for policy in policy_results:
if policy.status == "VIOLATED":
return Decision(
status="REJECT",
reason=f"Policy violation: {policy.id}",
confidence=1.0
)
# All rules must pass for APPROVE
failed_rules = [r for r in rule_results if not r.passed]
if failed_rules:
return Decision(
status="REJECT",
reason=f"Failed rules: {[r.id for r in failed_rules]}",
confidence=0.9
)
return Decision(
status="APPROVE",
reason="All rules and policies satisfied",
confidence=1.0
)
Decision Types by Industry
The decisions Decision Engineering models vary by industry. See the Decision Catalogue in Part 2 for the full specification:
| Industry | Decisions | Rules Source | Compliance Requirements |
|---|---|---|---|
| Retail | Approve Refund, Replenish Inventory, Optimize Price, Select Carrier | Return policy, Inventory thresholds, Pricing algorithms, Carrier SLAs | Consumer protection, Tax regulations, Data privacy |
| Telecom | Activate SIM, Scale Network, Prioritize Incident, Allocate Bandwidth | Activation rules, Capacity thresholds, SLA matrices, QoS policies | Telecom regulations, Spectrum licensing, Data retention |
| Banking | Approve Loan, Block Card, Detect Fraud, Authorize Payment | Credit scoring, Fraud patterns, Transaction limits, Authentication rules | KYC/AML, PCI-DSS, Basel III, Consumer lending regulations |
| Manufacturing | Replace Machine, Order Materials, Schedule Production, Accept Defect | Maintenance schedules, Supply contracts, Capacity planning, Quality thresholds | Safety regulations, Environmental compliance, Industry standards |
| Healthcare | Recommend Treatment, Approve Claim, Prioritize Patient, Authorize Referral | Clinical guidelines, Insurance rules, Acuity scoring, Referral protocols | HIPAA, FDA regulations, Clinical trial requirements |
Each decision encodes the business rules, regulatory constraints, risk thresholds, and escalation policies specific to that industry. A loan approval decision in banking encodes LTV ratios and credit scores. An inventory replenishment decision in retail encodes lead times and safety stock. The decision model is versioned, tested, and auditable independent of any agent or LLM.
Decision Testing
Decision models must be tested like software:
Click to expand code
class TestRefundDecision:
def setup(self):
self.model = RefundDecisionModel(version="1.2.0")
def test_approve_within_window(self):
context = ContextObject(
request={"order_id": "123", "reason": "defective"}
)
objects = [
Order(id="123", days_since_delivery=5, status="delivered"),
Customer(id="C1", tier="gold", return_history="clean")
]
decision = self.model.evaluate(context, objects)
assert decision.status == "APPROVE"
assert decision.confidence > 0.9
def test_reject_outside_window(self):
context = ContextObject(
request={"order_id": "456", "reason": "changed mind"}
)
objects = [
Order(id="456", days_since_delivery=45, status="delivered"),
Customer(id="C2", tier="standard", return_history="clean")
]
decision = self.model.evaluate(context, objects)
assert decision.status == "REJECT"
assert "outside_return_window" in decision.reason
def test_escalate_high_value(self):
context = ContextObject(
request={"order_id": "789", "reason": "defective"}
)
objects = [
Order(id="789", days_since_delivery=3, status="delivered", value=5000),
Customer(id="C3", tier="standard", return_history="clean")
]
decision = self.model.evaluate(context, objects)
assert decision.status == "ESCALATE"
assert "high_value" in decision.reason
The Problem with Prompts as Business Logic
Prompts are great for instructing a model. They are terrible for encoding business logic. Prompts cannot be unit tested. They cannot be versioned reliably. They cannot be shared across agents without duplication. They cannot be audited without manual review. They degrade silently when models change.
Decision Engineering solves this by extracting business logic from prompts and reifying it as software. The prompt becomes thin. It instructs the model how to reason, but the rules, constraints, and policies it reasons over live in the decision fabric. When a regulation changes, you update the decision model, not every prompt that references the regulation.
Decision Engineering Metrics
| Metric | Definition | Target | How to Measure |
|---|---|---|---|
| Decision Accuracy | Correct decisions / Total decisions | > 95% | Sampling and human review |
| Policy Compliance | Decisions following all policies | 100% | Automated policy check |
| Traceability Coverage | Decisions with complete traces | 100% | Audit log analysis |
| Escalation Rate | Decisions escalated to humans | < 10% | Count escalations / total |
| Decision Latency (p95) | Time to reach decision | < 500ms | Distributed tracing |
| Model Drift Detection | Decision pattern changes over time | Alert on > 5% shift | Statistical monitoring |
| Test Coverage | Decision models with tests | > 90% | Code coverage analysis |
Discipline 3: Action Engineering
Most architectures expose tools. Action Engineering exposes business capabilities. The difference is critical.
A tool is an API endpoint. It does one thing. It has inputs and outputs. It executes when called. An action is a business capability that may orchestrate dozens of technical operations, handle errors, retry failures, enforce policies, and report outcomes. “Recover Production Service” is not a tool. It is an action that coordinates restarts, drain operations, Terraform execution, incident updates, engineer notifications, health checks, and ticket closures.
What Action Engineering Owns
The Action Engineering team owns Layer 5 of the reference architecture - the Action Fabric. Their remit includes:
Action definitions. Each action is defined by its business outcome, its preconditions, its execution plan, its rollback procedure, its policy constraints, and its success criteria. Actions are versioned, documented, and discoverable through a registry.
Idempotency and safety. Actions that execute autonomously must be safe to retry and safe to roll back. The Action Engineering team designs each action to handle partial failures, network interruptions, and concurrent invocations. They build idempotency keys and state machines that prevent duplicate execution from causing harm.
Observability for actions. Each action emits telemetry about its execution: duration, success or failure, resources consumed, policies violated, rollbacks triggered, and business outcome achieved. This telemetry feeds the observability and learning layers of the reference architecture.
Action registry. A catalog of every business capability exposed to agents, with metadata about what each action does, what preconditions it requires, what permissions it needs, which teams own it, and what its SLOs are. Agents discover actions through the registry. Governance enforces that agents can only call actions within their declared scope.
Security boundaries. Actions enforce authorization at runtime. An agent cannot call an action outside its scope. An action cannot access resources outside its own authorization. The Action Engineering team designs these boundaries to be defense-in-depth - enforced at the action layer, at the network layer, and at the resource layer.
The Action Definition Schema
Every action follows a structured definition:
Click to expand code
action:
name: "ProcessRefund"
version: "1.3.0"
owner: "payments-team"
description: "Process a customer refund through payment gateway"
preconditions:
- type: "policy_check"
policy: "refund_eligibility_v2"
- type: "identity_check"
required_role: "customer_service_agent"
- type: "state_check"
entity: "order"
expected_state: "delivered"
inputs:
- name: "order_id"
type: "string"
required: true
- name: "reason"
type: "enum"
values: ["defective", "wrong_item", "changed_mind", "other"]
required: true
- name: "amount"
type: "decimal"
required: false
default: "order.total"
execution_plan:
- step: "validate_order"
tool: "order_service.validate"
timeout: "5s"
retries: 2
- step: "check_eligibility"
tool: "policy_engine.evaluate"
timeout: "2s"
retries: 1
- step: "process_payment"
tool: "payment_gateway.refund"
timeout: "30s"
retries: 3
idempotency_key: "refund_{order_id}_{timestamp}"
- step: "update_inventory"
tool: "inventory_service.restore"
timeout: "10s"
retries: 2
- step: "notify_customer"
tool: "notification_service.send"
template: "refund_processed"
timeout: "5s"
retries: 1
- step: "log_decision"
tool: "audit_service.log"
timeout: "2s"
retries: 1
rollback_plan:
- step: "reverse_payment"
tool: "payment_gateway.charge"
condition: "step_failed(process_payment)"
- step: "notify_failure"
tool: "notification_service.send"
template: "refund_failed"
success_criteria:
- "payment_gateway.refund.status == 'SUCCESS'"
- "inventory_service.restore.status == 'SUCCESS'"
- "notification_service.send.status == 'SUCCESS'"
observability:
metrics:
- "action_duration_seconds"
- "action_success_total"
- "action_failure_total"
- "action_rollback_total"
traces:
- "action_id"
- "order_id"
- "customer_id"
logs:
- level: "info"
message: "Refund processed for order {order_id}"
- level: "error"
message: "Refund failed for order {order_id}"
condition: "status == 'FAILED'"
Code Example: Action Execution
Click to expand code
class ActionExecutor:
def __init__(self, registry: ActionRegistry, temporal: TemporalClient):
self.registry = registry
self.temporal = temporal
async def execute(self, action_name: str, inputs: dict) -> ActionResult:
# Step 1: Look up action definition
action_def = self.registry.get(action_name)
if not action_def:
raise ActionNotFoundError(action_name)
# Step 2: Check preconditions
for precondition in action_def.preconditions:
if not await self.check_precondition(precondition, inputs):
return ActionResult(
status="PRECONDITION_FAILED",
reason=f"Precondition failed: {precondition.type}"
)
# Step 3: Create idempotency key
idempotency_key = self.generate_idempotency_key(action_name, inputs)
# Step 4: Check for duplicate execution
existing = await self.check_idempotency(idempotency_key)
if existing:
return existing
# Step 5: Execute via Temporal workflow
workflow_id = f"action-{action_name}-{idempotency_key}"
result = await self.temporal.execute_workflow(
workflow_id=workflow_id,
workflow_type="ActionWorkflow",
input=ActionWorkflowInput(
action=action_def,
inputs=inputs,
idempotency_key=idempotency_key
),
timeout=action_def.timeout
)
# Step 6: Log result
await self.log_execution(action_name, inputs, result)
return result
async def execute_step(self, step: ExecutionStep, context: dict) -> StepResult:
try:
# Execute with timeout
result = await asyncio.wait_for(
self.execute_tool(step.tool, context),
timeout=step.timeout
)
return StepResult(
step=step.name,
status="SUCCESS",
output=result
)
except asyncio.TimeoutError:
# Retry if retries remain
if step.retries > 0:
step.retries -= 1
return await self.execute_step(step, context)
return StepResult(
step=step.name,
status="TIMEOUT",
error="Execution timed out"
)
except Exception as e:
# Handle failure
if step.retries > 0:
step.retries -= 1
return await self.execute_step(step, context)
return StepResult(
step=step.name,
status="FAILED",
error=str(e)
)
Actions by Industry
The actions Action Engineering exposes vary by industry:
| Industry | Actions | Complexity | Orchestration |
|---|---|---|---|
| Retail | Reserve Stock, Issue Refund, Ship Order, Apply Promotion | Medium | Payment + Inventory + Notification |
| Telecom | Provision Subscriber, Restart Network Node, Assign Engineer, Update Billing | High | Activation + Billing + Network + Notification |
| Banking | Transfer Funds, Freeze Account, Generate Statement, Issue Card | High | Auth + Ledger + Compliance + Notification |
| Manufacturing | Create Work Order, Shutdown Line, Dispatch Maintenance, Update Inventory | High | ERP + MES + IoT + Notification |
| Healthcare | Schedule Appointment, Generate Prescription, Admit Patient, Send Referral | High | EHR + Billing + Insurance + Notification |
Each action orchestrates multiple technical operations behind a single business capability. “Provision Subscriber” in telecom activates the SIM, updates billing, triggers a welcome message, logs compliance, and notifies the customer. “Issue Refund” in retail checks return policy, validates the purchase, processes the payment reversal, updates inventory, and notifies the customer. The agent asks for the business outcome. Action Engineering handles the rest.
Tools vs. Actions: A Comparison
| Dimension | Tool | Action |
|---|---|---|
| Scope | Single API call | Business capability |
| Orchestration | None | Multi-step workflow |
| Error handling | Caller handles | Self-healing with rollback |
| Idempotency | Optional | Required |
| Observability | Basic logging | Full trace + metrics |
| Security | Per-call auth | Scope-based authorization |
| Versioning | API versioning | Semantic versioning |
| Documentation | OpenAPI spec | Business outcome + technical plan |
A tool sends an email. An action executes customer communication - it selects the right template, populates it with context, applies compliance checks, routes through approval if needed, sends, tracks delivery, logs for audit, and reports outcome.
A tool runs a database query. An action generates a compliance report - it assembles data from multiple sources, applies aggregation rules, formats for the requester, checks data freshness, caches the result, and notifies the requester when complete.
Agents should reason in business language: “notify the customer,” “generate the report,” “recover the service.” Actions translate business language into technical execution. This is the enterprise equivalent of a system call.
Action Safety Patterns
| Pattern | Description | When to Use |
|---|---|---|
| Idempotency Key | Prevent duplicate execution | All state-changing actions |
| Circuit Breaker | Stop execution on repeated failures | External service calls |
| Compensation | Reverse completed steps on failure | Multi-step workflows |
| Dead Letter Queue | Capture failed actions for retry | Async processing |
| Rate Limiting | Throttle execution frequency | External API calls |
| Timeout | Kill execution after deadline | All actions |
| Human-in-the-Loop | Pause for approval before execution | Destructive actions |
Action Engineering Metrics
| Metric | Definition | Target | How to Measure |
|---|---|---|---|
| Action Success Rate | Successful executions / Total | > 99% | Execution logging |
| Action Latency (p95) | Time to complete action | < 5s | Distributed tracing |
| Rollback Rate | Rollbacks / Total executions | < 1% | Execution logging |
| Idempotency Violations | Duplicate executions prevented | 0 | Idempotency check logging |
| Security Violations | Unauthorized action attempts | 0 | Auth logging |
| Action Coverage | Actions with complete definitions | 100% | Registry analysis |
| SLO Compliance | Actions meeting SLO targets | > 99% | SLI/SLO monitoring |
How the Three Disciplines Work Together
Context Engineering answers: “What does the enterprise know?”
Decision Engineering answers: “What should the enterprise decide?”
Action Engineering answers: “What should the enterprise do?”
Together they form the core of the Enterprise Intelligence Platform team:

Each discipline feeds the next. Context informs decisions. Decisions select actions. Actions produce outcomes. Outcomes flow back as learning that improves context, decisions, and actions.
Organizational Placement
The Enterprise Intelligence Platform team is not an ML team. It is not an infrastructure team. It is a new function that sits alongside existing platform disciplines:
| Existing Tech Platform | Intelligence Platform | Reports To |
|---|---|---|
| Cloud Engineering | Context Engineering | VP Platform |
| Infrastructure Engineering | Decision Engineering | VP Platform |
| API Gateway Team | Action Engineering | VP Platform |
| Security Engineering | Trust Plane | VP Security |
| Observability Team | Intelligence Observability | VP Platform |
In practice, the Intelligence Platform team starts with 3-5 people and grows to one engineer per discipline for every four to six agent teams. The ratio mirrors what Platform Engineering learned: a small, focused platform team creates more leverage than the agent teams it supports.
The team reports to the same engineering leadership as the existing Platform Engineering organization. This is critical. If the Intelligence Platform reports to an AI applications team, it becomes subservient to that team’s roadmap. If it reports to Platform Engineering, it serves the entire organization.
Common Organizational Mistakes
The most common mistakes when standing up Enterprise Intelligence Engineering: placing the team under an AI Applications group instead of Platform Engineering, which limits scope to one team’s roadmap. Not creating dedicated discipline teams, which forces every agent team to build its own retrieval pipeline and decision logic. Getting the ratio wrong - you need one platform engineer per discipline for every four to six agent teams. Not planning for hiring, because these are new roles that cannot be backfilled by existing ML engineers or data engineers without retraining. Ignoring feedback loops, which means the platform never learns from its own outcomes.
What I’ve Learned
Context is the new infrastructure. The quality of your AI output depends more on context quality than model selection. Treat context as managed infrastructure with SLOs, deployment pipelines, and quality gates.
Business logic does not belong in prompts. Extract rules, policies, and constraints into versioned, testable decision models. Prompts should instruct reasoning, not encode business logic.
Actions are business capabilities, not API calls. Design actions around business outcomes, with idempotency, safety, observability, and security built in. Agents reason in business language. Actions execute in technical reality.
The three disciplines must be designed as one system. Context feeds decisions. Decisions select actions. Actions produce outcomes that feed back into context and decisions. Breaking this cycle creates fragmentation.
The Intelligence Platform team serves every agent, not one team. Place it alongside existing platform disciplines with organization-wide scope. The ratio is one platform engineer per discipline for every four to six agent teams.
Context Engineering, Decision Engineering, and Action Engineering are new roles. You cannot backfill them with existing ML engineers, data engineers, or platform engineers without retraining. Invest in the skills or hire for them.
Metrics are non-negotiable. You cannot improve what you cannot measure. Build quality metrics into every discipline from day one. Context precision, decision accuracy, action success rate - these are your SLOs.
The feedback loop is the platform’s intelligence. Every decision and outcome becomes data that improves future decisions. Without the feedback loop, you have automation. With it, you have intelligence.
You have the architecture. You have the disciplines. Now the question is: can you operate it reliably at scale?
Part 4 of the Enterprise Intelligence Platform Playbook covers the AI Decision Pipeline - how you standardize enterprise intelligence at scale.