2026/8/6 9:54:47

代码硬编码与LLM决策分析及SOP执行情况

代码硬编码与LLM决策分析及SOP执行情况 根据对代码的全面分析我将系统梳理硬编码规则、LLM判断的规则以及系统是否遵循prompt.yaml中的SOP流程。一、硬编码规则在Java代码中写死的逻辑1.流程控制与默认行为位置硬编码内容AgentOrchestrator.process()最大循环次数maxLoops 5超限后发送固定兜底消息。AgentState历史记录最多保留50条if (history.size() 50) { history.remove(0); }。AgentOrchestrator解析LLM响应失败时降级消息抱歉我没理解您的意思。或抱歉系统暂时无法处理请稍后再试。。ToolRegistry工具名称硬编码tools.put(sales, new SalesTool())。SalesTool旧实现状态转换映射硬编码如greet_gift_intro→GIFT_CLAIM_GUIDE。RedisSessionManagerTTL固定为7天、键名前缀硬编码。AgentFlowEngine.evaluateCondition()使用LLM判断条件但prompt为硬编码字符串。2.业务逻辑中的固定阈值与概率位置硬编码内容ConversationDecisionEngine判断是否主动跟进minutesSinceLastActivity 3消息长度阈值100、50决定回复数量购买意愿阈值0.7。MessageGenerator添加思考痕迹的概率0.1消息相似度阈值0.8微思考响应截断长度30。HumanBehaviorEngine大量概率和阈值如random.nextDouble() 0.3设备类型因子、时间段因子等有默认值。ProactiveConversationService响应概率阈值0.6。KnowledgeService检索结果默认限制topK3。CustomerServiceAgent阶段完成条件的描述文本硬编码在buildConversationReplyPrompt中。3.Prompt构建中的固定文本许多buildXXXPrompt方法中使用String.format或字符串拼接包含了大量固定引导语、案例、规则说明例如MessageGenerator.buildMessagePrompt()中的系统角色设定、案例。StrictSalesEngine.buildStateTransitionPrompt()中的“强制规则”、“皮肤问题处理规则”。ConversationOrchestrator.buildSystemPrompt()中的工作时间、称呼、策略提示等。AgentThinkingEngine.think()中的输出格式说明。这些固定文本虽然在代码中但本质是用于引导LLM并非业务逻辑硬编码但它们作为字符串嵌入代码不利于灵活修改。4.枚举与状态映射StrictSalesState枚举定义所有阶段阶段间的流转逻辑未硬编码由LLM决定但状态值本身固定。StagePlan在StageGoalResolver中硬编码了默认阶段计划但从prompt.yaml加载的配置会覆盖。5.工具类中的简单规则OrderStatusTool简单查询订单并返回固定模板键。SalesTool旧硬编码了输入指令到状态的映射。二、通过LLM判断的规则由LLM动态决策1.核心对话决策组件LLM决策内容AgentOrchestrator调用LLM生成ThoughtResult决定动作SPEAK/TOOL/WAIT/END、消息内容、工具调用、是否更新阶段。StrictSalesEngine调用LLM生成StateMachineDecision决定下一状态、动作、消息列表、是否完成阶段、是否介绍自己等。StreamingThinkEngine调用LLM生成StreamThought决定意图、消息、等待时间、后续想法等用于持续思考。MessageGenerator所有生成回复的方法均调用LLM包括普通回复、主动跟进、异议处理、产品介绍、情绪安抚等。EnhancedDecisionEngine/ProactiveDecisionService使用LLM判断是否主动跟进及跟进内容。ConversationDecisionService使用LLM决定是否说话及消息内容。DecisionModelService使用LLM做是否回应、回应类型等决策。IntentEvaluatorService使用LLM评估意图、是否主动跟进等。2.认知与情感分析组件LLM分析内容CognitiveEngine使用LLM分析意图、情绪、实体、核心需求、购买意愿、风险等级通过analyzeWithDashScope。EmotionAnalyzerLLM使用LLM分析情绪维度愤怒、焦虑、怀疑等。EnhancedEmotionAnalyzer使用LLM进行细粒度情绪分析返回情绪类型、强度、子情绪等。BeautyIntentClassifier使用LLM进行意图分类多意图。3.条件判断与规则评估组件LLM判断内容AgentFlowEngine.evaluateCondition()使用LLM判断边缘条件如是否满足跳转条件。StrictSalesEngine.isDuplicateByLLM()使用LLM判断消息是否为重复消息。StrictSalesEngine.violateSop()使用LLM判断回复是否违反SOP。StrictSalesEngine.mustFollow()使用LLM判断当前是否必须严格遵循SOP。PolicyEngine中的部分决策使用LLM处理异议、价值主张应用等但部分为硬编码规则。4.内容生成与优化LLMRAGService使用LLM生成高质量回复、处理异议、情绪安抚、产品介绍。PersonalizedPlanService使用LLM生成个性化护肤方案optimizePlanWithLLM。SalesChampionImitationService使用LLM生成模仿销冠风格的回复。AgentLearningService使用LLM分析对话、提取经验、生成改进策略。三、系统是否按照prompt.yaml中的SOP流程执行1.配置加载与使用PromptProperties加载prompt.yamlPromptService提供访问接口。阶段配置stageConfigs被StrictSalesEngine.init()加载并存入stageConfigsMap在构建LLM Prompt时动态注入。完成条件与禁止话题在CustomerServiceAgent.buildConversationReplyPrompt()和StrictSalesEngine.buildStateTransitionPrompt()中通过promptService.getStageGoal()、getStageCompletionCondition()、getForbiddenTopics()获取并放入Prompt中引导LLM遵循。话术模板stageStateMachine中的标准话术在StrictSalesEngine.getStateTemplate()中被使用当LLM未提供消息时作为兜底。在MessageGenerator中也通过promptService.get(key)获取各种模板如greetGiftIntro用于构建Prompt或直接使用。异议处理流程objectionHandlingFlow通过PromptService被ObjectionHandlingFlow.buildFromConfig()加载并在SalesPolicyEngine.buildObjectionHandlingPrompt()中作为参考注入Prompt。2.执行机制决策依赖LLM所有状态推进、是否完成阶段、是否发送消息等核心决策均由LLM根据Prompt中的SOP描述做出。引导而非强制系统将SOP的目标、完成条件、禁止话题等作为“知识”提供给LLM但LLM的最终输出可能偏离SOP例如未达到完成条件却推进阶段。此时系统会接受LLM的决策除非解析失败则降级没有强制校验或修正。兜底措施当LLM未提供消息时会使用getStateTemplate()返回的预设话术当解析失败时会返回默认回复或等待。但这些兜底不能保证完全符合SOP。3.验证在StrictSalesEngine的parseStateMachineDecision()中会解析LLM返回的nextState、stageComplete等字段并直接设置状态。没有额外的SOP合规校验。虽然存在violateSop()方法但它仅在ReplyValidator.validateAndRepair()中被调用该验证器在AgentRouter中被使用用于修复违反SOP的回复但该验证是在回复生成后且修复也依赖LLM并非严格拦截。在ConversationPolicyEngine中mustFollowSop标志由LLM判断但后续执行仍由StrictSalesEngine处理。4.结论系统会参考prompt.yaml中的SOP流程但并非硬性执行。SOP的描述目标、完成条件、禁止话题、话术模板被注入到LLM的Prompt中由LLM自主决定是否遵守。由于LLM可能产生偏离实际执行效果依赖于LLM的语义理解能力和Prompt设计的有效性。四、改进建议1.减少硬编码将AgentOrchestrator中的循环次数、兜底消息、历史长度等配置化到application.yml或prompt.yaml。将MessageGenerator中的思考标记、案例文本等抽取为配置通过PromptService加载。将各类阈值如主动跟进时间、参与度阈值移到配置文件中。将SalesTool中的状态映射改为配置或完全由LLM决策。2.增强SOP合规性在StrictSalesEngine中增加后置校验LLM返回的nextState是否与当前阶段允许的下一阶段列表匹配可从配置读取。增加stageComplete的校验若LLM认为阶段完成但实际用户未满足完成条件可通过规则检查则强制设置stageCompletefalse并重新生成。在回复发送前用violateSop方法做快速校验若违反则使用默认话术覆盖。为每个阶段配置允许的下一阶段列表在状态更新时进行合法性检查。3.优化LLM决策质量在Prompt中更明确地强调SOP的权威性使用类似“你必须严格遵守以下规则”的强约束语句。使用Few-shot示例展示正确的阶段推进场景。对阶段完成条件进行更详细的描述并提示LLM如果未满足条件不能推进。通过以上措施可以在保持LLM灵活性的同时增强系统对SOP的执行力减少偏差。我们被要求分析代码中哪些规则是硬编码的哪些是通过LLM判断的以及是否按照prompt.yaml中的SOP流程执行。我们需要基于提供的代码进行全面分析。代码规模很大我们需要系统地梳理。首先理解项目AI Agent系统核心是对话流程。主要组件包括AgentOrchestrator, AgentState, StrictSalesEngine, StreamingThinkEngine, MessageGenerator, PromptService等。系统通过LLM决策但也有一些硬编码逻辑。我们要从代码中提取硬编码规则和LLM判断的地方并验证是否遵循prompt.yaml中的SOP。一、硬编码规则硬编码规则指在Java代码中直接写死的逻辑不依赖LLM或配置文件。AgentOrchestrator中的循环和默认处理:maxLoops 5最多循环5次。当LLM响应解析失败时降级发送固定消息抱歉我没理解您的意思。 或 抱歉系统暂时无法处理请稍后再试。在process方法中根据ThoughtResult的action执行不同逻辑SPEAK、TOOL、WAIT、END。这是基于JSON解析的但具体流程控制是硬编码的。AgentState中的历史长度限制:if (history.size() 50) { history.remove(0); }固定50条历史。ToolRegistry:注册工具时硬编码了工具名称映射。例如tools.put(sales, new SalesTool());。但SalesTool本身逻辑也是硬编码的在tools/SalesTool.java中。SalesTool工具实现:SalesTool.execute中有switch-case根据input执行不同的阶段转移。例如greet_gift_intro- 状态设为GIFT_CLAIM_GUIDEgift_claim_guide- 状态设为WAITING_FOR_GIFT_CONFIRMATIONask_photo- 状态设为ASKING_FOR_PHOTO这些状态名和转换是硬编码的。但是注意在StrictSalesEngine中也有类似的决策可能SalesTool已弃用实际分析ToolRegistry中使用了OrderStatusTool但SalesTool似乎用于辅助状态转换而主要状态机在StrictSalesEngine中。CustomerServiceAgent中的阶段完成条件:在buildConversationReplyPrompt中有对阶段完成条件的描述但这些描述是写在Java字符串中的而不是完全从配置读取。虽然这些条件文本是硬编码的但它们被注入到prompt中由LLM判断是否完成。但硬编码了条件文本。ConversationDecisionEngine中的决策逻辑:shouldSpeak、shouldProactiveFollowUp、shouldBeSilent等方法中有硬编码的时间判断如3分钟、10秒、概率随机等。determineMessageCount中硬编码了根据消息长度返回1-3条消息。determineStrategy根据购买意愿阈值0.7决定策略。MessageGenerator中的硬编码:大量硬编码的prompt字符串例如在generateWithFallback、generate、buildMessagePrompt等方法中使用String.format构造prompt其中包含了很多固定的文本描述。在addHumanElements中有硬编码的思考标记数组和概率0.1。在processMicroThinkingResponse中有截断消息长度、添加标点等硬编码逻辑。在generateWithDiversity中硬编码了相似度阈值0.8和重试次数3。在generateWithTemplate中硬编码了根据策略类型返回的默认兜底。HumanBehaviorEngine:有大量硬编码的概率和阈值例如random.nextDouble() 0.3、设备类型因子、时间段因子等虽然有从配置读取但默认值硬编码。RedisSessionManager中的TTL和常量:DEFAULT_TTL Duration.ofDays(7)硬编码。一些键名前缀硬编码如session:%s:epoch等。AgentFlowEngine:evaluateCondition中直接调用LLM判断但prompt是硬编码的字符串。ConversationOrchestrator:在buildSystemPrompt方法中有大量硬编码的规则文本例如“工作时间10:00~19:00”、“称呼客户为“亲爱的”或“姐妹””、“如果客户情绪负面愤怒、失望先道歉安抚”等。这些虽然是用于prompt的但内容是硬编码的不是从配置读取。StrictSalesEngine中的硬编码:getStageGoal方法中有switch-case硬编码了阶段目标字符串。buildStateTransitionPrompt中硬编码了“强制规则”等文本但也是用于prompt。在parseStateMachineDecision中当nextState无效时默认设置为StrictSalesState.GREETING_GIFT_INTRO并且有硬编码的默认话术。getStateTemplate中从配置读取但若读取不到有硬编码的兜底。isDuplicateByLLM中如果LLM调用失败返回false没有重试等。其他服务中的硬编码:例如在CognitiveEngine中有硬编码的意图映射switch(intent)。EmotionAnalyzerLLM中有硬编码的默认值。KnowledgeService中retrieveRelevantDocs默认limit为3硬编码。ProactiveConversationService中阈值0.6硬编码。二、通过LLM判断的规则这部分是指决策由LLM完成系统将上下文组织成prompt调用LLM解析返回的JSON来驱动行为。AgentOrchestrator的思考循环:核心调用LLMClient.call生成ThoughtResult包含action、message、toolName等然后根据action执行。所以整个思考过程决定说/调用工具/等待/结束是由LLM决定的。StrictSalesEngine的状态转换:在process方法中调用LLM生成StateMachineDecision决定下一状态、动作、话术等。这是核心的状态机由LLM基于当前状态、用户消息、对话历史等决策。在processWithProactiveRequest中同样使用LLM决策。注意尽管状态转换由LLM决策但状态枚举和部分约束是硬编码的。StreamingThinkEngine:thinkWithLLM方法中调用LLM生成StreamThought包含intent、message、nextThoughts等。这用于持续思考也是LLM决策。MessageGenerator的大部分消息生成:所有生成回复的方法generateWithFallback、generate、generateNextSentence等最终都调用LLM生成具体回复文本。虽然构建prompt时有大量硬编码但最终的回复由LLM决定。决策类服务:EnhancedDecisionEngine.decide使用LLM判断是否主动跟进。ProactiveDecisionService.decide使用LLM决定主动联系。ConversationDecisionService.decide使用LLM决定是否说话及消息。DecisionModelService使用LLM做决策。IntentEvaluatorService使用LLM评估意图。情绪分析:EmotionAnalyzerLLM使用LLM分析情绪。EnhancedEmotionAnalyzer也使用LLM分析。认知分析:CognitiveEngine中调用了EnhancedCognitiveResult的增强分析使用了LLM通过analyzeWithDashScope或备用。意图分类:BeautyIntentClassifier使用LLM进行意图分类。DynamicIntentClassifier可以选择使用ML或规则但最终都会调用LLM或ML。内容生成:LLMRAGService使用LLM生成高质量回复。条件判断:AgentFlowEngine中的evaluateCondition使用LLM判断条件。三、是否按照prompt.yaml中的SOP流程执行prompt.yaml定义了完整的SOP流程包括阶段配置、阶段目标、完成条件、禁止话题、话术模板等。这些内容在系统中如何被使用阶段定义和完成条件:prompt.yaml中的stageConfigs定义了每个阶段的goal、completionCondition、forbiddenTopics等。在StrictSalesEngine.init中通过promptProperties.getTemplates().getStageConfigs()加载这些配置并存入stageConfigsMap。在buildStateTransitionPrompt中会动态注入当前阶段的完成条件、阶段目标等作为prompt的一部分给LLM。在CustomerServiceAgent.buildConversationReplyPrompt中也使用了promptService.getStageGoal(currentStage)和getForbiddenTopics来构建prompt。所以阶段目标和完成条件是通过配置驱动的但LLM仍然需要根据这些条件判断是否完成阶段。因此系统会参考prompt.yaml中的SOP但最终决策由LLM做出LLM可能会偏离SOP。话术模板:prompt.yaml中的stageStateMachine定义了各阶段的标准话术如STRICT_SALES_GREETING等。在StrictSalesEngine中getStateTemplate会从promptProperties.getTemplates().getStageStateMachine()中获取对应状态的模板。当LLM没有提供消息时会使用这些模板。此外在MessageGenerator中也会使用promptService.get(key)获取各种模板如greetGiftIntro等。但注意这些模板主要作为兜底或参考实际回复仍由LLM生成除非LLM未提供消息。主动跟进话术:proactiveMessages在prompt.yaml中定义用于主动跟进场景。在StrictSalesEngine中getProactiveMessagesForState会读取这些但似乎没有直接使用实际在StrictSalesEngine.processWithProactiveRequest中可能使用模板生成话术。异议处理流程:objectionHandlingFlow定义了不同异议类型的处理步骤。这些配置在ObjectionHandlingFlow类中通过buildFromConfig加载但实际使用似乎不多在SalesPolicyEngine中有buildObjectionHandlingPrompt会使用这些配置但也作为prompt的一部分。关键点系统确实会读取prompt.yaml中的配置并将其融入prompt中引导LLM遵循SOP。但是LLM的决策是自由的理论上可能不遵守SOP。不过由于prompt中强调了SOP的重要性例如你必须严格按照SOP流程引导客户且提供了阶段目标、完成条件等LLM有较大可能遵循。但无法保证100%执行。四、总结硬编码规则主要集中在循环次数、历史长度、默认兜底、某些工具逻辑、时间阈值、概率、字符串拼接构建prompt时的固定文本等。LLM判断的规则包括整体思考决策说/等待/调用工具、状态转换、消息生成、主动跟进判断、情绪分析、意图分类等。SOP流程执行系统通过读取prompt.yaml中的阶段配置、话术模板等将其注入到LLM的prompt中引导LLM按照SOP执行。因此LLM会参考SOP但不是硬编码强制执行的。若LLM输出不符合SOP系统会有一些兜底如使用默认话术但不会强制纠正。五、改进建议如果想减少硬编码可以进一步将更多配置移到prompt.yaml或数据库例如将AgentOrchestrator中的最大循环次数、默认兜底消息等配置化。将MessageGenerator中的硬编码案例、思考标记等也配置化。将各种阈值、概率从代码中移到配置文件。将阶段转移的规则更依赖LLM减少硬编码的状态映射。当前设计已经很好地结合了LLM和配置使得流程灵活。但需注意LLM可能产生不符合SOP的结果因此需要增加更多的验证和纠错机制如输出格式校验、SOP合规检查。目前已有一些检查如StrictSalesEngine中解析JSON但未做SOP合规性后置校验。建议在LLM输出后可以增加一个合规检查层确保输出的nextState符合预期的阶段流程如果不符则修正或重新生成。