Онлайн час в Google Meet
Лого на 91. НЕГ „Проф. Константин Гълъбов“

12. клас · Избираем модул · Урок 5

AI асистент за SQL

Как се иска заявка от езиков модел — схема, диалект, примерни редове — и как се проверява върнатото: типичните халюцинации и протокол в четири стъпки.

Помощник, на когото не се вярва

Четири седмици писахте подзаявки, съединения и групирания на ръка. Един езиков модел пише такава заявка за две секунди — и в повечето случаи тя изглежда убедително. Точно това е проблемът. Моделът не изпълнява заявката, не вижда вашата база и не знае дали резултатът е верен. Той е виждал милиони заявки и предлага най-вероятното продължение на вашия въпрос.

Затова в този курс AI асистентът е инструмент като калкулатора: ускорява работата, но отговорността за резултата е ваша. Уменията от уроци 2–4 не са излишни — без тях не можете да прочетете и проверите върнатата заявка. Днес учим три неща: как да питаме, какво бърка асистентът и как да го хванем.

Как се пита

Най-честата причина за грешна заявка не е моделът, а промптът. „Напиши ми заявка за средния успех по клас“ не казва нито как се казват таблиците, нито коя колона е успехът, нито в коя СУБД ще се изпълнява. Моделът ще си измисли всичко липсващо.

Добър промпт за SQL

Съдържа схемата на базата (операторите CREATE TABLE или списък таблица → колони), диалекта (MySQL, SQLite, SQL Server), няколко примерни реда, въпроса на естествен език и — ако го знаете — очаквания резултат за примерните данни.

Схемата на учебната база — за копиране в промпта

Диалект: SQLite (същото ще пусна и в MySQL).

CREATE TABLE classes (id INTEGER PRIMARY KEY, name TEXT NOT NULL);
CREATE TABLE students (id INTEGER PRIMARY KEY, name TEXT NOT NULL,
  grade REAL NOT NULL, class_id INTEGER REFERENCES classes(id));
CREATE TABLE subjects (id INTEGER PRIMARY KEY, name TEXT NOT NULL);
CREATE TABLE marks (id INTEGER PRIMARY KEY, student_id INTEGER REFERENCES students(id),
  subject_id INTEGER REFERENCES subjects(id), mark REAL NOT NULL, date TEXT);

Примерни редове:
classes:  (1,'11А'), (2,'11Б'), (3,'11В')
students: (1,'Александра Иванова',5.75,1), (4,'Георги Стоянов',3.50,2)
subjects: (1,'Информатика'), (2,'Математика'), (3,'БЕЛ')
marks:    (1,1,6.00,'2026-02-10'), (4,3,4.00,'2026-02-15')

grade е годишният успех на ученика; mark е отделна оценка по предмет.
Не всички ученици имат оценки в marks.

Въпрос: ...
  • Схемата спира най-честата халюцинация — измислени колони като students.class или marks.grade.
  • Диалектът спира TOP 3 и GETDATE() от SQL Server там, където трябва LIMIT 3 и date('now').
  • Примерните редове и бележката „не всички имат оценки“ насочват към LEFT JOIN, когато е нужен.
  • Очакваният резултат („за примерните данни трябва да се получат 3 реда“) дава на модела — и на вас — нещо за сравнение.

Какво бърка асистентът

Халюцинация

Уверено изказано твърдение, което не е вярно: колона, която не съществува; функция от друг диалект; логика, която дава правдоподобен, но грешен резултат. Моделът не различава своите верни и грешни отговори — и двата звучат еднакво сигурно.

Типична грешкаКак изглеждаКак се хваща
Несъществуваща колона или таблицаSELECT class FROM studentsСУБД дава грешка „no such column“ — най-лесният случай
Грешен диалектSELECT TOP 3 … / GETDATE()синтактична грешка в SQLite/MySQL; в SQL Server щеше да мине
WHERE вместо HAVINGWHERE AVG(mark) > 5грешка „misuse of aggregate“; условие върху агрегат е за HAVING
Забравен GROUP BYSELECT class_id, AVG(grade) FROM studentsSQLite връща един ред без грешка; MySQL — грешка или един ред
JOIN, който дублира редовеAVG(s.grade) … JOIN marksняма грешка; средното е претеглено по броя оценки — вижте пример 1
COUNT(*) при LEFT JOINCOUNT(*) вместо COUNT(m.id)ученик без оценки получава 1 вместо 0 — вижте пример 3
Уверена грешна заявкасинтаксисът е верен, резултатът — несамо с ръчно сметнат резултат върху малки данни

Протокол за проверка

Проверката не е „пускам и гледам дали излиза нещо“. Четири стъпки, в този ред:

  1. Прочетете заявката ред по ред. За всяка таблица — съществува ли; за всяка колона — в тази таблица ли е; за всеки JOIN — по кои колони и дали не умножава редове; има ли агрегат без GROUP BY.
  2. Изпълнете я върху малки данни — учебната база тук има 9 ученици и 12 оценки. Всичко се смята на ръка.
  3. Сравнете с ръчно сметнат резултат — поне за един ред. Средният успех на 11В е (5.95 + 4.40 + 5.30) / 3 = 5.22. Ако заявката казва 5.95, нещо дублира или губи редове.
  4. Тествайте граничен случай: ученик без оценки, клас без ученици, две еднакви стойности при сортиране, NULL в колона. Точно там уверените заявки падат.

Какво трябва да запомниш

  • Промптът носи схемата, диалекта, примерни редове и очаквания резултат — иначе моделът измисля липсващото.
  • Три молби: напиши, обясни, провери. Третата е най-полезната.
  • Грешките със синтаксис ги хваща СУБД; грешките в логиката (дублиращ JOIN, COUNT(*) при LEFT JOIN, забравен GROUP BY) — само вие.
  • Протокол: прочети → изпълни върху малки данни → сравни с ръчна сметка → тествай граничен случай.
  • Заявка, която не можете да обясните ред по ред, не е ваша.