Safeguard
Developer Tools•

How to chunk source code for retrieval without cutting functions in half

Fixed size chunks split functions mid body. Parse the code and chunk by function or class instead. A practical guide with sizes and overlap to test.

Safeguard Security Team
4 min read

Chunk source code along its syntax: one function, method or class per chunk, with the file path and signature attached. Fixed size splitting cuts bodies in half and strips context, which hurts retrieval. A parser such as tree-sitter makes syntax aware chunking practical across many languages.

Why chunking matters at all

A search index cannot return a whole repository. It returns chunks. If a chunk starts in the middle of one function and ends in the middle of the next, its embedding describes neither. The question "where do we validate tokens?" then retrieves two half answers.

Anthropic's retrieval write-up notes that chunk size, boundaries and overlap all affect retrieval performance, and that documents are usually split into chunks of no more than a few hundred tokens.

The naive approach and its failure

Splitting every 500 characters is easy. It also produces chunks like this: the last three lines of parse_header, a blank line, and the first lines of parse_body. The signature, the docstring and the return value are in different chunks.

Use a parser

Tree-sitter describes itself as a parser generator and incremental parsing library. It builds a syntax tree for a file, works with a wide range of languages, is fast enough to run on every keystroke in an editor, and still returns useful results when the code has syntax errors. That last point matters, because real repositories contain broken files.

With a tree you can walk the nodes and emit one chunk per function or class definition. For a deeper look at what a parse tree can do, see taint analysis with tree-sitter.

A chunking recipe to try

  1. Parse each file.
  2. Emit a chunk for each top level function and each method.
  3. For a class, emit the class header plus a list of method names as one chunk, and each method as its own chunk.
  4. Prepend metadata as plain text: file path, language, enclosing class, and the signature.
  5. If a function exceeds your size limit, split at statement boundaries inside it, and repeat the signature at the top of each part.
  6. For files with no useful structure (config, markdown, SQL), fall back to splitting on headings or blank lines.

Add context to each chunk

A chunk that says return cache.get(key) means little alone. Anthropic's contextual retrieval method prepends a short, chunk specific explanation before the chunk is embedded and before the keyword index is built. Their example adds a company name and time period to a financial snippet. For code, the same idea is a one line summary such as "method of SessionStore, reads a session from the cache by id."

Anthropic reports that this reduced retrieval failures, measured as one minus recall at 20, from 5.7 percent to 3.7 percent with contextual embeddings, and to 2.9 percent when combined with contextual keyword search. Those are their datasets, so treat them as an indication to test, not a promise.

Overlap and size

Syntax aware chunks need less overlap. If you do split large functions, a small overlap of a few lines helps. Try two or three settings and measure, using the method in how to evaluate a code search system.

Quick check

Should tests be indexed with the code?

Often yes, tagged as tests. They show how functions are used. Keep the tag so you can filter them out of some queries.

What about generated or vendored code?

Usually exclude it. It adds volume and noise. Index it separately if you need to answer questions about dependencies.

Sources

Last reviewed: 19 October 2026.

Never miss an update

Weekly insights on software supply chain security, delivered to your inbox.

Self-healing security runs on Safeguard.

Your first fix PR is minutes away.

No sales call required, even your agent can complete the purchase over MCP.