Field Notes Blog cover AI-Assisted Development

Using Claude Code as an Agentic Development System: Advisor Agents, Memory, and Deploying to EKS

How I use Claude Code's agent system to build AI systems — with a mandatory Advisor that catches production bugs, persistent memory that compounds across sessions, and a full EKS deployment architecture.

AP
Ashutosh Upadhyay
Platform Engineer | AI/ML Infrastructure | AWS & Kubernetes

Updated 4 October 2026 with technical corrections.

The Meta-Problem: Building AI With AI

I've built and deployed a production multi-agent AI system — 35 tools, 4 specialized agent roles, running on EKS with full Langfuse observability. But here's the meta question: how do you actually build and deploy these systems efficiently?

My answer: treat your development environment itself as an agentic system. I use Claude Code — not as a simple autocomplete, but as a multi-agent development platform with:

Key insight: The same patterns that make your AI system better (adversarial review, specialization, memory) also make your development process better when you apply them to how you use AI coding tools.

The Advisor Agent: Mandatory Architecture Review

The most impactful pattern in my setup is a mandatory Advisor agent — a senior reviewer that runs on a frontier-tier model (Opus) and must be consulted before every significant decision.

# .claude/agents/advisor.md (simplified)
---
name: advisor
description: Senior architecture reviewer. Must be invoked before
  any significant decision, before finalizing plans, and after every
  code change.
model: opus
tools: Read, Grep, Bash  # Bash included for log/status reads; prompt instructs no file writes
---

You are a senior technical reviewer. You receive a structured summary
and give a concrete recommendation. You have read-only access to
verify claims against the actual codebase.

Rules:
- You are a REVIEWER, not an implementer. Never modify files.
- Identify the core risk or assumption being made.
- Flag architectural trade-offs that may not be obvious.
- Give a CONCRETE recommendation, not just pros/cons.
- Point out anything missing that would change your answer.

When the Advisor Must Be Invoked

This isn't optional or "nice to have." I've configured it as a hard rule:

1
Before starting work — before committing to any architecture or implementation approach
2
During work — when encountering recurring errors, unfamiliar APIs, or when changing approach
3
After every code change — before bumping versions or declaring something ready to deploy
4
Before declaring done — the final sanity check before shipping

Why this matters: The Advisor has caught production bugs in changes I considered "trivial" — wrong data types silently corrupting outputs, pre-signed URLs that asked for a 7-day lifetime but would expire with the pod's short-lived IRSA credentials, iframe security headers that would block rendering in production. Every single one of these would have been a production incident.

The Development Workflow: Plan → Question → Implement → Review

Agentic Development Workflow with Advisor Phase 1: PLAN Ask clarifying questions Document approach in markdown Phase 2: QUESTION Second round of questions Refine plan based on answers ADVISOR REVIEW Phase 3: IMPLEMENT (Parallel Subagents) Agent: Task A Backend changes Agent: Task B Frontend changes Agent: Task C K8s manifests Agent: Task D Tests / Docs ADVISOR REVIEW Catches bugs in "trivial" changes Version Bump release checklist Jenkins Build → EKS Memory Persists across sessions feedback + context
Figure 1: The full development workflow — plan, question, implement with parallel agents, mandatory advisor review, then deploy

Persistent Memory: Context That Compounds

One of the most underused features of Claude Code is its persistent memory system. I maintain a structured memory index that carries hard-won knowledge across sessions:

~/.claude/projects/<project>/memory/ ├── MEMORY.md # Index — first 200 lines load each session; topic files on demand ├── user_role.md # Who I am, what I work on ├── feedback_planning.md # "Always ask questions before implementing" ├── feedback_no_auto_commit.md # "Never git push without asking" ├── feedback_image_bump.md # "Run the release checklist; discover files by grep" ├── project_current.md # What version is live, what's pending ├── reference_pricing.md # Claude API pricing (verified, not guessed) └── feedback_conciseness.md # "No verbose output, lead with the answer"

Key memory types and their purpose:

Type What It Stores Why It Matters
Feedback Corrections + confirmed approaches Past corrections are indexed in every session
Project Current state, versions, blockers New sessions start with full context
Reference External resources, API versions, pricing Facts verified once, re-read instead of re-guessed
User Role, expertise level, preferences Explanations tailored to your level

Example: After I got burned 3 times forgetting to update one of 14 files during a version bump, that became a feedback memory. Now every version bump starts from a release checklist that finds the files by grep rather than a remembered count — the memory carries the lesson; the checklist applies it (see Releasing an AI System Is Not Like Releasing Software).

The Full EKS Deployment Architecture

Here's how the complete agentic AI system deploys to production on Amazon EKS:

Production EKS Deployment Architecture Users (Browser) NGINX Ingress + OAuth2 Proxy EKS Cluster (Namespace: ai-agent) SvelteKit UI deployment-ui.yaml | Service FastAPI Orchestrator deployment.yaml | Routes queries to agents Data Scout replicas: 2 Sonnet model Analyst replicas: 1 Sonnet model Synthesizer replicas: 2 Opus model Critic replicas: 1 Opus model CronJobs (Automated Ingestion) Daily: data refresh | Weekly: ontology | Ad-hoc: schema sync Monitoring Stack Langfuse traces | Prometheus metrics | ADOT (OpenTelemetry) AWS Services Bedrock Claude API S3 Data Lake DynamoDB Knowledge Graph Secrets Mgr ExternalSecret IAM (IRSA) SA → IAM Role ConfigMap: model selection, feature flags, cache TTLs Service-to-service: shared-secret auth
Figure 2: Full EKS production architecture — separate deployments per agent role, AWS services via IRSA, automated ingestion CronJobs

Key Kubernetes Patterns

1. Separate Deployment per Agent Role

Each agent role is its own Kubernetes Deployment with its own Service. This gives you:

2. ConfigMap-Driven Model Selection

# configmap.yaml
apiVersion: v1
kind: ConfigMap
metadata:
  name: agent-config
data:
  SCOUT_MODEL: "us.anthropic.claude-sonnet-4-6"
  SYNTHESIZER_MODEL: "us.anthropic.claude-opus-5"
  CRITIC_MODEL: "us.anthropic.claude-opus-5"
  KNOWLEDGE_GRAPH_TABLE: "agent-kg"
  CACHE_TTL_HOURS: "24"
  TOKEN_BUDGET: "10000000"
  LANGFUSE_ENABLED: "true"

Model selection lives in a ConfigMap, not in code. When a new Claude model drops, the model ID is a ConfigMap change, not a code change — but a new model generation can still change the request shape (see the Opus 5 migration), so test the swap before trusting it.

3. IRSA for Zero-Credential Pods

# iam/trust-policy.json (simplified)
{
  "Version": "2012-10-17",
  "Statement": [{
    "Effect": "Allow",
    "Principal": {
      "Federated": "arn:aws:iam::ACCOUNT:oidc-provider/oidc.eks.REGION.amazonaws.com/id/OIDC_ID"
    },
    "Action": "sts:AssumeRoleWithWebIdentity",
    "Condition": {
      "StringEquals": {
        "oidc.eks.REGION.amazonaws.com/id/OIDC_ID:sub": "system:serviceaccount:ai-agent:agent-sa"
      }
    }
  }]
}

Pods assume IAM roles via IRSA (IAM Roles for Service Accounts). No AWS credentials stored anywhere — not in secrets, not in env vars, not in code. The pod's service account maps to an IAM role that grants access to S3, DynamoDB, Bedrock, and Secrets Manager.

4. Automated Data Freshness via CronJobs

# cronjob-auto-ingest.yaml
apiVersion: batch/v1
kind: CronJob
metadata:
  name: daily-data-refresh
spec:
  schedule: "0 6 * * *"  # 6 AM UTC daily
  concurrencyPolicy: Forbid
  jobTemplate:
    spec:
      activeDeadlineSeconds: 21600  # 6-hour timeout
      template:
        spec:
          restartPolicy: OnFailure  # Job pods must be OnFailure or Never
          containers:
            - name: ingest
              image: agent:${VERSION}
              command: ["python", "-m", "agent.jobs.ingest", "--source", "all"]

Langfuse in the Production Stack

Langfuse sits alongside Prometheus and OpenTelemetry as part of the monitoring deployment:

Observability Stack — Three Pillars Prometheus + Grafana Infrastructure metrics Pod CPU / Memory Request latency (p95) Error rates CronJob success/fail Langfuse LLM-specific observability Per-role traces + spans Token cost per query Tool call success rates Quality scoring over time ADOT (OpenTelemetry) Distributed traces Cross-service spans AWS service call latency S3/DynamoDB timing Bedrock API tracking
Figure 3: Three-pillar observability — infra (Prometheus), LLM behavior (Langfuse), distributed traces (OpenTelemetry/ADOT)

The "Build the Builder" Feedback Loop

Here's the meta-pattern that makes all of this compound:

  1. Langfuse traces from the production agent reveal quality issues
  2. Those issues become development tasks in the next session
  3. The Advisor agent reviews the proposed fix
  4. Fix is implemented using parallel subagents
  5. Advisor reviews the implementation and catches edge cases
  6. Version bump (all manifest files) — Advisor verifies nothing was missed
  7. Deploy → Langfuse traces the improvement → loop

Every production observation becomes a development action. Every development session compounds knowledge into memory. The system gets better at building itself.

30
Release Checklist Items
4
Agent Deployments
3
CronJobs (Daily/Weekly/Adhoc)

What I'd Do Differently Starting Today

1. Start with the Advisor pattern from day one

I made the Advisor mandatory after it caught its fourth would-be production bug — each one found before it shipped.

2. Set up Langfuse before writing the first agent

Retrofitting observability is painful. Instrument from the beginning. Even if the first version is one agent with one tool, trace it. The data compounds.

3. Use ConfigMaps for everything that might change

Model names, feature flags, cache TTLs, token budgets — if it might change without a code change, it belongs in a ConfigMap. A model ID swap is a ConfigMap edit; a new model generation can still need a code change.

4. Write the memory system for your future self

Every hard-won lesson — every "oh, I missed that file again" or "that API changed" — goes into persistent memory immediately. Future sessions start where you left off, not from scratch.

The Full Stack — Summary

Layer Technology Purpose
Development Claude Code + Advisor Agent AI-assisted dev with mandatory review
Backend FastAPI + Strands SDK Agent orchestration + tool execution
Frontend SvelteKit Interactive research UI
Models AWS Bedrock (Claude) Tiered: Sonnet (fast) + Opus (reasoning)
Data S3 (Parquet) + DynamoDB Data lake + knowledge graph
Observability Langfuse + Prometheus + ADOT LLM traces + infra metrics + distributed traces
Platform EKS + IRSA + ExternalSecrets Zero-credential, auto-scaling Kubernetes
CI/CD Jenkins + Kustomize Build → push → deploy pipeline
Ingestion K8s CronJobs Automated data freshness

If you're building agentic AI systems, the investment in your development workflow is as important as the system itself. An Advisor that catches bugs before production, memory that compounds lessons, and Langfuse traces that reveal what's actually happening — these aren't luxuries. They're what separate a demo from a production system.

The tools exist. The patterns work. The main barrier is discipline: always invoke the Advisor, always trace with Langfuse, always persist lessons to memory. The compound effect is remarkable.

Follow-up: I evaluated moving this platform to a managed agent runtime — what genuinely improves, what quietly stays your problem, and why a hybrid split was the honest answer — in What a Managed Agent Runtime Actually Changes and EKS or Managed Agent Runtime?

If you're building similar systems or have questions about deploying agents on EKS, feel free to connect.

#ClaudeCode #AgenticAI #EKS #Kubernetes #Langfuse #DevWorkflow #PlatformEngineering #AWSBedrock #AIInProduction
Share

Disclaimer: The views and opinions expressed in this post are my own and do not represent those of my employer or any organisation I am associated with.

Comments & Discussion