Переделываю систему под агента-планировщика
This commit is contained in:
@@ -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
37
agent/executor.py
Normal 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
26
agent/plan_reviewer.py
Normal 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
40
agent/planner.py
Normal 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
|
||||
Reference in New Issue
Block a user