Files
MultiAgent/agent/reviewer.py
2026-04-12 09:03:37 +05:00

100 lines
4.3 KiB
Python
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
from typing import Optional, Dict, Any
from langchain_core.messages import HumanMessage, SystemMessage
from langchain_ollama import ChatOllama
import json
from config import MODEL_NAME, TEMPERATURE, LLM_HOST
from models import CodeSolution, ReviewResult, ReviewComment, Task
import re
class ReviewerAgent:
"""Агент-ревьювер: проверяет качество кода"""
def __init__(self):
self.llm = ChatOllama(
model=MODEL_NAME,
temperature=0.1,
base_url=LLM_HOST,
num_predict=2048
)
def review(self, task: Task, solution: CodeSolution) -> ReviewResult:
"""Проверяет код и возвращает замечания"""
system_prompt = """Ты - строгий ревьювер кода. Твоя задача:
1. Проверить соответствие требованиям
2. Найти логические ошибки и баги
3. Оценить читаемость и стиль кода
4. Проверить покрытие тестами
5. Найти проблемы безопасности
6. Предложить улучшения
Оценивай код критически. Будь конкретен в замечаниях, указывай файлы и строки.
Допустимые уровни severity (от критичного к информационному):
- critical: блокирующие ошибки (безопасность, падения)
- major: серьёзные логические ошибки, неверная работа
- minor: стиль, читаемость, мелкие баги
- warning: потенциальные проблемы, улучшения, edge cases
- info: предложения, рекомендации, необязательные улучшения
- suggestion: альтернативные подходы
Верни JSON с полями:
- status: "approved", "changes_requested", или "rejected"
- comments: массив объектов с полями: file, line, severity, text
- summary: краткое резюме ревью
"""
# Формируем представление кода для ревью
code_for_review = ""
for filename, content in solution.files.items():
code_for_review += f"\n--- {filename} ---\n{content}\n"
if solution.tests:
code_for_review += "\n--- TESTS ---\n"
for testname, test_content in solution.tests.items():
code_for_review += f"\n--- {testname} ---\n{test_content}\n"
user_prompt = f"""
Требование: {task.requirement}
Код на ревью:
{code_for_review}
Описание решения разработчика: {solution.description}
Проведи ревью. Будь строг, но справедлив.
"""
messages = [
SystemMessage(content=system_prompt),
HumanMessage(content=user_prompt)
]
response = self.llm.invoke(messages)
# Парсим JSON ответ
try:
content = response.content
if "```json" in content:
content = content.split("```json")[1].split("```")[0]
elif "```" in content:
content = content.split("```")[1].split("```")[0]
data = json.loads(content.strip())
comments = []
for comment_data in data.get("comments", []):
comments.append(ReviewComment(
line=comment_data.get("line"),
file=comment_data.get("file"),
severity=comment_data.get("severity", "major"),
text=comment_data.get("text", "")
))
return ReviewResult(
status=data.get("status", "changes_requested"),
comments=comments,
summary=data.get("summary", "")
)
except Exception as e:
raise ValueError(f"Failed to parse reviewer response: {e}\nResponse: {response.content}")