v3.1 + 批次0: 智能回复重构基线 - ApprovalMatcher + 关键词降级 + 文档速修 + v4.0任务书面化

This commit is contained in:
Simon
2026-07-17 23:08:59 +08:00
parent 5a77a89ab1
commit 3ed86d5fb3
181 changed files with 19738 additions and 2655 deletions
+190 -4
View File
@@ -1,10 +1,18 @@
# =============================================================================
# 企微IT智能服务台 — AI Wingman API 路由
# =============================================================================
# 说明:坐席端 AI 智能副驾驶 API,包含 3 个核心端点:
# 1. POST /api/conversations/{id}/wingman/draft — 生成 AI 草稿回复
# 2. POST /api/conversations/{id}/wingman/summary — 生成会话自动摘要
# 3. POST /api/conversations/{id}/wingman/tags — 生成自动标签建议
# 说明:坐席端 AI 智能副驾驶 API,包含以下端点:
#
# 基础能力(3 个):
# 1. POST /api/conversations/{id}/wingman/draft — 生成 AI 草稿回复
# 2. POST /api/conversations/{id}/wingman/summary — 生成会话自动摘要
# 3. POST /api/conversations/{id}/wingman/tags — 生成自动标签建议
#
# AI 辅助消息框(4 个,v_next):
# 4. POST /api/conversations/{id}/wingman/autocomplete — 自动补齐
# 5. POST /api/conversations/{id}/wingman/tone-adjust — 语气调整
# 6. POST /api/conversations/{id}/wingman/polish — 文字润色
# 7. POST /api/conversations/{id}/wingman/rewrite — 智能改写
#
# 所有端点需要坐席认证(get_current_agent
# =============================================================================
@@ -21,6 +29,12 @@ from app.models.agent import Agent
from app.models.conversation import Conversation
from app.models.message import Message
from app.services.wingman_service import WingmanService
from app.schemas.wingman_assist import (
AutocompleteRequest,
ToneAdjustRequest,
PolishRequest,
RewriteRequest,
)
from app.utils.response import ERR_NOT_FOUND, success_response
# 复用坐席认证依赖
@@ -225,3 +239,175 @@ async def suggest_tags(
)
return success_response(data=result)
# --------------------------------------------------------------------------
# POST /api/conversations/{conversation_id}/wingman/autocomplete
# --------------------------------------------------------------------------
@router.post("/conversations/{conversation_id}/wingman/autocomplete")
async def autocomplete(
conversation_id: str,
request: AutocompleteRequest,
agent: Agent = Depends(get_current_agent),
db: AsyncSession = Depends(get_db),
wingman_service: WingmanService = Depends(dep_wingman_service),
):
"""自动补齐。
坐席输入停顿超过 800ms 后,前端请求 AI 生成下一句补齐建议。
Args:
conversation_id: 会话ID
request: 补齐请求(当前文本、光标位置、最大长度)
agent: 当前坐席
db: 数据库会话
wingman_service: Wingman 服务实例
Returns:
Dict: 统一响应格式,包含补齐文本和置信度
"""
# 1. 验证坐席身份 + 会话存在性
await _validate_conversation(conversation_id, agent, db)
# 2. 获取最近 5 条消息作为上下文
messages = await _get_recent_messages(conversation_id, db, limit=5)
# 3. 调用 WingmanService 生成补齐
result = await wingman_service.generate_completion(
conversation_id=conversation_id,
current_text=request.current_text,
messages=messages,
max_length=request.max_length,
)
return success_response(data=result)
# --------------------------------------------------------------------------
# POST /api/conversations/{conversation_id}/wingman/tone-adjust
# --------------------------------------------------------------------------
@router.post("/conversations/{conversation_id}/wingman/tone-adjust")
async def tone_adjust(
conversation_id: str,
request: ToneAdjustRequest,
agent: Agent = Depends(get_current_agent),
db: AsyncSession = Depends(get_db),
wingman_service: WingmanService = Depends(dep_wingman_service),
):
"""语气调整。
坐席选中一段文字后,选择目标语气(专业/友好/简洁),AI 对选中文字改写。
Args:
conversation_id: 会话ID
request: 语气调整请求(选中文字、完整输入框内容、目标语气)
agent: 当前坐席
db: 数据库会话
wingman_service: Wingman 服务实例
Returns:
Dict: 统一响应格式,包含改写后的文字、语气和变更摘要
"""
# 1. 验证坐席身份 + 会话存在性
await _validate_conversation(conversation_id, agent, db)
# 2. 获取最近 5 条消息作为上下文
messages = await _get_recent_messages(conversation_id, db, limit=5)
# 3. 调用 WingmanService 进行语气调整
result = await wingman_service.adjust_tone(
conversation_id=conversation_id,
selected_text=request.selected_text,
full_text=request.full_text,
tone=request.tone,
messages=messages,
)
return success_response(data=result)
# --------------------------------------------------------------------------
# POST /api/conversations/{conversation_id}/wingman/polish
# --------------------------------------------------------------------------
@router.post("/conversations/{conversation_id}/wingman/polish")
async def polish(
conversation_id: str,
request: PolishRequest,
agent: Agent = Depends(get_current_agent),
db: AsyncSession = Depends(get_db),
wingman_service: WingmanService = Depends(dep_wingman_service),
):
"""文字润色。
对坐席输入的文字进行扩写/压缩/纠错处理。
Args:
conversation_id: 会话ID
request: 润色请求(待润色文字、操作类型、是否携带上下文)
agent: 当前坐席
db: 数据库会话
wingman_service: Wingman 服务实例
Returns:
Dict: 统一响应格式,包含润色后的文字、操作类型和变更摘要
"""
# 1. 验证坐席身份 + 会话存在性
await _validate_conversation(conversation_id, agent, db)
# 2. 可选携带对话上下文(由请求参数控制)
messages = []
if request.conversation_context:
messages = await _get_recent_messages(conversation_id, db, limit=5)
# 3. 调用 WingmanService 进行润色
result = await wingman_service.polish_text(
conversation_id=conversation_id,
text=request.text,
action=request.action,
messages=messages,
)
return success_response(data=result)
# --------------------------------------------------------------------------
# POST /api/conversations/{conversation_id}/wingman/rewrite
# --------------------------------------------------------------------------
@router.post("/conversations/{conversation_id}/wingman/rewrite")
async def rewrite(
conversation_id: str,
request: RewriteRequest,
agent: Agent = Depends(get_current_agent),
db: AsyncSession = Depends(get_db),
wingman_service: WingmanService = Depends(dep_wingman_service),
):
"""智能改写。
基于对话上下文和知识库,为坐席生成多个不同风格的备选回复。
Args:
conversation_id: 会话ID
request: 改写请求(当前输入文本、生成版本数、是否包含知识库引用)
agent: 当前坐席
db: 数据库会话
wingman_service: Wingman 服务实例
Returns:
Dict: 统一响应格式,包含多个版本的回复文本、风格标签和来源
"""
# 1. 验证坐席身份 + 会话存在性
await _validate_conversation(conversation_id, agent, db)
# 2. 获取最近 10 条消息作为上下文(改写需要更多上下文)
messages = await _get_recent_messages(conversation_id, db, limit=10)
# 3. 调用 WingmanService 进行改写
result = await wingman_service.rewrite_versions(
conversation_id=conversation_id,
current_text=request.current_text,
messages=messages,
generate_count=request.generate_count,
include_knowledge=request.include_knowledge,
)
return success_response(data=result)