# LocAgent: graph-guided agents for code localization

> LocAgent parses a repository into a directed heterogeneous graph so an LLM agent can search for the files a change belongs in, with a BM25 sparse index alongside the graph. It is a research framework with an ACL 2025 paper behind it, and the released artefacts are indexes and fine-tuned models rather than a product.

**gersteinlab/LocAgent** — [ACL 2025] Graph-guided agentic framework for code localization https://arxiv.org/abs/2503.09089

- Repository: https://github.com/gersteinlab/LocAgent
- Stars: 634 · Forks: 97
- Language: Python
- License: Apache-2.0
- Published: 2026-10-21 · Updated: 2026-10-21 · Language: en
- Canonical page: https://hysenlabs.com/projects/gersteinlab-locagent

## The problem is finding the right file, not writing the fix

The Overview section states the aim directly: LocAgent is a framework that addresses code localization through graph-based representation. By parsing codebases into directed heterogeneous graphs, it creates a lightweight representation that captures code structures and their dependencies, enabling LLM agents to effectively search and locate relevant entities through powerful multi-hop reasoning.

Code localization is the step before code generation. Given a natural language description of a bug or a feature, the system has to decide which files, functions and classes are involved. The paper's abstract makes the difficulty concrete, saying that existing approaches struggle to efficiently navigate complex codebases when identifying relevant code snippets, and that the challenge lies in bridging natural language problem descriptions with the target code elements, which often requires reasoning across hierarchical structures and multiple dependencies.

That is the framing that makes the graph approach make sense. A flat embedding of the repository gives an agent a similarity ranking. A graph gives it something a ranking cannot: structure. If a symbol calls another, if a class is defined in one file and used in another, if a change to a function affects three call sites, those are edges, and an agent that can walk them can reason about a change site in a way that pure retrieval cannot.

The work was published at ACL 2025, with the paper linked from the README, and the framework was released alongside a benchmark and two fine-tuned models.

## Two indexes, one graph and one sparse retrieval

The mechanics of the localization run are visible in the launch instructions, and they come down to two indexes that the agent can search.

The first is the graph index, built by a batch script that parses a repository and produces the directed heterogeneous graph of its code entities. The second is a BM25 sparse index over the same code, and the two are handed to the agent as separate tools: a structured navigation over the graph and a keyword search over the text.

The directories for both are exported as environment variables before a run:

```
   export GRAPH_INDEX_DIR='{INDEX_DIR}/{DATASET_NAME}/graph_index_v2.3'
   export BM25_INDEX_DIR='{INDEX_DIR}/{DATASET_NAME}/BM25_index'
```

The path templates are worth noticing, because they show the shape of the artefacts. The graph index is versioned inside its name, `graph_index_v2.3`, which is a sensible thing to do for a format that a research pipeline rewrites regularly, and both directories are nested by dataset name so that a single index root can hold the indexes for several benchmarks at once.

The instructions also say that if the indexes are not generated in advance, the graph index will be generated during the localization process. So the batch build is described as optional but recommended, and the difference is cost: a prebuilt index means the same repository is parsed once, while on-the-fly generation means it is parsed for every issue that touches it.

## The run script is a policy with switches, and two of them are model workarounds

The main entry point is `auto_search_main.py`, and the README describes a run of it in full:

```
   python auto_search_main.py \
      --dataset 'czlll/SWE-bench_Lite' \
      --split 'test' \
      --model 'azure/gpt-4o' \
      --localize \
      --merge \
      --output_folder $result_path/location \
      --eval_n_limit 300 \
      --num_processes 50 \
      --use_function_calling \
      --simple_desc
```

The README's own explanations of the flags are the most revealing part, because two of them are workarounds for model limitations rather than features.

`localize` starts the localization process and `merge` merges the result of multiple samples, which is how a single run is repeated and the results pooled. `use_function_calling` enables the function calling features of LLMs, and the README says that if it is disabled, codeact will be used to support function calling, so the agent still has tools either way.

`simple_desc` is the more interesting one. The README says it uses simplified function descriptions due to certain LLM limitations, and advises setting it to False for better performance when using Claude. In other words, the tool descriptions the agent sees are a compatibility shim, and the project tells you to turn the shim off for one model family and leave it on for others. That is a fair thing for a research codebase to do and an awkward thing for a library to require, and it tells you the tool surface was designed around several model providers at once.

The remaining flags are about scale. `--eval_n_limit` bounds how many instances are evaluated, and `--num_processes 50` is the same parallelism idea as in the index build.

## Datasets are the other half of the configuration

The dataset argument is not a detail, because the graph index is built per repository and per dataset, and the README lists what is supported.

The choices are `czlll/SWE-bench_Lite`, `czlll/Loc-Bench_V1` which is adapted for code localization, and the SWE-bench series datasets `princeton-nlp/SWE-bench_Lite`, `princeton-nlp/SWE-bench_Verified` and `princeton-nlp/SWE-bench`. The default, as the README notes, is SWE-Bench_Lite.

The index build script takes the same kinds of arguments:

```
   python dependency_graph/batch_build_graph.py \
         --dataset 'czlll/Loc-Bench_V1' \
         --split 'test' \
         --num_processes 50 \
         --download_repo
```

and the README documents the three path-related options: `repo_path` is the directory where you plan to pull or have already pulled the codebase, `index_dir` is the base directory where the generated graph index will be saved, and `download_repo` decides whether the codebase is downloaded to `repo_path` before indexing.

So there is a genuine dependency between the two steps. A repository that appears in more than one benchmark issue has to be indexed, and the index is keyed by dataset, which means the same code can be indexed several times under different names. The Loc-Bench dataset and the two fine-tuned Qwen2.5-Coder models are published on Huggingface under the `czlll` account, along with the benchmark itself.

## Setup is a conda environment and a very large requirements file

The setup section is three commands, and they are worth reading because the environment is pinned hard:

```
   git clone git@github.com:gersteinlab/LocAgent.git
   cd LocAgent

   conda create -n locagent python=3.12
   conda activate locagent
   pip install -r requirements.txt
```

Python 3.12 in a conda environment, and a fully pinned requirements file. The contents of that file describe the stack better than any summary would. There is `litellm` at 1.52.1, which is the model access layer, and it is what lets a single run talk to a model named azure/gpt-4o and to the local Qwen models through the same interface.

There is a large `llama-index` family, the core plus the agent, programme, reader, retriever and embedding integrations for both Azure OpenAI and OpenAI, along with `llama-cloud` and `llama-parse`. There is `bm25s` at 0.2.3 for the sparse index, `faiss-cpu` for vector search, `datasets` at 3.1.0 for the benchmark loading, `huggingface-hub`, `networkx` for graph work, and `azure-identity` and `msal` for authentication.

The size of that list is the practical cost of this framework. A researcher reproducing the paper accepts it, since the numbers have to come out the same. An engineer who wants a file finder for their own repository would not.

The repository root is consistent with that: `auto_search_main.py` for the run, `build_bm25_index.py` for the sparse index, `dependency_graph/` for the graph construction, `repo_index/` and `util/` for the surrounding machinery, `plugins/` for the tools the agent can call, `evaluation/` for the metrics, `scripts/` for the launch wrappers, and `sft_train.py` for the fine-tuning side.

## CodeNib now serves the search and navigation tools

The note at the top of the README describes a change in how the tools are obtained, and it is worth understanding before anything else.

CodeNib serves LocAgent's search and graph-navigation tools from reusable, manifest-backed symbol-graph and BM25 indexes, without building a separate LocAgent index. The integration starts from a prepared `repo_manifest.json` and runs LocAgent's localization policy over these indexes, while model training and the original reproduction pipeline remain in this repository.

So there are now two routes to the same agent behaviour. The route in this repository builds the LocAgent graph index itself, with the batch script and the `graph_index_v2.3` format, and that is the one the paper used. The CodeNib route skips the index build and reuses symbol-graph and BM25 indexes that were prepared elsewhere, with a manifest describing them.

The reason to know about this is cost and reuse. A team that already has a CodeNib index for a repository does not need to reparse it, and the policy that decides which files to return is unchanged. A team reproducing the paper needs the original pipeline, and the README is explicit that it is still here.

The CodeNib project publishes its own documentation, an adapter and a provider implementation, so the integration is a documented contract rather than a description.

## Evaluation is a notebook, and the numbers come from the abstract

After localization the results are saved in a JSONL file, and the README says you can evaluate them using `evaluation.eval_metric.evaluate_results`, with a demonstration in `evaluation/run_evaluation.ipynb`.

The evaluation is therefore part of the repository rather than something a separate harness does, and the notebook is the quickest way to see the same numbers the paper reports.

Those numbers are in the abstract, and they are the reason to look at the project at all. With the fine-tuned Qwen-2.5-Coder-Instruct-32B model, the abstract says the method achieves comparable results to state of the art proprietary models at greatly reduced cost, approximately an 86 percent reduction, reaching up to 92.7 percent accuracy on file-level localization, and improving downstream GitHub issue resolution success rates by 12 percent for multiple attempts, Pass@10.

Those are the paper's own claims, and this repository is the code that produced them, so anyone evaluating it should start from the abstract's numbers and check the reproduction rather than take them on trust. The fine-tuned models themselves are published on Huggingface, Qwen2.5-Coder-7B-CL and Qwen2.5-Coder-32B-CL, and `sft_train.py` in the repository is the training side of the same pipeline.

On maintenance, the repository is not archived, the last push was on 2026-08-12, there are no GitHub releases, and the licence is Apache-2.0 with a LICENSE file at the root.

## Conclusion

LocAgent fits a research team studying code localization, or an engineer who wants to reproduce a file-level localization result on a SWE-bench style issue and needs the graph index and the fine-tuned Qwen2.5-Coder models that the paper used. It is the wrong tool for a product team that needs a maintained library, since the repository ships a research pipeline with no releases. Verify first which dataset and split you intend to use, since the index has to be built per repository and dataset, and read the CodeNib note, because the search and graph-navigation tools are now served from reusable indexes rather than from this repository's own index builder.

## FAQ

### What problem does LocAgent solve?

It addresses code localization through graph-based representation. By parsing codebases into directed heterogeneous graphs, it captures code structures and their dependencies so LLM agents can search and locate relevant entities through multi-hop reasoning.

### How do I set up LocAgent?

Clone the repository, create a conda environment with python=3.12, activate it and run pip install -r requirements.txt. The requirements file is fully pinned and includes litellm for model access, the llama-index family, bm25s, faiss-cpu and datasets.

### What are GRAPH_INDEX_DIR and BM25_INDEX_DIR for?

They point at the generated graph index and the BM25 sparse index, and the README says that if they are not generated in advance, the graph index will be generated during the localization process. Building them in batch first is described as optional but recommended.

### What do the --use_function_calling and --simple_desc flags do?

The README says --use_function_calling enables the function calling features of LLMs, and that if it is disabled, codeact will be used to support function calling. The --simple_desc flag uses simplified function descriptions due to certain LLM limitations, and should be set to False for better performance when using Claude.

### How do I evaluate LocAgent's results?

After localization the results are saved in a JSONL file, and you can evaluate them with evaluation.eval_metric.evaluate_results. A demonstration notebook is provided at evaluation/run_evaluation.ipynb, and the paper's results are quoted in the README abstract.

## Sources

- [gersteinlab/LocAgent on GitHub](https://github.com/gersteinlab/LocAgent)
- [Issues](https://github.com/gersteinlab/LocAgent/issues)
- [License: Apache-2.0](https://github.com/gersteinlab/LocAgent/blob/master/LICENSE)
- [README](https://github.com/gersteinlab/LocAgent/blob/master/README.md)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/gersteinlab-locagent
