<НА ГЛАВНУЮ

Создание агента ReAct с интеграцией логики Prolog, Gemini и LangGraph: подробное руководство по программированию

Подробное руководство по созданию агента ReAct, интегрирующего логику Prolog с Gemini и LangGraph, что позволяет выполнять сложные рассуждения и обрабатывать запросы на естественном языке.

Интеграция символьной логики с генеративным ИИ

В этом руководстве показано, как объединить символьную логику с генеративным ИИ, используя PySwip для встраивания базы знаний Prolog, обертывая предикаты как инструменты LangChain и связывая всё в агента стиля ReAct. В процессе создаются правила семейных отношений, математические предикаты, такие как факториал, и утилиты для работы со списками. Агент планирует, вызывает инструменты и рассуждает над результатами, переводя вопросы на естественном языке в точные запросы Prolog и возвращая структурированные JSON-данные.

Установка зависимостей

Сначала устанавливаем SWI-Prolog и необходимые Python-библиотеки:

!apt-get install swi-prolog -y
!pip install pyswip langchain-google-genai langgraph langchain-core

Это позволит связать логику Prolog с моделью Gemini.

Инициализация окружения и LLM

Подключаем PySwip для работы с Prolog, LangChain и LangGraph для инструментов, а также Gemini 1.5 Flash для языковой модели. Устанавливаем ключ API Google как переменную окружения.

import os
from pyswip import Prolog
from langchain_google_genai import ChatGoogleGenerativeAI
from langchain_core.tools import tool
from langgraph.prebuilt import create_react_agent
import json
 
GOOGLE_API_KEY = "Use Your Own API Key Here"
os.environ["GOOGLE_API_KEY"] = GOOGLE_API_KEY
 
llm = ChatGoogleGenerativeAI(model="gemini-1.5-flash", temperature=0)

Создание расширенного интерфейса Prolog

Оборачиваем SWI-Prolog в класс AdvancedPrologInterface, который загружает базу знаний с семейными отношениями, математическими предикатами и утилитами для списков. Метод query() выполняет запросы Prolog и возвращает результаты в формате JSON или сообщения об ошибках.

class AdvancedPrologInterface:
   def __init__(self):
       self.prolog = Prolog()
       self._load_knowledge_base()
  
   def _load_knowledge_base(self):
       """Загрузить полную базу знаний Prolog"""
       rules = [
           "parent(john, mary, alice)",
           "parent(john, mary, bob)",
           "parent(bob, susan, charlie)",
           "parent(alice, david, emma)",
           "parent(charlie, lisa, frank)",
          
           "male(john)", "male(bob)", "male(david)", "male(charlie)", "male(frank)",
           "female(mary)", "female(alice)", "female(susan)", "female(emma)", "female(lisa)",
          
           "grandparent(X, Z) :- parent(X, _, Y), parent(Y, _, Z)",
           "sibling(X, Y) :- parent(P1, P2, X), parent(P1, P2, Y), X \\= Y",
           "uncle(X, Y) :- sibling(X, Z), parent(Z, _, Y), male(X)",
           "aunt(X, Y) :- sibling(X, Z), parent(Z, _, Y), female(X)",
           "cousin(X, Y) :- parent(P1, _, X), parent(P2, _, Y), sibling(P1, P2)",
          
           "factorial(0, 1)",
           "factorial(N, F) :- N > 0, N1 is N - 1, factorial(N1, F1), F is N * F1",
          
           "list_member(X, [X|_])",
           "list_member(X, [_|T]) :- list_member(X, T)",
           "list_length([], 0)",
           "list_length([_|T], N) :- list_length(T, N1), N is N1 + 1",
          
           "animal(dog)", "animal(cat)", "animal(whale)", "animal(eagle)",
           "mammal(dog)", "mammal(cat)", "mammal(whale)",
           "bird(eagle)", "bird(sparrow)",
           "can_fly(eagle)", "can_fly(sparrow)",
           "can_swim(whale)", "can_swim(fish)",
           "aquatic_mammal(X) :- mammal(X), can_swim(X)"
       ]
      
       for rule in rules:
           try:
               self.prolog.assertz(rule)
           except Exception as e:
               print(f"Warning: Could not assert rule '{rule}': {e}")
  
   def query(self, query_string):
       """Выполнить запрос Prolog и вернуть результаты"""
       try:
           results = list(self.prolog.query(query_string))
           return results if results else [{"result": "No solutions found"}]
       except Exception as e:
           return [{"error": f"Query failed: {str(e)}"}]

Обёртывание запросов Prolog в инструменты LangChain

Интерфейс Prolog оборачивается в LangChain инструменты для работы с семейными отношениями, математическими операциями (например, факториалом) и расширенными запросами (дети, братья/сёстры, двоюродные).

prolog_interface = AdvancedPrologInterface()
 
@tool
def family_relationships(query: str) -> str:
   """
   Запрос семейных отношений в формате Prolog.
   Примеры: 'parent(john, mary, X)', 'sibling(X, Y)', 'grandparent(X, charlie)'
   """
   results = prolog_interface.query(query)
   return json.dumps(results, indent=2)
 
@tool
def mathematical_operations(operation: str, number: int) -> str:
   """
   Выполнение математических операций с помощью Prolog.
   Поддерживаемые операции: 'factorial'
   Пример: operation='factorial', number=5
   """
   if operation == "factorial":
       query = f"factorial({number}, Result)"
       results = prolog_interface.query(query)
       return json.dumps(results, indent=2)
   else:
       return json.dumps([{"error": f"Operation '{operation}' not supported"}])
 
@tool
def advanced_queries(query_type: str, entity: str = "") -> str:
   """
   Выполнение расширенных запросов по отношениям.
   Типы: 'all_children', 'all_grandchildren', 'all_siblings', 'all_cousins'
   """
   queries = {
       'all_children': f"parent(_, _, {entity})" if entity else "parent(_, _, X)",
       'all_grandchildren': f"grandparent(_, {entity})" if entity else "grandparent(_, X)",
       'all_siblings': f"sibling({entity}, X)" if entity else "sibling(X, Y)",
       'all_cousins': f"cousin({entity}, X)" if entity else "cousin(X, Y)"
   }
  
   if query_type in queries:
       results = prolog_interface.query(queries[query_type])
       return json.dumps(results, indent=2)
   else:
       return json.dumps([{"error": f"Query type '{query_type}' not supported"}])

Создание и использование агента ReAct

Регистрируем эти инструменты и создаём агента ReAct с Gemini как языковой моделью. Определены функции для анализа семейных отношений, демонстрации сложных рассуждений и интерактивной сессии.

tools = [family_relationships, mathematical_operations, advanced_queries]
agent = create_react_agent(llm, tools)
 
# Функции для запуска анализов, демонстрации рассуждений и общения с агентом определены.

Тестирование и запуск решения

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

Итог

Этот подход объединяет точность символьных рассуждений Prolog с гибкостью понимания естественного языка Gemini. Скрипт предоставляет основу для расширения баз знаний, добавления новых доменов или интеграции альтернативных языковых моделей, подходит для создания интерактивных интерфейсов или API.

Полные исходные коды и ноутбуки доступны, все заслуги принадлежат оригинальным исследователям.

🇬🇧

Switch Language

Read this article in English

Switch to English