- IntentShortcut 泛化成规则表(Rule{短语集 → Intent}):加新意图只需
① 一条 Intent ② 一个短语集 ③ RULES.add(...),不用动 AgentOrchestrator。
新增 NOTICE_PUBLISH —— 仅教职工(notice.publish),学生无落点则落回模型如实说明。
短语表只收带「发/发布」动词的说法(发布公告/发个公告/发布校园公告/发通知…),
光说「公告」「通知」更像查询,不收,避免误判。
- ★ 修 prepareOptionCall 漏拼字典工具的 fixed 参数:公文部门字典是
/api/dict/List?type=1,丢了 type 前端取回的是「没指定类型」的结果 → 空下拉。
- deptId 补 optionsKeys("k","v"):平台通用字典返回 {k,v} 而非 id/name;
服务端兜底 fetchDictOptions 的候选键也补上 k/v。
- ★ 移除 notice.publish 的 publishType 与 deptName:后端 /api/notice/Create 就是
直接发布(无 publishType 字段,是否转审批由学校「应用设置」绑定的流程决定),
声明它会让用户以为选了「存草稿」却仍然直接发出;deptName 由后端按 deptId 反查字典。
- system prompt 加第 10 条说明。
- 测试:新增 NoticeIntentFormTest(7),IntentDirectFormTest 加教师/学生两条公告用例
(仍用「一调就炸」的假 LLM 证明不过大模型);全量 71/71。
This commit is contained in:
@@ -113,8 +113,8 @@ public class AgentOrchestrator {
|
||||
ChatResponse resp = new ChatResponse();
|
||||
resp.setSessionId(session.getSessionId());
|
||||
|
||||
// ★ 裸意图直达:「我要请假」这类只有意图、没有细节的句子,直接按身份弹表单,
|
||||
// 不交给大模型决策(模型可能先去查字典、或自行编造时间直接提交,都不合预期)。
|
||||
// ★ 裸意图直达:「我要请假」「发布校园公告」这类只有意图、没有细节的句子,直接按身份弹表单,
|
||||
// 不交给大模型决策(模型可能先去查字典、或自行编造参数直接提交,都不合预期)。
|
||||
ChatResponse direct = directForm(req.getMessage(), caller, authorizedModIds, roles, session, out);
|
||||
if (direct != null) {
|
||||
return direct;
|
||||
@@ -408,8 +408,9 @@ public class AgentOrchestrator {
|
||||
/* ==================== 表单:缺参拦截 与 直提交 ==================== */
|
||||
|
||||
/**
|
||||
* 裸意图直达:命中「只有意图、没有细节」的句子(如「我要请假」)时,
|
||||
* 按当前身份直接构建表单返回 —— 学生拿「请假申请」,教职工拿「请假登记(帮学生请假)」。
|
||||
* 裸意图直达:命中「只有意图、没有细节」的句子(如「我要请假」「发布校园公告」)时,
|
||||
* 按当前身份直接构建表单返回 —— 请假:学生拿「请假申请」、教职工拿「请假登记(帮学生请假)」;
|
||||
* 发布公告:只有教职工能直达,学生落回模型(由模型的权限准则如实说明)。
|
||||
*
|
||||
* <p>判据与能力目录 / 模型侧过滤**完全一致**({@code visibleTools}),
|
||||
* 因此不存在「直达出一个本身份无权使用的表单」的可能;不命中或不适用就返回 {@code null},
|
||||
@@ -449,8 +450,8 @@ public class AgentOrchestrator {
|
||||
resp.setForm(form);
|
||||
resp.setReply(reply);
|
||||
out.emit(AgentEvent.of("form", "需要补充信息:" + String.join("、", form.getMissing())));
|
||||
log.info("意图直达弹表单:session={} 身份={} 工具={}", session.getSessionId(),
|
||||
staff ? "教职工" : "学生", def.getName());
|
||||
log.info("意图直达弹表单:session={} 意图={} 身份={} 工具={}", session.getSessionId(),
|
||||
intent.getName(), staff ? "教职工" : "学生", def.getName());
|
||||
finish(resp, session, 0, 0, out);
|
||||
return resp;
|
||||
}
|
||||
@@ -811,11 +812,12 @@ public class AgentOrchestrator {
|
||||
continue;
|
||||
}
|
||||
JSONObject o = (JSONObject) item;
|
||||
String value = firstOf(o, "id", "value", "code", "dictId", "typeId", "key");
|
||||
// "k"/"v" 是平台通用字典(/api/dict/List)的形态,与业务 VO(classId/className)并存
|
||||
String value = firstOf(o, "id", "value", "code", "dictId", "typeId", "key", "k");
|
||||
if (StringUtils.isBlank(value)) {
|
||||
continue;
|
||||
}
|
||||
String label = firstOf(o, "name", "label", "text", "title", "dictName", "value");
|
||||
String label = firstOf(o, "name", "label", "text", "title", "dictName", "v", "value");
|
||||
Map<String, String> one = new LinkedHashMap<>();
|
||||
one.put("value", value);
|
||||
one.put("label", StringUtils.isBlank(label) ? value : label);
|
||||
@@ -1007,6 +1009,10 @@ public class AgentOrchestrator {
|
||||
.append("「帮学生登记请假」= 教师给学生登记(免审直接生效,必须先选班级与学生)。")
|
||||
.append("下发给你的工具已按当前身份过滤,按标题选即可,不要互换。\n");
|
||||
|
||||
sb.append("10. ★ 「发布校园公告」是**立即发布、全站可见**的动作:必须拿到标题、正文、发文部门三项;")
|
||||
.append("缺哪项就照常调用工具让系统弹表单,不要自己编造发文部门,也不要用文字反复追问。")
|
||||
.append("该工具只对教职工下发(学生身份看不到),学生要求发布公告时如实说明身份不够。\n");
|
||||
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user