Защо моделът не знае вашите неща
Моделът е обучен върху текстове до определена дата и не съдържа правилника на училището, конспекта за изпита или документацията на вашия проект. Попитан за тях, той ще произведе правдоподобен, но измислен отговор — видяхте го в урок 16.
Три изхода: да дообучим модела (скъпо и бавно), да залепим всички документи в промпта (не се побират и струват скъпо) или да намерим само нужните няколко абзаца и да подадем тях. Третото се нарича RAG и е точно търсенето по смисъл от урок 25 плюс едно извикване на модела.
RAG (retrieval-augmented generation)
Подход, при който преди отговора системата намира подходящи откъси от собствените документи и ги вмъква в промпта, а моделът отговаря само по тях.
Подготовка на документите
Нарязване на парчета
Документите се режат на парчета (chunks) от няколко изречения до абзац. Твърде голямо парче носи шум и запълва прозореца; твърде малко губи контекста и става неразбираемо само по себе си.
- Режете по естествени граници — празен ред, подзаглавие, — а не на сляпо по брой символи.
- Пазете при всяко парче откъде е дошло: файл и номер на абзац. Това е източникът в отговора.
- Добавете името на документа в началото на всяко парче — така „чл. 12“ знае, че е от правилника (урок 25, задача 2).
def narezhi(ime_fail, tekst):
abzaci = [a.strip() for a in tekst.split("\n\n") if a.strip()]
return [{"iztochnik": f"{ime_fail}, абзац {i + 1}", "tekst": a}
for i, a in enumerate(abzaci)]Вектори
Всяко парче получава вектор — със същата функция vektori от урок 25 (Gemini или локалният модел). При 30 парчета списък в паметта стига; при хиляди — таблицата с JSON колона от миналия урок.
Отговарянето
- Въпросът се превръща във вектор със същия модел като парчетата.
- Намират се
k= 3 парчета с най-голяма косинусова близост. - Строи се промпт: указание „отговори само по текста“, парчетата с източниците им, въпросът.
- Моделът отговаря; отговорът се показва заедно с източниците.
SISTEMNO = (
"Отговаряш САМО въз основа на подадения текст. "
"Ако отговорът не се съдържа в него, напиши точно: „Не се съдържа в документите.“ "
"Накрая посочи източника в квадратни скоби.")
kontekst = "\n\n".join(f"[{p['iztochnik']}] {p['tekst']}" for p in namereni)
otg = client.models.generate_content(
model="gemini-2.5-flash",
contents=f"ТЕКСТ:\n{kontekst}\n\nВЪПРОС: {vapros}",
config=types.GenerateContentConfig(system_instruction=SISTEMNO, temperature=0))Кога да каже „не знам“
Търсенето по вектори винаги връща нещо — и за „колко струва обядът“ ще намери „най-близкото“ парче, дори то да е за екскурзията. Затова „не знам“ има две линии:
- Праг на близостта — ако най-близкото парче е под прага, моделът изобщо не се вика: отговорът е „не знам“ веднага. Пести лимит и не дава на модела повод да измисля.
- Указанието в промпта — ако парчетата са минали прага, но отговорът все пак го няма в тях, моделът трябва да го каже.
PRAG = 0.45 # различен за всеки модел — измерете го в задача 3
namereni = nameri(vapros, k=3)
if namereni[0]["blizost"] < PRAG:
return "Не се съдържа в документите.", []Къде се къса веригата
- Търсенето не е намерило нужното — най-честият проблем. Моделът не може да отговори по текст, който не е получил.
- Парчето е разкъсано — списък или таблица, срязани по средата, объркват отговора.
- Противоречиви източници — стар и нов правилник; моделът няма как да знае кой е в сила, ако не му кажем.
- Моделът игнорира текста и отговаря от своите знания. Срещу това помагат изричното указание и искането за цитат.
Чатботът
„Чатбот“ в Colab е цикъл: input → търсене → промпт → отговор → пак. Документите идват от самите ученици — текстови файлове, качени в тетрадката с files.upload(). Това е и ядрото на AI компонента в проекта ви от урок 27 нататък: същата верига, само документите и интерфейсът са ваши.
Какво трябва да запомниш
- RAG не дообучава модела — подава му нужните откъси в промпта.
- Документите се режат по естествени граници; всяко парче пази източника си.
- Търсенето е по косинусова близост от урок 25; моделът получава само k най-близки парчета.
- „Не знам“ има две линии: праг на близостта преди извикването и указание в промпта.
- Грешен отговор → първо гледаме намерените парчета: ако верният текст не е там, вината е в търсенето.