ДОбился запуска
This commit is contained in:
6
.gitignore
vendored
Normal file
6
.gitignore
vendored
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
__pycache__
|
||||||
|
agent_env
|
||||||
|
.lock
|
||||||
|
.sqlite
|
||||||
|
qdrant_data
|
||||||
|
qdrant_storage
|
||||||
@@ -1,15 +1,13 @@
|
|||||||
from typing import TypedDict, List, Optional, Annotated
|
from typing import TypedDict, List, Optional, Annotated
|
||||||
import operator
|
import operator
|
||||||
from langchain_community.llms import Ollama
|
from langchain_community.llms import Ollama
|
||||||
from langchain_community.embeddings import OllamaEmbeddings
|
|
||||||
from langchain_community.vectorstores import Qdrant
|
from langchain_community.vectorstores import Qdrant
|
||||||
from langchain.text_splitter import RecursiveCharacterTextSplitter
|
|
||||||
from langchain_community.document_loaders import DirectoryLoader, PyPDFLoader
|
from langchain_community.document_loaders import DirectoryLoader, PyPDFLoader
|
||||||
from langgraph.graph import StateGraph, END
|
from langgraph.graph import StateGraph, END
|
||||||
from langgraph.graph.message import add_messages
|
from langgraph.graph.message import add_messages
|
||||||
from langchain_core.messages import HumanMessage, AIMessage, SystemMessage
|
from langchain_core.messages import AIMessage, SystemMessage
|
||||||
from langchain.tools import tool
|
from langchain.tools import tool
|
||||||
from langchain.agents import AgentExecutor, create_react_agent
|
# from langchain.agents import AgentExecutor, create_react_agent
|
||||||
import numpy as np
|
import numpy as np
|
||||||
|
|
||||||
# Определяем состояние агента
|
# Определяем состояние агента
|
||||||
@@ -22,16 +20,11 @@ class AgentState(TypedDict):
|
|||||||
|
|
||||||
# Инициализация LLM через Ollama
|
# Инициализация LLM через Ollama
|
||||||
llm = Ollama(
|
llm = Ollama(
|
||||||
model="llama3.2:3b",
|
model="qwen2.5-coder-16k:14b",
|
||||||
temperature=0.1, # Низкая температура для консистентности
|
temperature=0.1, # Низкая температура для консистентности
|
||||||
num_predict=1024, # Максимальная длина ответа
|
num_predict=1024, # Максимальная длина ответа
|
||||||
)
|
)
|
||||||
|
|
||||||
# Инициализация эмбеддингов
|
|
||||||
embeddings = OllamaEmbeddings(
|
|
||||||
model="nomic-embed-text", # Хорошие локальные эмбеддинги
|
|
||||||
)
|
|
||||||
|
|
||||||
# Создаем инструменты для агента
|
# Создаем инструменты для агента
|
||||||
@tool
|
@tool
|
||||||
def search_knowledge_base(query: str) -> str:
|
def search_knowledge_base(query: str) -> str:
|
||||||
@@ -127,6 +120,3 @@ def create_agent_graph():
|
|||||||
workflow.add_edge("generate", END)
|
workflow.add_edge("generate", END)
|
||||||
|
|
||||||
return workflow.compile()
|
return workflow.compile()
|
||||||
|
|
||||||
# Создаем и компилируем граф
|
|
||||||
agent_graph = create_agent_graph()
|
|
||||||
@@ -1,6 +1,10 @@
|
|||||||
import gradio as gr
|
import gradio as gr
|
||||||
import asyncio
|
import asyncio
|
||||||
|
import os
|
||||||
from typing import List
|
from typing import List
|
||||||
|
from agent_core import create_agent_graph
|
||||||
|
from local_knowledge_base import LocalKnowledgeBase
|
||||||
|
from langchain_core.messages import HumanMessage
|
||||||
|
|
||||||
class AgenticRAGInterface:
|
class AgenticRAGInterface:
|
||||||
def __init__(self, agent_graph, knowledge_base):
|
def __init__(self, agent_graph, knowledge_base):
|
||||||
@@ -61,8 +65,15 @@ class AgenticRAGInterface:
|
|||||||
self.conversation_history = []
|
self.conversation_history = []
|
||||||
return "История очищена", ""
|
return "История очищена", ""
|
||||||
|
|
||||||
|
# Инициализируем базу
|
||||||
|
kb = LocalKnowledgeBase()
|
||||||
|
# Загружаем документы (если есть)
|
||||||
|
if os.path.exists("./documents"):
|
||||||
|
kb.load_documents("./documents")
|
||||||
|
|
||||||
|
|
||||||
# Создаем интерфейс
|
# Создаем интерфейс
|
||||||
interface = AgenticRAGInterface(agent_graph, kb)
|
interface = AgenticRAGInterface(create_agent_graph(), kb)
|
||||||
|
|
||||||
# Создаем Gradio интерфейс
|
# Создаем Gradio интерфейс
|
||||||
def create_gradio_interface():
|
def create_gradio_interface():
|
||||||
|
|||||||
@@ -1,19 +1,28 @@
|
|||||||
import os
|
import os
|
||||||
from qdrant_client import QdrantClient
|
from qdrant_client import QdrantClient
|
||||||
from qdrant_client.models import Distance, VectorParams, PointStruct
|
from qdrant_client.models import Distance, VectorParams, PointStruct
|
||||||
from langchain_community.document_loaders import TextLoader, PyPDFLoader, DirectoryLoader
|
from langchain_community.document_loaders import (
|
||||||
from langchain.text_splitter import Language
|
TextLoader,
|
||||||
|
PyPDFLoader,
|
||||||
|
DirectoryLoader,
|
||||||
|
)
|
||||||
|
from langchain_text_splitters import Language, RecursiveCharacterTextSplitter
|
||||||
|
from langchain_community.embeddings import OllamaEmbeddings
|
||||||
|
|
||||||
|
|
||||||
class LocalKnowledgeBase:
|
class LocalKnowledgeBase:
|
||||||
def __init__(self, collection_name="documents", persist_dir="./qdrant_data"):
|
def __init__(self, collection_name="documents", persist_dir="./qdrant_data"):
|
||||||
# Инициализируем клиент Qdrant
|
# Инициализируем клиент Qdrant
|
||||||
self.client = QdrantClient(
|
self.client = QdrantClient(
|
||||||
path=persist_dir, # Локальное хранение
|
path=persist_dir, prefer_grpc=True # Локальное хранение
|
||||||
prefer_grpc=True
|
|
||||||
)
|
)
|
||||||
|
|
||||||
self.collection_name = collection_name
|
self.collection_name = collection_name
|
||||||
self.embeddings = embeddings
|
|
||||||
|
# Инициализация эмбеддингов
|
||||||
|
self.embeddings = OllamaEmbeddings(
|
||||||
|
model="nomic-embed-text", # Хорошие локальные эмбеддинги
|
||||||
|
)
|
||||||
|
|
||||||
# Создаем коллекцию если её нет
|
# Создаем коллекцию если её нет
|
||||||
self._create_collection()
|
self._create_collection()
|
||||||
@@ -28,22 +37,21 @@ class LocalKnowledgeBase:
|
|||||||
collection_name=self.collection_name,
|
collection_name=self.collection_name,
|
||||||
vectors_config=VectorParams(
|
vectors_config=VectorParams(
|
||||||
size=768, # Размерность эмбеддингов nomic-embed-text
|
size=768, # Размерность эмбеддингов nomic-embed-text
|
||||||
distance=Distance.COSINE
|
distance=Distance.COSINE,
|
||||||
)
|
),
|
||||||
)
|
)
|
||||||
print(f"Создана коллекция {self.collection_name}")
|
print(f"Создана коллекция {self.collection_name}")
|
||||||
|
|
||||||
def load_documents(self, directory_path: str):
|
def load_documents(self, directory_path: str):
|
||||||
"""Загрузка документов из директории"""
|
"""Загрузка документов из директории"""
|
||||||
loaders = {
|
loaders = {
|
||||||
'.pdf': PyPDFLoader,
|
".pdf": PyPDFLoader,
|
||||||
'.txt': lambda path: DirectoryLoader(path, glob="**/*.txt"),
|
".txt": lambda path: DirectoryLoader(path, glob="**/*.txt"),
|
||||||
'.docx': lambda path: DirectoryLoader(path, glob="**/*.docx"),
|
".docx": lambda path: DirectoryLoader(path, glob="**/*.docx"),
|
||||||
'.hpp': lambda path: TextLoader(path, encoding='utf-8'),
|
".hpp": lambda path: TextLoader(path, encoding="utf-8"),
|
||||||
'.cpp': lambda path: TextLoader(path, encoding='utf-8'), # добавить
|
".cpp": lambda path: TextLoader(path, encoding="utf-8"), # добавить
|
||||||
'.h': lambda path: TextLoader(path, encoding='utf-8'), # добавить
|
".h": lambda path: TextLoader(path, encoding="utf-8"), # добавить
|
||||||
'.cc': lambda path: TextLoader(path, encoding='utf-8'), # добавить
|
".cc": lambda path: TextLoader(path, encoding="utf-8"), # добавить
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
all_documents = []
|
all_documents = []
|
||||||
@@ -65,7 +73,7 @@ class LocalKnowledgeBase:
|
|||||||
language=Language.CPP,
|
language=Language.CPP,
|
||||||
chunk_size=1000,
|
chunk_size=1000,
|
||||||
chunk_overlap=200,
|
chunk_overlap=200,
|
||||||
length_function=len
|
length_function=len,
|
||||||
)
|
)
|
||||||
|
|
||||||
chunks = text_splitter.split_documents(all_documents)
|
chunks = text_splitter.split_documents(all_documents)
|
||||||
@@ -91,26 +99,20 @@ class LocalKnowledgeBase:
|
|||||||
"text": doc.page_content,
|
"text": doc.page_content,
|
||||||
"source": doc.metadata.get("source", "unknown"),
|
"source": doc.metadata.get("source", "unknown"),
|
||||||
"page": doc.metadata.get("page", 0),
|
"page": doc.metadata.get("page", 0),
|
||||||
"file_type": "cpp"
|
"file_type": "cpp",
|
||||||
}
|
},
|
||||||
)
|
)
|
||||||
points.append(point)
|
points.append(point)
|
||||||
|
|
||||||
# Пакетная загрузка каждые 100 точек
|
# Пакетная загрузка каждые 100 точек
|
||||||
if len(points) >= 100:
|
if len(points) >= 100:
|
||||||
self.client.upsert(
|
self.client.upsert(collection_name=self.collection_name, points=points)
|
||||||
collection_name=self.collection_name,
|
|
||||||
points=points
|
|
||||||
)
|
|
||||||
points = []
|
points = []
|
||||||
print(f"Индексировано {i+1} документов")
|
print(f"Индексировано {i+1} документов")
|
||||||
|
|
||||||
# Загружаем оставшиеся
|
# Загружаем оставшиеся
|
||||||
if points:
|
if points:
|
||||||
self.client.upsert(
|
self.client.upsert(collection_name=self.collection_name, points=points)
|
||||||
collection_name=self.collection_name,
|
|
||||||
points=points
|
|
||||||
)
|
|
||||||
|
|
||||||
print(f"Индексация завершена. Всего документов: {len(documents)}")
|
print(f"Индексация завершена. Всего документов: {len(documents)}")
|
||||||
|
|
||||||
@@ -120,26 +122,22 @@ class LocalKnowledgeBase:
|
|||||||
query_embedding = self.embeddings.embed_query(query)
|
query_embedding = self.embeddings.embed_query(query)
|
||||||
|
|
||||||
# Ищем в Qdrant
|
# Ищем в Qdrant
|
||||||
search_result = self.client.search(
|
search_result = self.client.query_points(
|
||||||
collection_name=self.collection_name,
|
collection_name=self.collection_name,
|
||||||
query_vector=query_embedding,
|
query=query_embedding,
|
||||||
limit=top_k
|
limit=top_k,
|
||||||
)
|
)
|
||||||
|
|
||||||
# Форматируем результаты
|
# Форматируем результаты
|
||||||
results = []
|
results = []
|
||||||
for hit in search_result:
|
for hit in search_result.points:
|
||||||
results.append({
|
results.append(
|
||||||
|
{
|
||||||
"text": hit.payload["text"],
|
"text": hit.payload["text"],
|
||||||
"score": hit.score,
|
"score": hit.score,
|
||||||
"source": hit.payload.get("source", "unknown")
|
"source": hit.payload.get("source", "unknown"),
|
||||||
})
|
}
|
||||||
|
)
|
||||||
|
|
||||||
return results
|
return results
|
||||||
|
|
||||||
# Инициализируем базу знаний
|
|
||||||
kb = LocalKnowledgeBase()
|
|
||||||
|
|
||||||
# Загружаем документы (если есть)
|
|
||||||
if os.path.exists("./documents"):
|
|
||||||
kb.load_documents("./documents")
|
|
||||||
Reference in New Issue
Block a user