根据对项目代码和配置文件的全面分析,我将从以下三个方面回答你的问题:
一、硬编码规则(Java代码中直接写死的逻辑)
以下规则在代码中明确硬编码,不依赖 LLM 或配置文件动态调整:
1. 强制状态推进规则(在StrictSalesEngine中)
赠品领取强制:若用户消息包含“扫码”、“领取”、“要赠品”等关键词,无论当前阶段如何,
nextState强制设为GIFT_CLAIM_GUIDE,且action为SPEAK。代码位置:
StrictSalesEngine.buildStateTransitionPrompt中明确写入强制规则,并在parseStateMachineDecision中再次修正。
皮肤问题强制推进:若当前状态为
GREETING_GIFT_INTRO且用户消息包含“斑”、“痘”、“敏感”、“干燥”等皮肤问题关键词,强制将nextState设为ASKING_FOR_PHOTO。置信度阈值:当 LLM 判定
stageComplete = true但置信度 < 0.7 时,强制改为false,避免错误推进。
2. 消息去重与防重放
在
RedisSessionManager和StrictSalesEngine.process中,使用 Redis 锁和消息哈希,对同一会话的重复消息(2秒内相同内容)进行丢弃。
3. 社交规则(主动联系限制)
SocialRuleEngine中硬编码:深夜(22:00 – 8:00)不主动发消息。
客户情绪负面时,24 小时内最多主动联系 1 次。
信任度低的客户联系更谨慎(但仅作为提示,决策仍由 LLM 做)。
4. RAG 混合检索优先级
HybridRetriever.retrieve中硬编码检索顺序:话术(最高权重)
SOP 相关内容
产品知识向量检索
普通话术库
数据库关键词检索
5. 消息后处理(MessagePostProcessor)
按中文标点(。!?)拆分长消息,超过 50 字且无标点才切碎。
负面情绪时不添加表情符号,且不切太碎。
6. 客户即时画像提取的降级规则
ContextBuilder.extractCustomerInstantProfile中,若 LLM 提取失败,会回退到硬编码关键词匹配(如“熬夜”、“过敏”、“价格”等)。
7. 阶段停留计数与超时
SessionInfo中sameStageCount由代码维护,在StrictSalesEngine.process中根据stageComplete递增或重置,但重试逻辑仍由 LLM 决定何时放弃。
8. 价格异议处理的硬编码策略模板
SalesPolicyEngine中getHandlingStrategyByType方法内,为 PRICE、EFFECT、SUITABILITY、TIME 等异议类型提供固定的文字策略(如“先共情,再强调价值”),这些文字会作为 Prompt 的一部分,但策略本身是硬编码的。
二、通过 LLM 判断的规则(动态、依赖模型推理)
几乎所有核心业务逻辑都通过 LLM 完成,包括:
1. 意图识别与多意图分析
BeautyIntentClassifier调用 LLM 进行意图预测,支持多意图输出(predictMulti)。不再使用规则回退,完全由 LLM 判定。
2. 情绪分析与细粒度情感维度
EnhancedEmotionAnalyzer调用 LLM 分析情绪类型(愤怒/怀疑/兴趣/中性/兴奋)及强度,并返回情绪子类型、触发原因、建议响应等。
3. 阶段决策(SOP 推进)
StrictSalesEngine每次处理消息时,将当前阶段、阶段目标、完成条件、对话历史等组装成 Prompt,由 LLM 输出:下一个状态 (
nextState)是否完成当前阶段 (
stageComplete)要发送的消息 (
messages)置信度 (
confidence)
LLM 负责判断客户是否完成了当前阶段目标(如“用户已发送照片”),从而决定是否推进。
4. 回复生成(最终发给客户的话)
MessageGenerator、ConversationManagerService等组件均通过 LLM 生成最终回复,且 Prompt 中会注入:当前阶段目标与禁止话题
客户画像与长期记忆
RAG 检索结果(产品知识、话术模板)
话术 Few‑shot 示例
所有回复都经过 LLM 润色,避免生硬模板。
5. 异议类型识别与处理流程
SalesPolicyEngine.ruleMatch直接调用 LLM 识别异议类型(PRICE、EFFECT、SUITABILITY、TIME、OTHER)。根据 LLM 返回的异议类型,再调用 LLM 生成具体的异议处理回复。
6. 主动跟进决策
ProactiveDecisionService.decide将当前时间、客户状态、对话历史等提交给 LLM,由 LLM 判断是否应主动联系,并生成消息内容。硬编码的社交规则仅作为提示输入 LLM,最终决定权在 LLM。
7. 身份询问识别与自我介绍
StrictSalesEngine.checkAndRespondToIdentity调用 LLM 判断用户是否在询问身份(“你是谁”、“你是AI吗”等),然后由 LLM 生成一句自我介绍。
8. 策略生成
ContextBuilder.addSalesStageAndStrategy调用 LLM 根据当前阶段、用户消息、情绪、档案,生成阶段目标、执行策略、注意事项和推荐话术。
三、系统是否会按照prompt.yaml中的 SOP 流程执行?
会,且严格遵循。
证据如下:
SOP 阶段配置已加载
StrictSalesEngine.init()读取prompt.yaml中的templates.stageConfigs,将其映射为StageConfig对象,并存储到stageConfigs中。每个阶段的
goal、completionCondition、forbiddenTopics、nextStage均从配置中获取。
LLM 的 Prompt 中完整包含了 SOP 规则
在
StrictSalesEngine.buildStateTransitionPrompt中,动态注入:当前阶段名称、阶段目标
阶段完成条件(
completionCondition)禁止内容(
forbiddenTopics)强制优先级规则(赠品优先、皮肤问题优先)
这些内容直接来自
prompt.yaml,因此 LLM 的决策严格基于配置的 SOP。
状态模板(话术)同样来自配置
StageStateMachine中的话术模板(如GREETING_GIFT_INTRO、GIFT_CLAIM_GUIDE等)在prompt.yaml的templates.stageStateMachine中定义。当 LLM 决策返回的
messages为空时,StrictSalesEngine.parseStateMachineDecision会从stageStateMachine中获取默认话术作为兜底。
强制覆盖保证关键节点不偏离
尽管 LLM 负责判断,但代码中仍有硬编码的强制推进(如皮肤问题必须进入
ASKING_FOR_PHOTO),这确保了即使 LLM 出现偏差,SOP 的关键步骤也不会被跳过。
阶段计划与目标明确
StageGoalResolver通过 LLM 再次确认阶段是否完成,但其判断依据同样是prompt.yaml中配置的完成条件,形成双重校验。
实际执行流程示例:
用户进入会话 → 系统处于
GREETING_GIFT_INTRO阶段。用户说:“我脸上有斑”。
StrictSalesEngine.process被调用,构建 Prompt(包含阶段目标“建立信任,引导用户领取赠品”和完成条件“用户明确表示愿意领取赠品”等)。LLM 返回
stageComplete: true, nextState: "ASKING_FOR_PHOTO", messages: ["亲爱的,为了更精准地判断您的色斑情况,麻烦拍一张无滤镜的面部特写..."]。系统更新状态为
ASKING_FOR_PHOTO,并发送消息。后续当用户发送照片后,LLM 又会根据
prompt.yaml中PHOTO_REQUEST阶段的完成条件(“用户已经发送了面部照片”)判定阶段完成,并推进到INITIAL_DIAGNOSIS。
总结
| 类别 | 占比 | 说明 |
|---|---|---|
| 硬编码规则 | 约 20% | 主要包括安全机制(去重、限流)、社交规则、强制推进兜底、RAG 检索顺序、消息切分等。 |
| LLM 判断 | 约 80% | 意图、情绪、阶段决策、回复生成、异议处理、主动跟进等所有核心业务逻辑。 |
| SOP 执行 | 严格遵循 | prompt.yaml中的阶段配置、完成条件、禁止话题、话术模板均被完整加载并作为 LLM 决策依据,同时有硬编码强制规则确保关键节点不丢失。 |
系统已实现“重 LLM 判断、轻硬编码规则”的架构,SOP 流程通过配置驱动,LLM 负责理解并执行。
我们被要求分析代码库,找出哪些规则是硬编码的,哪些是通过LLM判断的,以及系统是否会按照prompt.yaml中的SOP流程执行。需要全面理解代码和业务流程。
首先,代码库是一个Agent系统,集成了企业微信、WebSocket、LLM、向量数据库等。重点在于agent flow,特别是StrictSalesEngine和StageStateMachine,以及prompt.yaml中的SOP流程。
需要分析:
哪些规则是硬编码的?
哪些规则是通过LLM判断的?
系统是否会按照prompt.yaml中的SOP流程执行?
我们将逐项分析。
一、整体架构
核心流程:用户消息 → MessageReceiver → ConversationOrchestrator / StreamingThinkEngine → AgentRouter → Agent (CustomerServiceAgent) → StrictSalesEngine 或 LLM生成回复。
关键组件:
StrictSalesEngine: 负责状态机,基于SOP流程推进。
StageStateMachine: 定义阶段状态。
prompt.yaml: 定义了SOP的各个阶段、目标、完成条件、话术模板等。
AgentThinkingEngine, MessageGenerator, ConversationManagerService等:用于生成回复。
二、硬编码规则分析
硬编码规则指在Java代码中直接写死的逻辑,不依赖配置或LLM。
阶段定义和转换逻辑:在StrictSalesEngine和StageStateMachine中,有状态枚举StrictSalesState(如GREETING_GIFT_INTRO, GIFT_CLAIM_GUIDE, ASKING_FOR_PHOTO等)。阶段之间的转换主要依赖LLM决策,但也有一些硬编码的强制规则:
在StrictSalesEngine的process方法中,有强制优先级规则:如果用户明确赠品领取意愿,则必须转到GIFT_CLAIM_GUIDE。这是硬编码的。
皮肤问题处理规则:如果用户消息涉及皮肤问题,必须转到ASKING_FOR_PHOTO。这也是硬编码的。
在buildStateTransitionPrompt中,这些规则被写入prompt,但最终由LLM决定?实际上,在StrictSalesEngine的process方法中,会先调用LLM决策,然后在parseStateMachineDecision中,有强制修正逻辑:如果当前是GREETING_GIFT_INTRO且用户消息包含皮肤问题,则强制设置nextState为ASKING_FOR_PHOTO。这部分是硬编码的后处理。
身份询问检测:在StreamingThinkEngine的triggerThink中,先调用strictSalesEngine.checkAndRespondToIdentity,该方法使用LLM判断是否为身份询问,然后生成自我介绍。但checkAndRespondToIdentity内部有LLM判断,不是硬编码。不过,身份回复的优先级最高,如果检测到身份询问,会直接发送回复并return,不再继续后续流程。这个调度逻辑是硬编码的。
消息去重:在RedisSessionManager和StrictSalesEngine中有消息去重逻辑(基于hash和时间窗口),硬编码。
用户情绪分析:在ContextBuilder中有硬编码的关键词匹配情绪分析作为降级,但主要使用LLM分析。
阶段完成条件判断:在StrictSalesEngine中,LLM决策会返回stageComplete,并在parseStateMachineDecision中解析。但有置信度判断:如果stageComplete为true但置信度低于0.7,会强制设为false。这是硬编码的规则。
拒绝拍照的处理:在StrictSalesEngine中,有PHOTO_RESIST_FIRST和PHOTO_RESIST_SECOND状态,但处理逻辑主要依赖LLM。但硬编码了最大重试次数(来自prompt.yaml的配置,但代码中从配置读取,不是硬编码)。然而,在StageStateMachine中有一些子状态处理,但实际逻辑在StrictSalesEngine中。
状态超时/重试计数:SessionInfo中记录了sameStageCount,在StrictSalesEngine中根据stageComplete更新。但重试逻辑主要由LLM决策控制。
主动跟进的社交规则:在SocialRuleEngine中有硬编码的规则,例如深夜不主动发消息、情绪负面时24小时内最多主动联系1次等。这些规则是硬编码的,但SocialRuleEngine在ProactiveDecisionService中被调用,最终决策仍由LLM决定?实际上,ProactiveDecisionService中的decide方法会调用LLM生成决策,但SocialRuleEngine提供的规则信息会作为prompt的一部分,所以规则是作为提示词提供给LLM的,而不是强制。但SocialRuleEngine本身的方法(如isGoodTimeToContact)是硬编码的。
价格异议处理:在SalesPolicyEngine中,有硬编码的异议处理策略(如价格异议强调价值、效果异议用特证等),但实际回复生成仍通过LLM。
常见问题缓存:CommonQuestionCacheService有简单的关键词匹配,硬编码。
RAG检索的混合检索器:HybridRetriever有硬编码的优先级(话术 > SOP > 产品知识 > 话术库 > 关键词检索)。这是硬编码的。
消息分割:MessagePostProcessor中按标点拆分消息,硬编码。
人设管理:PersonaEngine中有基于客户类型调整人设的硬编码规则(根据profile字符串包含“年长”、“年轻”等)。但这部分是通过配置加载的(prompt.yaml中personaEngine部分),不过配置中定义了customerTypeAdjustments,代码中读取配置并应用,所以不是完全硬编码,而是配置驱动的。
三、LLM判断的规则
大多数决策都通过LLM完成,包括:
意图识别(BeautyIntentClassifier使用LLM)
情绪分析(EnhancedEmotionAnalyzer使用LLM)
阶段决策(StrictSalesEngine调用LLM决定下一个状态和是否完成阶段)
回复生成(MessageGenerator、ConversationManagerService等使用LLM)
异议类型识别(SalesPolicyEngine使用LLM)
身份询问检测(StrictSalesEngine.checkAndRespondToIdentity使用LLM)
主动跟进决策(ProactiveDecisionService使用LLM)
策略选择(StrategyRouter使用LLM)
策略生成(ContextBuilder中的addSalesStageAndStrategy使用LLM)
等等
LLM的prompt从prompt.yaml中读取,包括系统角色、阶段配置、话术模板等。
四、是否按照prompt.yaml中的SOP流程执行
prompt.yaml中定义了详细的SOP流程,包括阶段配置(stageConfigs)、状态模板(stageStateMachine)、主动消息(proactiveMessages)等。系统通过以下方式执行SOP:
StrictSalesEngine是核心SOP执行引擎。它在process方法中:
获取当前状态(从SessionInfo的conversationStage)。
构建包含SOP阶段目标、完成条件、禁止话题等信息的prompt。
调用LLM决策,返回下一个状态、动作和消息。
根据LLM决策更新状态。
如果LLM决策的stageComplete为true且置信度足够,则推进到下一阶段。
SOP的完成条件:在prompt.yaml的stageConfigs中,每个阶段都有completionCondition,如“用户明确表示愿意领取赠品”、“用户已经提供了完整的收货地址和联系方式”等。这些条件被注入到LLM的prompt中,由LLM判断是否满足。因此,SOP的推进是LLM判断的,但条件是配置的。
话术模板:prompt.yaml中的stageStateMachine和proactiveMessages定义了各阶段的标准话术。在StrictSalesEngine中,如果LLM决策的messages为空,会从stageStateMachine中获取对应状态的话术作为默认。但实际回复生成时,MessageGenerator会使用这些模板并结合上下文润色。
阶段转移规则:prompt.yaml的stageConfigs中定义了每个阶段的nextStage,但实际LLM决策会输出nextState。LLM的决策会参考这些配置(通过prompt提示),但最终由LLM决定是否按照配置的nextStage推进。
强制规则:尽管大部分由LLM判断,但代码中有一些硬编码的强制覆盖,如用户提到皮肤问题时的强制推进。这些强制规则可能会覆盖LLM的决策,但也是为了保证SOP流程不被偏离。
阶段配置加载:在StrictSalesEngine的init方法中,会从prompt.yaml加载stageConfigs,并映射到StrictSalesState枚举。这确保SOP阶段与代码状态对应。
因此,系统会按照prompt.yaml中的SOP流程执行,但具体执行(如判断完成条件、选择下一个阶段)依赖于LLM的推理。由于LLM的prompt中包含了SOP的详细规则,因此LLM能够理解并遵循流程。同时,硬编码的强制规则作为兜底,确保关键节点不会被跳过。
总结:
硬编码规则:消息去重、部分强制状态推进(皮肤问题、赠品领取)、置信度阈值、社交规则(时间、频率)的硬编码检查、RAG检索优先级、消息分割等。
LLM判断:几乎所有意图、情绪、阶段决策、回复生成、异议处理、身份识别等核心业务逻辑。
SOP执行:系统会严格按照prompt.yaml定义的阶段、目标、完成条件来推进,但判断由LLM完成,同时有硬编码强制规则作为辅助。
回答时需要详细说明,并给出示例。