feat: add governed customer service agent

This commit is contained in:
张胜宇
2026-09-10 19:51:08 +08:00
parent 511a8ca18f
commit e9b3d272f0
15 changed files with 765 additions and 3 deletions
+31 -1
View File
@@ -1,5 +1,6 @@
import hashlib
import json
from collections.abc import Sequence
from dataclasses import dataclass
from datetime import UTC, datetime, timedelta
from uuid import uuid4
@@ -20,6 +21,7 @@ from app.model.platform import AgentRun, RequestIdempotency
from app.model.session import ConversationSession
from app.repository.outbox_repository import OutboxRepository
from app.service.agent.bootstrap import get_agent_factory
from app.service.agent.customer_service_routing import CustomerServiceIntentRouter
from app.service.agent.factory import AgentFactory
@@ -30,6 +32,20 @@ class RunAccepted:
status: str = "queued"
def build_outbox_metadata(
request: AgentRequest, prior_user_messages: Sequence[str]
) -> dict[str, object]:
"""构造 Worker 使用的内部元数据,不信任外部传入的闲聊计数。"""
metadata = request.metadata
if request.agent_type == "customer_service":
metadata = metadata.model_copy(update={
"chitchat_streak": CustomerServiceIntentRouter.chitchat_streak(
prior_user_messages, request.message
)
})
return metadata.model_dump(mode="json")
class AgentRunApplicationService:
def __init__(self, session: AsyncSession, factory: AgentFactory | None = None) -> None:
self.session = session
@@ -89,6 +105,20 @@ class AgentRunApplicationService:
raise RuntimeError("idempotency record has no run")
return RunAccepted(run.run_id, run.trace_id, run.status)
# 仅读取当前会话最近三条用户消息;第四条闲聊即触发一次自然业务引导。
prior_user_messages = list(await self.session.scalars(
select(ConversationMessage.content)
.where(
ConversationMessage.session_id == request.session_id,
ConversationMessage.role == "user",
)
.order_by(ConversationMessage.id.desc())
.limit(3)
))
outbox_metadata = build_outbox_metadata(
request, tuple(reversed(prior_user_messages))
)
trace_id = context.trace_id
message = ConversationMessage(
session_id=request.session_id, customer_id=user_id, portal="api",
@@ -121,7 +151,7 @@ class AgentRunApplicationService:
payload={
"run_id": run_id,
"actor_type": "visitor" if "visitor" in context.roles else "authenticated",
"metadata": request.metadata.model_dump(mode="json"),
"metadata": outbox_metadata,
},
occurred_at=now,
))