← Back to blog

Why ctxd: Let the agent grep

TL;DR

Use ctxd. It is simpler and cheaper, and it works just as well, if not better.

Frequent updates, tight budgets, latency targets. Fewer moving parts, fewer ways to break.

DimensionctxdEmbedding RAG
Setup complexitySimple. Copy text and retain paths.Multiple stages. Split text, embed chunks and maintain a vector index.
TuningNone.Chunk size and overlap, embedding model, retrieval depth and optional reranking.
Embedding compute and API costFree. No embedding generation or embedding API fees.Paid compute. CPU/GPU time for embedding and re-embedding. Hosted APIs and indexes add service fees.
Query latencyNo embedding step. Text scans and repeated agent turns can add latency.Indexed lookup. Query embedding and optional reranking add latency.
File updatesInstant after sync. Updated text is searchable without re-embedding.Time + compute cost. Rebuild affected chunks, re-embed changed text and update the index.
Vocabulary matchingPattern-based. The agent must supply useful terms or try alternatives.Similarity-based. Can retrieve related wording without an exact term match.

Free software still uses compute and storage. The agent’s model can add usage charges with either approach.

Speed depends on corpus size, hardware, caching and the agent’s search strategy. These are architectural trade-offs; end-to-end performance still needs benchmarking.

You ask an agent how to roll back a deployment after its health checks fail. It finds a line about restoring the previous image. But the instruction immediately above it says to stop the rollout first.

The agent needs a way to read beyond the match. Grep first search. No embeddings. That is our starting point for ctxd: searchable text, source paths and tools the agent can call again.

ctxd’s local tracker keeps selected folders available through ctxfs. Your application gives the agent tools to inspect paths, search text and read source files. The agent chooses the queries.

What an embedding engine adds

Embedding-based retrieval usually splits text into chunks, encodes them as vectors and maintains an index. Each layer brings decisions: where chunks end, which embedding model to use and how to keep the index current.

We want to start with searchable text and source reads. Follow the same runbook through preparation, a question and a source edit.

01Prepare files

ctxd

A runbook is copied into a tracked folder. Its text stays readable, with its original path and source lines.
Text and its source. ctxd stores a searchable text copy. Folder selection, supported formats and retention still need attention.

Embedding RAG

The runbook splits into overlapping chunks. Each chunk becomes a vector linked to its source.
Text plus a derived representation. Chunk boundaries, the embedding model and the vector index become part of retrieval.
  1. Chunk the document. Split the source into passages with overlap. ctxd keeps a searchable text copy with its path; it does not need this chunking stage.
  2. Embed the chunks. Encode each chunk, then store its vector and source ID in an index. The chunking rules and model determine this representation.

02Ask a question

ctxd

A regex match leads to a source read that reveals the missing stop-the-rollout instruction.
Match, then read. The agent chooses a pattern, checks matching paths and reads the surrounding source. Regex can return irrelevant matches too.

Embedding RAG

The selected chunk leads to its parent runbook, which contains the missing stop-the-rollout instruction.
From chunks to context. This example adds reranking and a source read after candidate retrieval.
  1. Embed the question. RAG encodes the question for similarity search. On the left, ctxd matches a pattern and reads the source.
  2. Find candidates. The vector search returns three candidates: a runbook, unrelated UI notes and an old deployment procedure.
  3. Fetch chunk text. Open the candidate passages. “Undo an edit” looks related, but it does not explain a deployment rollback. Some stores return this text with the search.
  4. Rerank the chunks. The runbook moves to the top. The other candidates fall away. Reranking adds another model pass in this example.
  5. Read the source document. Follow chunk B back to the runbook. The preceding line supplies the prerequisite: stop the rollout before restoring the image.

03Change a file

ctxd

A successful scan refreshes the searchable text copy; stored history may retain previous text.
Refresh the text copy. Searches see the edit after a successful scan. Stored history may retain earlier text.

Embedding RAG

The index retains an unchanged vector and replaces the two affected entries.
Keep derived data current. Changed chunks need matching vectors and source links. Unchanged chunks can reuse embeddings.
  1. Read the changed text. One line changes. ctxd refreshes its text copy after a successful scan; RAG must also refresh the representations derived from that text.
  2. Rebuild affected chunks. The edit crosses an overlap: c2 and c3 both change. c1 stays intact. Different splitters can shift further boundaries.
  3. Re-embed changed chunks. c2 and c3 need new vectors. c1 can reuse its existing vector when the pipeline supports reuse.
  4. Update vectors and source links. Keep c1, replace c2 and c3, and reconcile source IDs. The index must agree with the current file.
Figure 1. The same retrieval lifecycle, with different dependencies. The excerpts, candidate ordering and vectors are schematic. Reranking and context expansion are choices in this example, not requirements of every RAG pipeline. Both approaches still need source selection, access controls and evidence checks. An embedding engine can run locally or in a managed service.

The weakness of grep-first search is the starting vocabulary. “Undo a deploy” may miss a file that says “rollback.” Searching for RUNBOOK will not find a file just because a reader would call it a runbook. Regex matches text patterns; it does not infer that meaning.

Today, an agent can list folders and paths, read headings, and try alternatives such as rollback|revert|undo. It can use terms discovered in one source to search the next. ctxd exposes those operations; the calling agent supplies the vocabulary and judges the evidence.

Our direction is to make that discovery loop easier to guide and inspect: choose a useful scope, try candidate terms, read evidence, then refine. Automatic vocabulary expansion is not part of the local search engine. The ctxfs guide describes the available read operations.

Read around the match

A regex can find an error code, a service name or a phrase. The result gives the caller a file path and line number to inspect.

In this example, searching for rollback finds line 3. Reading the surrounding passage reveals the step that comes before it.

The completed search returns only runbook.md line 3: Rollback: restore the previous image tag, then recheck health. Earlier lines do not match the pattern.
Search supplies a lead. This query completes and finds line 3. The instruction on line 2 contains no match for “rollback,” so it is absent.
The full runbook has a Deployment notes heading, then line 2: If deployment health checks fail, stop the rollout. Line 3 gives the rollback procedure.
Reading reveals the prerequisite. The surrounding passage establishes the order: stop the rollout, restore the image, then recheck health.
Figure 2. A complete search is not a complete answer. Both panels use the reproducible file below. The highlighted prerequisite changes the procedure the agent can infer. Text wraps within each numbered source line.

That read may reveal another file or a term worth searching. A caller can narrow the next query to a folder or path prefix. The agent follows the evidence, and developers can inspect its sequence of calls.

Try the two calls

Use the local service from the quickstart. The example calls its ctxfs API to find a line, then read its context.

Create and track the example file

On your workstation, as your normal user, start in a directory where ctxd-thesis-example does not exist:

Terminal window
mkdir ctxd-thesis-example && cat > ctxd-thesis-example/runbook.md <<'TEXT'
# Deployment notes
If deployment health checks fail, stop the rollout.
Rollback: restore the previous image tag, then recheck health.
TEXT

Track this folder using the quickstart. Wait for a successful scan. Find its root ID with ctxd folders list and the service URL with ctxd config show.

Replace <ROOT_ID> below with that folder’s ID. The API URL uses the default local address; change it if your service uses another address.

Terminal window
CTXD_EXAMPLE_ROOT='local-files/<ROOT_ID>'
CTXD_EXAMPLE_API='http://127.0.0.1:8765/api/ctxfs'

Search for the matching line, then read the three-line passage:

Terminal window
curl --get "$CTXD_EXAMPLE_API/grep" \
--data-urlencode 'pattern=(?i)rollback' \
--data-urlencode "prefix=$CTXD_EXAMPLE_ROOT" \
--data-urlencode 'limit=20'
curl --get "$CTXD_EXAMPLE_API/read-lines" \
--data-urlencode "path=$CTXD_EXAMPLE_ROOT/runbook.md" \
--data-urlencode 'start_line=1' \
--data-urlencode 'end_line=3'

The search returns one matching line. The read returns all three lines, including the instruction to stop the rollout. An agent can use that evidence before deciding what to do next.

Know what a result leaves out

  • Different wording can be missed. Regex matches text patterns; it does not rank by meaning. A synonym may need another query.
  • A response can be partial. Inspect complete and stopped_by before treating search results as exhaustive.
  • Tracked files take time to refresh. Changes become searchable after a successful scan. See the local tracker guide for service controls.

ctxd keeps local copies of tracked text. See the security and data guide for retention and sharing details.

Build on an inspectable interface

The local implementation is MIT licensed. Developers can inspect how files are tracked and what each call returns.

Direct file access may already serve your application. ctxd adds a common interface and folder tracking, with a service and storage to manage. We want to make that trade-off useful for agents that need to follow the evidence across files.

Glossary

TermMeaning
EmbeddingA vector representation used to compare queries and passages by similarity.
ChunkA portion of a document indexed as a retrieval unit.
RerankingScoring retrieved candidates against the query to reorder them.
Context expansionFetching neighboring passages or a parent document around a retrieved chunk.

References

Research and technical sources behind the design:

  1. Is Grep All You Need?: retrieval tools and how results reach the agent.
  2. SWE-agent: Agent-Computer Interfaces Enable Automated Software Engineering: interfaces for navigating, searching and editing files.
  3. Towards Retrieving Interaction Spaces for Agentic Search: selecting a workspace for an agent to explore.
  4. Retrieval architectures: retrieval components and agentic workflows.
  5. Vector indexing, embedding models and retrieval tuning: chunks, vectors, model choices and retrieval settings.
  6. Document management: refreshing an index when source documents change.
  7. Parent-document retrieval and retrieval postprocessing: fetching broader context and reranking candidate passages.

The papers evaluate their own systems and conditions. Choosing no embeddings is our design decision; these references do not establish a universal retrieval winner or measure ctxd.

Read the source. Try the local workflow. Help shape the project.

Explore ctxd on GitHub