Agentic architecture
Claude Code's Agentic Architecture → Lessons for Ogur
What Claude Code Actually Is (Architecturally)
Claude Code is not "a chatbot with tools." It's a multi-agent runtime with a clear separation between:
- A coordinator layer (routes work, manages lifecycle, owns state)
- Specialist agents (isolated tool pools, scoped system prompts, one job each)
- A swarm bus (inter-agent messaging, broadcast, cross-session routing)
- A persistent memory layer (scoped: user / project / local)
- A continuous monitoring primitive (KAIROS: always-on async agents that survive parent termination)
Every design decision in Claude Code optimizes for the same constraint Ogur faces: many independent tasks that must run concurrently without corrupting each other's context.
The 7 Structural Patterns — and What They Mean for Ogur
- Specialist Agents with Declared Contracts
In Claude Code, each agent is defined with explicit metadata: model, tools (allow-list), disallowedTools, permissionMode, maxTurns, background. There is no "general agent doing everything."
Ogur implication: Ogur's sources/ already hints at this — but treat each source as a formal agent definition, not just a Python class. Each monitor should declare: - What it's allowed to access (FDA, ClinicalTrials.gov, SEC EDGAR, PubMed, news) - Its execution budget (rate limits, max tokens, cost ceiling) - Whether it runs sync (on-demand query) or async (always-on watcher) - What signal schema it produces
The drug/trial landscape is too broad for one generalist. A CompetitorPipelineAgent and a RegulatoryFilingAgent have fundamentally different update frequencies, data shapes, and reliability profiles — they should not share a context.
- The Coordinator Pattern (Orchestrator vs. Executor Split)
Claude Code's Coordinator Mode separates the agent that decides what to do from the agents that do it. The coordinator never directly touches files — it delegates and synthesizes. Leaf agents never see each other's outputs.
Ogur implication: Ogur needs a Signal Orchestrator that: 1. Receives a query or trigger ("What is Merck doing in NSCLC?") 2. Fans out to specialist monitors 3. Receives normalized Signal objects back 4. Deduplicates (Ogur already has content_hash — this is the right primitive) 5. Synthesizes and ranks by strategic relevance
Without this split, you get coupled spaghetti: a source that scrapes ClinicalTrials.gov shouldn't be making judgments about competitive significance. That's the coordinator's job.
- Sync vs. Async as a First-Class Lifecycle Decision
Claude Code uses a single flag (shouldRunAsync) to route execution. Async agents get their own AbortController — they survive the parent being killed and terminate only via an explicit killAgents call. This is architecturally clean.
Ogur implication: Ogur has two fundamentally different use modes:
┌───────────────┬─────────────────────┬─────────────────┬───────────────────────────────┐ │ Mode │ Trigger │ Latency │ Example │ │ │ │ requirement │ │ ├───────────────┼─────────────────────┼─────────────────┼───────────────────────────────┤ │ On-demand │ BD team asks a │ Seconds │ "What's the enrollment status │ │ (sync) │ question │ │ of NCT0123?" │ ├───────────────┼─────────────────────┼─────────────────┼───────────────────────────────┤ │ Always-on │ Scheduled / │ Minutes to │ "Alert when a competitor │ │ (async) │ event-driven │ hours │ files a new IND" │ └───────────────┴─────────────────────┴─────────────────┴───────────────────────────────┘
These must be separate execution paths from the start. Mixing them leads to always-on monitors blocking interactive queries, or interactive queries timing out because a scraper is hogging the event loop. Design the async path to be fire-and-forget with notification on completion — exactly Claude Code's pattern.
- KAIROS: The Always-On Primitive
KAIROS is listed as an unreleased feature, but its signature is visible in the agent system: it triggers async execution and represents a proactive module — an agent that runs continuously without being prompted.
This is the most important pattern for Ogur. Claude Code is a reactive tool (you type, it acts). Ogur is fundamentally proactive — it must surface intelligence before the BD team knows to ask.
Ogur implication: Design a Watcher Layer modeled on KAIROS: - Watchers are long-lived async agents registered with a cron schedule - Each watcher owns a specific monitoring scope (a drug, a company, a trial) - On signal detection, they push to an alert queue (not directly to the user) - A separate Digest Agent reads the queue and synthesizes a strategic briefing
The Watcher should have no opinion about strategic significance — it only detects change. Judgment lives in the Digest Agent.
- The Swarm Bus → Signal Deduplication and Cross-Agent Coordination
Claude Code's SendMessageTool enables agents to communicate: point-to-point, broadcast (*), or via Unix domain sockets for cross-session peers. This solves the problem of multiple agents discovering the same fact independently.
Ogur implication: Multiple source agents will surface the same signal (e.g., a Pfizer/BioNTech collaboration announced in a press release, an SEC 8-K, and a ClinicalTrials.gov update). Ogur's content_hash dedup is necessary but not sufficient — two different hashes can represent the same intelligence.
Design a Signal Bus where: - Source agents publish raw signals - A dedup/merge step reconciles semantic equivalents (not just hash equivalents) - Downstream agents (ranking, synthesis) consume from the bus, not directly from sources
This decouples ingestion from analysis and allows sources to be added/removed without touching downstream logic.
- Memory Scoping: Three Layers for Three Purposes
Claude Code has three memory scopes: user (who they are, preferences), project (ongoing work, decisions), local (session-only). Each serves a different persistence horizon.
Ogur implication: Pharma intelligence has a natural three-layer memory structure:
┌─────────┬───────────────────────────┬──────────────────────────────────────────────────┐ │ Layer │ Ogur equivalent │ Examples │ ├─────────┼───────────────────────────┼──────────────────────────────────────────────────┤ │ User │ Client profile │ Which therapeutic areas, competitive set, deal │ │ │ │ stage │ ├─────────┼───────────────────────────┼──────────────────────────────────────────────────┤ │ Project │ Active intelligence │ Ongoing BD target analysis, competitor watch │ │ │ threads │ │ ├─────────┼───────────────────────────┼──────────────────────────────────────────────────┤ │ Signal │ Raw intelligence store │ The Signal table — already exists │ └─────────┴───────────────────────────┴──────────────────────────────────────────────────┘
What's missing from the current schema is the client context layer. Right now Ogur collects signals without knowing who cares about them or why. A BD team tracking Roche in oncology needs different signal filtering than a strategy team mapping the ADC landscape. Memory scoping makes Ogur's output relevant, not just accurate.
- Model Tiering: Match Compute to Task Complexity
Claude Code assigns different models to different agent types. Explore/Plan agents use haiku (fast, cheap, read-only). Coordination and synthesis use more capable models. The key insight: omitClaudeMd: true on read-only agents "saves ~5-15 Gtok/week" at scale.
Ogur implication: Ogur will run continuously — model cost is not a one-time concern. Design a compute tier from the start:
┌──────────────────────────────────────────┬────────────┬────────────────────────────────┐ │ Task │ Model tier │ Rationale │ ├──────────────────────────────────────────┼────────────┼────────────────────────────────┤ │ Signal classification ("is this │ Fast/cheap │ High volume, binary decision │ │ relevant?") │ │ │ ├──────────────────────────────────────────┼────────────┼────────────────────────────────┤ │ Entity extraction (drug names, trial │ Fast/cheap │ Structured output, low │ │ IDs) │ │ ambiguity │ ├──────────────────────────────────────────┼────────────┼────────────────────────────────┤ │ Competitive significance scoring │ Mid-tier │ Requires domain judgment │ ├──────────────────────────────────────────┼────────────┼────────────────────────────────┤ │ Strategic synthesis / briefing │ Powerful │ High-stakes, low-frequency │ │ generation │ │ │ └──────────────────────────────────────────┴────────────┴────────────────────────────────┘
Running a powerful model on classification is the equivalent of using a surgeon to take blood pressure — correct but wasteful at scale.
The Architectural Blueprint for Ogur
Synthesizing all seven patterns, Ogur's target architecture looks like:
┌─────────────────────────────────────────────────────┐ │ WATCHER LAYER (KAIROS) │ │ Scheduled async agents — one per monitoring scope │ │ Detect change, publish raw signals, no judgment │ └──────────────────────┬──────────────────────────────┘ │ raw signals ┌──────────────────────▼──────────────────────────────┐ │ SIGNAL BUS │ │ Dedup (hash + semantic), normalize, enrich │ │ → Signal table (already exists) │ └──────────────────────┬──────────────────────────────┘ │ deduplicated signals ┌──────────────────────▼──────────────────────────────┐ │ COORDINATOR / ORCHESTRATOR │ │ Routes on-demand queries + scheduled digests │ │ Fans out to specialist agents, synthesizes output │ └────────┬────────────────────────┬───────────────────┘ │ on-demand │ scheduled digest ┌────────▼────────┐ ┌─────────▼──────────┐ │ Query Agents │ │ Digest Agent │ │ (sync, fast) │ │ (async, powerful) │ │ One per source │ │ Reads alert queue │ │ Haiku-class LLM │ │ Opus-class LLM │ └─────────────────┘ └────────────────────┘ │ ┌──────────▼──────────┐ │ Client Memory Layer │ │ Who cares, and why │ └─────────────────────┘
The Three Things to Build Next (in order)
- Formalize the agent contract — Every source becomes an explicit agent definition with declared scope, budget, and output schema. No agent does more than one thing.
- Build the Watcher Layer first — The always-on, async, cron-driven monitors are Ogur's core value. An on-demand query tool is useful; a system that tells you what you didn't know to ask is the product.
- Add client memory before adding more sources — More data without relevance filtering is noise. The client profile layer (which therapeutic areas, which companies, which deal stage) is what transforms raw signals into actionable intelligence.
★ Insight ───────────────────────────────────── - Claude Code's most transferable pattern is the coordinator/executor split — the orchestrator never directly touches data, it only routes and synthesizes. This prevents the common failure mode where a single "smart agent" accumulates too many responsibilities and becomes unmaintainable. - The shouldRunAsync single-flag routing is deceptively simple. It works because the decision is made once at spawn time, not scattered across the agent's lifecycle. Ogur should adopt the same discipline: classify every monitor as sync or async at registration time, never dynamically. - KAIROS (always-on) combined with the Digest pattern solves Ogur's core product question: how do you surface intelligence nobody knew to request? The answer is proactive watchers feeding a synthesis layer — not a smarter query interface.