7-Layer Agent Platform Architecture: Why Misdiagnosis Happens and How to Fix It

This article defines a 7-layer architecture for self-built Agent platforms, illustrates three real-world misdiagnoses caused by layer confusion, compares four layering approaches, provides a self-check matrix for different product stages, and warns against four common architectural pitfalls.

James' Growth Diary
James' Growth Diary
James' Growth Diary
7-Layer Agent Platform Architecture: Why Misdiagnosis Happens and How to Fix It

Aligning Terminology

The article defines 14 key terms used throughout:

Avatar (分身) — a configured Agent bundling persona, knowledge, and tools.

Workspace (工作区) — the file directory the avatar can read/write.

Release (发布) — pushing the avatar and workspace online.

Container (容器) — the isolated runtime environment.

Orchestration Layer (编排层) — prepares containers, updates files, starts/stops containers.

Runtime (运行时) — the program inside the container that talks to the model and calls tools.

Host (宿主) — the user-facing shell (web, WeCom, CLI, IDE).

Presentation Layer (展示层) — how the same answer renders in different hosts.

Asset (素材) — reusable capabilities: skills, knowledge bases, tool configs.

Container Pool (容器池) — pre-warmed empty containers for instant allocation.

External Capability (对外能力) — OpenAPI, MCP gateway, credentials.

Gateway (网关) — first door for incoming requests, handles auth and routing.

MCP / OpenAPI — two standard interfaces: MCP for avatars calling external tools, OpenAPI for external systems calling avatars.

Common tech terms (BFF, SSE, sidecar, Token, fail-closed) are used without explanation.

Three Misdiagnoses, All Rooted in Layer Confusion

Scene 1: Site Unreachable, Yet Team Tunes Model Params

Symptom: Users report "AI down." First reaction: check model vendor status, tweak params, swap models. Reality: page white-screens or static assets (images, scripts) 404; the chat request never leaves the browser.

Misdiagnosis: Model outage / bad frontend deploy / "whole Agent platform unavailable."

Truth: Stuck at the Traffic Gateway (static files, site entry routing). This layer governs "can the site open" — separate from "which container serves the chat." Debugging the Agent path here is like changing a bulb on an unpowered lamp.

Scene 2: No First Token, But Blaming Frontend SSE

Symptom: Site loads, chat shows endless spinner. Frontend team pulled in to debug SSE, retries, timeouts.

Misdiagnosis: "Streaming flaky again" / "Browser incompatibility."

Truth: Common blockers: Container Pool empty (no free containers / containers not ready) or stuck between Front Gateway → Container Runtime (auth, container selection, first connection). Frontend honestly renders "zero bytes received" as a spinner. Before blaming the presentation layer, ask whether the execution layer has any work.

Scene 3: Tool Call Fails, Yet Team Restarts Chat Runtime

Symptom: Chat works for a couple turns, then internal tool call fails. Someone restarts the container runtime; someone clears session cache.

Misdiagnosis: Runtime broken / session data corrupted.

Truth: Usually stuck at External Capability layer — MCP gateway, Token, auth page. Permissions and identity don't "auto-resolve" in the model, nor are they fixed by restarting the runtime.

Common thread: the architecture diagram had service names but no responsibility layers. Layering keeps you turning the right screw under pressure; mixing layers wastes the golden hour and drags the whole troubleshooting chain off course.

How to Slice: Trade-offs of Four Approaches

How you slice the diagram determines whether you mix layers. Industry uses at least four slicing methods, each with gains and traps.

By Deployment Service (microservice inventory) — aligns with ops; risks missing logical layers, diagram loses fidelity as services split.

By Team Ownership (big-corp matrix) — clear accountability; user path fragmented, cross-team symptoms unowned.

By Request Path (gateway/BFF) — good for troubleshooting; diagram turns into spaghetti, multiple entries blur it.

By Responsibility Layer (chosen) (self-built Agent platform) — clarifies "can chat / can work"; requires discipline: don't say what shouldn't be said, keep naming stable.

"Align with ops" and "align with user path" are fundamentally different. Agent pain lives in cross-deployment responsibility gaps: site-open vs container-enter, workspace-update vs chat-start, token-issue vs tool-loop.

We borrow: troubleshooting intuition from request-path slicing; accountability clarity from team slicing (but pinned to layers, not internal nicknames); cloud-product common sense: traffic entry separate from actual work.

We reject: internal deployment names as public architecture — readers learn nothing, may leak topology; one diagram mixing services, teams, domains — looks info-rich, navigation value zero; "logical layer disappearance" — only container instance names, no responsibility names like External Capability / Orchestration / Runtime.

Public architecture talks responsibility layers; internal troubleshooting maps to concrete services. Public channel covers the former; the latter stays in your code maps.

Seven Layers and Two Boxes That Must Stay Separate

The self-built Agent platform collapses into seven fixed layers, reused all season:

① Access Layer          Browser / WeCom / IDE / CLI / External Systems
② Traffic Gateway       Static assets (images, scripts) + site entry routing (governs "site open")
③ Main Platform         Portal + BFF (avatars, assets, permissions, session entry)
④ External Capability   OpenAPI · MCP Gateway · Token/Auth
⑤ Orchestration         Scheduler / Container Pool (release, sandbox, pre-warmed containers)
⑥ Agent Path            Front Gateway (auth, container select) → Container Runtime
                        (optional add-ons: file distribution / workspace sync / Web IDE)
⑦ Client Tools          Platform CLI · IDE Plugin

Layer ④ is bidirectional : avatars call external tools via MCP (outbound); external systems call avatars via OpenAPI (inbound). Both directions must pass credentials. Named "External Capability" because it doesn't manage the chat itself — only what capabilities the platform exposes, to whom, and on what grounds .

Two judgments worth pinning:

"Open site" and "enter a container for chat" fail in completely different ways → Traffic Gateway and Agent Front Gateway must be two separate boxes . Merging them is the mother of layer confusion.

Portal handles identity, assets, session entry; but the model's repeated tool-call → observe → decide-next-tool loop (tool loop) mostly runs inside the container runtime. Treating the BFF as the workhorse piles state on the wrong layer.

Pushing down: "can work" depends on tool governance, workspace updates, sandbox isolation → layers ④⑤⑥ are the main battlefield for "can work." The minimal chat path ①→③→⑥ only proves "can chat."

When boxes merge, minds merge too. Classic scripts: chat fails → check traffic gateway timeout → increase body limit → zero help; or page 404 → restart container runtime → time gone.

Tag Every Request with a Layer Label

Invariant: every request in tracing must carry "which layer" and "what it intends to do" — no service nicknames. Nicknames change; layers are relatively stable.

TypeScript example defining Layer enum and RequestTag interface with layer, entry (web/im/ide/cli/openapi), intent (open_site/chat/publish/tool/admin). A routeHint function maps intent to expected layer sequence.

// TypeScript
// Rule: every request in logs must write "which layer" + "what it intends to do"
type Layer =
  | "ingress"              // Access: where user comes from
  | "edge_gateway"         // Traffic Gateway: governs site open
  | "platform"             // Main Platform: portal and backend APIs
  | "capability"           // External Capability: OpenAPI and MCP
  | "orchestrator"         // Orchestration: prepare containers, update files
  | "agent_gateway"        // Agent Front Gateway: auth, select container
  | "runtime"              // Runtime: container that actually works
  | "client";              // Client: CLI, IDE plugin

interface RequestTag {
  layer: Layer;
  entry: "web" | "im" | "ide" | "cli" | "openapi";
  intent: "open_site" | "chat" | "publish" | "tool" | "admin";
}

function routeHint(tag: RequestTag): string {
  if (tag.intent === "open_site") return "edge_gateway → platform";
  if (tag.intent === "chat") return "platform → agent_gateway → runtime";
  if (tag.intent === "tool") return "capability → runtime";
  if (tag.intent === "publish") return "platform → orchestrator → runtime workspace";
  return "platform";
}

Python example defines path constants: CHAT_PATH, OPENAPI_CHAT_PATH, PUBLISH_PATH, OPEN_SITE_PATH, and an assert_converge test ensuring web and CLI chat both converge on ["agent_gateway", "runtime"].

# Python
# Rule: web and CLI chat must converge on same runtime; difference only in presentation.
CHAT_PATH = ["platform", "agent_gateway", "runtime"]
OPENAPI_CHAT_PATH = ["capability", "agent_gateway", "runtime"]
PUBLISH_PATH = ["platform", "orchestrator", "runtime"]
OPEN_SITE_PATH = ["edge_gateway", "platform"]

def assert_converge(chat_from_web: list[str], chat_from_cli: list[str]) -> None:
  assert chat_from_web[-2:] == ["agent_gateway", "runtime"]
  assert chat_from_cli[-2:] == ["agent_gateway", "runtime"]

Different entries, same kernel. Diagram must show "convergence point": after front gateway, shared container runtime. If web, WeCom, CLI each run their own kernel, one logic change means three edits, three consistency nightmares.

Failure Boundaries:

Tag lost → default re-label by "intent", don't guess via service name.

OpenAPI chat may pass through External Capability first, but must still converge into Front Gateway → Runtime. Shortcutting straight to runtime discards unified auth and routing.

Publish requests go through Orchestration to update workspace. If publish succeeds but chat fails, correlation fields (session id / avatar id / time window) must be pre-agreed; otherwise they look like unrelated incidents.

One Runtime, Three Shapes

Orchestration launches containers in three shapes by purpose: Usage Shape (使用态) , Development Shape (开发态) , Evolution Shape (进化态) . Names don't matter; key is same dialogue engine, different sidecars attached .

Usage — Real users on web/WeCom/external API. Extra sidecars: dialogue engine only (minimal).

Development — Developers editing avatar in Web IDE. Extra sidecars: dialogue engine + workspace sync + Web IDE.

Evolution — Automated evolution pipeline improving avatar. Extra sidecars: dialogue engine + workspace sync + Web IDE.

Development and Evolution have identical process composition ; difference is who triggers and who receives the result: human opens IDE, edits, clicks publish; pipeline auto-launches, lets Agent self-edit, pushes result back to Orchestration. So when debugging, check who launched it , not just what's running.

Usage optimizes for container density and first-token latency; Development/Evolution need full IDE experience — naturally diverge on "how many pre-warmed containers" and "which image." This foreshadows later posts on container pool watermarks and first-response budgets, not ops hygiene.

Special case: guest and shared conversations use Container Pool — pre-warmed public containers, anyone drops into an existing one, no dedicated spin-up.

File distribution mostly happens at publish — Orchestration calls file agent to push packaged files into workspace. Don't interpret as "every container runs a sidecar permanently"; diagram places it in a separate corner to remind: it's triggered per event, not resident per container.

TypeScript example: Shape type, ContainerSetup interface, setupFor function returning minimal setup for usage, full setup for development/evolution.

// TypeScript
// Rule: shape only decides extra sidecars, never changes dialogue engine
type Shape = "usage" | "develop" | "evolution";

interface ContainerSetup {
  runtime: true;           // dialogue engine always present
  workspaceSync: boolean;  // whether workspace sync attached
  webIde: boolean;         // whether Web IDE attached
}

function setupFor(shape: Shape): ContainerSetup {
  // Usage: minimal, only dialogue engine
  if (shape === "usage") {
    return { runtime: true, workspaceSync: false, webIde: false };
  }
  // Develop and Evolution share same components; difference is who launches and who receives result
  return { runtime: true, workspaceSync: true, webIde: true };
}

Python example: publish_then_chat returns "fail_closed:workspace_stale" if publish fails — fail-closed = stop on error, don't soldier on.

# Python
# Rule: workspace update failure must fail-closed or give explicit degradation notice.
def publish_then_chat(publish_ok: bool) -> str:
  if not publish_ok:
    return "fail_closed:workspace_stale"  # fail-closed = stop on error, don't soldier on
  return "ready_to_chat"

Failure Boundaries:

Development shape carries more sidecars, but usage shape must still have "mid-stream cancel" and "connection reuse." Process is minimal; discipline isn't.

Workspace sync failure must fail-closed or give explicit degradation notice. Silently serving stale workspace = "fake can-work."

After container pool strategy splits by shape, monitoring must split too. One metric set for all → at peak you won't know which shape drained the pool.

Walkthrough: Open → Publish → Chat

One story threads the seven layers. Each step has decision points — A or B, who may fail.

Open Site: Access → Traffic Gateway → Portal. Decision: On failure, check Traffic Gateway and static files first, never jump to chat runtime. Who may fail: Static files occasional retry ok; auth failure must block, no "guest can chat anyway."

Publish Avatar: Portal BFF → Scheduler → File Distribution updates workspace → Container ready. Decision: Workspace update fails — still allow chat? Default no, unless product explicitly accepts "chat with old files." Who may fail: File distribution retryable; publish pipeline state must be queryable, not manual container stare.

User Chats: Portal BFF → Front Gateway (auth, select container, route) → Container Runtime → Result events flow back to user's host for presentation. Decision: Dedicated container or pool? Guests/shared → pool; identified users → dedicated. Wrong choice = cost and isolation both wrong. Who may fail: Pre-warm (prep container early) can fail, fallback to on-demand; auth and permission checks cannot be lazy-passed.

Via OpenAPI / CLI: External caller or CLI → External Capability → still converge into Front Gateway → Runtime. Decision: Allow OpenAPI shortcut straight to runtime? Default no — unified auth and routing worth more than "one less hop."

Call Internal Enterprise Tool: Runtime follows config via MCP; Token/Auth lives in External Capability layer, not "auto-magic" in model. Decision: CLI, WeCom (no UI hosts) — how to ask permission? Can simplify prompt, but "must ask" cannot be dropped.

After this walk you should recite: Site entry, chat entry, tool entry — three things, three layers of responsibility. Can't recite, diagram hasn't entered the brain.

Self-Check: Which Layer Is Your Diagram Missing?

Matrix across four product stages:

Dimension                | Only a chat page | Add local IDE | Add orchestration framework | Cloud container pool
-------------------------|------------------|---------------|-----------------------------|-------------------
Site entry layer         | Yes              | Yes           | Yes                         | Yes (often multi-region)
Agent Front Gateway      | Usually absent   | Weak          | Weak or self-built          | Recommended
Scheduler / Container Pool| Absent          | Absent        | Weak                        | Hard requirement
Container Runtime        | Absent or fake   | Local process | Often in-process            | Hard requirement
Tool / External interfaces| Few             | Medium        | Medium                      | Strong
Multi-host presentation  | Weak             | IDE strong    | Depends on integration      | Web/WeCom/CLI all needed

Rules of thumb:

No real mutation, no multi-tenancy → Only a chat page suffices.

Cloud pool not your problem, team codes locally → Add local IDE suffices.

Want full control, willing to build gateway and pool → Add orchestration framework fits.

Multiple entries + isolation + governance → Cloud container pool . Missing scheduler or Agent Path → still just an enhanced chat page.

Self-check mantra: If you claim "we built an Agent platform" but can't draw Scheduler and Runtime, you're mostly building an enhanced chat page wrapper. Harsh, but saves person-years.

Four Pitfalls

Pitfall 1: Two Gateways Drawn as One Box

Lure: Both called "gateway"; ops diagrams love merging all forwarding into one.

Wrong Fix: Uniformly increase timeouts, scale "gateway cluster" hoping both site-open and chat improve together.

Right Fix: Split into two boxes, two troubleshooting narratives. Traffic Gateway owns site-open; Agent Front Gateway owns which-container.

Pitfall 2: Internal Service Names as Public Architecture Lecture

Dumping internal service names into public talks guarantees cold room: you're explaining your module split, audience lacks context, hears nothing. Cause: internal runbook copy-pasted. For public, stick to the seven-layer Chinese names here; map internally. Secrets stay secret — that's boundary, not insecurity.

Pitfall 3: CLI and IDE Drawn Outside Runtime as Side Toys

Lure: Client teams ship independently; diagram laziness.

Wrong Fix: Allow CLI and OpenAPI to permanently bypass auth and routing → second Agent system grows.

Right Fix: They are first-class entries. Capabilities must converge on Agent Path; only presentation may diverge.

Pitfall 4: Publish Chain Missing from Architecture Diagram

Chat demos rarely depend on "just published," so publish becomes ops appendix, diagram only shows chat arrows, workspace update left to "everyone knows." Then production hits "persona change not effective" — everyone's first instinct: check model. "Can work" inherently includes "how workspace updates" — no publish on diagram, no credible can-work.

Summary

Self-built Agent speaks via 7-layer responsibility diagram: Access, Traffic Gateway, Main Platform, External Capability, Orchestration, Agent Path, Client.

Traffic Gateway owns site-open, Agent Front Gateway owns container routing — merging guarantees misdiagnosis.

Multiple entries must converge on Agent Path, not replicate multiple kernels.

Usage shape = dialogue engine only; Development/Evolution add workspace sync + Web IDE — container pool and image strategy therefore diverge.

If you can draw Scheduler and Runtime, you earn the title "Agent platform"; otherwise it's a chat page wrapper.

Requests must carry layer tags: intent decides path, nicknames cannot replace navigation.

When discussing architecture, ban product names only — speak with the 7-layer responsibility diagram; Traffic Gateway and Agent Front Gateway must be separate.

Next post will cover three most confused terms: Model, Runtime, Host ; if you're eager for the execution layer, jump ahead to Container Runtime for Agents .

Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

MCPsystem designruntimetroubleshootinglayered architectureAI platformOpenAPIorchestrationAgent Architecturecontainer pool
James' Growth Diary
Written by

James' Growth Diary

I am James, focusing on AI Agent learning and growth. I continuously update two series: “AI Agent Mastery Path,” which systematically outlines core theories and practices of agents, and “Claude Code Design Philosophy,” which deeply analyzes the design thinking behind top AI tools. Helping you build a solid foundation in the AI era.

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.