Giving Your Coding Assistant Real Project Context
Part 13's search_codebase does a real, literal string search — genuinely effective when the right keyword is known, but it misses a request phrased differently than the actual code. This part applies the LLM & Advanced AI series' own embedding techniques to fix that, directly for this coding agent.
The real, concrete gap this closes
Part 13's search: search_codebase("redirect") finds files containing
the literal word "redirect" — but misses a real file implementing
the same behavior using next/navigation's redirect() function with
no literal comment using that exact word
Embedding-based search: correctly finds the semantically relevant
file regardless of exact wording — the same real gap the LLM &
Advanced AI series closed for document retrieval, now applied to codeBuilding a real, pre-indexed codebase summary
import os
from shared.embeddings import embed_text
import chromadb
client = chromadb.PersistentClient(path="./codebase_index")
collection = client.get_or_create_collection("codebase")
def index_codebase(root_dir: str) -> None:
for dirpath, _, filenames in os.walk(root_dir):
for filename in filenames:
if not filename.endswith((".py", ".tsx", ".ts")):
continue
filepath = os.path.join(dirpath, filename)
with open(filepath) as f:
content = f.read()
summary = summarize_file_purpose(content, filepath) # a
# real, direct application of the AI Projects
# series' own summarizer
collection.add(documents=[summary], ids=[filepath], metadatas=[{"filepath": filepath}])def summarize_file_purpose(content: str, filepath: str) -> str:
response = client.messages.create(
model="claude-sonnet-5", max_tokens=200,
system="Summarize this file's real purpose in 2-3 sentences, for a code-search index.",
messages=[{"role": "user", "content": f"File: {filepath}\n\n{content[:3000]}"}],
)
return response.content[0].textThis directly reuses the AI Projects series' own summarizer — each real file gets a genuine, concise summary of its actual purpose, which then gets embedded and indexed exactly like the LLM & Advanced AI series' own document indexing.
A real, new semantic search tool for the agent
def semantic_code_search(query: str, top_n: int = 5) -> list[dict]:
results = collection.query(query_texts=[query], n_results=top_n)
return [
{"filepath": meta["filepath"], "summary": doc}
for doc, meta in zip(results["documents"][0], results["metadatas"][0])
]tools.append({
"name": "semantic_code_search",
"description": "Search the codebase by MEANING, not exact keywords — use this when a literal keyword search might miss the relevant real file",
"input_schema": {"type": "object", "properties": {"query": {"type": "string"}}, "required": ["query"]},
})Giving the agent BOTH search_codebase (part 13, exact literal matching) and this new semantic_code_search tool — rather than replacing one with the other — is directly the hybrid search principle from the LLM & Advanced AI series: exact keyword search excels at finding a specific, known real term; semantic search excels at finding the right file when the actual, correct wording isn't known in advance. Real coding tasks benefit from both.
A real, measured speed improvement
Without pre-indexing (part 13): the agent may need several real
loop iterations — search, read, search again — to locate the
right real file for an unfamiliar request
With pre-indexing (this part): semantic_code_search often finds the
correct real file in ONE call, directly reducing the number of
real loop iterations (and real API cost) needed to answerThe real, honest maintenance cost this adds
This real index needs re-running (part 16 of the LLM & Advanced AI
series' own re-indexing coverage applies identically here)
whenever the codebase changes meaningfully — a genuine, ongoing
cost, not a one-time setupThis is worth weighing honestly against part 13's simpler version — for a small, real codebase, a live keyword and file-read search alone may be entirely sufficient; pre-indexing earns its real, added maintenance cost specifically once a codebase grows large enough that blind, iterative search genuinely becomes slow or unreliable.
FAQ
How often does the index need to be rebuilt?
Whenever the codebase changes meaningfully — there's no automatic trigger in this implementation. A real setup would hook index_codebase into a git pre-commit or CI step for the changed files specifically, rather than re-indexing everything from scratch on every change.
What happens if the agent searches for a file that was deleted since the last index?
semantic_code_search would still return it, since the index is only as current as the last run — the agent's subsequent read_file call on that path would then fail, which is a real, visible signal something's stale rather than a silent wrong answer.
Is this worth building for a small project?
Not usually — the honest maintenance-cost section above is the actual answer here. A codebase small enough that search_codebase from part 13 reliably finds things in one or two tries doesn't need this; it earns its cost specifically once that stops being true.
Next: building a real multi-agent AI system — coordinating several, distinct agents together for GreenDesk's genuinely complex, real customer onboarding process.