mirror of
https://github.com/hanzoai/papers.git
synced 2026-11-03 02:27:30 +00:00
260 lines
13 KiB
TeX
260 lines
13 KiB
TeX
\section{The Seven-Layer Architecture}
|
|
|
|
\label{sec:architecture}
|
|
|
|
\subsection{Design Principles}
|
|
|
|
The UAH architecture is guided by three principles. First, \textbf{separation
|
|
of concerns}: each layer has a single, well-defined responsibility. Second,
|
|
\textbf{typed interfaces}: all inter-layer communication uses typed contracts
|
|
with explicit invariants. Third, \textbf{cross-layer visibility}: every layer
|
|
emits structured telemetry that is readable by every other layer.
|
|
|
|
We define each layer formally as a tuple:
|
|
\begin{equation}
|
|
L_i = \left(\mathcal{I}_i,\; \mathcal{O}_i,\; \mathcal{S}_i,\;
|
|
F_i,\; \Phi_i\right),
|
|
\end{equation}
|
|
where $\mathcal{I}_i$ is the input type space, $\mathcal{O}_i$ is the output
|
|
type space, $\mathcal{S}_i$ is the internal state space, $F_i :
|
|
\mathcal{I}_i \times \mathcal{S}_i \to \mathcal{O}_i \times \mathcal{S}_i$ is
|
|
the layer's transition function, and $\Phi_i$ is the set of invariants that
|
|
must hold before and after each transition.
|
|
|
|
The complete UAH system is the composition:
|
|
\begin{equation}
|
|
\text{UAH} = L_7 \circ L_6 \circ L_5 \circ L_4 \circ L_3 \circ L_2 \circ L_1,
|
|
\end{equation}
|
|
where $\circ$ denotes functional composition with the cross-layer telemetry
|
|
bus providing side-channel communication between non-adjacent layers.
|
|
|
|
\subsection{Layer 1: LLM Access}
|
|
|
|
\begin{definition}[LLM Access Layer]
|
|
$L_1 = \left(\mathcal{I}_1, \mathcal{O}_1, \mathcal{S}_1, F_1, \Phi_1\right)$ where:
|
|
\begin{align*}
|
|
\mathcal{I}_1 &= \text{CompletionRequest} \times \text{RoutingPolicy} \\
|
|
\mathcal{O}_1 &= \text{CompletionResponse} \times \text{UsageMetrics} \\
|
|
\mathcal{S}_1 &= \text{ProviderPool} \times \text{CostLedger} \times \text{CapacityMap} \\
|
|
\Phi_1 &= \{\text{latency} \leq \tau_{\max},\; \text{cost} \leq \text{budget},\;
|
|
\text{availability} \geq 0.999\}
|
|
\end{align*}
|
|
\end{definition}
|
|
|
|
The LLM Access layer provides a unified interface to 100+ model providers
|
|
through a single API endpoint. The routing policy $\pi_{\text{route}} :
|
|
\text{Request} \to \text{Provider}$ is a learned function that minimizes
|
|
expected cost subject to latency and availability constraints:
|
|
\begin{equation}
|
|
\pi_{\text{route}}^*(r) = \argmin_{p \in \mathcal{P}}
|
|
\mathbb{E}\left[\text{cost}(p, r) \mid \text{lat}(p, r) \leq \tau_{\max}\right],
|
|
\end{equation}
|
|
where $\mathcal{P}$ is the set of available providers and $\text{lat}(p, r)$
|
|
is the predicted latency for request $r$ on provider $p$.
|
|
|
|
Key invariants include: (i) requests must receive responses within
|
|
$\tau_{\max}$ regardless of provider failures (achieved via automatic failover),
|
|
(ii) all usage is tracked in the cost ledger with sub-cent granularity, and
|
|
(iii) provider-specific constraints (context limits, rate limits, content
|
|
policies) are enforced transparently.
|
|
|
|
The layer supports heterogeneous model types: chat completions, embeddings,
|
|
image generation, audio transcription, and tool-use completions. The routing
|
|
function adapts dynamically: if a provider returns a 429 (rate limit), the
|
|
capacity map is updated and subsequent requests are routed away automatically.
|
|
|
|
\subsection{Layer 2: Tool Protocol}
|
|
|
|
\begin{definition}[Tool Protocol Layer]
|
|
$L_2 = \left(\mathcal{I}_2, \mathcal{O}_2, \mathcal{S}_2, F_2, \Phi_2\right)$ where:
|
|
\begin{align*}
|
|
\mathcal{I}_2 &= \text{ToolCallRequest} \times \text{ExecutionContext} \\
|
|
\mathcal{O}_2 &= \text{ToolCallResult} \times \text{AuditRecord} \\
|
|
\mathcal{S}_2 &= \text{ToolRegistry} \times \text{SandboxPool} \times
|
|
\text{PolicyEngine} \\
|
|
\Phi_2 &= \{\text{isolation} \geq \text{sandbox-level},\;
|
|
\text{idempotency} \in \{\text{safe, idempotent, unsafe}\}\}
|
|
\end{align*}
|
|
\end{definition}
|
|
|
|
The Tool Protocol layer implements the Model Context Protocol (MCP) standard
|
|
as its wire format, providing 54 built-in tools across seven categories:
|
|
|
|
\begin{itemize}[leftmargin=1.5em]
|
|
\item \textbf{Filesystem} (12 tools): read, write, patch, tree, glob,
|
|
watch, diff, archive, permissions, metadata.
|
|
\item \textbf{Shell Execution} (8 tools): run, background, kill, stdin,
|
|
stdout, stderr, env, signal.
|
|
\item \textbf{Code Intelligence} (10 tools): AST parse, symbol lookup,
|
|
type check, lint, refactor, definition, references, rename, format, complete.
|
|
\item \textbf{Search} (8 tools): ripgrep text, vector semantic, SQL
|
|
structured, web, docs, code, image, multimodal.
|
|
\item \textbf{Browser Automation} (9 tools): navigate, click, type,
|
|
screenshot, extract, form, cookie, network, accessibility.
|
|
\item \textbf{Process Management} (4 tools): list, kill, logs, signal.
|
|
\item \textbf{Agent Orchestration} (3 tools): spawn, handoff, broadcast.
|
|
\end{itemize}
|
|
|
|
Each tool is annotated with an idempotency class:
|
|
\begin{equation}
|
|
\text{IdempotencyClass} \in \{\texttt{SAFE},\; \texttt{IDEMPOTENT},\;
|
|
\texttt{UNSAFE}\},
|
|
\end{equation}
|
|
which determines retry behavior and sandbox isolation requirements. The policy
|
|
engine enforces per-agent capability constraints using a capability lattice
|
|
$\mathcal{C} = \langle C, \leq \rangle$ where $c_1 \leq c_2$ iff capability
|
|
$c_2$ subsumes $c_1$. An agent $a$ may invoke tool $t$ iff $\text{cap}(t) \leq
|
|
\text{grants}(a)$.
|
|
|
|
\subsection{Layer 3: Agent Runtime}
|
|
|
|
\begin{definition}[Agent Runtime Layer]
|
|
$L_3 = \left(\mathcal{I}_3, \mathcal{O}_3, \mathcal{S}_3, F_3, \Phi_3\right)$ where:
|
|
\begin{align*}
|
|
\mathcal{I}_3 &= \text{Task} \times \text{AgentSpec} \times \text{Context} \\
|
|
\mathcal{O}_3 &= \text{TaskResult} \times \text{Trace} \\
|
|
\mathcal{S}_3 &= \text{AgentGraph} \times \text{WorkflowStore} \times
|
|
\text{MemoryStore} \\
|
|
\Phi_3 &= \{\text{progress} \geq 0,\; |\text{context}| \leq C_{\max},\;
|
|
\text{quorum} \geq 1\}
|
|
\end{align*}
|
|
\end{definition}
|
|
|
|
The Agent Runtime executes agent graphs where nodes are individual agents and
|
|
edges represent handoff relationships. An agent $a_i$ is specified as:
|
|
\begin{equation}
|
|
a_i = \left(\text{name}_i,\; \text{model}_i,\; \text{instructions}_i,\;
|
|
\text{tools}_i,\; \text{handoffs}_i,\; \text{guardrails}_i\right),
|
|
\end{equation}
|
|
with $\text{handoffs}_i \subseteq \{a_j : j \neq i\}$ defining the subgraph
|
|
of agents to which $a_i$ can delegate.
|
|
|
|
Execution follows a triage-route-execute protocol. An orchestrator agent
|
|
receives the initial task, classifies it by type and complexity, routes to the
|
|
appropriate specialist agent (or spawns multiple agents for parallelizable
|
|
subtasks), and aggregates results. The runtime enforces three invariants:
|
|
(i) at least one agent is always making progress, (ii) context compression is
|
|
applied before any agent's context exceeds $C_{\max}$ tokens, and (iii) every
|
|
handoff is recorded atomically in the workflow store for resumability.
|
|
|
|
Memory is organized into three tiers following prior work~\cite{hanzo2024sdk}:
|
|
\begin{itemize}[leftmargin=1.5em]
|
|
\item \textbf{Working memory}: Current context window (ephemeral).
|
|
\item \textbf{Episodic memory}: Compressed summaries of prior turns
|
|
(persisted in Qdrant with embedding-based retrieval).
|
|
\item \textbf{Semantic memory}: Structured facts and learned patterns
|
|
(persisted in PostgreSQL with pgvector).
|
|
\end{itemize}
|
|
|
|
\subsection{Layer 4: Channel Integration}
|
|
|
|
\begin{definition}[Channel Integration Layer]
|
|
$L_4 = \left(\mathcal{I}_4, \mathcal{O}_4, \mathcal{S}_4, F_4, \Phi_4\right)$ where:
|
|
\begin{align*}
|
|
\mathcal{I}_4 &= \text{InboundMessage} \times \text{ChannelMetadata} \\
|
|
\mathcal{O}_4 &= \text{OutboundMessage} \times \text{DeliveryReceipt} \\
|
|
\mathcal{S}_4 &= \text{ChannelRegistry} \times \text{IdentityMap} \times
|
|
\text{ConversationStore} \\
|
|
\Phi_4 &= \{\text{identity.verified},\; \text{channel.active},\;
|
|
\text{delivery.at\_least\_once}\}
|
|
\end{align*}
|
|
\end{definition}
|
|
|
|
The Channel Integration layer provides a unified identity and conversation
|
|
model across 15 supported channels:
|
|
\begin{itemize}[leftmargin=1.5em, itemsep=0pt]
|
|
\item \textbf{Messaging}: Slack, Discord, Telegram, WhatsApp, iMessage,
|
|
SMS (Twilio).
|
|
\item \textbf{Email}: Gmail, Outlook (via IMAP/SMTP + OAuth).
|
|
\item \textbf{Developer}: GitHub (issues/PRs/comments), GitLab, Linear,
|
|
Jira.
|
|
\item \textbf{Voice}: Phone (Twilio), Zoom, Google Meet.
|
|
\item \textbf{Web}: REST API, WebSocket, Embedded chat widget.
|
|
\end{itemize}
|
|
|
|
The identity model maps channel-specific identities to a canonical user
|
|
representation: $\phi : \text{ChannelIdentity} \to \text{CanonicalUser}$.
|
|
This allows a conversation started on Slack to be resumed on email without
|
|
loss of context. Conversation state is persisted with a monotonic sequence
|
|
number per channel-session pair, ensuring at-least-once delivery semantics.
|
|
|
|
\subsection{Layer 5: Compute Tiers}
|
|
|
|
The Compute Tiers layer is developed extensively in Section~\ref{sec:tiers}.
|
|
For the purposes of the layered definition:
|
|
|
|
\begin{definition}[Compute Tiers Layer]
|
|
$L_5 = \left(\mathcal{I}_5, \mathcal{O}_5, \mathcal{S}_5, F_5, \Phi_5\right)$ where:
|
|
\begin{align*}
|
|
\mathcal{I}_5 &= \text{ComputeRequest} \times \text{TierPolicy} \\
|
|
\mathcal{O}_5 &= \text{ExecutionEnvironment} \times \text{ResourceMetrics} \\
|
|
\mathcal{S}_5 &= \text{TierMap} \times \text{AllocationTable} \times
|
|
\text{MigrationLog} \\
|
|
\Phi_5 &= \{\text{tier.available},\; \text{resources.within\_quota},\;
|
|
\text{isolation.enforced}\}
|
|
\end{align*}
|
|
\end{definition}
|
|
|
|
\subsection{Layer 6: Self-Improvement}
|
|
|
|
\begin{definition}[Self-Improvement Layer]
|
|
$L_6 = \left(\mathcal{I}_6, \mathcal{O}_6, \mathcal{S}_6, F_6, \Phi_6\right)$ where:
|
|
\begin{align*}
|
|
\mathcal{I}_6 &= \text{ExecutionTrace} \times \text{OutcomeSignal} \\
|
|
\mathcal{O}_6 &= \text{PolicyUpdate} \times \text{KnowledgeUpdate} \\
|
|
\mathcal{S}_6 &= \text{ExperienceBank} \times \text{PolicyStore} \times
|
|
\text{EvalHistory} \\
|
|
\Phi_6 &= \{\text{improvement.monotonic},\;
|
|
\text{regression.bounded}\}
|
|
\end{align*}
|
|
\end{definition}
|
|
|
|
The Self-Improvement layer operates four nested feedback loops at different
|
|
timescales:
|
|
|
|
\begin{enumerate}[leftmargin=1.5em]
|
|
\item \textbf{In-context loop} (seconds): Reflects on current task
|
|
execution, adjusts subsequent steps based on observed errors.
|
|
\item \textbf{Session loop} (minutes): Summarizes session outcomes,
|
|
updates the working memory with session-specific patterns.
|
|
\item \textbf{Periodic loop} (hours): Analyzes aggregated traces,
|
|
identifies systematic failure modes, updates routing policies.
|
|
\item \textbf{Epochal loop} (days): Fine-tunes specialist models or
|
|
updates semantic memory with distilled knowledge from completed tasks.
|
|
\end{enumerate}
|
|
|
|
The improvement constraint $\Phi_6$ requires that mean task-completion rate
|
|
over any rolling 24-hour window is non-decreasing across epochs, and that any
|
|
regression exceeding a threshold $\epsilon_{\text{reg}} = 0.02$ triggers an
|
|
automatic rollback of the offending policy update.
|
|
|
|
\subsection{Layer 7: Observability}
|
|
|
|
\begin{definition}[Observability Layer]
|
|
$L_7 = \left(\mathcal{I}_7, \mathcal{O}_7, \mathcal{S}_7, F_7, \Phi_7\right)$ where:
|
|
\begin{align*}
|
|
\mathcal{I}_7 &= \text{TelemetryEvent} \times \text{LayerID} \\
|
|
\mathcal{O}_7 &= \text{StructuredLog} \times \text{Metric} \times \text{Span} \\
|
|
\mathcal{S}_7 &= \text{TraceStore} \times \text{MetricStore} \times
|
|
\text{AlertRuleSet} \\
|
|
\Phi_7 &= \{\text{latency.p99} \leq 10\text{ms},\;
|
|
\text{loss} = 0,\; \text{retention} \geq 30\text{d}\}
|
|
\end{align*}
|
|
\end{definition}
|
|
|
|
The Observability layer provides a unified telemetry pipeline across all
|
|
other layers. Every LLM call, tool invocation, agent handoff, tier migration,
|
|
and improvement event is captured as a structured span in the OpenTelemetry
|
|
format~\cite{opentelemetry2023}. Spans are correlated by a globally unique
|
|
$\texttt{trace\_id}$ that is injected at task ingestion and propagated through
|
|
all seven layers.
|
|
|
|
The layer enforces three coverage invariants: (i) every agent action must
|
|
produce a span, (ii) every LLM call must record model, provider, input tokens,
|
|
output tokens, cost, and latency, and (iii) every error must capture the full
|
|
stack trace and the conversation context at the time of failure.
|
|
|
|
% ============================================================================
|
|
% 4. TIERED COMPUTE RUNTIME
|
|
% ============================================================================
|