feat(agent): 增加 LLM 路由与诊断日志
This commit is contained in:
@@ -1,5 +1,6 @@
|
||||
from __future__ import annotations
|
||||
|
||||
import logging
|
||||
from threading import Thread
|
||||
from uuid import uuid4
|
||||
|
||||
@@ -36,6 +37,9 @@ NODE_DEFINITIONS = [
|
||||
]
|
||||
|
||||
|
||||
logger = logging.getLogger("review_agent.file_summary.workflow")
|
||||
|
||||
|
||||
def default_skill_registry() -> SkillRegistry:
|
||||
registry = SkillRegistry()
|
||||
registry.register(ArchiveExtractSkill())
|
||||
@@ -65,6 +69,14 @@ def create_file_summary_batch(
|
||||
)
|
||||
if not active_attachments:
|
||||
raise ValueError("当前对话没有可用附件。")
|
||||
logger.info(
|
||||
"File summary batch creation started",
|
||||
extra={
|
||||
"conversation_id": conversation.pk,
|
||||
"user_id": user.pk,
|
||||
"attachment_ids": [attachment.pk for attachment in active_attachments],
|
||||
},
|
||||
)
|
||||
|
||||
batch = FileSummaryBatch.objects.create(
|
||||
conversation=conversation,
|
||||
@@ -82,6 +94,10 @@ def create_file_summary_batch(
|
||||
WorkflowNodeRun.objects.create(batch=batch, node_code=code, node_name=name)
|
||||
|
||||
record_event(batch, "workflow_created", {"batch_id": batch.pk, "batch_no": batch.batch_no})
|
||||
logger.info(
|
||||
"File summary batch created",
|
||||
extra={"batch_id": batch.pk, "batch_no": batch.batch_no},
|
||||
)
|
||||
return batch
|
||||
|
||||
|
||||
@@ -91,6 +107,7 @@ class WorkflowExecutor:
|
||||
self.registry = registry or default_skill_registry()
|
||||
|
||||
def run(self) -> None:
|
||||
logger.info("Workflow run started", extra={"batch_id": self.batch.pk})
|
||||
self.batch.status = FileSummaryBatch.Status.RUNNING
|
||||
self.batch.started_at = timezone.now()
|
||||
self.batch.save(update_fields=["status", "started_at"])
|
||||
@@ -100,6 +117,10 @@ class WorkflowExecutor:
|
||||
for node in self.batch.node_runs.order_by("id"):
|
||||
self._run_node(node)
|
||||
except Exception as exc:
|
||||
logger.exception(
|
||||
"Workflow run failed",
|
||||
extra={"batch_id": self.batch.pk, "error": str(exc)},
|
||||
)
|
||||
self.batch.status = FileSummaryBatch.Status.FAILED
|
||||
self.batch.error_message = str(exc)
|
||||
self.batch.finished_at = timezone.now()
|
||||
@@ -111,8 +132,17 @@ class WorkflowExecutor:
|
||||
self.batch.finished_at = timezone.now()
|
||||
self.batch.save(update_fields=["status", "finished_at"])
|
||||
record_event(self.batch, "workflow_completed", {"batch_id": self.batch.pk})
|
||||
logger.info("Workflow run completed", extra={"batch_id": self.batch.pk})
|
||||
|
||||
def _run_node(self, node: WorkflowNodeRun) -> None:
|
||||
logger.info(
|
||||
"Workflow node started",
|
||||
extra={
|
||||
"batch_id": self.batch.pk,
|
||||
"node_code": node.node_code,
|
||||
"node_name": node.node_name,
|
||||
},
|
||||
)
|
||||
now = timezone.now()
|
||||
node.status = WorkflowNodeRun.Status.RUNNING
|
||||
node.progress = 10
|
||||
@@ -132,6 +162,15 @@ class WorkflowExecutor:
|
||||
if skill_name:
|
||||
result = self.registry.execute(skill_name, WorkflowContext(batch=self.batch))
|
||||
if not result.success:
|
||||
logger.warning(
|
||||
"Workflow node skill failed",
|
||||
extra={
|
||||
"batch_id": self.batch.pk,
|
||||
"node_code": node.node_code,
|
||||
"skill_name": skill_name,
|
||||
"result_message": result.message,
|
||||
},
|
||||
)
|
||||
raise RuntimeError(result.message or f"{node.node_name}执行失败")
|
||||
|
||||
node.status = WorkflowNodeRun.Status.SUCCESS
|
||||
@@ -144,11 +183,17 @@ class WorkflowExecutor:
|
||||
"node_progress",
|
||||
{"node_code": node.node_code, "status": node.status, "progress": node.progress},
|
||||
)
|
||||
logger.info(
|
||||
"Workflow node finished",
|
||||
extra={"batch_id": self.batch.pk, "node_code": node.node_code},
|
||||
)
|
||||
|
||||
|
||||
def start_file_summary_workflow(batch: FileSummaryBatch, *, async_run: bool = True) -> None:
|
||||
executor = WorkflowExecutor(batch)
|
||||
if not async_run:
|
||||
logger.info("Workflow starting synchronously", extra={"batch_id": batch.pk})
|
||||
executor.run()
|
||||
return
|
||||
logger.info("Workflow starting asynchronously", extra={"batch_id": batch.pk})
|
||||
Thread(target=executor.run, daemon=True).start()
|
||||
|
||||
Reference in New Issue
Block a user