Context & Engineering Objective
HVAC codes are hierarchical, cross-referenced, and full of requirements whose meaning depends on the relationship between an equipment type, a location, a material, a safety device, or a standard. A conventional keyword search can find matching words, but it does not naturally answer questions such as where a furnace is prohibited or which clearance applies to a specific installation.
This project converts the source document into an explicit Neo4j knowledge graph and lets a user ask natural-language questions without writing Cypher. The active system is best described as a graph-first regulatory question-answering prototype: structured graph retrieval is operational, while semantic vector retrieval remains a planned extension in the current clean-graph build.
Role & Project Scope
I developed the document-ingestion, graph-modeling, entity-normalization, query-generation, agent, validation, and Streamlit layers represented in the public repository. The prototype is intended to demonstrate auditable retrieval from one HVAC code corpus. It is not a production compliance service, a substitute for reviewing the governing code, or a multi-code authority.
- Preserve chapter, section, subsection, and table structure while extracting code text from PDF documents
- Represent precise compliance relationships such as prohibited locations, required clearances, safety devices, and referenced standards
- Translate a user's question into safe, targeted graph retrieval without requiring Cypher knowledge
- Normalize abbreviations and user phrasing before generating a schema-aware graph query
- Return requirements with the source sections needed for verification
Methodology
The ingestion pipeline first extracts PDF text, identifies chapters and nested sections, and preserves the section number as the primary traceability key. Tables receive separate Table and TableRow nodes instead of being flattened into surrounding prose. A domain vocabulary and fuzzy matching normalize equipment, locations, materials, standards, and safety devices before relationship extraction.
- Parsed HVAC code PDFs with PyMuPDF and pdfplumber, retaining 667 sections, 20 tables, and 182 table rows
- Used spaCy, pattern matching, and an HVAC vocabulary to identify equipment, locations, materials, standards, safety devices, and their relationships
- Loaded a graph schema with 10 node types and nine relationship types into Neo4j
- Stored the originating section in each regulatory relationship through a
code_refproperty - Generated schema-aware, read-only Cypher from the normalized question and returned the graph result to a LangChain ReAct agent
- Validated and sanitized Streamlit inputs before they entered the agent workflow
The two-stage query path separates entity recognition from relationship retrieval. For example, a user’s shorthand for an air-conditioning unit is first normalized to the graph vocabulary; the subsequent prompt generates Cypher against known node and relationship types. This reduces the burden on the language model and keeps section references attached to the retrieved result.
Engineering Decisions & Trade-Offs
Cypher-first retrieval was selected because the highest-value questions are relational and precise. An embedding may find prose that resembles “furnace in a bedroom,” while an explicit PROHIBITED_IN edge can return the location, reason, and originating section directly. The graph therefore carries both domain meaning and evidence provenance.
Tables were modeled separately because clearance and gauge requirements often live in rows rather than prose. Materialized section paths preserve document hierarchy, and fuzzy vocabulary matching absorbs user-language variation without changing the graph schema. The agent prompt restricts generated queries to read-only clauses, while the application rejects empty, oversized, and suspicious inputs before execution.
The repository defines CypherQuery, VectorSearch, and HybridSearch interfaces, but they are not three equivalent production paths. The current ETL explicitly skips vector-index creation. VectorSearch checks for that index and reports that it is unavailable; HybridSearch therefore combines the valid Cypher result with an unavailable-vector message. The page shows this boundary instead of presenting planned functionality as completed work.
Results & Validation
Documented ETL output The repository documentation records a graph with 974 nodes and 1,328 relationships, including 667 sections, 20 tables, and 182 table rows. These totals describe the documented ingestion run; they were not independently regenerated during the portfolio rewrite.
Implemented path The active Cypher workflow supports section lookups and structured questions about prohibitions, clearances, required devices, permitted locations, standards, and table data. Returned relationship properties include the section reference needed for a traceable answer.
The technical roadmap lists success-rate and response-time figures, but the public repository does not contain the stated executable 22-query evaluation suite. Those figures are therefore omitted here. The defensible result is the implemented, section-referenced retrieval architecture—not an unsupported production-accuracy claim.
Impact, Limitations & Next Steps
The project demonstrates how regulatory text can be converted into an explicit information model that supports inspectable retrieval. Its practical value is auditability: a user can see which relationship was traversed and which code section supports the answer. That structure is more appropriate for precise compliance questions than relying on embedding similarity alone.
The current prototype covers one source corpus, uses pattern-based relationship extraction, depends on an external language model for Cypher generation and synthesis, and has no published reproducible evaluation harness. Generated queries are checked against a blocklist of mutating Cypher keywords before execution, but that guardrail is not a complete Cypher parser or evidence of least-privilege database credentials. Vector and hybrid retrieval should remain labeled as future work until embeddings, TextChunk relationships, a Neo4j vector index, and failure-mode tests are added. A stronger next phase would introduce a versioned question set, compare generated answers against expert-reviewed references, and report citation correctness separately from answer completeness.