AI Engineer · Phoenix, Arizona

Harianth Kalavala

I build retrieval systems that turn unstructured data into something production can depend on. Above is my own work, modelled as the kind of graph I build for a living.

01 Why

I finished my bachelor's in Hyderabad and moved to Arizona a few months later, in 2023.

I came for the master's at ASU, and I came to find out how somewhere else thinks — a different country, different people, a different set of defaults about how things get built and why they get built that way.

That instinct turned out to be most of the job. The useful part of retrieval work is rarely the model; it's asking what a system is actually being asked for, rather than what it was originally designed to answer.

The useful part is rarely the model.

02 Now

AI Engineer at XNode AI

06/2025 – Present · Remote

I architected an enterprise information catalog unifying metadata across PostgreSQL and five other sources, and the ingestion, validation and indexing that keeps it fed.

100K+

Data assets

Discoverable and lineage-tracked through the catalog.

99%+

Pipeline uptime

Ingestion and indexing in production, behind CI/CD and monitoring.

The call that mattered

When similarity isn't enough

Vector retrieval is excellent at finding what a document says. Preserving how things relate to each other is a different problem: chunking optimises for semantic similarity, and a relationship spanning several chunks doesn't survive that split intact. Adding more context doesn't recover it, because the structure is gone before the model ever sees it.

Three text chunks, each holding part of a relationship, with the connections between them broken

Chunked for similarity

The relationship is lost in the split.

The same entities stored as nodes joined by labelled edges, so the relationship survivesbuilt_withproduced

Modelled explicitly

The relationship is the data.

That's not a flaw in RAG so much as a question it was never shaped to answer. So for relational queries I stopped asking retrieval to infer connections and modelled them directly — entity and relationship extraction into Neo4j and Graphiti, running alongside the vector layer rather than replacing it.

Building a graph with correct relations costs a significant number of tokens up front: you pay once at ingestion instead of paying again at every query. It earns that back only if the system answers enough relational questions to justify it — which is exactly the bet worth checking before you make it.

~35%

Faster contextual search

After modelling relationships explicitly rather than inferring them.

03 Explore

The whole thing, as a graph

Every node is a real entity from my work and every edge a relationship that actually exists. Drag to orbit, hover a node to read it, click to pin.

04 Built

Outside the day job

LangGraph Agentic Platform

A multi-agent system for supply chain resilience: real-time news analytics, geospatial risk scoring, and automated alerting. I designed the orchestration layer: state management, tool routing, memory, and the LLM decision loops.

  • LangGraph
  • LangChain
  • Python
  • LLMs
View code →

~60%

Less manual monitoring

Agent orchestration replacing hand-watched supply-chain signals.

Registry Points

A lookup over the World Swing Dance Council's competitor registry. Type part of a name and it finds the dancer, then returns their points by division, how close they are to moving up, a chart of their competitions over time, and a comparison against other dancers on the same axis. Lookups take about a seventh of a second: the original asked the registry for a session token first, and nothing ever checked it.

  • Next.js
  • React
  • REST APIs
  • Vercel
Visit site →

10

Dependencies, down from 53

Twenty-eight Radix packages removed for components that are a few lines of markup.

Trailblaze AZ

A route planner that picks the pretty way instead of the quick one. Every drivable road in Arizona is scored for how close it runs to woodland, wilderness and water, then checked against the roads the state has officially designated scenic. Ask it for Phoenix to Sedona and it sends you over the Mogollon Rim rather than up the interstate, shows the climb that explains the extra two hours, and works out when to leave to arrive in golden hour.

  • Next.js
  • OSRM
  • OpenStreetMap
  • Python
  • MapLibre
Visit site →

931,043

Roads scored

Every drivable way in Arizona, rated against the state's own designated byways.

Retrace

Drop in an OpenTelemetry trace of an LLM app and see what it did: the calls as a tree with timing, and for each one the model, the token counts with cache and reasoning details, the conversation that was sent and what came back, the tool calls, the tools offered and any error. It reads the four shapes such a file comes in, the Python SDK's JSON, OTLP and both of Phoenix's exports, and needs no server or account. The sample is five real spans exported by the OpenTelemetry SDK. It came out of fixing the instrumentors that write these files: six pull requests to four projects, Arize's OpenInference, Traceloop's OpenLLMetry, OpenLIT and Comet's Opik, the first merged the same day.

  • JavaScript
  • OpenTelemetry
  • OpenInference
Open the sample →

4

File shapes read

Every reader is checked in headless Chrome against the same five spans, which must give the same tree whichever shape they arrive in. The two Phoenix readers were corrected against exports from a Phoenix run locally.

Upstream

Type a GitHub username and see every pull request that person has sent to somebody else's project, grouped by project, each marked merged, open or closed with how long it took, and the totals: sent, merged, projects, maintainers, median time to a merge. One search against GitHub's API from the browser, nothing stored. It exists because the profile page counts everything and answers nothing; this answers the one question that matters when you work on other people's code.

  • JavaScript
  • GitHub API
See mine →

33

Pull requests upstream

Sent to twenty eight projects and twenty five maintainers, thirteen merged so far, each one a bug proved with a program before it was sent.

Resolve

A DNS resolver in one Python file, no libraries: it builds the query bytes, starts at a root server and follows each referral down itself instead of asking someone else's resolver to do it. Ask it for en.wikipedia.org with -v and you watch a root server hand it to .org, .org hand it to Wikimedia, and Wikimedia answer with an alias it then chases from scratch. It handles the parts that make real name servers awkward: compression pointers into the same packet, referrals that arrive without the addresses they refer to, and replies too big for a UDP packet, which have to be asked again over TCP. Since then it has learned what a resolver run in production does: it caches answers and missing names for as long as their records allow, offers EDNS0 so big answers fit in one packet, believes each server only about its own zone, and tells each server only the next label down, so the root learns you wanted something in .org and nothing more.

  • Python
  • DNS
  • Sockets
View code →

3

Hops from the root

The root names .org, .org names Wikimedia, Wikimedia answers. The test checks one live name against the system resolver and must agree exactly.

deflate

A gzip compressor built from its two ideas: LZ77, which replaces anything already seen with go back and copy, and Huffman coding, which spends fewer bits on the symbols that occur most. It writes real .gz files, picks the cheapest of the format's three block types so incompressible input never grows, and every test hands the file to Python's gzip, to zlib and to the gzip program, because a compressor checked by its own decompressor only proves the two share the same misunderstanding. It reads gzip files too, but for the same reason its decompressor is only ever tested on files zlib wrote, at every level, and on broken ones it must refuse.

  • Python
  • DEFLATE
  • Huffman
View code →

1 to 3%

Off gzip -9 on real text

Smaller than gzip on repetitive input. Lazy matching, gzip's own trick of checking whether a match one byte later is longer, closed most of the gap that was there.

trace-rays

A ray tracer in one Python file: spheres on a checkered floor with shadows, reflections, a highlight and a glass ball that turns the floor behind it upside down, written to a PNG it encodes itself. Every pixel is one question asked backwards, from the eye rather than the lamp, and shadows and reflections are the same question asked again from the surface. The checks never compare pictures: they pin the geometry, compare one point of floor with and without the sphere that shadows it, and let Pillow decode the PNG.

  • Python
  • Graphics
View code →

13

Breakages caught

The occlusion test, the PNG filter byte, the quadratic's roots and the surface normal first, then seven for the glass and two for its shadow, each removed on purpose and each failing a check.

ember

A programming language written in Rust with no dependencies: a compiler to bytecode, a stack virtual machine, closures that share the variables they capture, lists and maps, a mark and sweep garbage collector and a REPL. Breaking each phase on purpose found two bugs from the first week, errors reported on the wrong line and every accented string corrupted, and two collector rules no test depended on. A tree-walking interpreter was written only to race it. A misspelt name or map key now suggests the one probably meant, the way Python does.

  • Rust
  • Compilers
  • Garbage collection
View code →

3 to 5x

Faster than a tree-walker

Over the same syntax tree, on recursion, a tight loop and a closure called a million times; level with CPython on recursion and just ahead of it on the closure.

Nibble

A small language that compiles to CHIP-8 machine code, written for the emulator below. Variables, arrays, constants, sprites, routines, loops, collisions, numbers and text: press compile and play it, with the real output shown as bytes under the screen and read back as Octo source beside them. Meteors, a dodging game with a score, three lives and a proper ending, comes to 418 of them, down from 504 as the compiler learned to flip a skip instead of jumping and to share one copy of what it repeats. Snake, Pong and Breakout followed once there were arrays, and Lights Out once there were bit operators; multiplication, which the machine lacks, is built from shifts and adds. Every program was recorded frame by frame before each change and matched exactly after.

  • JavaScript
  • Compilers
  • Canvas
Write a program →

53

Bytes from a dozen lines

Every test compiles a program and runs it on the machine. Each example must also come out identical under the six instructions interpreters disagree about.

CHIP-8

A virtual machine from 1977, rebuilt from its instruction set and running in a browser, with both of the extensions people later built on it: SUPER-CHIP's larger screen and scrolling, and XO-CHIP's second colour plane, sixty four kilobytes of memory and waveform sound. Every program in the community archive runs, and because none of them record how they are played, the page works out which keys each one watches by playing it. It can also read any program back as Octo source, telling code from sprites by walking every path the machine could take; all 104 listings compile back to the identical bytes through Octo's own compiler. It is also the machine Nibble compiles for.

  • JavaScript
  • Canvas
  • Web Audio
Play it →

86

Programs quietly running wrong

Six instructions have two accepted readings, and the archive records which each program expects. It had been ignoring that. It reads them now.

05 Foundations

Where the data instincts came from

2.5M+

Item repository

Physical and digital collection kept accurate and retrievable.

10/2023 – 05/2025

Mesa, AZ

Data & Operations Analyst

Arizona State University · Library Systems

  • Managed data integrity across a 2.5M+ item physical and digital repository, one of the largest university collection systems in the US.
  • Built an archival inventory and reporting system indexing 9,500+ records, improving operational visibility by 40%.
  • Automated metadata validation and root-cause analysis in Python and SQL, cutting record duplication by 20%.
  • Tomalee Doan LibAid Award, 2nd place — Fall 2024.

05/2024 – 08/2024

Boston, MA

Software Engineering Intern · Interactive Media

Idori Inc.

  • Analysed user interaction data to surface behavioural insights, driving three targeted feature improvements and a 54% increase in engagement.
  • Built modular, data-driven UI components in Agile sprints.

Education

Arizona State University

M.S. Information Technology (STEM)

GPA 4.0 / 4.0 · May 2025

Neil Gogte Institute of Technology

B.E. Computer Science & Engineering

GPA 8.2 / 10 · Jun 2023

06 Contact

Open to AI engineering roles

If you're building retrieval systems that have to hold up in production, I'd like to hear about it.

© 2026 Harianth Kalavala