package com.xly.agent; import dev.langchain4j.service.MemoryId; import dev.langchain4j.service.SystemMessage; import dev.langchain4j.service.UserMessage; import dev.langchain4j.service.V; /** * 优化后:新增场景专属交互规则,大模型仅处理当前场景业务指令 */ public interface ErpAiAgent { @SystemMessage(""" 1. 方法匹配:先精准拆解用户查询的核心业务意图,再自动匹配唯一符合用户问题的工具方法(MethodNo),禁止自创,规则如下; 1.1 匹配方法时,无需考虑工具描述(@TOOL)中 1.必填参数,2.选填参数,示例,parameters内容 四个部分的内容; 1.2 匹配方法时,只关注工具描述(@TOOL)中 “当用户” 和 “时,必须调用本工具”两个短语之间的内容; 1.3 调用工具前,不需要询问用户提供缺失的参数 2. 参数提取:提取该工具的全部参数,与描述完全一致,严格按标注类型赋值,规则如下: 2.1 数字无引号,为空时禁止赋值0; 2.2 如果有空格需要去掉空格后再提取。 """) @UserMessage("用户输入:{{userInput}}") String chat(@MemoryId String userId, @V("userInput") String userInput); /** * 动态表结构:自然语言解释SQL执行结果 * 入参:用户问题、执行的SQL、表结构、JSON格式结果 */ @SystemMessage(""" 你是专业的业务数据分析师,严格遵循以下**通用规则**解释查询结果,适用于所有业务场景: 1. 解释风格:贴合业务场景,无任何SQL专业术语,用口语化、简洁的商业语言说明,避免技术词汇; 2. 数据准确:严格按照JSON执行结果解释,不夸大、不遗漏、不编造数据,数值与结果完全一致; 3. 输出格式:仅返回解释内容,不要列出ID,无多余标题、换行、符号,结果为空时直接返回“未查询到相关数据” 3.1. 所有数字格式必须以纯文本形式输出,严禁使用千分位分隔符(即不要出现逗号 ",")示例:正确写法是 1000000,错误写法是 1,000,000,即使数字很大,也请保持连续的数字串,不要打断。 3.2 所有日期请转换为 YYYY-MM-DD 格式(例如:2026-03-15),严禁包含时间部分(如小时、分钟、秒)(例如:2026-03-15 00:00:00),也不要包含时区信息。” 3.3. 金额,单价,数量 严禁使用千分位分隔符(即不要出现逗号 ",")示例:正确写法是 2400056,错误写法是 2,400,056 即使数字很大,也请保持连续的数字串,不要打断。 4. 长度控制:单条解释不超过150字,条理清晰,重点突出核心数据/趋势; 5. 禁止重复:不重复用户问题、不重复执行的SQL语句,仅针对结果做业务解读。 """) @UserMessage(""" 【业务场景表结构信息】 表结构详情:{{tableStruct}} 【查询相关信息】 用户原始查询:{{userInput}} 执行的MySQL SQL:{{sql}} SQL执行结果(JSON格式):{{result}} 请根据上述信息+通用规则,对查询结果做业务解释: """) String explainSqlResult(@MemoryId String userId, @V("userInput") String userInput, @V("sql") String sql, @V("tableStruct") String tableStruct, @V("result") String result); /** * 动态表结构:自然语言解释SQL执行结果 * 入参:用户问题、执行的SQL、表结构、JSON格式结果 */ @SystemMessage(""" 你是专业的业务数据分析师,请分析以下查询结果: 【用户问题】 {{userInput}} 【数据字段说明】 {{sMilvusFiledDescription}} 【查询结果数据(JSON格式)】 {{result}} 【分析要求】 1. 解释风格:贴合业务场景,无任何SQL专业术语,用口语化、简洁的商业语言说明,避免技术词汇; 2. 数据准确:严格按照JSON执行结果解释,不夸大、不遗漏、不编造数据,数值与结果完全一致; 3. 输出格式: 3.1. 如果用户要求"表格形式展示",先输出简短文字说明,然后输出Markdown格式的表格 3.2. 如果用户未要求表格,仅返回解释内容,不要列出ID,无多余标题、换行、符号 3.3. 结果为空时直接返回"未查询到相关数据" 3.4. 所有数字格式必须以纯文本形式输出,严禁使用千分位分隔符(即不要出现逗号 ",") 3.5. 所有日期请转换为 YYYY-MM-DD 格式,严禁包含时间部分 4. 长度控制:单条解释不超过150字,条理清晰,重点突出核心数据/趋势; 5. 禁止重复:不重复用户问题、不重复执行的SQL语句,仅针对结果做业务解读。 """) @UserMessage(""" 【用户查询】 {{userInput}} 【字段说明】 {{sMilvusFiledDescription}} 【查询结果】 用户原始查询:{{userInput}} 执行查询向量库后结果(JSON格式):{{result}} 请根据上述信息+通用规则,对查询结果做业务解释: """) String explainMilvusResult(@MemoryId String userId, @V("userInput") String userInput, @V("sMilvusFiledDescription") String sMilvusFiledDescription, @V("result") String result); /** * AI路由判断接口 * true: 走聚合查询(MySQL) * false: 走向量检索(Milvus) */ // @SystemMessage(""" // 你是一个智能查询路由专家,请根据用户需求判断应该使用哪种查询方式。 // // 判断标准: // 1. 返回 true(聚合查询/MySQL)的场景: // - 需要计算统计指标:总数、总和、平均值、最大/最小值、占比 // - 需要数据汇总:分组统计、排行榜、TopN // - 包含关键词:统计、求和、汇总、排名、平均、数量、总额、最高、最低、占比、分组、分析、趋势 // - 示例:统计本月销售总额、查询销量前10的商品、各品类占比分析 // // 2. 返回 false(向量检索/Milvus)的场景: // - 查询明细数据:XXX的销售订单明细、XXX的客户信息、具体内容详情 // - 查找相似内容:根据语义查找相关文档、推荐相似商品 // - 模糊匹配:不确定具体关键词,需要语义理解 // - 内容检索:查找包含特定概念的文档 // - 包含关键词:明细、详情、查询明细、查找、搜索、匹配、推荐、相似、相关、类似 // - 示例:李留记的销售订单明细、查询关于人工智能的文档、找相似的图片 // // 重要规则: // - 只返回 true 或 false,不要返回其他内容 // - 不要解释,不要添加额外文字 // - 如果用户要求"表格形式展示",返回 false(明细查询) // - 如果用户指定具体人名、具体对象,返回 false(明细查询) // """) // @UserMessage("用户需求:{{userInput}}") @SystemMessage(""" 你是一个智能查询路由专家。请根据【用户需求】,只返回 true 或 false - 如果用户需求包含以下关键词:统计、求和、汇总、排名、TopN、平均、数量、总额、最高、最低、占比、分组,则返回true - 如果用户需求属于模糊匹配、普通语义检索,查询明细,(例如:查询报价单明细,查询客户信息),则返回false - 查询明细数据:XXX的销售订单明细、XXX的客户信息、具体内容详情,则返回false - 模糊匹配:不确定具体关键词,需要语义理解,则返回false """) @UserMessage(""" 【用户需求】 {{userInput}} """) Boolean routeQuery(@MemoryId String userId, @V("userInput") String userInput); /** * 生成 Milvus 过滤条件 */ @SystemMessage(""" MILVUS 标量过滤条件生成规则(严格遵守): 1. 语法规范: - 允许的操作符:==, !=, like - 逻辑组合:&& (AND), || (OR) - 所有字段都是字符串类型,值必须使用单引号包裹 - 字符串中的单引号需要转义:'O''Reilly' 2. 可用字段(只能使用这些字段): - {{sMilvusFiled}} 字段说明: - {{sMilvusFiledDescription}} 3. 重要规则: - 只使用上述可用字段,不要创建新字段 - 如果用户提到了文档类型(如"报价单"、"订单"等),但可用字段中没有类型字段,则忽略该条件 - 只提取有明确值的字段条件 4. 生成规则: - 如果没有提取到任何具体条件,返回空字符串 - 从用户输入中提取明确的字段条件 - 识别模式:字段名 + 操作符 + 值 - 示例: * "单据号 INV001" → sBillNo == 'INV001' * "客户编号 C001" → sCustomerNo == 'C001' * "销售人员张三" → sSalesManName == '张三' * "产品包含手机" → sProductStyle like '%手机%' 5. 输出格式: - 仅返回纯过滤条件,无任何解释、换行、备注 - 单条件:sBillNo == 'INV001' - 多条件:(sBillNo == 'INV001' && sCustomerNo == 'C001') - 无条件:直接返回空字符串 """) @UserMessage(""" 【用户查询】 - {{userInput}} 【可用字段】 - {{sMilvusFiled}} 【字段说明】 - {{sMilvusFiledDescription}} """) String getMilvusFilter(@MemoryId String userId, @V("userInput") String userInput, @V("sMilvusFiled") String sMilvusFiled, @V("sMilvusFiledDescription") String sMilvusFiledDescription); }