Build a coding agent (RAG)
Give a chat model knowledge of your codebase: embed the repo, retrieve the most relevant chunks for a question, and feed them to the model. Embeddings and chat run on the same AIx key and bill to one wallet.
1 · Set up the client
from openai import OpenAI
client = OpenAI(base_url="https://api.aix.theaimart.co/v1", api_key="$AIX_KEY")
EMBED = "BAAI/bge-large-en-v1.5"
CHAT = "anthropic/claude-sonnet-4-6" # or deepseek-ai/DeepSeek-V3.2, Qwen/Qwen3-Coder-...
2 · Chunk & embed the repo
import os, glob
def chunks(text, size=1200, overlap=150):
for i in range(0, len(text), size - overlap):
yield text[i:i + size]
docs = [] # [(path, chunk_text)]
for path in glob.glob("src/**/*.*", recursive=True):
try:
text = open(path, encoding="utf-8").read()
except Exception:
continue
for c in chunks(text):
docs.append((path, c))
# Embed in batches (max 100 inputs per request)
vectors = []
for i in range(0, len(docs), 100):
batch = [c for _, c in docs[i:i + 100]]
res = client.embeddings.create(model=EMBED, input=batch)
vectors.extend(d.embedding for d in res.data)
✦ Tip
For anything beyond a quick script, store vectors in a real store (pgvector, Qdrant, LanceDB) instead of memory — the API call is identical, only persistence changes.
3 · Retrieve the top matches
import numpy as np
mat = np.array(vectors)
mat /= np.linalg.norm(mat, axis=1, keepdims=True)
def search(query, k=6):
q = client.embeddings.create(model=EMBED, input=query).data[0].embedding
q = np.array(q); q /= np.linalg.norm(q)
scores = mat @ q
return [docs[i] for i in scores.argsort()[-k:][::-1]]
4 · Answer with retrieved context
def ask(question):
hits = search(question)
context = "\n\n".join(f"# {path}\n{chunk}" for path, chunk in hits)
r = client.chat.completions.create(
model=CHAT,
messages=[
{"role": "system", "content": "Answer using ONLY the provided code context. Cite file paths."},
{"role": "user", "content": f"Context:\n{context}\n\nQuestion: {question}"},
],
)
return r.choices[0].message.content
print(ask("Where do we verify the API key?"))
Cost & latency tips
- Embed once, cache the vectors — re-embed only changed files.
- Retrieval keeps the prompt small → cheaper + faster than dumping the whole repo.
- Use a cheaper chat model for routine Q&A and a stronger one for hard refactors —
switch by changing the
CHATstring.
Next steps
- Tool & function calling — let the agent run actions
- Streaming a chat UI — show answers token-by-token