156 lines
5.0 KiB
Python
156 lines
5.0 KiB
Python
"""去AI化Agent - 消除AI生成痕迹"""
|
||
|
||
import logging
|
||
import time
|
||
from datetime import datetime, timezone
|
||
|
||
from app.agent_framework.base import BaseAgent
|
||
from app.agent_framework.prompts import DEAI_TEMPLATE
|
||
from app.agent_framework.protocol import (
|
||
AgentCapability,
|
||
AgentType,
|
||
TaskMessage,
|
||
TaskResult,
|
||
TaskStatus,
|
||
)
|
||
from app.services.llm import LLMFactory, LLMError
|
||
|
||
logger = logging.getLogger(__name__)
|
||
|
||
|
||
class DeAIAgent(BaseAgent):
|
||
"""内容去AI化处理,消除AI生成特征
|
||
|
||
支持的任务类型:
|
||
- deai_process: 对内容进行去AI化处理
|
||
"""
|
||
|
||
def __init__(self):
|
||
super().__init__(
|
||
name="deai_agent",
|
||
agent_type=AgentType.DEAI_AGENT,
|
||
version="1.0.0",
|
||
)
|
||
|
||
def get_capabilities(self) -> AgentCapability:
|
||
return AgentCapability(
|
||
agent_name=self.name,
|
||
agent_type=self.agent_type,
|
||
version=self.version,
|
||
supported_tasks=["deai_process"],
|
||
max_concurrency=2,
|
||
description="内容去AI化Agent:消除AI生成特征,使文章更自然流畅",
|
||
)
|
||
|
||
async def execute(self, task: TaskMessage) -> TaskResult:
|
||
"""执行去AI化任务"""
|
||
started_at = datetime.now(timezone.utc)
|
||
start_time = time.monotonic()
|
||
|
||
try:
|
||
output = await self._process(task)
|
||
|
||
elapsed = time.monotonic() - start_time
|
||
return TaskResult(
|
||
task_id=task.task_id,
|
||
agent_name=self.name,
|
||
status=TaskStatus.COMPLETED,
|
||
output_data=output,
|
||
error_message=None,
|
||
started_at=started_at,
|
||
completed_at=datetime.now(timezone.utc),
|
||
metrics={
|
||
"elapsed_seconds": round(elapsed, 2),
|
||
"task_type": task.task_type,
|
||
},
|
||
)
|
||
|
||
except LLMError as e:
|
||
elapsed = time.monotonic() - start_time
|
||
logger.error(f"DeAIAgent LLM error on task {task.task_id}: {e}")
|
||
return TaskResult(
|
||
task_id=task.task_id,
|
||
agent_name=self.name,
|
||
status=TaskStatus.FAILED,
|
||
output_data=None,
|
||
error_message=f"LLM调用失败: {e}",
|
||
started_at=started_at,
|
||
completed_at=datetime.now(timezone.utc),
|
||
metrics={
|
||
"elapsed_seconds": round(elapsed, 2),
|
||
"task_type": task.task_type,
|
||
},
|
||
)
|
||
|
||
except Exception as e:
|
||
elapsed = time.monotonic() - start_time
|
||
logger.error(f"DeAIAgent task {task.task_id} failed: {e}")
|
||
return TaskResult(
|
||
task_id=task.task_id,
|
||
agent_name=self.name,
|
||
status=TaskStatus.FAILED,
|
||
output_data=None,
|
||
error_message=str(e),
|
||
started_at=started_at,
|
||
completed_at=datetime.now(timezone.utc),
|
||
metrics={
|
||
"elapsed_seconds": round(elapsed, 2),
|
||
"task_type": task.task_type,
|
||
},
|
||
)
|
||
|
||
async def _process(self, task: TaskMessage) -> dict:
|
||
"""执行去AI化处理
|
||
|
||
input_data 字段:
|
||
- content: str (必填,待处理的文章内容)
|
||
- style: str (可选,目标风格: 口语化/叙事化/评论风格)
|
||
- preserve_structure: bool (可选,是否保留原有结构)
|
||
"""
|
||
input_data = task.input_data
|
||
content = input_data.get("content", "")
|
||
if not content:
|
||
raise ValueError("input_data必须包含非空的'content'字段")
|
||
|
||
# 上报进度:开始
|
||
await self.report_progress(
|
||
task_id=task.task_id,
|
||
progress=0.1,
|
||
message="开始去AI化处理...",
|
||
)
|
||
|
||
variables = {
|
||
"original_content": content,
|
||
"target_style": input_data.get("style", "自然流畅"),
|
||
"preserve_structure": "是" if input_data.get("preserve_structure", True) else "否",
|
||
}
|
||
messages = DEAI_TEMPLATE.render(variables)
|
||
|
||
# 上报进度:调用LLM
|
||
await self.report_progress(
|
||
task_id=task.task_id,
|
||
progress=0.3,
|
||
message="正在调用LLM进行去AI化改写...",
|
||
)
|
||
|
||
provider = LLMFactory.get_default()
|
||
response = await provider.chat(
|
||
messages,
|
||
temperature=0.9,
|
||
max_tokens=len(content) * 3,
|
||
)
|
||
|
||
# 上报进度:完成
|
||
await self.report_progress(
|
||
task_id=task.task_id,
|
||
progress=1.0,
|
||
message=f"去AI化处理完成,原文{len(content)}字 -> 处理后{len(response.content)}字",
|
||
)
|
||
|
||
return {
|
||
"content": response.content,
|
||
"original_word_count": len(content),
|
||
"processed_word_count": len(response.content),
|
||
"usage": response.usage,
|
||
}
|