diff --git a/solutions/6a02e23da6fe2e4ac16acf65_Агент_с_RAG_памятью/cli_client.py b/solutions/6a02e23da6fe2e4ac16acf65_Агент_с_RAG_памятью/cli_client.py
new file mode 100644
index 0000000..069eeb2
--- /dev/null
+++ b/solutions/6a02e23da6fe2e4ac16acf65_Агент_с_RAG_памятью/cli_client.py
@@ -0,0 +1,124 @@
+#!/usr/bin/env python3
+# -*- coding: utf-8 -*-
+
+"""
+cli_client.py
+
+Интерактивный клиент для работы с агентом RAG‑памяти.
+Поддерживает команды:
+ /add
– добавить документ в базу знаний
+ /search – выполнить семантический поиск
+ /quit – выйти из программы
+"""
+
+import sys
+from typing import List
+
+# Предполагается, что модули с инструментами уже реализованы и находятся в пакете `rag_agent`.
+# Импортируем необходимые функции.
+try:
+ from rag_agent.tools import add_to_knowledge_base, search_knowledge_base # noqa: F401
+except Exception as exc:
+ print(f"Ошибка при импорте инструментов: {exc}", file=sys.stderr)
+ sys.exit(1)
+
+
+def parse_command(line: str) -> (str, List[str]):
+ """
+ Разбирает строку команды и возвращает имя команды и список аргументов.
+ Команда начинается с символа '/'.
+ """
+ if not line.startswith("/"):
+ raise ValueError("Команды должны начинаться со знака '/'.")
+ parts = line.strip().split(maxsplit=1)
+ cmd = parts[0]
+ args_str = parts[1] if len(parts) > 1 else ""
+ # Для /add аргументы разделены пробелом: title content
+ # Чтобы сохранить пробелы в содержимом, делаем split только один раз.
+ return cmd, [args_str]
+
+
+def handle_add(args: List[str]) -> None:
+ """
+ Обработчик команды /add.
+ Ожидает строку вида " ".
+ """
+ if not args or not args[0]:
+ print("Ошибка: нужно указать заголовок и содержимое.")
+ return
+ # Разделяем на заголовок и контент. Заголовок – первое слово, остальное – контент.
+ parts = args[0].split(maxsplit=1)
+ if len(parts) < 2:
+ print("Ошибка: нужно указать как минимум заголовок и содержимое.")
+ return
+ title, content = parts[0], parts[1]
+ try:
+ add_to_knowledge_base(content=content, title=title)
+ print(f"Документ '{title}' успешно добавлен в базу знаний.")
+ except Exception as exc:
+ print(f"Ошибка при добавлении документа: {exc}")
+
+
+def handle_search(args: List[str]) -> None:
+ """
+ Обработчик команды /search.
+ Ожидает строку запроса.
+ """
+ if not args or not args[0]:
+ print("Ошибка: нужно указать поисковый запрос.")
+ return
+ query = args[0]
+ try:
+ results = search_knowledge_base(query=query, max_results=5)
+ if not results:
+ print("Ничего не найдено.")
+ return
+ print(f"Найдено {len(results)} результатов:")
+ for i, res in enumerate(results, 1):
+ # Предполагаем, что результат – словарь с полями 'title' и 'content'.
+ title = res.get("metadata", {}).get("title", "Без названия")
+ snippet = res.get("content")[:200] + ("..." if len(res.get("content", "")) > 200 else "")
+ print(f"\n{i}. {title}\n {snippet}")
+ except Exception as exc:
+ print(f"Ошибка при поиске: {exc}")
+
+
+def main() -> None:
+ """
+ Основной цикл интерактивного клиента.
+ """
+ print("=== RAG‑память CLI ===")
+ print("Доступные команды:")
+ print("/add – добавить документ в базу знаний")
+ print("/search – выполнить семантический поиск")
+ print("/quit – выйти из программы\n")
+
+ while True:
+ try:
+ line = input("> ").strip()
+ except (EOFError, KeyboardInterrupt):
+ print("\nВыход.")
+ break
+
+ if not line:
+ continue
+
+ try:
+ cmd, args = parse_command(line)
+ except ValueError as ve:
+ print(ve)
+ continue
+
+ if cmd == "/add":
+ handle_add(args)
+ elif cmd == "/search":
+ handle_search(args)
+ elif cmd == "/quit":
+ print("До свидания!")
+ break
+ else:
+ print(f"Неизвестная команда: {cmd}")
+
+
+if __name__ == "__main__":
+ main()
\ No newline at end of file