Files
task-6a02e23da6fe2e4ac16acf65/main.py
T

117 lines
4.5 KiB
Python

import os
import asyncio
from langchain_ollama import ChatOllama, OllamaEmbeddings
from langchain_qdrant import QdrantVectorStore
from langchain_text_splitters import RecursiveCharacterTextSplitter
from langchain_core.documents import Document
from langchain.tools import tool
from langchain_core.messages import HumanMessage
from deepagents import create_deep_agent
from deepagents.backends import CompositeBackend, LocalShellBackend, FilesystemBackend
# Инициализация эмбеддингов и LLM через Ollama
embeddings = OllamaEmbeddings(model="nomic-embed-text")
llm = ChatOllama(model="llama3")
# Инициализация QdrantVectorStore
vector_store = QdrantVectorStore(
host="localhost",
port=6333,
collection_name="knowledge",
embedding_function=embeddings,
)
# Чанкинг текста
splitter = RecursiveCharacterTextSplitter(chunk_size=1000, chunk_overlap=200)
@tool
def search_knowledge_base(query: str, max_results: int = 3) -> str:
"""Поиск в базе знаний."""
docs = vector_store.similarity_search(query, k=max_results)
return "\n".join(d.page_content for d in docs) if docs else "No results."
@tool
def add_to_knowledge_base(content: str, title: str = "doc") -> str:
"""Добавление документа в базу знаний."""
vector_store.add_documents([Document(page_content=content, metadata={"title": title})])
return f"Added: {title}"
# Backend для deepagents
backend = CompositeBackend([
LocalShellBackend(workspace_dir="./workspace"),
FilesystemBackend(),
])
# Создание агента
agent = create_deep_agent(
model=llm,
tools=[search_knowledge_base, add_to_knowledge_base],
backend=backend,
system_prompt="You are a helpful assistant. Use the provided tools to search and add knowledge.",
)
def load_documents_from_dir(dir_path: str):
"""Загрузка всех .txt файлов из директории в векторную базу."""
for root, _, files in os.walk(dir_path):
for file in files:
if file.lower().endswith(".txt"):
file_path = os.path.join(root, file)
with open(file_path, "r", encoding="utf-8") as f:
content = f.read()
chunks = splitter.split_text(content)
docs = [Document(page_content=chunk, metadata={"title": file}) for chunk in chunks]
vector_store.add_documents(docs)
async def main():
# Загрузка документов из папки data (если есть)
data_dir = "./data"
if os.path.isdir(data_dir):
load_documents_from_dir(data_dir)
print("RAG Agent ready. Commands:")
print("/add <file_path> - добавить документ")
print("/search <query> - поиск в базе")
print("/quit - выйти")
while True:
user_input = input("> ").strip()
if not user_input:
continue
if user_input.startswith("/quit"):
print("Goodbye.")
break
elif user_input.startswith("/add"):
parts = user_input.split(maxsplit=1)
if len(parts) < 2:
print("Usage: /add <file_path>")
continue
file_path = parts[1]
if not os.path.isfile(file_path):
print(f"File not found: {file_path}")
continue
with open(file_path, "r", encoding="utf-8") as f:
content = f.read()
title = os.path.basename(file_path)
message = f"Add document titled {title} with content: {content}"
result = await agent.ainvoke(
{"messages": [HumanMessage(content=message)]},
{"configurable": {"thread_id": "session-1"}},
)
print(result["messages"][-1].content)
elif user_input.startswith("/search"):
parts = user_input.split(maxsplit=1)
if len(parts) < 2:
print("Usage: /search <query>")
continue
query = parts[1]
message = f"Search the knowledge base for: {query}"
result = await agent.ainvoke(
{"messages": [HumanMessage(content=message)]},
{"configurable": {"thread_id": "session-1"}},
)
print(result["messages"][-1].content)
else:
print("Unknown command. Use /add, /search, /quit.")
if __name__ == "__main__":
asyncio.run(main())