|
@@ -23,7 +23,7 @@
|
|
|
| 3 | **下一步思路(Next Steps)** | 可执行动作清单,每条指明"在哪做"(跳转到对应页面/工具) |
|
|
| 3 | **下一步思路(Next Steps)** | 可执行动作清单,每条指明"在哪做"(跳转到对应页面/工具) |
|
|
|
| 4 | **追问下钻** | 对任一条线索继续追问,走普通对话流(复用现有富渲染块) |
|
|
| 4 | **追问下钻** | 对任一条线索继续追问,走普通对话流(复用现有富渲染块) |
|
|
|
|
|
|
|
|
-### 1.1 线索类型(沿用 `AI_AGENT.md` 领域术语)
|
|
|
|
|
|
|
+### 1.1 线索类型(沿用 `../../AI_AGENT.md` 领域术语)
|
|
|
|
|
|
|
|
| 线索类型 | 触发特征(从持续联系数据可判) |
|
|
| 线索类型 | 触发特征(从持续联系数据可判) |
|
|
|
|---|---|
|
|
|---|---|
|
|
@@ -188,7 +188,7 @@
|
|
|
|
|
|
|
|
#### 4.1.2 表结构
|
|
#### 4.1.2 表结构
|
|
|
|
|
|
|
|
-DDL 落 `sql/`(沿用项目现有目录与命名习惯)。字段风格**对齐现有的 `agent_chat_session` / `agent_message`**:
|
|
|
|
|
|
|
+DDL 落 `../../sql`(沿用项目现有目录与命名习惯)。字段风格**对齐现有的 `agent_chat_session` / `agent_message`**:
|
|
|
时间列用 `create_at` / `update_at`(`LocalDateTime`,`@TableField(fill = FieldFill.INSERT / INSERT_UPDATE)`),
|
|
时间列用 `create_at` / `update_at`(`LocalDateTime`,`@TableField(fill = FieldFill.INSERT / INSERT_UPDATE)`),
|
|
|
半结构化数据用 `jsonb`(`@TableField(typeHandler = JsonbTypeHandler.class, jdbcType = JdbcType.OTHER)`)。
|
|
半结构化数据用 `jsonb`(`@TableField(typeHandler = JsonbTypeHandler.class, jdbcType = JdbcType.OTHER)`)。
|
|
|
字段命名也与 `agent_message` 保持一致(`role` / `content` / `content_type` / `token_count` / `metadata` /
|
|
字段命名也与 `agent_message` 保持一致(`role` / `content` / `content_type` / `token_count` / `metadata` /
|
|
@@ -410,7 +410,7 @@ zsjz:
|
|
|
|
|
|
|
|
**决策:放在 `module/agent/insight/` 子包,不新建 `module/insight`。**
|
|
**决策:放在 `module/agent/insight/` 子包,不新建 `module/insight`。**
|
|
|
|
|
|
|
|
-理由:`AI_AGENT.md` §4 规定 `<domain>` 为固定取值集合(`agent/call/dm/.../trans`),`insight` 不在其中;且该能力与 agent 子系统强耦合(复用 `HarnessAgent`、`AgentStateStore`、工具与 `SqlResultStore`)。**「独立存储」的诉求由独立的两张表满足**,模块不必强行拆。
|
|
|
|
|
|
|
+理由:`../../AI_AGENT.md` §4 规定 `<domain>` 为固定取值集合(`agent/call/dm/.../trans`),`insight` 不在其中;且该能力与 agent 子系统强耦合(复用 `HarnessAgent`、`AgentStateStore`、工具与 `SqlResultStore`)。**「独立存储」的诉求由独立的两张表满足**,模块不必强行拆。
|
|
|
|
|
|
|
|
```
|
|
```
|
|
|
ai-server/src/main/java/com/zsjz/ai/module/agent/insight/
|
|
ai-server/src/main/java/com/zsjz/ai/module/agent/insight/
|
|
@@ -532,7 +532,7 @@ sysPrompt(session) =
|
|
|
|
|
|
|
|
**返回形态**:`/insight/**` 与 `/chat/**` 一致采用**裸返回**(不走 `Result<T>` 包装),
|
|
**返回形态**:`/insight/**` 与 `/chat/**` 一致采用**裸返回**(不走 `Result<T>` 包装),
|
|
|
理由:前端 `aiHttp.*Raw`(`isTransformResponse:false`)可直接复用,避免两套取值逻辑。
|
|
理由:前端 `aiHttp.*Raw`(`isTransformResponse:false`)可直接复用,避免两套取值逻辑。
|
|
|
-(这是对 `AI_AGENT.md` §4「新增代码一律用 Result」的**有意偏离**,与既有 `/chat/**` 保持同一风格,文档化在此。)
|
|
|
|
|
|
|
+(这是对 `../../AI_AGENT.md` §4「新增代码一律用 Result」的**有意偏离**,与既有 `/chat/**` 保持同一风格,文档化在此。)
|
|
|
|
|
|
|
|
### 4.5 静态人设提示词要点(`prompts/insight/CALL_CONTINUOUS_INSIGHT.md`)
|
|
### 4.5 静态人设提示词要点(`prompts/insight/CALL_CONTINUOUS_INSIGHT.md`)
|
|
|
|
|
|
|
@@ -590,7 +590,7 @@ ai-frontend/src/
|
|
|
| `<style>` | 抽屉样式与页面 `.continuous-page` 变量对齐,复用 `trans-analysis-table-ui.less` 的色板与圆角 |
|
|
| `<style>` | 抽屉样式与页面 `.continuous-page` 变量对齐,复用 `trans-analysis-table-ui.less` 的色板与圆角 |
|
|
|
|
|
|
|
|
**图标(踩坑点)**:`AI 研判` 用 `i-mdi:auto-fix`、线索卡等级用 `i-mdi:alert-decagram-outline` 等,
|
|
**图标(踩坑点)**:`AI 研判` 用 `i-mdi:auto-fix`、线索卡等级用 `i-mdi:alert-decagram-outline` 等,
|
|
|
-**必须**在 `uno.config.ts` 的 `safelist` 中登记(`AI_AGENT.md` §8 坑 1 —— `menu.json` / 动态拼类名不会被扫描)。
|
|
|
|
|
|
|
+**必须**在 `uno.config.ts` 的 `safelist` 中登记(`../../AI_AGENT.md` §8 坑 1 —— `menu.json` / 动态拼类名不会被扫描)。
|
|
|
|
|
|
|
|
### 5.3 状态机(`useContinuousInsight`)
|
|
### 5.3 状态机(`useContinuousInsight`)
|
|
|
|
|
|
|
@@ -642,9 +642,9 @@ idle → creating(建会话)→ streaming(首轮/追问)→ done
|
|
|
- [x] 前端 `pnpm type:check` + `pnpm lint:eslint` 无错
|
|
- [x] 前端 `pnpm type:check` + `pnpm lint:eslint` 无错
|
|
|
(注:仓库 `person` / `trans` 模块有大量**既有**类型错误,与本功能无关;
|
|
(注:仓库 `person` / `trans` 模块有大量**既有**类型错误,与本功能无关;
|
|
|
本次改动文件单独跑 ESLint / Stylelint / 类型检查均为 0 错)
|
|
本次改动文件单独跑 ESLint / Stylelint / 类型检查均为 0 错)
|
|
|
-- [x] **新增两张表**:`agent_insight_session` / `agent_insight_message`,DDL 落 `sql/`;
|
|
|
|
|
- 确认**未改动** `agent_chat_session` / `agent_message` / 元数据三表
|
|
|
|
|
- (`InsightStorageContractTest#insightTablesAreIndependentFromChatTables` 断言 DDL 不引用通用对话表)
|
|
|
|
|
|
|
+- [x] **新增两张表**:`agent_insight_session` / `agent_insight_message`,DDL 落 `../../sql`;
|
|
|
|
|
+ 确认 **未改动** `agent_chat_session` / `agent_message` / 元数据三表
|
|
|
|
|
+ (`InsightStorageContractTest#insightTablesAreIndependentFromChatTables` 断言 DDL 不引用通用对话表)
|
|
|
- [x] **`uk_aim_session_seq (session_id, seq)` 唯一约束到位**;`seq` 由 `UPDATE ... RETURNING last_seq` 原子分配
|
|
- [x] **`uk_aim_session_seq (session_id, seq)` 唯一约束到位**;`seq` 由 `UPDATE ... RETURNING last_seq` 原子分配
|
|
|
(两条都有测试;另有「全 insight 包不出现 `max(seq)`」的扫描断言)
|
|
(两条都有测试;另有「全 insight 包不出现 `max(seq)`」的扫描断言)
|
|
|
- [x] **没有任何 SQL 只按 `session_id` 查**(消息查询一律带 `case_id`),并有测试覆盖
|
|
- [x] **没有任何 SQL 只按 `session_id` 查**(消息查询一律带 `case_id`),并有测试覆盖
|
|
@@ -716,7 +716,7 @@ idle → creating(建会话)→ streaming(首轮/追问)→ done
|
|
|
|
|
|
|
|
### 10.1 后端新增(23 个 Java + 2 XML + 1 提示词 + 1 DDL)
|
|
### 10.1 后端新增(23 个 Java + 2 XML + 1 提示词 + 1 DDL)
|
|
|
|
|
|
|
|
-落位 `ai-server/src/main/java/com/zsjz/ai/module/agent/insight/`:
|
|
|
|
|
|
|
+落位 `../../ai-server/src/main/java/com/zsjz/ai/module/agent/insight`:
|
|
|
|
|
|
|
|
| 目录 | 文件 |
|
|
| 目录 | 文件 |
|
|
|
|---|---|
|
|
|---|---|
|
|
@@ -733,7 +733,7 @@ idle → creating(建会话)→ streaming(首轮/追问)→ done
|
|
|
| `controller/` | `ContinuousInsightController` |
|
|
| `controller/` | `ContinuousInsightController` |
|
|
|
|
|
|
|
|
资源:`resources/mappers/insight/{AgentInsightSessionMapper,AgentInsightMessageMapper}.xml`、
|
|
资源:`resources/mappers/insight/{AgentInsightSessionMapper,AgentInsightMessageMapper}.xml`、
|
|
|
-`resources/prompts/insight/CALL_CONTINUOUS_INSIGHT.md`、`sql/insight_agent_tables.sql`。
|
|
|
|
|
|
|
+`resources/prompts/insight/CALL_CONTINUOUS_INSIGHT.md`、`../../sql/insight_agent_tables.sql`。
|
|
|
|
|
|
|
|
改动既有文件 2 处:
|
|
改动既有文件 2 处:
|
|
|
- `module/agent/tools/AgentToolRegistry.java` —— `registerBusinessTools(Toolkit)` 保留原签名,新增
|
|
- `module/agent/tools/AgentToolRegistry.java` —— `registerBusinessTools(Toolkit)` 保留原签名,新增
|
|
@@ -780,7 +780,7 @@ idle → creating(建会话)→ streaming(首轮/追问)→ done
|
|
|
而 `CREATE TABLE IF NOT EXISTS` 对「表已存在」的情况**整句跳过**,连内部约束一起跳过;
|
|
而 `CREATE TABLE IF NOT EXISTS` 对「表已存在」的情况**整句跳过**,连内部约束一起跳过;
|
|
|
只有语句外的 `CREATE INDEX IF NOT EXISTS` 才会被补建。
|
|
只有语句外的 `CREATE INDEX IF NOT EXISTS` 才会被补建。
|
|
|
|
|
|
|
|
-**已修复**:新增 `sql/insight_agent_tables_align.sql`(幂等补丁,23 条语句全部执行成功),补齐:
|
|
|
|
|
|
|
+**已修复**:新增 `../../sql/insight_agent_tables_align.sql`(幂等补丁,23 条语句全部执行成功),补齐:
|
|
|
|
|
|
|
|
| 对象 | 状态 |
|
|
| 对象 | 状态 |
|
|
|
|---|---|
|
|
|---|---|
|
|
@@ -796,9 +796,9 @@ idle → creating(建会话)→ streaming(首轮/追问)→ done
|
|
|
|
|
|
|
|
### 10.5 未做 / 待办
|
|
### 10.5 未做 / 待办
|
|
|
|
|
|
|
|
-- **`table_info` / `table_field` 元数据未登记**:经核对,这两张元数据表登记的是**案情/公安数据库表**
|
|
|
|
|
|
|
+- **`table_info` / `table_field` 元数据未登记**:经核对,这两张元数据表登记的是 **案情/公安数据库表**
|
|
|
(`cert_info` / `entry_rec` / `vehicle_info` …,`classify='公安数据库'`),供 Agent 的 SQL schema 检索使用;
|
|
(`cert_info` / `entry_rec` / `vehicle_info` …,`classify='公安数据库'`),供 Agent 的 SQL schema 检索使用;
|
|
|
- 本功能两张表建在 **master 平台库**、Agent 不检索它们,故**不属于** `AI_AGENT.md` §5「新增表结构同步补元数据」的适用范围。
|
|
|
|
|
|
|
+ 本功能两张表建在 **master 平台库**、Agent 不检索它们,故 **不属于** `../../AI_AGENT.md` §5「新增表结构同步补元数据」的适用范围。
|
|
|
- **需要真实数据库的用例未覆盖**:`seq` 并发不重号、级联删除生效这两条依赖 PG 行级锁与真实外键,
|
|
- **需要真实数据库的用例未覆盖**:`seq` 并发不重号、级联删除生效这两条依赖 PG 行级锁与真实外键,
|
|
|
本项目没有 Testcontainers / H2 基础设施,无法在内存库里验证 —— 已用静态断言覆盖其前置条件(见 §10.6)。
|
|
本项目没有 Testcontainers / H2 基础设施,无法在内存库里验证 —— 已用静态断言覆盖其前置条件(见 §10.6)。
|
|
|
- **`GET /insight/continuous/clues`** 已按设计**仅预留**,未接任何页面。
|
|
- **`GET /insight/continuous/clues`** 已按设计**仅预留**,未接任何页面。
|