Правки solution.py: Apply all the changes described in the instructions: replace
This commit is contained in:
+65
-126
@@ -5,9 +5,7 @@ from typing import Dict, List
|
|||||||
|
|
||||||
import requests
|
import requests
|
||||||
from bs4 import BeautifulSoup
|
from bs4 import BeautifulSoup
|
||||||
from langchain.agents import Tool, AgentExecutor, initialize_agent, AgentType
|
from openai import OpenAI
|
||||||
from langchain.llms.openai import OpenAI
|
|
||||||
from langchain.schema import AgentAction, AgentFinish
|
|
||||||
from rich.console import Console
|
from rich.console import Console
|
||||||
from rich.table import Table
|
from rich.table import Table
|
||||||
|
|
||||||
@@ -48,160 +46,102 @@ class VirtualFileSystem:
|
|||||||
|
|
||||||
|
|
||||||
# --------------------------------------------------------------------------- #
|
# --------------------------------------------------------------------------- #
|
||||||
# Инструменты для агента
|
# Инструменты
|
||||||
# --------------------------------------------------------------------------- #
|
# --------------------------------------------------------------------------- #
|
||||||
def create_search_tool() -> Tool:
|
|
||||||
|
def web_search(query: str) -> str:
|
||||||
"""
|
"""
|
||||||
Возвращает инструмент поиска в интернете.
|
Выполняет поиск в интернете через DuckDuckGo и возвращает первые 3 результата.
|
||||||
Использует DuckDuckGo (без API‑ключа).
|
|
||||||
"""
|
"""
|
||||||
|
url = "https://duckduckgo.com/html/"
|
||||||
|
params = {"q": query}
|
||||||
|
try:
|
||||||
|
resp = requests.get(url, params=params, timeout=10)
|
||||||
|
resp.raise_for_status()
|
||||||
|
except Exception as e:
|
||||||
|
return f"Ошибка при поиске: {e}"
|
||||||
|
|
||||||
def search(query: str) -> str:
|
soup = BeautifulSoup(resp.text, "html.parser")
|
||||||
"""Ищет query и возвращает первые 3 ссылки с заголовками."""
|
results = []
|
||||||
url = "https://duckduckgo.com/html/"
|
for a in soup.select("a.result__a")[:3]:
|
||||||
params = {"q": query}
|
title = a.get_text(strip=True)
|
||||||
try:
|
href = a["href"]
|
||||||
resp = requests.get(url, params=params, timeout=10)
|
match = re.search(r"uddg=([^&]+)", href)
|
||||||
resp.raise_for_status()
|
if match:
|
||||||
except Exception as e:
|
href = requests.utils.unquote(match.group(1))
|
||||||
return f"Ошибка при поиске: {e}"
|
results.append(f"{title}\n{href}")
|
||||||
|
return "\n\n".join(results) or "Ничего не найдено."
|
||||||
soup = BeautifulSoup(resp.text, "html.parser")
|
|
||||||
results = []
|
|
||||||
for a in soup.select("a.result__a")[:3]:
|
|
||||||
title = a.get_text(strip=True)
|
|
||||||
href = a["href"]
|
|
||||||
# DuckDuckGo иногда оборачивает ссылку в redirect
|
|
||||||
match = re.search(r"uddg=([^&]+)", href)
|
|
||||||
if match:
|
|
||||||
href = requests.utils.unquote(match.group(1))
|
|
||||||
results.append(f"{title}\n{href}")
|
|
||||||
return "\n\n".join(results) or "Ничего не найдено."
|
|
||||||
|
|
||||||
return Tool(
|
|
||||||
name="InternetSearch",
|
|
||||||
func=search,
|
|
||||||
description=(
|
|
||||||
"Используется для поиска информации в интернете. "
|
|
||||||
"Вход: строка запроса. Выход: список ссылок и заголовков."
|
|
||||||
),
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
def create_file_tool(vfs: VirtualFileSystem) -> Tool:
|
def create_file(vfs: VirtualFileSystem, filename: str, content: str) -> str:
|
||||||
"""
|
"""
|
||||||
Возвращает инструмент создания/обновления виртуального файла.
|
Создаёт или обновляет виртуальный файл.
|
||||||
"""
|
"""
|
||||||
|
vfs.write(filename, content)
|
||||||
def write_file(args: str) -> str:
|
return f"Файл '{filename}' успешно создан/обновлён."
|
||||||
"""
|
|
||||||
Ожидает строку в формате:
|
|
||||||
filename=<имя>
|
|
||||||
content=
|
|
||||||
<текст>
|
|
||||||
|
|
||||||
Пример:
|
|
||||||
filename=summary.txt
|
|
||||||
content=
|
|
||||||
Это пример содержания.
|
|
||||||
"""
|
|
||||||
try:
|
|
||||||
parts = args.split("content=", 1)
|
|
||||||
if len(parts) != 2:
|
|
||||||
return "Неверный формат. Используйте: filename=<имя>\ncontent=\n<текст>"
|
|
||||||
header, body = parts
|
|
||||||
filename_match = re.search(r"filename=([^\n]+)", header.strip())
|
|
||||||
if not filename_match:
|
|
||||||
return "Не найдено имя файла (filename=...)."
|
|
||||||
filename = filename_match.group(1).strip()
|
|
||||||
content = body.strip()
|
|
||||||
vfs.write(filename, content)
|
|
||||||
return f"Файл '{filename}' успешно создан/обновлён."
|
|
||||||
except Exception as e:
|
|
||||||
return f"Ошибка при записи файла: {e}"
|
|
||||||
|
|
||||||
return Tool(
|
|
||||||
name="CreateFile",
|
|
||||||
func=write_file,
|
|
||||||
description=(
|
|
||||||
"Создаёт или обновляет виртуальный файл. "
|
|
||||||
"Вход: строка с 'filename=<имя>' и 'content=' + текст."
|
|
||||||
),
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
def create_export_tool(vfs: VirtualFileSystem) -> Tool:
|
|
||||||
"""
|
|
||||||
Инструмент для выгрузки всех файлов в реальную файловую систему.
|
|
||||||
"""
|
|
||||||
|
|
||||||
def export(args: str) -> str:
|
|
||||||
"""Выгружает файлы в директорию, указанную в args (по умолчанию текущая)."""
|
|
||||||
directory = args.strip() or "."
|
|
||||||
try:
|
|
||||||
vfs.export_all(directory)
|
|
||||||
return f"Все файлы выгружены в '{os.path.abspath(directory)}'."
|
|
||||||
except Exception as e:
|
|
||||||
return f"Ошибка при экспорте файлов: {e}"
|
|
||||||
|
|
||||||
return Tool(
|
|
||||||
name="ExportFiles",
|
|
||||||
func=export,
|
|
||||||
description=(
|
|
||||||
"Выгружает все виртуальные файлы на диск. "
|
|
||||||
"Вход: путь к директории (можно оставить пустым)."
|
|
||||||
),
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
# --------------------------------------------------------------------------- #
|
# --------------------------------------------------------------------------- #
|
||||||
# Основной агент
|
# Основной логика
|
||||||
# --------------------------------------------------------------------------- #
|
# --------------------------------------------------------------------------- #
|
||||||
def build_agent(vfs: VirtualFileSystem) -> AgentExecutor:
|
|
||||||
"""
|
|
||||||
Создаёт и возвращает готовый агент.
|
|
||||||
"""
|
|
||||||
llm = OpenAI(temperature=0, model_name="gpt-3.5-turbo") # или другой LLM
|
|
||||||
|
|
||||||
tools = [
|
def run_agent(task: str, vfs: VirtualFileSystem) -> str:
|
||||||
create_search_tool(),
|
"""
|
||||||
create_file_tool(vfs),
|
Выполняет задачу с помощью OpenAI LLM.
|
||||||
create_export_tool(vfs),
|
"""
|
||||||
]
|
client = OpenAI()
|
||||||
|
# Формируем запрос к модели
|
||||||
agent_executor = initialize_agent(
|
prompt = (
|
||||||
tools,
|
f"Задача: {task}\n"
|
||||||
llm,
|
"Используйте web_search для получения информации.\n"
|
||||||
agent=AgentType.ZERO_SHOT_REACT_DESCRIPTION,
|
"Сформируйте краткое резюме (не более 300 слов) и сохраните его в файл summary.txt."
|
||||||
verbose=True,
|
|
||||||
handle_parsing_errors=True,
|
|
||||||
)
|
)
|
||||||
return agent_executor
|
# Получаем ответ модели
|
||||||
|
try:
|
||||||
|
response = client.chat.completions.create(
|
||||||
|
model="gpt-3.5-turbo",
|
||||||
|
temperature=0,
|
||||||
|
messages=[{"role": "user", "content": prompt}],
|
||||||
|
)
|
||||||
|
except Exception as e:
|
||||||
|
return f"Ошибка при вызове OpenAI: {e}"
|
||||||
|
|
||||||
|
summary_text = response.choices[0].message.content.strip()
|
||||||
|
# Сохраняем в виртуальный файл
|
||||||
|
create_file(vfs, "summary.txt", summary_text)
|
||||||
|
return summary_text
|
||||||
|
|
||||||
|
|
||||||
|
def flush_virtual_fs(vfs: VirtualFileSystem) -> str:
|
||||||
|
"""
|
||||||
|
Экспортирует все файлы из виртуальной файловой системы на диск.
|
||||||
|
"""
|
||||||
|
try:
|
||||||
|
vfs.export_all(".")
|
||||||
|
return f"Все файлы выгружены в '{os.path.abspath('.')}'."
|
||||||
|
except Exception as e:
|
||||||
|
return f"Ошибка при экспорте файлов: {e}"
|
||||||
|
|
||||||
|
|
||||||
# --------------------------------------------------------------------------- #
|
# --------------------------------------------------------------------------- #
|
||||||
# Точка входа
|
# Точка входа
|
||||||
# --------------------------------------------------------------------------- #
|
# --------------------------------------------------------------------------- #
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
console = Console()
|
console = Console()
|
||||||
vfs = VirtualFileSystem()
|
vfs = VirtualFileSystem()
|
||||||
|
|
||||||
# Пример задачи: собрать информацию о новых возможностях Python 3.11 и сохранить в файл.
|
|
||||||
task = (
|
task = (
|
||||||
"Найди последние новости и обновления по версии Python 3.11, "
|
"Найди последние новости и обновления по версии Python 3.11, "
|
||||||
"создай краткое резюме (не более 300 слов) и сохрани его в файле summary.txt."
|
"создай краткое резюме (не более 300 слов) и сохрани его в файле summary.txt."
|
||||||
)
|
)
|
||||||
|
|
||||||
console.print("[bold cyan]Запуск агента...[/]")
|
console.print("[bold cyan]Запуск агента...[/]")
|
||||||
agent = build_agent(vfs)
|
result = run_agent(task, vfs)
|
||||||
|
|
||||||
# Запускаем агент
|
|
||||||
result = agent.run(task)
|
|
||||||
|
|
||||||
console.print("\n[green]Итоговое сообщение от агента:[/]\n")
|
console.print("\n[green]Итоговое сообщение от агента:[/]\n")
|
||||||
console.print(result)
|
console.print(result)
|
||||||
|
|
||||||
# Выводим список виртуальных файлов
|
|
||||||
console.print("\n[bold magenta]Виртуальные файлы, созданные агентом:[/]")
|
console.print("\n[bold magenta]Виртуальные файлы, созданные агентом:[/]")
|
||||||
table = Table(show_header=True, header_style="bold blue")
|
table = Table(show_header=True, header_style="bold blue")
|
||||||
table.add_column("Имя файла", style="dim")
|
table.add_column("Имя файла", style="dim")
|
||||||
@@ -209,8 +149,7 @@ def main():
|
|||||||
table.add_row(fname)
|
table.add_row(fname)
|
||||||
console.print(table)
|
console.print(table)
|
||||||
|
|
||||||
# Экспортируем файлы в текущую директорию
|
export_result = flush_virtual_fs(vfs)
|
||||||
export_result = agent.run("ExportFiles")
|
|
||||||
console.print("\n[green]Результат экспорта:[/]")
|
console.print("\n[green]Результат экспорта:[/]")
|
||||||
console.print(export_result)
|
console.print(export_result)
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user