July 5, 2026

SchemAI — an AI-powered schematic assistant for KiCad

Building an open-source tool that parses KiCad schematics into a structured circuit graph and lets you ask an LLM questions about your design — architecture, code walkthrough, and future plans.

  • kicad
  • electronics
  • ai
  • python
  • open-source

I’ve been thinking about how to bring LLM-based analysis into electronics design. KiCad’s schematic format (.kicad_sch) is already structured text — an S-expression tree that describes every component, pin, wire, and label in the design. That means you don’t need computer vision to “understand” a schematic. You can parse it, build a connectivity graph, and feed that graph to an LLM.

This post introduces SchemAI, a proof-of-concept tool I built that does exactly that.

What it does

You point SchemAI at a KiCad schematic and ask questions:

$ python3 main.py board.kicad_sch "Explain the power delivery section"

Or use interactive mode:

$ python3 main.py board.kicad_sch
> /focus U7
> What voltage does this regulator output?
> Are the decoupling capacitors correctly placed?

The LLM sees a structured YAML representation of the circuit — components with pin names, nets with connectivity — not pixels. This turns out to be much more reliable than trying to interpret a screenshot.

Architecture

The tool is about 300 lines of Python split across four files:

SchemAI/
├── sexpr_parser.py     # S-expression parser (pyparsing)
├── kicad_sch.py        # KiCad schematic → circuit graph
├── llm_interface.py    # LLM backend (opencode)
└── main.py             # CLI entry point

1. Parse the S-expression (sexpr_parser.py)

KiCad’s .kicad_sch format is a sexpr tree. Using pyparsing, the parser turns this:

(symbol
    (lib_id "Device:R")
    (at 113.03 90.17 0)
    (property "Reference" "R1")
    (property "Value" "1K")
    (pin "1" (uuid "..."))
    (pin "2" (uuid "...")))

Into a nested Python list that the rest of the tool can traverse.

2. Extract components and connectivity (kicad_sch.py)

The schematic parser walks the sexpr tree and builds two things:

  • Components: each placed symbol with its reference, value, and pin definitions (resolved from lib_symbols)
  • Nets: groups of connected coordinates built from wire segments, junction points, and label assignments

Pin coordinates are matched to wire endpoints by computing absolute positions from the symbol’s placement and the library pin offsets. Every coordinate that’s electrically connected (via wires and junctions) forms a net group, and labels give those nets meaningful names.

The result is a YAML representation like this:

components:
  U7:
    value: TLV73328PDBVT
    pins: {'1': 'VIN', '2': 'GND', '3': 'EN', '4': 'NC', '5': 'VOUT'}

nets:
  net_#PWR0108_U7:
    connections: [#PWR0108:1, U7:1]
  net_#PWR0122_U7:
    connections: [#PWR0122:1, U7:5]

3. Send to an LLM (llm_interface.py)

The YAML is sent to an LLM via opencode (though you can substitute ollama, OpenAI, or Anthropic). The prompt tells the model to analyze the circuit as an electronics engineer — identify ICs, trace power topology, flag potential issues.

Real-world example

Running /focus U7 on a camera board schematic containing OV9281 image sensors, TLV733 regulators, and level shifters:

The TLV73328PDBVT is a low-dropout regulator converting +3.3V to +2.8V. Pin 3 (EN) is tied to ground — for an active-high enable part, this means the regulator is disabled. The output net (+2.8V) will float unless the enable pin is pulled high.

The LLM correctly identified a real issue: the EN pin was grounded. This is exactly the kind of review an AI assistant can add on top of traditional ERC.

Limitations (current PoC)

The proof-of-concept works well on individual sheets but has some gaps:

  • Global nets: Power symbols like +3V3 appear as separate nets per instance instead of being merged into one global net. A power symbol label lookup is needed.
  • Multi-sheet designs: Hierarchical sheets aren’t traversed yet — you get one sheet at a time.
  • Pin coordinate resolution: Symbol rotation and mirroring aren’t fully handled, which can cause missed connections on complex multi-unit symbols.
  • Context window: Large schematics blow past the 8K token context window. The /focus command works around this by only sending the subcircuit around a selected component.

Future development

The graph-based core opens up several directions beyond the current PoC:

Deterministic analysis (graph algorithms)

Before the LLM even sees the data, graph algorithms can handle:

  • Signal path tracing: shortest path between two pins, with component type awareness
  • Power tree reconstruction: trace from each power input through regulators to every powered pin
  • Floating pin detection: pins connected to nothing (beyond basic ERC)
  • Topology classification: identify common patterns (voltage dividers, RC filters, differential pairs)

Better AI integration

  • Multi-round conversation: remember context across follow-up questions
  • Component datasheet injection: pull pin functions from .kicad_sym or real datasheets
  • Design review checklist: systematic checks for decoupling, pull-ups, level compatibility
  • Auto-generated documentation: describe the full schematic in prose

KiCad integration

The natural end state is a KiCad Action Plugin that:

  • Runs inside KiCad’s GUI
  • Responds to selection events (“explain what I clicked”)
  • Shows results in a docked panel
  • Highlights nets or components on the canvas when referenced

Architectural vision

The broader vision is a layered system where deterministic algorithms handle what they’re good at (signal tracing, topology, ERC) and the LLM focuses on interpretation and discussion:

              KiCad
                ↓
      Schematic Parser
                ↓
        Circuit Graph
                ↓
    ┌───────────┴───────────┐
    │                       │
  Rule-based            AI reasoning
  analysis              (LLM)
    │                       │
  ERC checks           Explanations
  Power tracing        Q&A
  Signal paths         Documentation
  Topology             Design review
    │                       │
    └───────────┬───────────┘
                ↓
        Chat / Panel UI

Getting started

The code is on GitHub: github.com/daniel-petrovic/SchemAI. Requires Python 3.10+, pyparsing, and opencode (or another LLM backend).

git clone <url> && cd SchemAI
python3 main.py your_schematic.kicad_sch

For the best experience, start the opencode server first:

opencode serve --port 4096 &
./start.sh your_schematic.kicad_sch

The /focus command is your best friend for large designs — it sends only the relevant subcircuit to the LLM, keeping responses fast and focused.

Why this approach works

KiCad’s structured format is the key insight here. Unlike image-based analysis of PDF schematics — which requires OCR, symbol detection, and net tracing — the .kicad_sch file already encodes the connectivity graph. An LLM that receives a graph of components and nets can reason about circuit behavior far more accurately than one looking at pixels.

The graph representation also means you can layer traditional algorithms alongside the LLM: shortest-path routing for signal tracing, connected-component analysis for power domains, and pattern matching for common topologies. The LLM doesn’t have to guess — it receives curated, structured data.

I’m planning to keep developing this. If you work with KiCad and have thoughts on what features would be most useful, feel free to reach out.