ChatGPT уже не работает? Простым графом я взломал его мозг — теперь ИИ самообучается, и это пугает

ChatGPT уже не работает? Простым графом я взломал его мозг — теперь ИИ самообучается, и это пугает

В этой статье представлен экспресс-гид по использованию графовых структур для автоматизации знаний, встроенных в промпты, чтобы создать эффективного чат-бот-агента для бизнеса или личных нужд.

Сколько бы я ни обращался к ChatGPT, мне не удаётся получить качественные ответы — нужных формулировок всё нет.

Порой кажется, что время утекает впустую, и я уверен, что вы знакомы с этим ощущением. Проблема не в топорном промпте — вероятнее всего, запрашиваемая информация недостаточно упорядочена.

Лично я не раз сталкивался с тем, что задавал ChatGPT вопрос, а в ответ получал что-то совершенно иное.

Если вы уже работали с ИИ-агентами, то, скорее всего, слышали о «цепочке рассуждений» (chain of thought). Это как бы вы просите большую языковую модель: «Подождите, дайте мне проанализировать шаг за шагом». Такой подход позволяет LLM демонстрировать пошаговый ход мыслей при решении задач.

Однако он полностью опирается на уже заложенные в модель данные и нередко не справляется с узкоспециализированными темами.

Что насчёт RAG (Retrieval-Augmented Generation)? Да, она обогащает ответы за счёт извлечения информации из внешних хранилищ. Но простая навалом поданная фактура не всегда помогает модели рассуждать глубже.

Учёные обнаружили, что графы знаний — наиболее удобная форма представления взаимосвязей.

Методы от «цепочки знаний» (chain-of-knowledge, CoK) до «рассуждений на графах» (reasoning on graphs, RoG) извлекают из графа оптимальные маршруты или планы для управления моделью.

Но все они базируются на статичной и полной БД, тогда как в реальном мире экспертные знания часто неполны и порой ошибочны.

Ещё хуже, что такие методы передают информацию лишь в одну сторону: граф отдаёт, а модель не возвращает обратно ни новых выводов, ни корректив.

В итоге искажения в графе накапливаются и закрепляются.

Учёные из Университета Джонса Хопкинса предложили систему EGO-Prompt, которая рассматривает экспертные знания как динамичный объект, а не застывший эталон. EGO-Prompt начинает с экспертной причинно-следственной модели, а затем непрерывно обновляет и промпты, и сам граф на основе реальных случаев.

Давайте взглянем на работающего чат-бота, чтобы проиллюстрировать идею.

https://embedd.srv.habr.com/iframe/6927e55efd37cf5ae3dc6480" width="100%" height="480" frameborder="0" loading="lazy

На вход подаётся заранее подготовленный набор данных, разделённый на обучающую, валидационную и тестовую части. Я всегда ищу самый простой и одновременно эффективный алгоритм для интеграции в свой проект.

При первом прогоне агент формирует системный промпт и семантический причинно-следственный граф (SCG), который показывает, как факторы взаимодействуют друг с другом. Этот черновой граф служит отправной точкой и не обязательно должен быть идеальным.

При появлении нового кейса (например, отчёта о диабете) система не смешивает всё в одну кучу.

Вместо этого задействуется двухступенчатый процесс. Первая модель выступает аналитиком: она сравнивает входные данные с SCG и извлекает несколько наиболее релевантных причинно-следственных цепочек.


Делегируйте рутину вместе с BotHub! Доступ без VPN, поддерживается оплата картами РФ. По ссылке — 100 000 бесплатных токенов на старте.


Если в кейсе не упоминается гипогликемия, аналитик исключит все цепочки, связанные с этим феноменом. Затем в дело вступает вторая модель — принимающая решение: она объединяет исходный кейс с подобранными рекомендациями и выносит обоснованный вердикт.

После прогноза система сверяет результат с эталоном. При расхождении активируется механизм «текстового градиента»: ментор, более мощная модель, создаёт отчёт с указанием ошибок в промптах или в SCG.

На основе обратной связи агент автоматически правит граф: добавляет, удаляет узлы или корректирует описания и системные промпты. Цикл повторяется, и SCG становится всё точнее и полнее.

В чём уникальность EGO-Prompt?

SCG представляет собой ориентированный ациклический граф (DAG). Узлы — семантические элементы задачи (например, «диабет», «низкий уровень глюкозы»), а рёбра — текстовые описания воздействий и влияний.


Важно, что начальный SCG может быть неполным и неточным — алгоритм постоянно исправит и доработает его, без необходимости жёстких каузальных допущений.

Это снижает нагрузку на экспертов и позволяет запускаться на «черновых» знаниях, постепенно достигая высокой точности.

Как это работает?


Эта система напоминает эволюцию «студента», «учебника» и «репетитора» в едином процессе:

  • LLM (студент): учится рассуждать по подсказкам и причинно-следственным диаграммам.

  • SCG (учебник): допускает ошибки и обновляется в реальном времени.

  • Текстовый градиент (конспект репетитора): постоянный движитель улучшений.

Когда студент ошибается, он обращается к репетитору (GPT-4o), который не выдаёт готовый ответ, а составляет «конспект» с анализом ошибки.

«Конспекты» разделяются на две части: обратная связь студенту и правки в SCG — добавление, удаление или корректировка связей.

Начинаем кодить

Сначала импортируем зависимости, задаём пустой ключ OpenAI (его нужно заполнить), импортируем утилиты и промпты, инициализируем параметры для эксперимента с набором «pandemic», где тестируется «gpt-4o-mini», а оценка проводится «gpt-4o».

import os  
os.environ['OPENAI_API_KEY'] = ""  

from utils import *  
from prompts import Prompts, TASK_LABELS, TAGS  

dataset_name = "pandemic"  
test_model    = "experimental:gpt-4o-mini"  
eval_model    = "gpt-4o"  
iteration     = 1  
date          = "0919"  
total_steps   = 5  
epoch         = 1  
batch_size    = 3

Затем импортируем промпты и метки для выбранного набора, инициализируем движки LLM и настраиваем бэкенд для градиентного расчёта.

cm_labels = TASK_LABELS[dataset_name]  
tags       = TAGS[dataset_name]  
CAUSAL_SYSTEM            = Prompts[dataset_name]['CAUSAL_SYSTEM']  
CAUSAL_SYSTEM_CONSTRAINT = Prompts[dataset_name]['CAUSAL_SYSTEM_CONSTRAINT']  
SYSTEM                   = Prompts[dataset_name]['SYSTEM']  

llm_api_eval = tg.get_engine(engine_name=eval_model)  
llm_api_test = tg.get_engine(engine_name=test_model, cache=False)  
tg.set_backward_engine(llm_api_eval, override=True)

Загружаем train/val/test, оборачиваем промпты в теги и выводим размеры наборов.

train_set, val_set, test_ori, eval_fn = load_task(  
    dataset_name, evaluation_api=llm_api_eval, prompt_col="organized_prompt"  
)  
train_loader = tg.tasks.DataLoader(train_set, batch_size=batch_size, shuffle=True)  

col = "organized_prompt" if dataset_name == 'swiss' else "prompt"  
for ds in (train_set, val_set, test_ori):  
    ds.data[col] = ds.data[col].apply(lambda x: f"{tags[0]}{x}{tags[1]}")  

print("Train/Val/Test lengths:", len(train_set), len(val_set), len(test_ori))

Создаём копию тестового набора, вызываем init() для подготовки промптов, моделей и оптимизаторов, и инициализируем словарь для результатов.

from copy import deepcopy  

test_set = deepcopy(test_ori)  
system_prompt, causal_prompt, model, causal_model, optimizer, optimizer_causal = init(  
    SYSTEM, CAUSAL_SYSTEM, llm_api_test, llm_api_eval, CAUSAL_SYSTEM_CONSTRAINT  
)  
results = {"test_f1": [], "validation_f1": [], "prompt": [], "system_prompt": [], "causal_prompt": []}

Функция run_one_worker() копирует датасеты, отслеживает лучшие F1, добавляет таймстемпы и запускает цикл итераций, оптимизирующий промпты и модели.

import time, copy, numpy as np  
from concurrent.futures import ThreadPoolExecutor, as_completed  

NUM_WORKERS = 1  

def run_one_worker(worker_id: int):  
    local_test = copy.deepcopy(test_set)  
    local_ori  = copy.deepcopy(test_ori)  
    local_val  = copy.deepcopy(val_set)  
    local_loader = train_loader  

    best_val, best_test = -np.inf, -np.inf  
    all_val_f1s, all_test_f1s = [], []  

    local_test.data[col] = local_ori.data[col].apply(  
        lambda x: f", {x}"  
    )  

    for cur_iter in range(iteration):  
        print(f"[W{worker_id}] Iter {cur_iter+1}/{iteration} start")  
        output_json = f"res/{date}_{dataset_name}_{test_model.split(':')[-1]}_w{worker_id}_it{cur_iter+1}.json"  
        initialize_json_file(output_json)  

        system_prompt, causal_prompt, model, causal_model, optimizer, optimizer_causal = init(  
            SYSTEM, CAUSAL_SYSTEM, llm_api_test, llm_api_eval, CAUSAL_SYSTEM_CONSTRAINT  
        )  

        results, _, _ = init_eval(  
            local_val, local_test, eval_fn, model, causal_model,  
            system_prompt, causal_prompt, cm_labels, iters=ITERS  
        )  

        results = run_training(  
            local_loader, local_val, local_test, eval_fn,  
            model, causal_model, system_prompt, causal_prompt,  
            optimizer, optimizer_causal, results, cm_labels,  
            output_json=output_json, epoch=epoch, steps=total_steps, iters=ITERS  
        )  

        all_val_f1s.append(results['validation_f1'])  
        all_test_f1s.append(results['test_f1'])  

        cur_val = results['validation_f1'][-1]  
        cur_test = results['test_f1'][-1]  
        if cur_val > best_val:  
            best_val, best_test = cur_val, cur_test  

        print(f"[W{worker_id}] Best val={best_val:.4f}, test@best={best_test:.4f}")  

    return {'best_test_f1': best_test, 'val_f1s': all_val_f1s, 'test_f1s': all_test_f1s, 'worker_id': worker_id}

Наконец, запускаем три параллельных потока, которые перебирают промпты и сохраняют лучшие F1 каждого.

NUM_WORKERS = 3  
ITERS       = 1  
total_steps = 5  
batch_size  = 3  

EGO_res = []  

with ThreadPoolExecutor(max_workers=NUM_WORKERS) as executor:  
    futures = [executor.submit(run_one_worker, i) for i in range(NUM_WORKERS)]  
    for fut in as_completed(futures):  
        res = fut.result()  
        EGO_res.append(res['best_test_f1'])  
        print(f"[Main] Worker {res['worker_id']} done. Best test_f1={res['best_test_f1']:.4f}")  

print("EGO_res (best F1 per worker):", EGO_res)

Заключение

Раньше ИИ учили по жёстким правилам, словно зубрилу: много фактов и жёсткий регламент. В результате мы получали блестящего повторителя, но робота, не способного справиться с новым заданием.

EGO-Prompt переворачивает эту парадигму: мы предоставляем ИИ черновой граф знаний и разрешаем ошибаться, обучая его анализировать и исправлять собственные промахи.


А теперь ваша очередь

Как вы считаете, станет ли такой подход новым стандартом для создания рассуждающих ИИ, или останется экспериментом в лабораториях?

Готовы ли мы доверить ИИ, способному самостоятельно учиться и развиваться, решение действительно важных задач?

Делитесь мнениями в комментариях, спасибо за внимание!

 

Источник

Читайте также