← Blog
· OLAV Team

OLAV vs. Log-Based AI: Why Network Operations Needs More Than a Smarter grep

Most 'AI for operations' tools are just putting an LLM on top of log search. OLAV takes the opposite approach: model the network engineer's entire workflow — collection, parsing, layered diagnosis, snapshot comparison, simulation, and change planning — as a team of AI specialists. Here's why that matters and how it works.

Architecture NetOps AI Agent Log Analysis Root Cause Analysis

The log trap

Here’s what most “AI for operations” tools do under the hood:

  1. Ship your logs to a vector database
  2. Put an LLM in front of it
  3. When something breaks, the LLM searches for relevant log lines and summarizes them

This is useful. It’s also exactly the same architecture as a documentation chatbot from 2023 — just pointed at log files instead of PDFs. When your network goes down at 3 AM, this is what you get back:

“Between 02:47 and 03:12, BGP peer 10.0.0.2 transitioned to Idle state 4 times. The logs show ‘BGP-5-ADJCHANGE’ events on R3. This may indicate a network connectivity issue. Recommended: check physical connectivity between R3 and its BGP peer.”

That’s a smarter grep. It told you what you already knew, offered something you’d do anyway, and couldn’t tell you why the peer went Idle — because it only has one data source (logs) and one analytical lens (pattern matching). It’s answering from the symptoms, not from the state.

What a network engineer actually does

When a real engineer troubleshoots “BGP peer down on R3,” they don’t start by reading log files. They follow a layered, evidence-driven process:

  1. State check — What’s the current interface status on R3? Is the physical link up? What does show ip bgp summary say right now?
  2. Topology check — Who is R3 connected to? Via which interfaces? What discovery protocol (LLDP/CDP)?
  3. L1→L4 bottom-up diagnosis — Is the interface administratively down? Wrong MTU? No IGP route to the peer’s loopback? ACL blocking TCP 179?
  4. Historical correlation — Was there a topology change right before the flap? Did the interface last-change timestamp match the BGP down time?
  5. Cross-snapshot comparison — Did anything change between the last known-good snapshot and now? New config line? Different neighbor list?
  6. Root cause — It’s not “BGP neighbor went down.” It’s “R3 Gi0/2 link was removed in the 04:00 maintenance window, breaking the IGP path to the peer’s loopback, which caused BGP to transition to Idle.”

This is fundamentally a multi-source, cross-layer, temporal correlation problem. Logs are one input — critical, but insufficient alone. The engineer needs structured device state, topology, routing tables, config text, and the ability to compare all of these across time.

Two fundamentally different architectures

flowchart LR
    subgraph A["Log-Based AI System"]
        L[Logs / Syslog] --> VDB[Vector DB]
        Q[User Query] --> LLM1[LLM]
        VDB --> LLM1
        LLM1 --> R1["'BGP went down — check connectivity'"]
    end

    subgraph B["OLAV NetOps"]
        direction TB
        SSH[Nornir SSH Collect] --> P[TextFSM / PaC Parse]
        P --> DB[(DuckDB<br/>12+ structured views)]
        S[Syslog Parquet] --> EVD[query_evidence]
        DB --> AG[NetOps Orchestrator]
        EVD --> AG
        AG --> RP[Reporter<br/>L1→L4 Investigation]
        AG --> AN[Analyzer<br/>Change Planning]
        AG --> SM[Simulator<br/>Batfish Verification]
        AG --> TP[Topology Engine<br/>CDP/LLDP/BGP]
        RP --> R2["Root Cause:<br/>'R3 Gi0/2 removed at 04:00 →<br/>IGP path lost → BGP Idle'"]
        AN --> R2
        SM --> R2
        TP --> R2
    end

    style A fill:#1a1a2e,stroke:#e94560,color:#eee
    style B fill:#0f3460,stroke:#16c79a,color:#eee

The log-based system is a single-agent RAG pipeline: embed, retrieve, summarize. It operates entirely inside a text similarity space. It cannot answer “what changed between yesterday and today” because yesterday’s structured state doesn’t exist in its vector database.

OLAV is a multi-agent operating system for network engineering: each specialist agent owns one capability domain, the orchestrator routes intent, and every agent is grounded in both structured state (DuckDB, 12+ auto-views of device show output) and unstructured evidence (syslog, command output, config text).

The data: structured state, not log lines

This is the deepest difference and the one that matters most at 3 AM. Here’s what each system has to work with:

Data LayerLog-Based AI SystemOLAV NetOps
Device inventory❌ Nonenetops.devices — hostname, platform, vendor, role, site, management IP
Interface state❌ Nonev_show_interfaces_auto / v_show_interfaces_terse_auto — admin/oper status, IP, MTU, last-change
BGP state❌ Nonev_bgp_neighbors_auto — peer, state, prefixes received, uptime, AS
OSPF state❌ Nonev_ospf_neighbors_auto — neighbor, state, area, interface
Topology❌ Nonetopology_links — CDP/LLDP adjacencies, source/dest device + interface
Routing table❌ Nonev_show_ip_route_auto — destination, next-hop, protocol, interface
Logs (syslog)✅ Primary sourcequery_evidence(source="syslog") — secondary evidence, cross-referenced with state
Config text⚠️ If ingestedquery_evidence(source="config") — running/startup config search
CLI output❌ Nonequery_evidence(source="command_output") — raw show command output text search
Snapshots (time series)❌ NonePer-snapshot history in parsed_outputs; diff_snapshots for row-level comparison

When a BGP peer flaps, the log system can tell you “it flapped.” OLAV can tell you:

  1. The interface was UP throughout (v_show_interfaces_terse_auto)
  2. But the IGP route to the peer’s loopback disappeared between snapshots (v_show_ip_route_auto, diff_snapshots)
  3. The topology shows R3’s Gi0/2 link was the only L2 path to that peer’s subnet (topology_links)
  4. A maintenance window at 04:00 matches the Gi0/2 updated_at timestamp (netops.devices)

That’s the difference between an alert and a root cause.

Knowledge injection: the team doesn’t start from zero

Here’s another structural gap. A log-based AI agent starts every query from scratch: it has the prompt, the user’s question, and the retrieved log lines. That’s it.

OLAV’s agents start every query with three layers of pre-injected knowledge:

flowchart TD
    subgraph Inject["Knowledge Injection (before agent runs)"]
        direction TB
        L1["Layer 1: guide.yaml<br/>Domain expertise<br/>e.g. 'BGP Idle → check interfaces first'<br/>e.g. 'L1→L4 bottom-up diagnosis sequence'"]
        L2["Layer 2: memory_primer<br/>Data profile at ingest time<br/>e.g. 'v_bgp_neighbors_auto has columns: peer, state, ...'<br/>e.g. 'state column values: Established(8), Idle(1)'"]
        L3["Layer 3: AutoRecall<br/>Lessons from past failures<br/>e.g. 'Last time: filter was too broad → LIMIT 20'<br/>e.g. 'This topology: R3-R4 link is redundant'"]
    end

    subgraph Agent["Sub-Agent Execution"]
        AG[Reporter / Analyzer / Simulator]
    end

    L1 --> AG
    L2 --> AG
    L3 --> AG
    Q[User Query] --> AG

    style Inject fill:#16213e,stroke:#0f3460,color:#eee
    style Agent fill:#0f3460,stroke:#16c79a,color:#eee

Layer 1guide.yaml files are domain expertise encoded as retrievable, scope-filtered instructions. When a user asks “why is BGP flapping,” the fault_analysis_workflow.guide.yaml is automatically injected. It tells the agent: “first gather L1 evidence (interface status), then L3 (route to peer), then L4 (TCP 179). Only descend to protocol attributes after L1-L4 clean.”

Layer 2memory_primer runs at ingest time, not query time. When device data is collected, it pre-computes the schema of every auto-view and the value distribution of every state column, and writes them to LanceDB. When the agent wakes up to answer a question, it already knows what tables exist, what columns they have, and what values are normal — without running a single DESCRIBE TABLE.

Layer 3AutoRecall captures failure patterns from past runs and injects them as constraints. If the agent ran a query with a too-broad filter last week and got 12,000 rows back (blowing context), next week’s query carries the lesson: “Last time on this topology, WHERE state='Established' returned 8 rows with LIMIT 20. Use that.”

This is not RAG. RAG retrieves similar documents. OLAV’s knowledge injection retrieves actionable constraints — guides that tell the agent how to think, schema that tells the agent what data exists, and reflections that tell the agent what not to do again.

The “team” architecture: one orchestrator, seven specialists

A single agent with 30 tools doesn’t work on a small local model — the tool schemas alone consume half the context window, and tool-selection errors multiply. OLAV takes the opposite approach:

flowchart TD
    U[User: 'Why is R3's BGP down?'] --> ORCH[NetOps Orchestrator<br/>3 tools: memory, search, delegate]

    ORCH --> R["task('reporter', ...)<br/>L1→L4 Investigation"]
    ORCH --> A["task('analyzer', ...)<br/>Change Plan Draft"]
    ORCH --> S["task('simulator', ...)<br/>Batfish Verification"]
    ORCH --> C["task('collector', ...)<br/>SSH Probe"]
    ORCH --> I["task('importer', ...)<br/>Offline Bundle Import"]
    ORCH --> T["task('topology', ...)<br/>Topology Queries"]
    ORCH --> L["task('learner', ...)<br/>Parser Learning"]

    R --> DB[(DuckDB<br/>Structured State)]
    R --> SL[Syslog Parquet]
    A --> DB
    S --> DB

    style ORCH fill:#1a1a2e,stroke:#e94560,color:#eee
    style R fill:#0f3460,stroke:#16c79a,color:#eee
    style A fill:#0f3460,stroke:#16c79a,color:#eee
    style S fill:#0f3460,stroke:#16c79a,color:#eee

Each specialist has only 4–7 tools — exactly what its domain needs. The reporter has execute_sql, inspect_blast_radius, format_and_export, and execute_skill_script — the last runs domain scripts like query_evidence and diff_snapshots. It cannot SSH to a device. It cannot write a change plan. The analyzer has a different tool set. The simulator has yet another. This is the principle of least authority, applied to AI agents.

The orchestrator is a pure router: it holds only memory (olav_recall_memory / olav_store_memory) and web_search, plus the framework-injected task() delegation. Its entire job is to classify intent and dispatch to one specialist. It does not reason about the problem. It does not synthesize results. It returns the specialist’s output verbatim.

Compare this to a log-based AI system: one agent, one prompt, one tool set — “search logs, then explain.” It’s a solo operator with a flashlight. OLAV is a NOC team.

The self-improving loop: getting smarter with every investigation

Here’s something log-based systems fundamentally can’t do: learn from their own mistakes and apply those lessons automatically.

sequenceDiagram
    participant U as User
    participant A as Agent
    participant TL as trace_learner
    participant M as LanceDB Memory
    participant AR as AutoRecall

    U->>A: "Why is BGP flapping on R3?"
    A->>A: Runs query with LIMIT 100 → 12,000 rows → context overflow
    A-->>U: Timeout / Partial Answer

    Note over TL: Post-mortem: captures failure pattern
    TL->>M: Write reflection:<br/>"BGP queries against this fleet MUST use LIMIT 20,<br/>filter by device_name. LIMIT 100 produced 12K rows."

    U->>A: "Why is BGP flapping on R3?" (next week)
    AR->>M: AutoRecall: fetch relevant reflections
    M-->>AR: "BGP queries: LIMIT 20, filter by device_name"
    AR-->>A: Injected into prompt BEFORE execution
    A->>A: Runs query with LIMIT 20, device_name='R3' → 8 rows
    A-->>U: Root cause analysis complete

This is the trace_learnerreflectionAutoRecall loop. Every failed tool call, every context overflow, every timeout leaves a trace. The learner distills these into compact, actionable constraints (one line each, 30-day TTL). On the next similar query, AutoRecall injects the constraint before the agent starts working — so the mistake is never repeated.

This loop operates without any human intervention. No prompt editing. No “fine-tuning with error examples.” The system observes failure → captures the lesson → applies it automatically on the next attempt. That’s AI-native operations engineering, not RAG with extra steps.

When logs aren’t enough: the Parser-as-Code answer

One more hard difference. What happens when a traditional log-based AI system encounters a device whose show output format it doesn’t recognize?

It fails. Gracefully, maybe, but it fails — “unknown format” or “no parser available.”

OLAV’s learner sub-agent takes a different approach. When a new device platform produces unparseable show command output:

  1. Multi-sample training — The learner groups raw outputs by (platform, command) across all devices, feeds them all to the LLM in one prompt
  2. PaC (Parser-as-Code) generation — The LLM emits a Python function, not a config file
  3. AST whitelist sandbox — The generated code is validated: no import os, no subprocess, no open() — only re, json, ipaddress, and a handful of safe modules
  4. Multi-device cross-validation — The parser must produce valid records for ≥70% of the expected data rows from all devices
  5. Quarantine for single-sample — A parser validated against only one device lands in _quarantine/ until a second corroborating sample arrives

This means OLAV can adapt to new hardware without anyone writing a TextFSM template. The system learns the format by observing multiple examples, validates the parser mechanically, and quarantines uncertain results. A log-based system cannot do this — it has no mechanism to convert unstructured device output into structured state.

Summary: the full capability matrix

CapabilityLog-Based AI SystemOLAV NetOps
Data sourcesSyslogSyslog + 12+ structured show command views + topology + device configs
Structured stateNoneFull DuckDB schema: devices, interfaces, BGP, OSPF, routes, topology, raw/parsed outputs
Temporal analysisTime-range log searchCross-snapshot row-level diff (diff_snapshots)
Root cause methodPattern matching → LLM summaryL1→L4 layered diagnosis → cross-layer contradiction detection → evidence chain
Knowledge managementRAG (retrieve similar log lines)3-layer injection: guide.yaml + memory_primer + AutoRecall reflections
Agent architectureSingle agent, all tools exposed1 orchestrator + 7 specialists, 4–7 tools each, principle of least authority
Unknown format handling”No parser available”PaC self-learning parser (AST sandbox + multi-device validation + quarantine)
Change planningNoneFull pipeline: analyze state → draft CLI per device + rollback → Batfish simulation → ContainerLab validation
Self-improvementNonetrace_learner → reflection → AutoRecall: failures captured as constraints, automatically applied
Context budget controlNone (full log dump)Tier-based: small=8K / medium=32K / large=200K, auto-truncation, summarization at 50% budget
Write safetyNone7-layer defense: default read-only, per-service control, dry-run, HITL, sandbox, network isolation, audit

The bottom line

A log-based AI system is a search engine with a polite summary on top. It tells you what happened, and sometimes what might be wrong, but always from the narrow perspective of log patterns.

OLAV is an AI-native network engineering operating system. It collects structured state, not just log lines. It diagnoses across layers, not just patterns. It compares across time, not just the current moment. It learns from failure and applies the lesson automatically. And it does all of this on hardware you already have — not on a cloud GPU cluster.

The difference isn’t incremental. It’s the difference between an alert and a diagnosis. Between a symptom and a root cause. Between a smarter grep and a network engineer who never sleeps.