ZuperAI-14B / toolkit /rag.py
Tyesee's picture
toolkit: rag.py
0639e48 verified
Raw History Blame Contribute Delete
3.02 kB
# -*- coding: utf-8 -*-
"""RAG по своей кодовой базе (№1): индексация + поиск + ответ по проекту.
Запуск:
python rag.py index <папка> — проиндексировать проект
python rag.py ask "где у меня логика авторизации?" [backend]
Работает без тяжёлых зависимостей (пересечение слов). Для лучшего качества можно
поставить sentence-transformers и заменить search() на эмбеддинги с косинусной близостью.
"""
import json
import os
import re
import sys
from brain import pick, generate
INDEX = "rag_index.json"
SKIP = {"venv", ".venv", ".git", "__pycache__", "node_modules", ".idea"}
def chunk_file(path):
code = open(path, encoding="utf-8").read()
lines = code.splitlines()
chunks = []
for i in range(0, len(lines), 50):
chunks.append((path, i + 1, "\n".join(lines[i:i + 50])))
return chunks
def index(folder):
chunks = []
for root, dirs, files in os.walk(folder):
dirs[:] = [d for d in dirs if d not in SKIP]
for f in files:
if f.endswith(".py"):
chunks.extend(chunk_file(os.path.join(root, f)))
json.dump(chunks, open(INDEX, "w", encoding="utf-8"), ensure_ascii=False)
print(f"проиндексировано чанков: {len(chunks)} -> {INDEX}")
def search(query, top=5):
if not os.path.exists(INDEX):
print(f"сначала проиндексируй: rag.py index <папка>")
return []
chunks = json.load(open(INDEX, encoding="utf-8"))
qwords = set(re.findall(r"\w+", query.lower()))
scored = []
for path, line, text in chunks:
twords = set(re.findall(r"\w+", text.lower()))
s = len(qwords & twords)
if s:
scored.append((s, path, line, text))
scored.sort(reverse=True)
return scored[:top]
def ask(query, backend):
hits = search(query)
if not hits:
print("ничего релевантного не найдено")
return
context = "\n\n".join(f"--- {p}:{l} ---\n{t[:800]}" for _, p, l, t in hits)
msgs = [{"role": "system",
"content": "Ты анализируешь кодовую базу. Отвечай по предоставленному "
"контексту, указывай файлы и строки."},
{"role": "user",
"content": f"Контекст из кодовой базы:\n{context}\n\nВопрос: {query}"}]
print(generate(backend, msgs, 1024))
def main():
args = sys.argv[1:]
if len(args) < 2:
print("usage: rag.py index <папка> | rag.py ask <вопрос> [backend]")
sys.exit(2)
if args[0] == "index":
index(args[1])
elif args[0] == "ask":
ask(" ".join(args[1:]), pick())
if __name__ == "__main__":
main()