ErpAiAgent.java
10.1 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
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);
}