Переделываю систему под агента-планировщика

This commit is contained in:
ki.sagidullin
2026-04-12 09:27:07 +05:00
parent ee6d12c5fb
commit 8f16a6d669
7 changed files with 255 additions and 35 deletions

View File

@@ -1,4 +1,5 @@
from .developer import DeveloperAgent
from .reviewer import ReviewerAgent
from .planner import PlannerAgent
__all__ = ["DeveloperAgent", "ReviewerAgent"]
__all__ = ["DeveloperAgent", "ReviewerAgent", "PlannerAgent"]

37
agent/executor.py Normal file
View File

@@ -0,0 +1,37 @@
# executor.py
from langchain.agents import AgentExecutor, create_tool_calling_agent
from langchain_ollama import ChatOllama
from langchain_core.prompts import ChatPromptTemplate
class ToolExecutor:
def __init__(self, tools):
self.tools = tools
self.llm = llm or ChatOllama(
model=MODEL_NAME,
temperature=0.0
)
self.agent = self._create_agent()
def _create_agent(self):
prompt = ChatPromptTemplate.from_messages([
("system", "Ты - исполнитель. У тебя есть доступ к инструментам. Выполняй шаги плана последовательно."),
("human", "{input}"),
("placeholder", "{agent_scratchpad}")
])
agent = create_tool_calling_agent(self.llm, self.tools, prompt)
return AgentExecutor(agent=agent, tools=self.tools, verbose=True)
def execute_plan(self, plan: List[Dict]) -> List[Dict]:
results = []
for step in plan:
tool_name = step["tool"]
args = step["args"]
# Превращаем шаг в текстовую команду для агента
command = f"Вызови инструмент {tool_name} с аргументами {args}"
result = self.agent.invoke({"input": command})
results.append({
"step": step,
"output": result["output"],
"success": True # можно анализировать ошибки
})
return results

26
agent/plan_reviewer.py Normal file
View File

@@ -0,0 +1,26 @@
# reviewer.py
from langchain_ollama import ChatOllama
from langchain_core.messages import SystemMessage, HumanMessage
class PlanReviewerAgent:
def __init__(self, llm=None):
self.llm = llm or ChatOllama(
model=MODEL_NAME,
temperature=0.0
)
def review(self, original_task: str, plan: List[Dict], execution_results: List[Dict]) -> dict:
system_prompt = """Ты - ревьювер. Оцени, достигнута ли цель задачи на основе выполненного плана.
Верни JSON с полями:
- "status": "approved" / "changes_requested" / "rejected"
- "feedback": пояснение
- "suggested_plan_correction": если нужно изменить план - предложи новый план (массив шагов)
"""
user_prompt = f"""
Задача: {original_task}
План: {json.dumps(plan, indent=2)}
Результаты выполнения: {json.dumps(execution_results, indent=2)}
Оцени результат.
"""
response = self.llm.invoke([SystemMessage(content=system_prompt), HumanMessage(content=user_prompt)])
return json.loads(response.content)

40
agent/planner.py Normal file
View File

@@ -0,0 +1,40 @@
# planner.py
from langchain_ollama import ChatOllama
from langchain_core.messages import SystemMessage, HumanMessage
import json
from typing import List, Dict
from config import MODEL_NAME
class PlannerAgent:
def __init__(self, llm=None):
self.llm = llm or ChatOllama(
model=MODEL_NAME,
temperature=0.0
)
def create_plan(self, task: str, tools_description: List[Dict]) -> List[Dict]:
system_prompt = """Ты - планировщик. Твоя задача - разбить запрос пользователя на последовательность шагов.
Каждый шаг - это вызов одного из доступных инструментов с конкретными аргументами.
Верни JSON массив шагов, где каждый шаг содержит:
- "tool": имя инструмента (строго из списка)
- "args": словарь аргументов для этого инструмента
- "description": краткое пояснение, зачем этот шаг
Инструменты и их аргументы:
{tools_description}
План должен быть линейным (шаг за шагом). Если нужны условия или циклы - разворачивай их в последовательность.
После выполнения всех шагов задача должна быть решена.
Верни ТОЛЬКО JSON массив, без лишнего текста."""
user_prompt = f"Задача: {task}"
tools_str = json.dumps(tools_description, indent=2)
messages = [
SystemMessage(content=system_prompt.format(tools_description=tools_str)),
HumanMessage(content=user_prompt)
]
response = self.llm.invoke(messages)
# парсим JSON
plan = json.loads(response.content)
return plan