8. Самописный поисковый агент на основе deep agents from scratch: client.py
This commit is contained in:
+101
@@ -0,0 +1,101 @@
|
|||||||
|
import sys
|
||||||
|
from typing import List
|
||||||
|
|
||||||
|
from langchain_ollama import OllamaEmbeddings, OllamaLLM
|
||||||
|
from langchain_qdrant import QdrantVectorStore
|
||||||
|
from qdrant_client import QdrantClient
|
||||||
|
from qdrant_client.http.models import Distance, VectorParams
|
||||||
|
|
||||||
|
# Конфигурация подключения к Qdrant
|
||||||
|
QDRANT_HOST = "localhost"
|
||||||
|
QDRANT_PORT = 6333
|
||||||
|
COLLECTION_NAME = "documents"
|
||||||
|
|
||||||
|
# Инициализация клиента Qdrant
|
||||||
|
qdrant_client = QdrantClient(host=QDRANT_HOST, port=QDRANT_PORT)
|
||||||
|
|
||||||
|
# Создание коллекции при необходимости
|
||||||
|
if COLLECTION_NAME not in qdrant_client.get_collections().collections:
|
||||||
|
qdrant_client.create_collection(
|
||||||
|
collection_name=COLLECTION_NAME,
|
||||||
|
vectors_config=VectorParams(size=768, distance=Distance.COSINE),
|
||||||
|
)
|
||||||
|
|
||||||
|
# Инициализация эмбеддинговой модели (nomic-embed-text)
|
||||||
|
embeddings = OllamaEmbeddings(model="nomic-embed-text")
|
||||||
|
|
||||||
|
# Создание векторного хранилища
|
||||||
|
vector_store = QdrantVectorStore(
|
||||||
|
client=qdrant_client,
|
||||||
|
collection_name=COLLECTION_NAME,
|
||||||
|
embeddings=embeddings,
|
||||||
|
)
|
||||||
|
|
||||||
|
# Инициализация LLM (llama3)
|
||||||
|
llm = OllamaLLM(model="llama3")
|
||||||
|
|
||||||
|
def add_document(text: str) -> None:
|
||||||
|
"""Добавляет документ в хранилище."""
|
||||||
|
vector_store.add_texts([text])
|
||||||
|
print("✅ Документ добавлен.")
|
||||||
|
|
||||||
|
def search_documents(query: str, k: int = 3) -> List[str]:
|
||||||
|
"""Ищет похожие документы и возвращает их тексты."""
|
||||||
|
results = vector_store.similarity_search_with_score(query, k=k)
|
||||||
|
docs = [doc.page_content for doc, _ in results]
|
||||||
|
return docs
|
||||||
|
|
||||||
|
def answer_query(query: str) -> str:
|
||||||
|
"""Получает ответ LLM на основе найденных документов."""
|
||||||
|
docs = search_documents(query)
|
||||||
|
context = "\n\n".join(docs)
|
||||||
|
prompt = f"Контекст:\n{context}\n\nВопрос: {query}\nОтвет:"
|
||||||
|
return llm.invoke(prompt)
|
||||||
|
|
||||||
|
def print_help() -> None:
|
||||||
|
"""Показывает список команд."""
|
||||||
|
help_text = """
|
||||||
|
Команды:
|
||||||
|
/add <текст> - добавить документ
|
||||||
|
/search <запрос> - поиск по запросу и вывод ответа LLM
|
||||||
|
/quit - выйти из программы
|
||||||
|
"""
|
||||||
|
print(help_text)
|
||||||
|
|
||||||
|
def main() -> None:
|
||||||
|
print("=== Самописный поисковый агент ===")
|
||||||
|
print_help()
|
||||||
|
while True:
|
||||||
|
try:
|
||||||
|
user_input = input("> ").strip()
|
||||||
|
except (EOFError, KeyboardInterrupt):
|
||||||
|
print("\nВыход.")
|
||||||
|
break
|
||||||
|
|
||||||
|
if not user_input:
|
||||||
|
continue
|
||||||
|
|
||||||
|
if user_input.startswith("/add "):
|
||||||
|
text = user_input[5:].strip()
|
||||||
|
if text:
|
||||||
|
add_document(text)
|
||||||
|
else:
|
||||||
|
print("⚠️ Текст не указан.")
|
||||||
|
elif user_input.startswith("/search "):
|
||||||
|
query = user_input[8:].strip()
|
||||||
|
if query:
|
||||||
|
answer = answer_query(query)
|
||||||
|
print("\nОтвет LLM:")
|
||||||
|
print(answer)
|
||||||
|
else:
|
||||||
|
print("⚠️ Запрос не указан.")
|
||||||
|
elif user_input == "/quit":
|
||||||
|
print("Выход.")
|
||||||
|
break
|
||||||
|
elif user_input == "/help":
|
||||||
|
print_help()
|
||||||
|
else:
|
||||||
|
print("❓ Неизвестная команда. Введите /help для списка команд.")
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
main()
|
||||||
Reference in New Issue
Block a user