Skip to main content

awgraph — the code graph your agent reads instead of grepping

An agent asked to fix a bug does not know which files matter, so it greps, opens whatever matched, and spends most of its context window on code it will not change. awgraph indexes the repository into a graph of symbols — functions, methods, classes, their calls and callers — and answers a natural-language task with the handful of chunks that task actually needs.

pip install awgraph

Python 3.10+. Nothing else is required to index and query.

What it costs, measured

The interesting question is not "is a graph better than grep" — it is what does each cost. Measured on a corpus of real commits, where the task is a commit message with the answer filenames stripped out and the truth is the set of files that commit actually modified:

retriever recall@10 context tokens per task
ranked multi-term grep 0.933 351,369
awgraph 0.800 1,503

86% of grep's recall for 0.43% of the context — a 234x reduction.

Read that honestly: grep still wins on recall. awgraph is not a better finder; it is a dramatically cheaper one, and on a long agent loop the context budget is usually what runs out first. If you need maximum recall and cost is no object, grep. If you are paying per token across thousands of turns, this is a different order of magnitude.

Caveats, because a benchmark without them is marketing: n=15 tasks, and only 33.3% of chunks carried embeddings on that run, so the semantic half was working at partial strength — the recall number understates it.

A naive fusion (run the graph, fall back to grep when it returns few files) was also measured: it reaches grep's 0.933 recall at 352,872 tokens — more than grep alone, because the fallback fires on nearly every task and pays both bills. Reported because it did not work; a smarter trigger is future work.

Setup: index once, embed lazily

Two costs, and only one of them scales with repo size.

step 2,400 chunks 43,730 chunks
parse + index 49.8s 75.5s
embed (CPU) ~97 min at ~450 vectors/min

Indexing is close to size-insensitive — 27x the files for 1.5x the time, because parsing runs across workers. Embedding is the part that hurts on CPU, so it is optional, cached and incremental: re-indexing reuses stored vectors and only embeds what changed.

Without any embedding backend, queries fall back to keyword scoring and still work. That fallback is silent by design and dangerous by nature — a graph with no vectors looks like a working graph that is merely worse. Check coverage rather than assuming it:

embedded = sum(1 for c in graph.chunks.values() if c.embedding is not None)
print(f"{embedded}/{len(graph.chunks)} chunks carry vectors")

Use it

import asyncio
from awgraph import CodeGraph

async def main():
    graph = CodeGraph(root_path="/abs/path/to/repo", auto_index=False)
    await graph.index_codebase("/abs/path/to/repo")   # absolute path required

    for chunk in await graph.hybrid_query("retry with exponential backoff", max_results=5):
        print(chunk.name, chunk.source_path, chunk.start_line)

asyncio.run(main())

index_codebase needs an absolute path. Given a relative one it walks nothing, indexes zero chunks, and returns successfully — so assert on len(graph.chunks) rather than on the absence of an exception.

The query does not need to contain the symbol name. Asking for "backoff policy for flaky calls" against a class documented as "Backoff policy for flaky calls" returns it by meaning, not by string match.

Where it sits

Three packages, three different questions about the same repository:

  • awgit — semantic version control. Stable node ids, semantic edit-ops, leases so concurrent agents do not overwrite each other, stacked commits with one PR each. It knows what changed and who is editing it.
  • awgraph — code intelligence. Symbols, call paths, dependencies, blast radius. It knows what the code is and what depends on what.
  • aither-adk — the agent runtime that consumes both.

The seam is the useful part: awgit tells you a commit touched RetryPolicy.next_delay; awgraph tells you what calls it and which tests cover it; the agent reads that instead of the repository.

Related work

GitNexus is the closest analogue and worth reading. Its recommended mode augments grep with graph context rather than replacing grep — a conclusion these measurements independently reach. Note its licence is PolyForm Noncommercial (source-available, commercial use forbidden), where awgraph is Apache 2.0. Its published figures measure SWE-bench task resolution; the numbers above measure retrieval recall. Those are different axes and should not be compared directly.

Licence

Apache 2.0.

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

awgraph-1.0.0.tar.gz (84.5 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

awgraph-1.0.0-py3-none-any.whl (83.7 kB view details)

Uploaded Python 3

File details

Details for the file awgraph-1.0.0.tar.gz.

File metadata

  • Download URL: awgraph-1.0.0.tar.gz
  • Upload date:
  • Size: 84.5 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for awgraph-1.0.0.tar.gz
Algorithm Hash digest
SHA256 32de7c8cf0cd00c96d1e2be85ff05ce0aa3e64e9994e331fede8db7439a3800c
MD5 dcdc62eaf6d6eba14feda618575cc50c
BLAKE2b-256 c934790169dc914194d1f85d39f5fb19d880ee09a6d714e1474b294884e2568a

See more details on using hashes here.

Provenance

The following attestation bundles were made for awgraph-1.0.0.tar.gz:

Publisher: pypi-publish.yml on Aitherium/awgraph

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file awgraph-1.0.0-py3-none-any.whl.

File metadata

  • Download URL: awgraph-1.0.0-py3-none-any.whl
  • Upload date:
  • Size: 83.7 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for awgraph-1.0.0-py3-none-any.whl
Algorithm Hash digest
SHA256 501f0145ef6970d34d295093321158d433b0a57861e3293c3f2c14fe0fd37d13
MD5 1d6405c0ff19cc16549defc8759dca31
BLAKE2b-256 bad67255ca58f0063a5efae5919750ed6e771952ba2e900331c199673dfa6844

See more details on using hashes here.

Provenance

The following attestation bundles were made for awgraph-1.0.0-py3-none-any.whl:

Publisher: pypi-publish.yml on Aitherium/awgraph

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Release history Release notifications | RSS feed

1.4.5

2 files

1.4.3

2 files

1.4.2

2 files

1.3.1

2 files

1.3.0

2 files

1.2.1

2 files

1.2.0

2 files

1.1.0

2 files

This release

1.0.0 This release

2 files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page