feat: add agent response depth control
This commit is contained in:
@@ -30,6 +30,7 @@ class AgentDebugService:
|
||||
version_overrides=payload.knowledgeVersions,
|
||||
preview_knowledge_ids=payload.knowledgeIds,
|
||||
prompt_override=payload.promptContent,
|
||||
response_depth=payload.responseDepth,
|
||||
)
|
||||
return RagResult(
|
||||
question=rag_result.question,
|
||||
|
||||
@@ -84,6 +84,7 @@ class KnowledgeAgentService:
|
||||
preview_knowledge_ids: list[int] | None = None,
|
||||
context_trace: list[dict] | None = None,
|
||||
prompt_override: str | None = None,
|
||||
response_depth: int | None = None,
|
||||
) -> RagResult:
|
||||
started = perf_counter()
|
||||
catalog = cls.get_knowledge_catalog(
|
||||
@@ -207,6 +208,7 @@ class KnowledgeAgentService:
|
||||
session_summary,
|
||||
summary_up_to_message_id,
|
||||
prompt_override=prompt_override,
|
||||
response_depth=response_depth,
|
||||
)
|
||||
return RagResult(
|
||||
question=question,
|
||||
|
||||
@@ -11,6 +11,7 @@ from app.models.user import User
|
||||
from app.services.chat_context_service import ChatContextService
|
||||
from app.services.feishu_service import FeishuKnowledgeService
|
||||
from app.services.knowledge_service import KnowledgeAccessService, KnowledgeScope
|
||||
from app.services.response_style_service import ResponseStyleService
|
||||
|
||||
NO_HIT_ANSWER = "当前知识库中未检索到相关内容,请联系管理员补充相关知识。"
|
||||
|
||||
@@ -119,6 +120,7 @@ class PromptService:
|
||||
session_summary: str | None = None,
|
||||
summary_up_to_message_id: int | None = None,
|
||||
prompt_override: str | None = None,
|
||||
response_depth: int | None = None,
|
||||
) -> list[dict[str, str]]:
|
||||
prompt = prompt_override.strip() if prompt_override and prompt_override.strip() else cls._load_active_prompt(db)
|
||||
|
||||
@@ -135,7 +137,8 @@ class PromptService:
|
||||
+ "[不可关闭的最低安全规则 v1]\n"
|
||||
+ "现实危险、自伤伤人风险应优先建议立即寻求线下专业帮助;医疗、法律、财务问题不得给出替代专业意见的结论;"
|
||||
+ "不得伪造老师观点或课程内容;不得输出整篇课程文章、大段连续原文,也不得通过多轮拼接还原完整资料。"
|
||||
+ cls._knowledge_type_rules(chunks),
|
||||
+ cls._knowledge_type_rules(chunks)
|
||||
+ ResponseStyleService.build_instruction(db, response_depth),
|
||||
}
|
||||
]
|
||||
|
||||
|
||||
@@ -0,0 +1,68 @@
|
||||
from __future__ import annotations
|
||||
|
||||
from sqlalchemy import select
|
||||
from sqlalchemy.orm import Session
|
||||
|
||||
from app.models.ai_config import SystemConfig
|
||||
|
||||
|
||||
RESPONSE_DEPTH_KEY = "agent_response_depth"
|
||||
DEFAULT_RESPONSE_DEPTH = 35
|
||||
MIN_RESPONSE_DEPTH = 0
|
||||
MAX_RESPONSE_DEPTH = 100
|
||||
|
||||
|
||||
class ResponseStyleService:
|
||||
@staticmethod
|
||||
def get_depth(db: Session) -> int:
|
||||
config = db.scalar(select(SystemConfig).where(SystemConfig.config_key == RESPONSE_DEPTH_KEY))
|
||||
if config is None:
|
||||
return DEFAULT_RESPONSE_DEPTH
|
||||
try:
|
||||
return _clamp_depth(int(config.config_value))
|
||||
except (TypeError, ValueError):
|
||||
return DEFAULT_RESPONSE_DEPTH
|
||||
|
||||
@staticmethod
|
||||
def set_depth(db: Session, depth: int, admin_id: int | None) -> SystemConfig:
|
||||
config = db.scalar(select(SystemConfig).where(SystemConfig.config_key == RESPONSE_DEPTH_KEY))
|
||||
if config is None:
|
||||
config = SystemConfig(config_key=RESPONSE_DEPTH_KEY, config_value=str(DEFAULT_RESPONSE_DEPTH))
|
||||
config.config_value = str(_clamp_depth(depth))
|
||||
config.description = "Agent 回答深度,0 为精简,100 为深入"
|
||||
config.updated_by = admin_id
|
||||
db.add(config)
|
||||
return config
|
||||
|
||||
@classmethod
|
||||
def build_instruction(cls, db: Session, depth: int | None = None) -> str:
|
||||
value = _clamp_depth(cls.get_depth(db) if depth is None else depth)
|
||||
if value <= 33:
|
||||
mode = "精简"
|
||||
rules = (
|
||||
"回答要短,通常控制在1到3段或3条以内;不展开心理分析、不复盘学员长篇经历,"
|
||||
"优先给出一句方向确认,再引导回到当下、身体感受和情绪觉察。建议只给当下最小一步,"
|
||||
"避免连续列出多个深入方案。"
|
||||
)
|
||||
elif value <= 66:
|
||||
mode = "平衡"
|
||||
rules = (
|
||||
"回答保持适中,可以先确认方向,再补充必要原因和1到3个可执行提醒;"
|
||||
"不做过度拆解,不把分析过程完整罗列出来。"
|
||||
)
|
||||
else:
|
||||
mode = "深入"
|
||||
rules = (
|
||||
"可以更完整地解释原因、步骤和注意事项,但仍要避免变成咨询式长篇分析;"
|
||||
"优先围绕回到当下、回到自身、觉察情绪和身体感受、如是释放来组织内容。"
|
||||
)
|
||||
return (
|
||||
"\n\n[回答深度控制]\n"
|
||||
f"当前回答深度:{value}/100({mode})。{rules}"
|
||||
"无论深度如何,都不要暴露内部分析过程;不要替学员做复杂人格判断;"
|
||||
"涉及功课反馈时,先判断方向是否偏离,再给最少必要的下一步。"
|
||||
)
|
||||
|
||||
|
||||
def _clamp_depth(value: int) -> int:
|
||||
return max(MIN_RESPONSE_DEPTH, min(MAX_RESPONSE_DEPTH, value))
|
||||
Reference in New Issue
Block a user