Commit Β·
39f7e06
1
Parent(s): 8318700
Update from architecture repo 2026-03-10
Browse files- index.html +72 -54
index.html
CHANGED
|
@@ -23,7 +23,7 @@
|
|
| 23 |
<div class="hero">
|
| 24 |
<h1>The <span>Agentic</span> Symphony</h1>
|
| 25 |
<p>An interactive map of all the moving pieces in a production agentic AI system.</p>
|
| 26 |
-
<div class="meta">v<strong id="version">2.
|
| 27 |
</div>
|
| 28 |
|
| 29 |
<!-- Stats -->
|
|
@@ -143,7 +143,7 @@
|
|
| 143 |
</div>
|
| 144 |
|
| 145 |
<footer>
|
| 146 |
-
<strong>The Agentic Symphony</strong> · v2.
|
| 147 |
By <a href="https://danielrosehill.com" target="_blank">Daniel Rosehill</a> / Carrot Cake AI ·
|
| 148 |
<a href="https://github.com/danielrosehill/agentic-ai-architecture-map" target="_blank">GitHub</a> ·
|
| 149 |
MIT License
|
|
@@ -153,7 +153,7 @@
|
|
| 153 |
// βββββββββββββββββββββββββββββββββββββββ
|
| 154 |
// ARCHITECTURE DATA (V2)
|
| 155 |
// βββββββββββββββββββββββββββββββββββββββ
|
| 156 |
-
const ARCH = {"meta":{"title":"Agentic AI Architecture Map","version":"2.0.0"},"layers":[{"id":"prompts","label":"Prompts","position":"center","order":1,"color":"#4a6fa5","description":"The instruction layer \u2014 where human intent enters the system.","nodes":[{"id":"user-prompt","label":"User Prompt","description":"The actual question or instruction from the end user."},{"id":"system-prompt","label":"System Prompt","description":"Developer-defined instructions that shape the model\u2019s behavior, persona, and constraints. Also the injection point for RAG context."},{"id":"vendor-prompt","label":"Vendor Prompt","description":"Hidden instructions baked in by the provider \u2014 RLHF alignment, safety guardrails. The model is never truly vanilla."}]},{"id":"models","label":"Models","position":"center","order":2,"color":"#8b5cf6","description":"Foundation models that power reasoning and generation.","nodes":[{"id":"commercial-models","label":"Commercial","description":"Proprietary frontier models \u2014 Claude, GPT, Gemini, Cohere."},{"id":"open-source-models","label":"Open Source","description":"Open-weight models \u2014 Llama, Mistral, Qwen, DeepSeek, Phi."},{"id":"fine-tuned-models","label":"Fine-Tuned","description":"Task-specific models fine-tuned on your data."},{"id":"embedding-models","label":"Embedding","description":"Embedding models for vector representations \u2014 power the vector store and RAG, not agent reasoning."}]},{"id":"inference","label":"Inference","position":"center","order":3,"color":"#6366f1","description":"Where and how models are served \u2014 the compute layer.","nodes":[{"id":"model-gateway","label":"Gateway","description":"Model gateway/router \u2014 handles model selection, load balancing, failover, rate limiting, cost tracking. OpenRouter (hosted) or LiteLLM (self-hosted)."},{"id":"cloud-apis","label":"Cloud APIs","description":"Hosted API endpoints \u2014 Anthropic, OpenAI, Google, AWS Bedrock."},{"id":"self-hosted","label":"Self-Hosted","description":"Your own servers \u2014 vLLM, TGI, Ollama."},{"id":"on-prem","label":"On-Prem","description":"Air-gapped data center deployments."},{"id":"edge","label":"Edge","description":"Lightweight models on devices \u2014 low latency, offline."},{"id":"prompt-cache","label":"Cache","description":"Prompt/response caching \u2014 semantic dedup, cost reduction, latency improvement."}]},{"id":"context-store","label":"Context Store","position":"center","order":4,"color":"#2563eb","style":"dashed","description":"Knowledge layer \u2014 RAG and persistent memory.","nodes":[{"id":"context-rag","label":"Context (RAG)","description":"Retrieval-Augmented Generation \u2014 grounding AI in your documents."},{"id":"memory","label":"Memory","description":"Multiple forms: mined, ad-hoc, implicit, structured."},{"id":"vector-store","label":"Vector Store","description":"Embedding-based semantic search indexes."}]},{"id":"agents","label":"Agents","position":"center","order":5,"color":"#e85d26","description":"Orchestration and execution \u2014 where AI systems reason, plan, and act.","nodes":[{"id":"orchestration","label":"Orchestration","description":"Routes to agents, pipelines, or workflows. Handles failures and state."},{"id":"agents-node","label":"Agents","description":"Autonomous systems that reason, plan, act. Tool selection is intelligent and non-deterministic. Execution is a loop."},{"id":"pipelines","label":"Pipelines","description":"Multi-step chains. Tools wired at design time \u2014 no intelligent selection."},{"id":"workflows","label":"Workflows","description":"Event-triggered sequences. Tools pre-configured at each node."}]},{"id":"mcp","label":"MCP","position":"center","order":6,"color":"#f5a623","description":"Model Context Protocol \u2014 the open standard for connecting AI to tools and data.","nodes":[{"id":"mcp-protocol","label":"Model Context Protocol","description":"The open standard for connecting AI models to external tools, services, and data sources."},{"id":"tool-registry","label":"Tool Registry","description":"Discovery mechanism for available tools \u2014 in MCP this is tools/list."}]},{"id":"hitl","label":"Human-in-the-Loop","position":"center","order":7,"color":"#b91c1c","description":"Approval checkpoints \u2014 the brakes on the system.","style":"checkpoint","nodes":[{"id":"hitl-checkpoint","label":"Human-in-the-Loop","description":"Humans review and authorize agent actions before execution."}]},{"id":"actions","label":"Actions","position":"center","order":8,"color":"#2563eb","style":"dashed","description":"External systems agents act on \u2014 bidirectional: agents read and write.","nodes":[{"id":"your-data","label":"Your Data","description":"Salesforce, HubSpot, Google Drive, Notion \u2014 via MCP."},{"id":"search-apis","label":"Search APIs","description":"Web search, news feeds, real-time data."},{"id":"external-services","label":"External Services","description":"Weather, time, public datasets."},{"id":"digital-wallets","label":"Digital Wallets","description":"Payment and financial actions \u2014 Stripe, crypto wallets, bank APIs."}]},{"id":"storage","label":"Storage","position":"center","order":9,"color":"#14b8a6","description":"Persistence \u2014 conversations, outputs, prompts.","nodes":[{"id":"conversations","label":"Conversations","description":"Persisted threads for auditing, replay, and context mining."},{"id":"outputs","label":"Outputs","description":"Generated text, structured data, files, artifacts."},{"id":"stored-prompts","label":"Prompts","description":"Prompt templates and versioned prompt libraries."},{"id":"postgres","label":"Postgres","description":"Production relational databases."},{"id":"data-lakes","label":"Data Lakes","description":"Large-scale unstructured storage \u2014 logs, documents, embeddings."}]},{"id":"frontends","label":"Frontends","position":"left","order":2,"color":"#4a6fa5","description":"User-facing interfaces.","nodes":[{"id":"frontends-card","label":"Frontends","description":"Chat windows, bots, web UIs, dashboards."}],"sub_items":["Chatbots","Slack","Telegram","Web UIs","Dashboards"]},{"id":"safety","label":"Safety","position":"right","order":2,"color":"#b91c1c","description":"Constraints at multiple points: input, agent, tool-level.","nodes":[{"id":"safety-card","label":"Safety","description":"Guardrails and oversight mechanisms."}],"sub_items":["Guardrails","Security Harnesses","Input Filtering"]},{"id":"observability","label":"Observability","position":"right","order":3,"color":"#065f46","description":"Eval, logging, monitoring. Feeds back into prompt optimization.","nodes":[{"id":"observability-card","label":"Observability","description":"Tracking decisions, quality, actions, health."}],"sub_items":["Eval","Logging","Monitoring"]},{"id":"destinations","label":"Destinations","position":"left","order":9,"color":"#7c3aed","description":"Downstream consumers of stored outputs.","nodes":[{"id":"prompt-library","label":"Prompt Library","description":"Versioned, curated prompt templates for reuse."},{"id":"wiki-km","label":"Wiki / KM","description":"Organizational knowledge management."},{"id":"data-warehouse","label":"Data Warehouse","description":"Analytics, compliance, long-term retention."}]}],"connections":[{"id":"input-flow","from":"frontends-card","to":"user-prompt","label":"INPUT","style":"dashed","color":"#4a6fa5","description":"User requests flow from frontend to prompt layer."},{"id":"prompts-to-models","from":"prompts","to":"models","color":"#4a6fa5","description":"Assembled prompts (user + system + vendor + RAG context + tool defs) sent to model."},{"id":"models-to-inference","from":"models","to":"inference","color":"#8b5cf6","description":"Selected model served through chosen inference path."},{"id":"gateway-to-cloud-apis","from":"model-gateway","to":"cloud-apis","color":"#6366f1","description":"Gateway routes to cloud APIs based on model selection, cost, latency, or fallback rules."},{"id":"gateway-to-self-hosted","from":"model-gateway","to":"self-hosted","color":"#6366f1","description":"Gateway routes to self-hosted endpoints. LiteLLM unifies local and cloud access."},{"id":"inference-to-agents","from":"inference","to":"agents","color":"#6366f1","description":"Inference results feed into the agent orchestration layer."},{"id":"orchestration-to-agents","from":"orchestration","to":"agents-node","style":"dashed","color":"#e85d26","description":"Dispatches to agents for intelligent, flexible execution."},{"id":"orchestration-to-pipelines","from":"orchestration","to":"pipelines","style":"dashed","color":"#e85d26","description":"Dispatches to pipelines when steps are known and fixed."},{"id":"orchestration-to-workflows","from":"orchestration","to":"workflows","style":"dashed","color":"#e85d26","description":"Dispatches to workflows for event-triggered execution."},{"id":"agentic-loop","from":"agents-node","to":"inference","style":"dashed","color":"#e85d26","label":"AGENTIC LOOP","description":"Iterative execution: after each tool result, agent returns to model. May loop many times per request.","invocation_pattern":"autonomous"},{"id":"agents-autonomous-to-mcp","from":"agents-node","to":"mcp","color":"#e85d26","label":"AUTONOMOUS","description":"Agents autonomously invoke tools \u2014 intelligent, non-deterministic selection.","invocation_pattern":"autonomous"},{"id":"pipelines-deterministic-to-mcp","from":"pipelines","to":"mcp","color":"#e85d26","style":"solid","label":"DETERMINISTIC","description":"Tools wired at design time. Developer decides sequence.","invocation_pattern":"deterministic"},{"id":"workflows-deterministic-to-mcp","from":"workflows","to":"mcp","color":"#e85d26","style":"solid","label":"DETERMINISTIC","description":"Tools pre-configured per workflow node, event-triggered.","invocation_pattern":"deterministic"},{"id":"mcp-to-hitl","from":"mcp","to":"hitl","color":"#f5a623","label":"TAKING ACTIONS","style":"solid","no_arrow":true,"description":"Actions pass through human approval before execution."},{"id":"hitl-to-actions","from":"hitl","to":"actions","color":"#b91c1c","description":"Approved actions proceed to external systems."},{"id":"actions-data-retrieval","from":"actions","to":"mcp-protocol","style":"dashed","color":"#2563eb","label":"DATA RETRIEVAL","description":"Data retrieved from external systems flows back through MCP. Actions are bidirectional.","invocation_pattern":"bidirectional"},{"id":"agents-to-storage","from":"agents","to":"storage","style":"dashed","color":"#14b8a6","description":"Agents persist conversations, outputs, and prompt data."},{"id":"storage-to-context","from":"storage","to":"context-store","style":"dashed","color":"#2563eb","label":"CONTEXT-MINING","description":"Mined memory pattern \u2014 outputs post-processed into retrievable context.","invocation_pattern":"transport"},{"id":"context-to-agents","from":"context-store","to":"agents","style":"dashed","color":"#2563eb","description":"Context feeds back into agents \u2014 the virtuous knowledge cycle."},{"id":"agents-adhoc-memory","from":"agents-node","to":"memory","style":"dashed","color":"#2563eb","label":"AD-HOC MEMORY","description":"Agent directly writes/reads memory artifacts. Agent decides what to remember.","invocation_pattern":"bidirectional"},{"id":"output-flow","from":"agents-node","to":"frontends-card","label":"OUTPUT","style":"dashed","color":"#e85d26","description":"Agent responses delivered back to user through frontend."},{"id":"safety-to-agents","from":"safety-card","to":"agents","color":"#b91c1c","description":"Safety guardrails constrain agent behavior."},{"id":"safety-to-prompts","from":"safety-card","to":"prompts","color":"#b91c1c","style":"dashed","description":"Input guardrails \u2014 injection detection, content filtering."},{"id":"safety-to-mcp","from":"safety-card","to":"mcp-protocol","color":"#b91c1c","style":"dashed","description":"Tool-level safety \u2014 restricting tool access, parameter validation."},{"id":"observability-to-agents","from":"observability-card","to":"agents","color":"#065f46","description":"Monitoring and logging of agent execution."},{"id":"observability-to-storage","from":"observability-card","to":"data-lakes","style":"dashed","color":"#065f46","description":"Traces, logs, metrics persisted for analysis."},{"id":"observability-to-prompts","from":"observability-card","to":"stored-prompts","style":"dashed","color":"#065f46","label":"PROMPT OPTIMIZATION","description":"Eval results drive prompt iteration and versioning."},{"id":"frontends-to-observability","from":"frontends-card","to":"observability-card","style":"dashed","color":"#4a6fa5","description":"User feedback and telemetry flow to observability."},{"id":"context-rag-to-system-prompt","from":"context-rag","to":"system-prompt","style":"dashed","color":"#2563eb","label":"CONTEXT INJECTION","description":"RAG results injected into system prompt."},{"id":"embedding-models-to-vector-store","from":"embedding-models","to":"vector-store","style":"dashed","color":"#8b5cf6","description":"Embedding models generate vectors for semantic search."},{"id":"stored-prompts-to-prompt-library","from":"stored-prompts","to":"prompt-library","style":"dashed","color":"#4a6fa5","description":"Curated prompts become a versioned library."},{"id":"outputs-to-wiki","from":"outputs","to":"wiki-km","style":"dashed","color":"#7c3aed","description":"Agent outputs published to knowledge management."},{"id":"outputs-to-data-warehouse","from":"outputs","to":"data-warehouse","style":"dashed","color":"#7c3aed","description":"Outputs flow to data warehouse for analytics and compliance."},{"id":"postgres-to-context-store","from":"postgres","to":"context-rag","style":"dashed","color":"#14b8a6","description":"DB records indexed into RAG pipeline."},{"id":"user-prompt-to-conversations","from":"user-prompt","to":"conversations","style":"dashed","color":"#4a6fa5","description":"Prompts persisted as conversations for context mining."},{"id":"conversations-to-postgres","from":"conversations","to":"postgres","style":"dashed","color":"#14b8a6","label":"USER CONTEXT MINING","description":"Conversations mined for user context \u2014 preferences, patterns, domain knowledge."}]};
|
| 157 |
|
| 158 |
// βββββββββββββββββββββββββββββββββββββββ
|
| 159 |
// HELPERS
|
|
@@ -263,7 +263,7 @@ document.querySelectorAll('nav .links a[href^="#"]').forEach(a => {
|
|
| 263 |
// βββββββββββββββββββββββββββββββββββββββ
|
| 264 |
(function initDiagram() {
|
| 265 |
const container = document.getElementById('diagram-container');
|
| 266 |
-
const W = 1000, H =
|
| 267 |
const centerW = 420;
|
| 268 |
const centerX = (W - centerW) / 2;
|
| 269 |
const centerCX = W / 2;
|
|
@@ -391,16 +391,16 @@ document.querySelectorAll('nav .links a[href^="#"]').forEach(a => {
|
|
| 391 |
const arrowsG = g.append('g');
|
| 392 |
const nodesG = g.append('g');
|
| 393 |
|
| 394 |
-
// Y positions β restructured: Prompts
|
|
|
|
| 395 |
const pY=20, pH=55;
|
| 396 |
const mY=95, mH=60;
|
| 397 |
-
const iY=175, iH=
|
| 398 |
-
const csY=
|
| 399 |
-
const aY=
|
| 400 |
-
const mcpY=
|
| 401 |
-
const hitlY=
|
| 402 |
-
const actY=
|
| 403 |
-
const stY=760, stH=80;
|
| 404 |
|
| 405 |
// ββ PROMPTS ββ
|
| 406 |
layerBox(nodesG, centerX, pY, centerW, pH, '#4a6fa5', 'Prompts');
|
|
@@ -417,18 +417,25 @@ document.querySelectorAll('nav .links a[href^="#"]').forEach(a => {
|
|
| 417 |
chip(nodesG, centerCX+160, mY+20, 'Embedding', '#a78bfa', 'Vector representations for RAG \u2014 distinct from generative LLMs.');
|
| 418 |
drawConn(arrowsG, centerCX, mY+mH, centerCX, iY, '#8b5cf6');
|
| 419 |
|
| 420 |
-
// ββ INFERENCE ββ
|
| 421 |
-
layerBox(nodesG, centerX, iY, centerW, iH, '#6366f1', 'Inference');
|
| 422 |
-
chip(nodesG, centerCX, iY+18, 'Gateway', '#6366f1', '
|
| 423 |
-
chip(nodesG, centerCX-110, iY+
|
| 424 |
-
chip(nodesG, centerCX-15, iY+
|
| 425 |
-
chip(nodesG, centerCX+75, iY+
|
| 426 |
-
chip(nodesG, centerCX+140, iY+
|
| 427 |
-
// Gateway routing arrows
|
| 428 |
-
arrowsG.append('path').attr('d',`M${centerCX},${iY+34} L${centerCX-110},${iY+48}`).attr('stroke','#6366f1').attr('stroke-width',1.5).attr('opacity',0.4).attr('stroke-dasharray','3 2');
|
| 429 |
-
arrowsG.append('path').attr('d',`M${centerCX},${iY+34} L${centerCX-15},${iY+48}`).attr('stroke','#6366f1').attr('stroke-width',1.5).attr('opacity',0.4).attr('stroke-dasharray','3 2');
|
| 430 |
// Cache
|
| 431 |
-
chip(nodesG, centerCX-170, iY+
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 432 |
|
| 433 |
drawConn(arrowsG, centerCX, iY+iH, centerCX, csY, '#6366f1');
|
| 434 |
|
|
@@ -490,30 +497,11 @@ document.querySelectorAll('nav .links a[href^="#"]').forEach(a => {
|
|
| 490 |
arrowsG.append('text').attr('x',centerCX+80).attr('y',(mcpY+mcpH+hitlY)/2+2).attr('text-anchor','start').attr('fill','#f5a623').attr('font-family','system-ui').attr('font-size','9').attr('font-weight','700').text('TAKING ACTIONS');
|
| 491 |
drawConn(arrowsG, centerCX, hitlY+hitlH, centerCX, actY, '#b91c1c');
|
| 492 |
|
| 493 |
-
// ββ ACTIONS (
|
| 494 |
layerBox(nodesG, centerX, actY, centerW, actH, '#2563eb', 'Actions', true);
|
| 495 |
-
chip(nodesG, centerCX-
|
| 496 |
-
chip(nodesG, centerCX+
|
| 497 |
-
chip(nodesG, centerCX
|
| 498 |
-
chip(nodesG, centerCX+75, actY+58, 'Digital Wallets', '#1d4ed8', 'Stripe, crypto, bank APIs.');
|
| 499 |
-
|
| 500 |
-
// ββ STORAGE ββ
|
| 501 |
-
drawConn(arrowsG, centerCX+100, aY+aH, centerCX+100, stY, '#14b8a6', {dashed:true, opacity:0.4});
|
| 502 |
-
layerBox(nodesG, centerX, stY, centerW, stH, '#14b8a6', 'Storage');
|
| 503 |
-
chip(nodesG, centerCX-120, stY+18, 'Conversations', '#14b8a6', 'Persisted threads for auditing and mining.');
|
| 504 |
-
chip(nodesG, centerCX-15, stY+18, 'Outputs', '#14b8a6', 'Generated text, data, artifacts.');
|
| 505 |
-
chip(nodesG, centerCX+75, stY+18, 'Prompts', '#14b8a6', 'Versioned prompt templates.');
|
| 506 |
-
chip(nodesG, centerCX-80, stY+50, 'Postgres', '#0d9488', 'Relational databases.');
|
| 507 |
-
chip(nodesG, centerCX+70, stY+50, 'Data Lakes', '#0d9488', 'Logs, documents, embeddings.');
|
| 508 |
-
|
| 509 |
-
// Storage -> Context Store feedback (curving left side, up)
|
| 510 |
-
arrowsG.append('path')
|
| 511 |
-
.attr('d', `M${centerX-4},${stY+stH/2} C${centerX-65},${stY+stH/2} ${centerX-65},${csY+csH/2} ${centerX},${csY+csH/2}`)
|
| 512 |
-
.attr('fill','none').attr('stroke','#2563eb').attr('stroke-width',1.5).attr('stroke-dasharray','4 3').attr('opacity',0.4);
|
| 513 |
-
arrowsG.append('polygon')
|
| 514 |
-
.attr('points',`${centerX},${csY+csH/2} ${centerX-7},${csY+csH/2+4} ${centerX-7},${csY+csH/2-4}`)
|
| 515 |
-
.attr('fill','#2563eb').attr('opacity',0.4);
|
| 516 |
-
arrowsG.append('text').attr('x',centerX-70).attr('y',(stY+csY+csH)/2).attr('text-anchor','middle').attr('fill','#2563eb').attr('font-family','system-ui').attr('font-size','8').attr('font-weight','700').attr('transform',`rotate(-90,${centerX-70},${(stY+csY+csH)/2})`).text('CONTEXT-MINING');
|
| 517 |
|
| 518 |
// ββ LEFT: FRONTENDS ββ
|
| 519 |
const fe = card(nodesG, leftCX, mY+20, 130, 65, '#4a6fa5', '\u{1F4BB}', 'Frontends', 'Chat windows, bots, web UIs, dashboards.');
|
|
@@ -534,6 +522,35 @@ document.querySelectorAll('nav .links a[href^="#"]').forEach(a => {
|
|
| 534 |
arrowsG.append('polygon').attr('points',`${leftCX+65},${fe.y+fe.h*0.7} ${leftCX+72},${fe.y+fe.h*0.7-4} ${leftCX+72},${fe.y+fe.h*0.7+4}`).attr('fill','#e85d26').attr('opacity',0.6);
|
| 535 |
arrowsG.append('text').attr('x',(centerX+leftCX+65)/2).attr('y',aY+aH*0.65+14).attr('text-anchor','middle').attr('fill','#e85d26').attr('font-family','system-ui').attr('font-size','9').attr('font-weight','700').text('OUTPUT');
|
| 536 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 537 |
// ββ RIGHT: SAFETY + OBSERVABILITY ββ
|
| 538 |
const safetyC = card(nodesG, rightCX, mY+20, 130, 65, '#b91c1c', '\u{1F6E1}\uFE0F', 'Safety', 'Guardrails at prompts, agents, and tool level.');
|
| 539 |
subChips(nodesG, rightCX, safetyC.y+safetyC.h+8, ['Guardrails'], '#b91c1c');
|
|
@@ -550,14 +567,15 @@ document.querySelectorAll('nav .links a[href^="#"]').forEach(a => {
|
|
| 550 |
drawConn(arrowsG, rightCX-65, obsC.cy, centerX+centerW, aY+55, '#065f46');
|
| 551 |
|
| 552 |
// ββ RIGHT LOWER: DESTINATIONS ββ
|
| 553 |
-
|
| 554 |
-
chip(nodesG, rightCX,
|
| 555 |
-
chip(nodesG, rightCX,
|
| 556 |
-
|
| 557 |
-
|
| 558 |
-
|
| 559 |
-
drawConn(arrowsG,
|
| 560 |
-
drawConn(arrowsG,
|
|
|
|
| 561 |
|
| 562 |
// Embedding -> Vector Store
|
| 563 |
drawConn(arrowsG, centerCX+160, mY+20+28, centerCX+140, csY+25, '#8b5cf6', {dashed:true, opacity:0.35});
|
|
|
|
| 23 |
<div class="hero">
|
| 24 |
<h1>The <span>Agentic</span> Symphony</h1>
|
| 25 |
<p>An interactive map of all the moving pieces in a production agentic AI system.</p>
|
| 26 |
+
<div class="meta">v<strong id="version">2.1.0</strong> · <strong id="node-count">38</strong> nodes · <strong id="conn-count">39</strong> connections · <strong>14</strong> layers</div>
|
| 27 |
</div>
|
| 28 |
|
| 29 |
<!-- Stats -->
|
|
|
|
| 143 |
</div>
|
| 144 |
|
| 145 |
<footer>
|
| 146 |
+
<strong>The Agentic Symphony</strong> · v2.1.0 ·
|
| 147 |
By <a href="https://danielrosehill.com" target="_blank">Daniel Rosehill</a> / Carrot Cake AI ·
|
| 148 |
<a href="https://github.com/danielrosehill/agentic-ai-architecture-map" target="_blank">GitHub</a> ·
|
| 149 |
MIT License
|
|
|
|
| 153 |
// βββββββββββββββββββββββββββββββββββββββ
|
| 154 |
// ARCHITECTURE DATA (V2)
|
| 155 |
// βββββββββββββββββββββββββββββββββββββββ
|
| 156 |
+
const ARCH = {"meta":{"title":"Agentic AI Architecture Map","version":"2.1.0"},"layers":[{"id":"prompts","label":"Prompts","position":"center","order":1,"color":"#4a6fa5","description":"The instruction layer \u2014 where human intent enters the system.","nodes":[{"id":"user-prompt","label":"User Prompt","description":"The actual question or instruction from the end user."},{"id":"system-prompt","label":"System Prompt","description":"Developer-defined instructions that shape the model\u2019s behavior, persona, and constraints. Also the injection point for RAG context."},{"id":"vendor-prompt","label":"Vendor Prompt","description":"Hidden instructions baked in by the provider \u2014 RLHF alignment, safety guardrails. The model is never truly vanilla."}]},{"id":"models","label":"Models","position":"center","order":2,"color":"#8b5cf6","description":"Foundation models that power reasoning and generation.","nodes":[{"id":"commercial-models","label":"Commercial","description":"Proprietary frontier models \u2014 Claude, GPT, Gemini, Cohere."},{"id":"open-source-models","label":"Open Source","description":"Open-weight models \u2014 Llama, Mistral, Qwen, DeepSeek, Phi."},{"id":"fine-tuned-models","label":"Fine-Tuned","description":"Task-specific models fine-tuned on your data."},{"id":"embedding-models","label":"Embedding","description":"Embedding models for vector representations \u2014 power the vector store and RAG, not agent reasoning."}]},{"id":"inference","label":"Inference","position":"center","order":3,"color":"#6366f1","description":"Where and how models are served \u2014 the compute layer. Gateway is optional: requests can route through a gateway or call endpoints directly.","nodes":[{"id":"model-gateway","label":"Gateway","description":"Model gateway/router \u2014 handles model selection, load balancing, failover, rate limiting, cost tracking. OpenRouter (hosted) or LiteLLM (self-hosted). Optional \u2014 agents can call endpoints directly."},{"id":"cloud-apis","label":"Cloud APIs","description":"Hosted API endpoints \u2014 Anthropic, OpenAI, Google, AWS Bedrock. Reachable via gateway or directly."},{"id":"self-hosted","label":"Self-Hosted","description":"Your own servers \u2014 vLLM, TGI, Ollama. Reachable via gateway or directly."},{"id":"on-prem","label":"On-Prem","description":"Air-gapped data center deployments."},{"id":"edge","label":"Edge","description":"Lightweight models on devices \u2014 low latency, offline."},{"id":"prompt-cache","label":"Cache","description":"Prompt/response caching \u2014 semantic dedup, cost reduction, latency improvement."}]},{"id":"context-store","label":"Context Store","position":"center","order":4,"color":"#2563eb","style":"dashed","description":"Knowledge layer \u2014 RAG and persistent memory.","nodes":[{"id":"context-rag","label":"Context (RAG)","description":"Retrieval-Augmented Generation \u2014 grounding AI in your documents."},{"id":"memory","label":"Memory","description":"Multiple forms: mined, ad-hoc, implicit, structured."},{"id":"vector-store","label":"Vector Store","description":"Embedding-based semantic search indexes."}]},{"id":"agents","label":"Agents","position":"center","order":5,"color":"#e85d26","description":"Orchestration and execution \u2014 where AI systems reason, plan, and act.","nodes":[{"id":"orchestration","label":"Orchestration","description":"Routes to agents, pipelines, or workflows. Handles failures and state."},{"id":"agents-node","label":"Agents","description":"Autonomous systems that reason, plan, act. Tool selection is intelligent and non-deterministic. Execution is a loop."},{"id":"pipelines","label":"Pipelines","description":"Multi-step chains. Tools wired at design time \u2014 no intelligent selection."},{"id":"workflows","label":"Workflows","description":"Event-triggered sequences. Tools pre-configured at each node."}]},{"id":"mcp","label":"MCP","position":"center","order":6,"color":"#f5a623","description":"Model Context Protocol \u2014 the open standard for connecting AI to tools and data.","nodes":[{"id":"mcp-protocol","label":"Model Context Protocol","description":"The open standard for connecting AI models to external tools, services, and data sources."},{"id":"tool-registry","label":"Tool Registry","description":"Discovery mechanism for available tools \u2014 in MCP this is tools/list."}]},{"id":"hitl","label":"Human-in-the-Loop","position":"center","order":7,"color":"#b91c1c","description":"Approval checkpoints \u2014 the brakes on the system.","style":"checkpoint","nodes":[{"id":"hitl-checkpoint","label":"Human-in-the-Loop","description":"Humans review and authorize agent actions before execution."}]},{"id":"actions","label":"Actions","position":"center","order":8,"color":"#2563eb","style":"dashed","description":"External systems agents act on \u2014 bidirectional: agents read and write.","nodes":[{"id":"your-data","label":"Your Data","description":"Salesforce, HubSpot, Google Drive, Notion \u2014 via MCP."},{"id":"external-services","label":"External Services","description":"Weather, time, public datasets."},{"id":"digital-wallets","label":"Digital Wallets","description":"Payment and financial actions \u2014 Stripe, crypto wallets, bank APIs."}]},{"id":"storage","label":"Storage","position":"left","order":9,"color":"#14b8a6","description":"Persistence \u2014 conversations, outputs, prompts.","nodes":[{"id":"conversations","label":"Conversations","description":"Persisted threads for auditing, replay, and context mining."},{"id":"outputs","label":"Outputs","description":"Generated text, structured data, files, artifacts."},{"id":"stored-prompts","label":"Prompts","description":"Prompt templates and versioned prompt libraries."},{"id":"postgres","label":"Postgres","description":"Production relational databases."},{"id":"data-lakes","label":"Data Lakes","description":"Large-scale unstructured storage \u2014 logs, documents, embeddings."}]},{"id":"frontends","label":"Frontends","position":"left","order":2,"color":"#4a6fa5","description":"User-facing interfaces.","nodes":[{"id":"frontends-card","label":"Frontends","description":"Chat windows, bots, web UIs, dashboards."}],"sub_items":["Chatbots","Slack","Telegram","Web UIs","Dashboards"]},{"id":"grounding","label":"Grounding","position":"left","order":5,"color":"#0891b2","description":"Real-time external data sources that ground agent responses in current information.","nodes":[{"id":"grounding-card","label":"Grounding","description":"External data sources that ground agent responses in current, real-world information."}],"sub_items":["Web Search","News Feeds","Real-Time Data"]},{"id":"safety","label":"Safety","position":"right","order":2,"color":"#b91c1c","description":"Constraints at multiple points: input, agent, tool-level.","nodes":[{"id":"safety-card","label":"Safety","description":"Guardrails and oversight mechanisms."}],"sub_items":["Guardrails","Security Harnesses","Input Filtering"]},{"id":"observability","label":"Observability","position":"right","order":3,"color":"#065f46","description":"Eval, logging, monitoring. Feeds back into prompt optimization.","nodes":[{"id":"observability-card","label":"Observability","description":"Tracking decisions, quality, actions, health."}],"sub_items":["Eval","Logging","Monitoring"]},{"id":"destinations","label":"Destinations","position":"left","order":9,"color":"#7c3aed","description":"Downstream consumers of stored outputs.","nodes":[{"id":"prompt-library","label":"Prompt Library","description":"Versioned, curated prompt templates for reuse."},{"id":"wiki-km","label":"Wiki / KM","description":"Organizational knowledge management."},{"id":"data-warehouse","label":"Data Warehouse","description":"Analytics, compliance, long-term retention."}]}],"connections":[{"id":"input-flow","from":"frontends-card","to":"user-prompt","label":"INPUT","style":"dashed","color":"#4a6fa5","description":"User requests flow from frontend to prompt layer."},{"id":"prompts-to-models","from":"prompts","to":"models","color":"#4a6fa5","description":"Assembled prompts (user + system + vendor + RAG context + tool defs) sent to model."},{"id":"models-to-inference","from":"models","to":"inference","color":"#8b5cf6","description":"Selected model served through chosen inference path."},{"id":"gateway-to-cloud-apis","from":"model-gateway","to":"cloud-apis","color":"#6366f1","description":"Gateway routes to cloud APIs based on model selection, cost, latency, or fallback rules."},{"id":"gateway-to-self-hosted","from":"model-gateway","to":"self-hosted","color":"#6366f1","description":"Gateway routes to self-hosted endpoints. LiteLLM unifies local and cloud access."},{"id":"direct-to-cloud-apis","from":"models","to":"cloud-apis","color":"#6366f1","style":"dashed","label":"DIRECT","description":"Direct inference path bypassing the gateway \u2014 agents call cloud API endpoints directly."},{"id":"direct-to-self-hosted","from":"models","to":"self-hosted","color":"#6366f1","style":"dashed","label":"DIRECT","description":"Direct inference path bypassing the gateway \u2014 agents call self-hosted endpoints directly."},{"id":"inference-to-agents","from":"inference","to":"agents","color":"#6366f1","description":"Inference results feed into the agent orchestration layer."},{"id":"orchestration-to-agents","from":"orchestration","to":"agents-node","style":"dashed","color":"#e85d26","description":"Dispatches to agents for intelligent, flexible execution."},{"id":"orchestration-to-pipelines","from":"orchestration","to":"pipelines","style":"dashed","color":"#e85d26","description":"Dispatches to pipelines when steps are known and fixed."},{"id":"orchestration-to-workflows","from":"orchestration","to":"workflows","style":"dashed","color":"#e85d26","description":"Dispatches to workflows for event-triggered execution."},{"id":"agentic-loop","from":"agents-node","to":"inference","style":"dashed","color":"#e85d26","label":"AGENTIC LOOP","description":"Iterative execution: after each tool result, agent returns to model. May loop many times per request.","invocation_pattern":"autonomous"},{"id":"agents-autonomous-to-mcp","from":"agents-node","to":"mcp","color":"#e85d26","label":"AUTONOMOUS","description":"Agents autonomously invoke tools \u2014 intelligent, non-deterministic selection.","invocation_pattern":"autonomous"},{"id":"pipelines-deterministic-to-mcp","from":"pipelines","to":"mcp","color":"#e85d26","style":"solid","label":"DETERMINISTIC","description":"Tools wired at design time. Developer decides sequence.","invocation_pattern":"deterministic"},{"id":"workflows-deterministic-to-mcp","from":"workflows","to":"mcp","color":"#e85d26","style":"solid","label":"DETERMINISTIC","description":"Tools pre-configured per workflow node, event-triggered.","invocation_pattern":"deterministic"},{"id":"mcp-to-hitl","from":"mcp","to":"hitl","color":"#f5a623","label":"TAKING ACTIONS","style":"solid","no_arrow":true,"description":"Actions pass through human approval before execution."},{"id":"hitl-to-actions","from":"hitl","to":"actions","color":"#b91c1c","description":"Approved actions proceed to external systems."},{"id":"actions-data-retrieval","from":"actions","to":"mcp-protocol","style":"dashed","color":"#2563eb","label":"DATA RETRIEVAL","description":"Data retrieved from external systems flows back through MCP. Actions are bidirectional.","invocation_pattern":"bidirectional"},{"id":"agents-to-storage","from":"agents","to":"storage","style":"dashed","color":"#14b8a6","description":"Agents persist conversations, outputs, and prompt data."},{"id":"storage-to-context","from":"storage","to":"context-store","style":"dashed","color":"#2563eb","label":"CONTEXT-MINING","description":"Mined memory pattern \u2014 outputs post-processed into retrievable context.","invocation_pattern":"transport"},{"id":"context-to-agents","from":"context-store","to":"agents","style":"dashed","color":"#2563eb","description":"Context feeds back into agents \u2014 the virtuous knowledge cycle."},{"id":"agents-adhoc-memory","from":"agents-node","to":"memory","style":"dashed","color":"#2563eb","label":"AD-HOC MEMORY","description":"Agent directly writes/reads memory artifacts. Agent decides what to remember.","invocation_pattern":"bidirectional"},{"id":"grounding-to-agents","from":"grounding-card","to":"agents","color":"#0891b2","style":"dashed","label":"GROUNDING","description":"Real-time external data \u2014 web search, news feeds, live APIs \u2014 grounds agent responses in current information."},{"id":"output-flow","from":"agents-node","to":"frontends-card","label":"OUTPUT","style":"dashed","color":"#e85d26","description":"Agent responses delivered back to user through frontend."},{"id":"safety-to-agents","from":"safety-card","to":"agents","color":"#b91c1c","description":"Safety guardrails constrain agent behavior."},{"id":"safety-to-prompts","from":"safety-card","to":"prompts","color":"#b91c1c","style":"dashed","description":"Input guardrails \u2014 injection detection, content filtering."},{"id":"safety-to-mcp","from":"safety-card","to":"mcp-protocol","color":"#b91c1c","style":"dashed","description":"Tool-level safety \u2014 restricting tool access, parameter validation."},{"id":"observability-to-agents","from":"observability-card","to":"agents","color":"#065f46","description":"Monitoring and logging of agent execution."},{"id":"observability-to-storage","from":"observability-card","to":"data-lakes","style":"dashed","color":"#065f46","description":"Traces, logs, metrics persisted for analysis."},{"id":"observability-to-prompts","from":"observability-card","to":"stored-prompts","style":"dashed","color":"#065f46","label":"PROMPT OPTIMIZATION","description":"Eval results drive prompt iteration and versioning."},{"id":"frontends-to-observability","from":"frontends-card","to":"observability-card","style":"dashed","color":"#4a6fa5","description":"User feedback and telemetry flow to observability."},{"id":"context-rag-to-system-prompt","from":"context-rag","to":"system-prompt","style":"dashed","color":"#2563eb","label":"CONTEXT INJECTION","description":"RAG results injected into system prompt."},{"id":"embedding-models-to-vector-store","from":"embedding-models","to":"vector-store","style":"dashed","color":"#8b5cf6","description":"Embedding models generate vectors for semantic search."},{"id":"stored-prompts-to-prompt-library","from":"stored-prompts","to":"prompt-library","style":"dashed","color":"#4a6fa5","description":"Curated prompts become a versioned library."},{"id":"outputs-to-wiki","from":"outputs","to":"wiki-km","style":"dashed","color":"#7c3aed","description":"Agent outputs published to knowledge management."},{"id":"outputs-to-data-warehouse","from":"outputs","to":"data-warehouse","style":"dashed","color":"#7c3aed","description":"Outputs flow to data warehouse for analytics and compliance."},{"id":"postgres-to-context-store","from":"postgres","to":"context-rag","style":"dashed","color":"#14b8a6","description":"DB records indexed into RAG pipeline."},{"id":"user-prompt-to-conversations","from":"user-prompt","to":"conversations","style":"dashed","color":"#4a6fa5","description":"Prompts persisted as conversations for context mining."},{"id":"conversations-to-postgres","from":"conversations","to":"postgres","style":"dashed","color":"#14b8a6","label":"USER CONTEXT MINING","description":"Conversations mined for user context \u2014 preferences, patterns, domain knowledge."}]};
|
| 157 |
|
| 158 |
// βββββββββββββββββββββββββββββββββββββββ
|
| 159 |
// HELPERS
|
|
|
|
| 263 |
// βββββββββββββββββββββββββββββββββββββββ
|
| 264 |
(function initDiagram() {
|
| 265 |
const container = document.getElementById('diagram-container');
|
| 266 |
+
const W = 1000, H = 840;
|
| 267 |
const centerW = 420;
|
| 268 |
const centerX = (W - centerW) / 2;
|
| 269 |
const centerCX = W / 2;
|
|
|
|
| 391 |
const arrowsG = g.append('g');
|
| 392 |
const nodesG = g.append('g');
|
| 393 |
|
| 394 |
+
// Y positions β restructured: Prompts -> Models -> Inference -> Context Store -> Agents -> MCP -> HITL -> Actions
|
| 395 |
+
// Storage and Grounding are now side elements (not in center column)
|
| 396 |
const pY=20, pH=55;
|
| 397 |
const mY=95, mH=60;
|
| 398 |
+
const iY=175, iH=85;
|
| 399 |
+
const csY=285, csH=65;
|
| 400 |
+
const aY=380, aH=85;
|
| 401 |
+
const mcpY=497, mcpH=55;
|
| 402 |
+
const hitlY=584, hitlH=28;
|
| 403 |
+
const actY=642, actH=75;
|
|
|
|
| 404 |
|
| 405 |
// ββ PROMPTS ββ
|
| 406 |
layerBox(nodesG, centerX, pY, centerW, pH, '#4a6fa5', 'Prompts');
|
|
|
|
| 417 |
chip(nodesG, centerCX+160, mY+20, 'Embedding', '#a78bfa', 'Vector representations for RAG \u2014 distinct from generative LLMs.');
|
| 418 |
drawConn(arrowsG, centerCX, mY+mH, centerCX, iY, '#8b5cf6');
|
| 419 |
|
| 420 |
+
// ββ INFERENCE (gateway optional) ββ
|
| 421 |
+
layerBox(nodesG, centerX, iY, centerW, iH, '#6366f1', 'Inference', false, 'Gateway Optional');
|
| 422 |
+
chip(nodesG, centerCX, iY+18, 'Gateway', '#6366f1', 'Optional model router \u2014 OpenRouter or LiteLLM. Routes to cloud or local endpoints.');
|
| 423 |
+
chip(nodesG, centerCX-110, iY+55, 'Cloud APIs', '#6366f1', 'Anthropic, OpenAI, Google, Bedrock.');
|
| 424 |
+
chip(nodesG, centerCX-15, iY+55, 'Self-Hosted', '#6366f1', 'vLLM, TGI, Ollama.');
|
| 425 |
+
chip(nodesG, centerCX+75, iY+55, 'On-Prem', '#818cf8', 'Air-gapped deployments.');
|
| 426 |
+
chip(nodesG, centerCX+140, iY+55, 'Edge', '#818cf8', 'On-device, offline.');
|
|
|
|
|
|
|
|
|
|
| 427 |
// Cache
|
| 428 |
+
chip(nodesG, centerCX-170, iY+55, 'Cache', '#818cf8', 'Prompt/response caching \u2014 cost and latency reduction.');
|
| 429 |
+
|
| 430 |
+
// VIA GATEWAY routing arrows (from Gateway chip down to Cloud APIs and Self-Hosted)
|
| 431 |
+
arrowsG.append('path').attr('d',`M${centerCX-15},${iY+34} L${centerCX-110},${iY+55}`).attr('stroke','#6366f1').attr('stroke-width',1.5).attr('opacity',0.5).attr('stroke-dasharray','3 2');
|
| 432 |
+
arrowsG.append('path').attr('d',`M${centerCX+5},${iY+34} L${centerCX-15},${iY+55}`).attr('stroke','#6366f1').attr('stroke-width',1.5).attr('opacity',0.5).attr('stroke-dasharray','3 2');
|
| 433 |
+
arrowsG.append('text').attr('x',centerCX-55).attr('y',iY+42).attr('text-anchor','middle').attr('fill','#6366f1').attr('font-family','system-ui').attr('font-size','7.5').attr('font-weight','700').text('VIA GATEWAY');
|
| 434 |
+
|
| 435 |
+
// DIRECT arrows (from top of inference box directly down to Cloud APIs and Self-Hosted, bypassing Gateway)
|
| 436 |
+
arrowsG.append('path').attr('d',`M${centerCX-110},${iY+4} L${centerCX-110},${iY+55}`).attr('stroke','#6366f1').attr('stroke-width',1.5).attr('opacity',0.4).attr('stroke-dasharray','5 3');
|
| 437 |
+
arrowsG.append('path').attr('d',`M${centerCX-15},${iY+4} L${centerCX-15},${iY+55}`).attr('stroke','#6366f1').attr('stroke-width',1.5).attr('opacity',0.4).attr('stroke-dasharray','5 3');
|
| 438 |
+
arrowsG.append('text').attr('x',centerCX-65).attr('y',iY+11).attr('text-anchor','middle').attr('fill','#6366f1').attr('font-family','system-ui').attr('font-size','7.5').attr('font-weight','700').attr('opacity',0.6).text('DIRECT');
|
| 439 |
|
| 440 |
drawConn(arrowsG, centerCX, iY+iH, centerCX, csY, '#6366f1');
|
| 441 |
|
|
|
|
| 497 |
arrowsG.append('text').attr('x',centerCX+80).attr('y',(mcpY+mcpH+hitlY)/2+2).attr('text-anchor','start').attr('fill','#f5a623').attr('font-family','system-ui').attr('font-size','9').attr('font-weight','700').text('TAKING ACTIONS');
|
| 498 |
drawConn(arrowsG, centerCX, hitlY+hitlH, centerCX, actY, '#b91c1c');
|
| 499 |
|
| 500 |
+
// ββ ACTIONS (no more Search APIs β moved to Grounding) ββ
|
| 501 |
layerBox(nodesG, centerX, actY, centerW, actH, '#2563eb', 'Actions', true);
|
| 502 |
+
chip(nodesG, centerCX-85, actY+28, 'Your Data', '#2563eb', 'Salesforce, HubSpot, Google Drive, Notion.');
|
| 503 |
+
chip(nodesG, centerCX+15, actY+28, 'External Services', '#2563eb', 'Weather, time, public datasets.');
|
| 504 |
+
chip(nodesG, centerCX+120, actY+28, 'Digital Wallets', '#1d4ed8', 'Stripe, crypto, bank APIs.');
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 505 |
|
| 506 |
// ββ LEFT: FRONTENDS ββ
|
| 507 |
const fe = card(nodesG, leftCX, mY+20, 130, 65, '#4a6fa5', '\u{1F4BB}', 'Frontends', 'Chat windows, bots, web UIs, dashboards.');
|
|
|
|
| 522 |
arrowsG.append('polygon').attr('points',`${leftCX+65},${fe.y+fe.h*0.7} ${leftCX+72},${fe.y+fe.h*0.7-4} ${leftCX+72},${fe.y+fe.h*0.7+4}`).attr('fill','#e85d26').attr('opacity',0.6);
|
| 523 |
arrowsG.append('text').attr('x',(centerX+leftCX+65)/2).attr('y',aY+aH*0.65+14).attr('text-anchor','middle').attr('fill','#e85d26').attr('font-family','system-ui').attr('font-size','9').attr('font-weight','700').text('OUTPUT');
|
| 524 |
|
| 525 |
+
// ββ LEFT: GROUNDING (near agents) ββ
|
| 526 |
+
const grC = card(nodesG, leftCX, aY+10, 130, 65, '#0891b2', '\u{1F310}', 'Grounding', 'Real-time external data that grounds agent responses.');
|
| 527 |
+
subChips(nodesG, leftCX, grC.y+grC.h+8, ['Web Search'], '#0891b2');
|
| 528 |
+
subChips(nodesG, leftCX, grC.y+grC.h+34, ['News Feeds'], '#0891b2');
|
| 529 |
+
subChips(nodesG, leftCX, grC.y+grC.h+60, ['Real-Time Data'], '#0891b2');
|
| 530 |
+
// Grounding -> Agents arrow
|
| 531 |
+
drawConn(arrowsG, leftCX+65, grC.cy, centerX, aY+40, '#0891b2', {dashed:true, label:'GROUNDING'});
|
| 532 |
+
|
| 533 |
+
// ββ LEFT LOWER: STORAGE (side card) ββ
|
| 534 |
+
const stCX = leftCX;
|
| 535 |
+
const stCardY = actY+10;
|
| 536 |
+
const storC = card(nodesG, stCX, stCardY, 130, 65, '#14b8a6', '\u{1F4BE}', 'Storage', 'Persistence \u2014 conversations, outputs, prompts, databases.');
|
| 537 |
+
subChips(nodesG, stCX, storC.y+storC.h+8, ['Conversations'], '#14b8a6');
|
| 538 |
+
subChips(nodesG, stCX, storC.y+storC.h+34, ['Outputs','Prompts'], '#14b8a6');
|
| 539 |
+
subChips(nodesG, stCX, storC.y+storC.h+60, ['Postgres'], '#14b8a6');
|
| 540 |
+
subChips(nodesG, stCX, storC.y+storC.h+86, ['Data Lakes'], '#14b8a6');
|
| 541 |
+
|
| 542 |
+
// Agents -> Storage arrow (from agents layer to side storage card)
|
| 543 |
+
drawConn(arrowsG, centerX, aY+aH-10, stCX+65, storC.cy, '#14b8a6', {dashed:true, opacity:0.5});
|
| 544 |
+
|
| 545 |
+
// Storage -> Context Store feedback (curving up from storage to context store)
|
| 546 |
+
arrowsG.append('path')
|
| 547 |
+
.attr('d', `M${stCX},${storC.y+10} C${stCX-40},${storC.y+10} ${stCX-40},${csY+csH/2} ${centerX},${csY+csH/2}`)
|
| 548 |
+
.attr('fill','none').attr('stroke','#2563eb').attr('stroke-width',1.5).attr('stroke-dasharray','4 3').attr('opacity',0.4);
|
| 549 |
+
arrowsG.append('polygon')
|
| 550 |
+
.attr('points',`${centerX},${csY+csH/2} ${centerX-7},${csY+csH/2+4} ${centerX-7},${csY+csH/2-4}`)
|
| 551 |
+
.attr('fill','#2563eb').attr('opacity',0.4);
|
| 552 |
+
arrowsG.append('text').attr('x',stCX-45).attr('y',(storC.y+csY+csH)/2).attr('text-anchor','middle').attr('fill','#2563eb').attr('font-family','system-ui').attr('font-size','8').attr('font-weight','700').attr('transform',`rotate(-90,${stCX-45},${(storC.y+csY+csH)/2})`).text('CONTEXT-MINING');
|
| 553 |
+
|
| 554 |
// ββ RIGHT: SAFETY + OBSERVABILITY ββ
|
| 555 |
const safetyC = card(nodesG, rightCX, mY+20, 130, 65, '#b91c1c', '\u{1F6E1}\uFE0F', 'Safety', 'Guardrails at prompts, agents, and tool level.');
|
| 556 |
subChips(nodesG, rightCX, safetyC.y+safetyC.h+8, ['Guardrails'], '#b91c1c');
|
|
|
|
| 567 |
drawConn(arrowsG, rightCX-65, obsC.cy, centerX+centerW, aY+55, '#065f46');
|
| 568 |
|
| 569 |
// ββ RIGHT LOWER: DESTINATIONS ββ
|
| 570 |
+
const destY = actY+10;
|
| 571 |
+
chip(nodesG, rightCX, destY+4, 'Prompt Library', '#4a6fa5', 'Versioned, reusable prompt templates.');
|
| 572 |
+
chip(nodesG, rightCX, destY+38, 'Wiki / KM', '#14b8a6', 'Organizational knowledge from agent outputs.');
|
| 573 |
+
chip(nodesG, rightCX, destY+72, 'Data Warehouse', '#6366f1', 'Analytics, compliance, long-term retention.');
|
| 574 |
+
|
| 575 |
+
// Storage -> Destinations arrows (from storage card to destinations on the right)
|
| 576 |
+
drawConn(arrowsG, stCX+65, storC.y+storC.h-10, rightCX-60, destY+4+14, '#4a6fa5', {dashed:true, opacity:0.4});
|
| 577 |
+
drawConn(arrowsG, stCX+65, storC.y+storC.h-5, rightCX-50, destY+38+14, '#14b8a6', {dashed:true, opacity:0.4});
|
| 578 |
+
drawConn(arrowsG, stCX+65, storC.y+storC.h, rightCX-60, destY+72+14, '#6366f1', {dashed:true, opacity:0.4});
|
| 579 |
|
| 580 |
// Embedding -> Vector Store
|
| 581 |
drawConn(arrowsG, centerCX+160, mY+20+28, centerCX+140, csY+25, '#8b5cf6', {dashed:true, opacity:0.35});
|