diff --git a/docs/agent-architecture.md b/docs/agent-architecture.md index 64994a0..96e9993 100644 --- a/docs/agent-architecture.md +++ b/docs/agent-architecture.md @@ -32,7 +32,7 @@ - **单 agent** = LangChain4j `AiServices` 原生 **tool-calling 循环**当 ReAct(不用老式文本 Thought/Action;qwen2.5 支持 function calling)。 - **退役** 8 场景 `SceneSelector` 路由 —— agent 自路由。 - **System prompt** = 角色 + **L1 业务域图(`viw_kg_domain`, 11 行)** + Skill 摘要列表 + 工具用法 + 安全约束。 -- **记忆** = `ChatMemory`(窗口化 + 超长摘要),持久化到 **Redis**(键:`chat:{userId}:{conversationId}`,带 TTL)。 +- **记忆** = `ChatMemory`(窗口化 + 超长摘要),持久化到 **Redis**(键:`chat:{userId}:{conversationId}`,带 TTL)。**多条命名会话/用户**:每用户一个会话列表,存储按 `conversationId` 分;按稳定身份(userId+品牌+子公司)寻址,**重登录/换 token 后接回历史**(token 不是会话 key)。 - **循环护栏**:最大工具迭代步数、单轮墙钟超时、单轮 LLM 调用上限。 ## 4. HITL 机制(无 LangGraph 的中断/续跑) @@ -72,6 +72,8 @@ **凭证透传(不变)**:用户 token 登录 ERP 后存浏览器;前端每请求带给 xlyAi → xlyAi 工具转发进 ERP API 的 `Authorization` 头;只在单次请求上下文临时持有,不长期存;**token 绝不进 prompt / LLM 可见文本**;基础设施凭证(Ollama/Milvus/DB 池)与用户凭证分离。 +**token 生命周期 = ERP web 会话(已查实 2026-07-21)**:xlyAi 转发的 `authorization` 就是 ERP 登录 token(前端逐请求传入 → `XlyErpService`/`session.setAuthorization` → 调 ERP 的 `Authorization` 头;xlyAi 自带的 `RedisTokenManager` 是**注释死代码**,不自造 token)。**长效、非一次性**,过期即 ERP 会话过期。⇒ (a) ERP API 返鉴权失败时,xlyAi 向对话框推**「登录过期」事件**(与网页一致);(b) **会话状态按稳定身份(userId+sBrandsId+sSubsidiaryId)+ conversationId 存,不按 token 存** → 重登录/换 token 后凭同一身份接回历史。**autonomy = 永远用户在场触发**(已定)→ 无需服务账号/委托令牌,链式续跑只在用户回到会话时发生,凭证模型最简。 + **⚠️ 授权:后端不是权限权威(2026-07-21 调查证实)** - ERP 后端 `getBusinessDataByFormcustomId` + **所有写/动作端点(add/update/delete/审核 doExamine)只验登录 `@Authorization`**;逐用户表单/菜单权限 `checkByUser` **被故意注释**(`// 朱总说不用放 20230626`)。 - 后端**只强制**:公司级租户隔离(`sBrandsId/sSubsidiaryId`)+ 行级 `jurisdiction` 数据范围。 @@ -177,14 +179,20 @@ ai_op_queue( **已定(2026-07-21)** - ✅ **写入需链式 → 必须跨会话状态**:写操作不是一次性。skill 可能"下单→据此生成入库",第二步依赖第一步**已执行**。⇒ 需 ERP 执行后**回调**通知 agent + **跨会话/长任务状态**(会话可在 ERP 执行完后 resume)。这超出单会话 ChatMemory,需要一个持久的「任务/流程实例」存储(Redis/DB)。 - ✅ **审计强制留痕**:金融类数据,记不可变审计(谁、何时、什么请求、什么 SQL、暂存/执行了什么)。审计独立于 Langfuse(LLM tracing ≠ 业务审计)。 +- ✅ **token = ERP web 长效 token(已查实)**;会话状态按 `userId+conversationId` 存(非 token),重登录接回;过期向对话框推「登录过期」。 +- ✅ **多条命名会话/用户**(会话列表侧栏;存储按 `conversationId` 分)。 +- ✅ **前端 = 保留 xlyAi 独立聊天页**(`/xlyAi/chat`,演进 `templates/chat.html` + `PageController`)。 +- ✅ **autonomy = 永远用户在场触发**(无服务账号/委托令牌;链式续跑在用户回到会话时发生)。 +- ✅ **模型 = 指定模型(云/本地皆可)**,不因出网特殊处理,走配置。 +- ✅ **部署 = 共库多品牌**(`xlyweberp_saas`,按列区分 `sBrandsId/sSubsidiaryId`)→ 租户隔离全局强制,KG/缓存/Query 一律按品牌切分。 +- ✅ **代码全面改造、写入 `master`**;改造前已完整备份(xlyAi `backup/pre-rearch-20260721`@`ac85337`;saas 后端 `backup/pre-rearch-20260721`@`382e97b`,快照含工作区,运行中的前后端未动)。 **开放** -1. **Query 越权锁法**:仅 `viw_*` vs 注入租户谓词 vs 复制 ERP 的表单/字段级 ACL —— **待现有 NL2SQL 安全调查结论后再定**(正在后台查:现状是否有租户过滤、是否会越级)。 -2. 部署形态:单品牌一实例 vs 多品牌共库(决定 KG/缓存/Query 是否按 `sBrandsId` 切分)。 -3. ERP 侧暂存执行器 + 预填 + 深链 + 执行回调归谁做、能否排期。 -4. 模型:qwen2.5:14b 多工具 tool-calling 可靠性(否则换模型 / 加 tool-call 参数校验兜底)。 -5. 多语言:仅中文 vs 支持 en/big5。 -6. 报价改双确认(失去即时提交)需业务确认。 -7. HITL `pendingInteraction` + 跨会话任务状态语义 + 前端事件协议,与前端团队对齐。 -8. KG 卡片召回:本地内存向量 vs 远端 Milvus 时机。 -9. 首个灰度只读场景选哪个。 +1. **Query 越权锁法**:仅 `viw_*` vs 注入租户谓词 vs 复制 ERP 表单级 ACL —— 待现有 NL2SQL 安全调查结论后定(倾向 A=`viw_*` + jsqlparser AST 注入租户)。 +2. **ERP 侧暂存执行器 + 预填 + 深链 + 执行回调** 归谁做、能否排期(写入阶段 P3 跨团队最大单点风险;**M1~M2 不依赖它**)。 +3. 模型多工具 tool-calling 可靠性 —— 跑起来实测,不行则换模型 / 加参数校验兜底(我自测)。 +4. 多语言:默认仅中文,预留可扩展。 +5. 报价改双确认(失去即时提交)需业务确认(写入阶段再定)。 +6. **formId 解析**:靠 KG 上下文让 LLM 推理 → 先搭框架、之后补 KgSearch;过渡期表单名模糊匹配 + 不唯一则 AskUser。 +7. 现网安全发现(后端表单权限被关 / NL2SQL 越权 / 读 API 可写)是否作为独立整改上报业务。 +8. 首个灰度只读场景选哪个(建议高频只读轻后果,如库存 / 应收账龄)。