feat(ai): add personal expense application memory
This commit is contained in:
@@ -135,6 +135,7 @@
|
||||
|
||||
- 用户可以查看“系统记住了什么、为什么记住、在哪里使用”,并支持修改、忘记和关闭个性化。
|
||||
- 企业管理员配置部门/企业记忆边界、有效期、敏感等级和自动化上限。
|
||||
- 首个个人记忆切片只在申请核对表展示“常用出行方式”来源、证据数量和可编辑状态,并提供“忘记此偏好”;不在本轮新建大型设置页,也不把风险画像当作个人偏好。
|
||||
|
||||
### 后端
|
||||
|
||||
@@ -158,6 +159,9 @@
|
||||
- `memory_evidence_links` 保留记忆与业务事件、决策、反馈、结果的来源关系。
|
||||
- 企业制度优先于部门基线,部门基线优先于个人偏好;冲突时返回解释。
|
||||
- 复用既有 AI 数据飞轮的 few-shot、golden case、Prompt 版本、Canary 和回归门禁。
|
||||
- 首个切片使用关系库精确键检索,只允许低敏枚举 `travel_application.transport_mode`;不复用当前缺少完整租户键的 FewShot/Qdrant 或员工风险画像存储个人记忆。
|
||||
- 记忆证据只从认证动作事务中的服务端核验纠正产生,关联 Decision、Feedback、Outcome 和 Expense Case;草稿、客户端观察、重复请求和同一 Case 多次修改不能重复计票。
|
||||
- 个人记忆只填充当前申请的空白软字段;当前明确输入、服务端 HR/组织主数据、企业制度和规则计算结果都优先于个人记忆。每次应用或抑制都返回可解释原因,不把优先级交给 Prompt 或 LLM 自行判断。
|
||||
|
||||
#### 节省与价值
|
||||
|
||||
@@ -186,9 +190,11 @@
|
||||
|
||||
#### 记忆激活
|
||||
|
||||
- 明确偏好可由用户确认后立即激活。
|
||||
- 隐式偏好必须达到最小一致证据数,并通过时间衰减、敏感性、企业规则冲突和异常值检查。
|
||||
- 错误标注、违规习惯和一次性例外不能直接变为默认记忆。
|
||||
- 明确偏好后续可由用户认证确认后立即激活;首个切片只实现隐式候选,不把普通字段编辑冒充明确授权。
|
||||
- 隐式出行方式偏好需要同租户、同员工、同场景和同归一化值的 3 个不同 Expense Case 服务端核验纠正,其中至少 2 个出现 `application_approved`,且首尾证据至少跨 7 天;同一 Case、重试、草稿续签只计一票。
|
||||
- `accepted`、`client_observed`、`draft_saved` 和单纯 `application_submitted` 只能作为观察信息,不能单独激活;退回、反向纠正、结果 reversed 或制度冲突会抑制现有记忆。
|
||||
- Candidate 默认 90 天有效,Active 默认 180 天;状态支持 `candidate / active / suppressed / expired / revoked`。相反值先抑制旧记忆并建立新候选,不原地覆盖;用户“忘记”后立即 revoked,清除可恢复值且不可自动复活。
|
||||
- 错误标注、违规习惯、一次性例外、自由文本和敏感字段不能直接变为默认记忆。
|
||||
|
||||
#### 风险与预审
|
||||
|
||||
@@ -213,7 +219,8 @@
|
||||
- `ai_decisions`:结构化 AI 建议与版本证据。
|
||||
- `ai_decision_feedback`:接受、修改、拒绝和忽略。
|
||||
- `workflow_outcomes`:退回、补件、审批、付款、审计和最终结果。
|
||||
- `memory_entries` / `memory_evidence_links`:分层记忆和来源。
|
||||
- `memory_entries`:按租户、作用域主体、场景、字段和值指纹保存候选/激活/抑制/过期/撤销状态,只允许白名单低敏值可恢复。
|
||||
- `memory_evidence_links`:把记忆与服务端 Decision、Feedback、Outcome、Expense Case 和业务结果关联;唯一键保证同一 Case 对同一候选最多计一票。
|
||||
- `automation_policies` / `automation_grants`:动作级自动化策略和授权。
|
||||
- `profile_baseline_snapshots`:持久化员工、部门、供应商、费用和流程基线。
|
||||
- `savings_opportunities` / `savings_realizations`:节省机会和实现结果。
|
||||
@@ -274,6 +281,8 @@
|
||||
- P0 数据契约即引入最小 `tenant_id`、数据库约束、行级过滤、向量库命名空间和对象存储前缀隔离;删除传播、数据导出和私有部署加固可在商业化阶段继续完善。
|
||||
- Expense Case 用户态查询只返回流程摘要:Case 基础状态、关系类型、事件类型、操作人、发生时间及白名单业务载荷;不返回关联资源 ID、幂等键、correlation、causation、聚合标识或 Outbox 投递状态。有权查看入口单据的本人、当前审批人、财务和管理员可查看整 Case 的安全摘要,无权限与跨租户查询继续以 404 隐藏资源存在性。
|
||||
- 申请预览签发与消费同时绑定 `tenant_id`、actor、Bearer 登录会话和会话 ID;动作入口按这些服务端事实锁行校验,不能只凭随机 UUID 授权。浏览器提供的模型来源、`finalValue`、用户和角色声明均不作为可信事实。
|
||||
- 个人记忆主体优先使用服务端 `employee_id`,缺失时才使用规范化用户名;所有唯一键、读取、证据外键和忘记动作都必须以 `tenant_id` 开头。同邮箱或同员工号在不同租户形成完全独立的记忆。
|
||||
- 记忆值采用 deny-by-default 白名单;首个切片仅保存规范枚举“飞机/火车/轮船”。事由、地点、日期、金额、客户/项目自由文本、附件、银行卡、收款人与支付账户均不得进入记忆明文、Prompt、向量 payload 或日志。
|
||||
- 外部 `/orchestrator/run` 的用户消息、定时任务和系统事件都必须携带有效登录会话,不能由请求体中的 `source` 自行声明可信内部来源;其中 `schedule` / `system_event` 只允许平台管理员触发。服务端使用登录态覆盖用户、租户、角色、管理员、员工、审批人和调度操作人别名,并移除客户端 preview/decision 状态。最近会话查询与删除只使用当前登录用户和租户,查询参数中的 `user_id` 仅保留协议兼容,不参与授权。
|
||||
- 预览与学习账本中的字段值使用独立、可版本化的费用申请密钥计算 HMAC-SHA256 指纹,密钥目录和文件权限分别为 `0700`、`0600`;核验旧决策必须使用其签发版本,缺失版本直接拒绝,不静默生成替代密钥。字段指纹同时编码“字段是否存在”,避免新增或删除字段被误判为采纳;训练资格仍保持关闭,直至审批、付款或人工核验闭环完成。
|
||||
- 自动化权限按动作、金额、场景、风险和有效期授予,不使用全局“允许 Agent 自动执行”开关。
|
||||
@@ -286,7 +295,8 @@
|
||||
- Qdrant/few-shot 不可用:使用 stable Prompt 和基础规则,不阻塞主流程。
|
||||
- 外部支付/ERP/税务连接器不可用:事件进入 retryable 状态,保留人工处理入口和幂等键。
|
||||
- 记忆冲突或可信度不足:只展示建议,不自动应用。
|
||||
- 预览签发超时或不可用:仍展示本地预览并允许编辑、保存和提交,内部标记为降级;此时只记录 `client_observed` 行为证据,不升级为服务端核验或训练样本。
|
||||
- 结构化预览签发超时或不可用:允许继续编辑和重新签发,但保存、提交保持 fail-closed;只有不存在结构化预览的历史兼容入口保留原有降级路径,且只能记录 `client_observed` 行为证据。
|
||||
- 记忆服务不可用、过期或校验失败:回退为“无个人记忆 + 当前规则”,不阻塞预览,也不读取跨租户、旧缓存或无租户向量样本。
|
||||
- Savings 证据不足:保留机会状态,不进入已实现节省。
|
||||
|
||||
## 算法与公式
|
||||
@@ -411,6 +421,7 @@ customer_contribution_margin
|
||||
- 一句话申请 → 票据归集 → 自动报销 → 预审 → 审批 → 付款事件 → 入账 → 归档端到端。
|
||||
- 持久开发库只读流式克隆 → Alembic 升级 → 历史回填 dry-run/apply/重复 apply → 服务端登录 → 旧单时间线查询 → 持久库不变验证。
|
||||
- AI 建议 → 用户修改 → 退回/通过 → 记忆候选 → 下次建议变化闭环。
|
||||
- 常用出行方式 1/2 次纠正保持候选,第 3 个不同 Case 且至少 2 次审批通过、跨 7 天后激活;当前输入覆盖、跨租户拒绝、忘记后不再预填。
|
||||
- 风险命中 → 人工确认/误报 → few-shot → 新版本回放 → Canary/回滚闭环。
|
||||
- 节省机会 → 负责人执行 → 实际结果 → 财务确认 → ROI 看板闭环。
|
||||
- 多租户同名员工、同号单据、向量检索和对象存储隔离测试。
|
||||
@@ -464,6 +475,8 @@ docker exec -w /app -e SERVER_VENV_DIR=/tmp/x-financial-server-venv \
|
||||
- Agent 会话租户边界:Orchestrator 与 Steward 动作运行时都把可信 `tenant_id` 写入会话状态;创建、恢复、幂等检查点重放、单条删除和批量删除同时校验租户与用户名,同名用户不能跨租户复用 decision 或动作结果。历史无租户状态的会话在认证入口 fail-closed,不会被恢复或删除。`agent_conversations` 仍缺少独立 `tenant_id` 列和数据库复合约束,后续迁移需要把当前应用层守卫下沉为结构化租户键。
|
||||
- 费用事件读取边界:用户态精简 DTO 和首批 HTTP 权限测试已完成;剩余风险是同一 URL 若已有外部客户端依赖旧内部字段会产生契约变更,且未来新增敏感 payload 字段必须继续显式进入白名单,不能恢复任意字典透传。
|
||||
- 反馈投毒:一次点击或违规习惯不能直接成为记忆,需要候选态、最小样本、制度约束和结果权重。
|
||||
- 记忆值恢复:现有学习账本只保存 HMAC 指纹,无法恢复具体偏好值;必须由独立记忆表在认证事务中只提取白名单枚举,不能为了复用把自由文本重新塞回账本。
|
||||
- 记忆与制度冲突:首个切片的三种交通方式当前均只有估价和舱等规则,没有“禁止某种交通方式”的制度维度;后续一旦增加按职级、路线或金额禁用交通方式的规则,必须先提供服务端允许性判定、抑制原因和回归用例,再允许个人记忆参与预填。
|
||||
- 自动化失控:高准确率不代表高风险动作可以无人值守,必须按动作授权并支持 shadow、Canary、抽检和回滚。
|
||||
- 虚假节省:风险暴露金额、暂缓付款和工时估算容易被夸大,必须由客户财务确认并执行去重。
|
||||
- 外部依赖:税务、支付、银行、商旅、ERP 和消息平台连接器存在可用性、资质和交付周期风险。
|
||||
@@ -538,3 +551,8 @@ docker exec -w /app -e SERVER_VENV_DIR=/tmp/x-financial-server-venv \
|
||||
- 2026-07-14(decision 生命周期加固):同一租户、用户、登录会话、conversation 和 HMAC 快照即使使用不同签发 request ID,也复用当前 active decision,避免多个并行 decision 命中草稿幂等捷径后遗留未消费状态。动作发现 decision 过期、已消费或不可用时,前端清空旧 ID、生成新的签发 request ID 并开放重新签发。
|
||||
- 2026-07-14(跨租户检查点加固):Steward 动作会话创建显式写入服务端租户;租户 A/B 即使使用相同用户名、conversation 和 trace,也会获得独立会话与 decision,不再跨租户返回幂等结果或敏感预览内容。
|
||||
- 2026-07-14(统一闭环验证):容器内服务端预览、Steward 动作/图运行、Orchestrator 外部来源授权及决策消费组合回归 50 项通过,Python Ruff F/I 通过;前端结构化动作、会话恢复、工作台路由、富确认和动作脚本共 18 项通过,Vite 生产构建通过。并行读取用户正在变动的规则工作簿曾触发 `openpyxl` ZIP 句柄竞争,相关套件改为串行后全部通过,未修改规则工作簿。
|
||||
- 2026-07-14(个人出行方式记忆):新增租户化 `memory_entries` 与 `memory_evidence_links`,首个切片只存储 `travel_application.transport_mode` 的“飞机/火车/轮船”。同一租户、员工、场景和值需要 3 个不同 Expense Case 的服务端核验纠正、至少 2 个当前审批通过且证据跨 7 天才激活;Candidate/Active 默认有效期分别为 90/180 天。
|
||||
- 2026-07-14(证据信任边界):记忆证据严格绑定当前 tenant、actor、employee、Case owner 和 Claim owner,并要求 Decision、Feedback、Outcome 指向同一申请、同一 Case 和同一个真实 `application_submitted` 业务事件;事件聚合必须是对应 `expense_claim`。同 Case 重放、invalidated/reversed 事实、最新退回、反向纠正和非白名单纠正不会继续支持 active 记忆。
|
||||
- 2026-07-14(应用、抑制与遗忘):个人记忆只补空白出行方式,任何当前显式值都优先。命中后服务端重新计算交通与总额估算再签发 canonical decision;记忆异常降级为无记忆,不阻塞预览。反向或非白名单纠正抑制 active,用户忘记后状态改为 revoked、清空可恢复值和指纹,旧请求不可复活。
|
||||
- 2026-07-14(前端记忆解释):申请核对表新增独立 `TravelReimbursementMemoryPanel`,展示已应用的常用出行方式、证据数量、学习回执和“忘记此偏好”入口;本地会话快照支持跨刷新恢复,忘记偏好不会篡改当前申请字段。
|
||||
- 2026-07-14(个人记忆验证):容器内个人记忆专项 16 项、记忆/预览决策/迁移/所有权组合回归 56 项通过且 1 项条件跳过、前端申请与记忆组合 83 项通过;一次性 PostgreSQL 迁移循环、Ruff、Vite 生产构建和 `git diff --check` 均通过。当前规则中心尚不存在交通方式禁用维度,制度冲突守卫作为后续规则扩展的前置门禁保留,不以恒真占位判断冒充已实现。
|
||||
|
||||
@@ -41,7 +41,8 @@
|
||||
证据:`ai_learning.py`、`expense_application_learning.py`、`20260714_0003_ai_learning_loop.py`;三类事实分别表达 AI 建议、用户采纳/显式字段纠正和业务结果,技术执行成功、用户反馈与工作流结果不复用同一状态。
|
||||
- [x] [CONCEPT: 业务事件与 AI 决策] 定义落单前服务端预览决策的签发、授权、过期、一次消费、重放和续签契约。
|
||||
证据:`ai_application_preview.py`、`expense_application_preview_decisions.py`、`expense_application_snapshot.py`;预览不创建空 Case,绑定租户、actor、登录会话与 conversation,30 分钟过期,保存/提交成功后一次消费;保存草稿在业务提交后尽力返回基于服务端事实的新 `decision_id`,续签失败不反转已成功动作。
|
||||
- [ ] [CONCEPT: 记忆与学习] 定义 `memory_entries`、证据链接、优先级、有效期、敏感等级、撤销和遗忘契约。
|
||||
- [x] [CONCEPT: 记忆与学习] 定义并实现 `memory_entries`、`memory_evidence_links`、优先级、有效期、敏感白名单、撤销和遗忘契约;首个切片仅覆盖 `travel_application.transport_mode`。
|
||||
证据:`ai_memory.py`、`expense_application_memory.py`、`expense_application_memory_evidence.py`、`20260714_0005_ai_memory.py`;记忆使用租户、主体、场景、字段和值指纹精确隔离,值只允许“飞机/火车/轮船”,服务异常降级为不应用记忆。
|
||||
- [ ] [CONCEPT: 自动化决策] 定义动作风险、金额阈值、置信度、证据完整度、可逆性、抽检率和企业授权策略。
|
||||
- [ ] [CONCEPT: 节省与价值] 定义 Savings Ledger 的机会、执行、实现、确认、去重和归因状态。
|
||||
- [ ] [CONCEPT: 连接器] 定义票据邮箱、税务、企业卡、商旅、支付、银行、ERP、消息和 SSO 连接器协议。
|
||||
@@ -115,8 +116,18 @@
|
||||
- [ ] [CONCEPT: 自动化决策] 实现 L0-L5 动作级自动化等级和资格计算器。
|
||||
- [ ] [CONCEPT: 自动化决策] 为每个动作实现硬白名单、金额上限、证据要求、抽检率和企业上限。
|
||||
- [ ] [CONCEPT: 风险与预审] 统一风险输出为事实、规则、证据、判断、建议动作和降级原因。
|
||||
- [ ] [CONCEPT: 记忆激活] 实现 candidate/active/suppressed/expired/revoked 记忆状态机。
|
||||
- [x] [CONCEPT: 记忆激活] 为首个个人出行方式切片实现 candidate/active/suppressed/expired/revoked 记忆状态机。
|
||||
证据:Candidate/Active 默认有效期分别为 90/180 天;反向或非白名单纠正抑制已激活记忆,过期后新证据创建新 generation,忘记后清值并阻止旧请求复活。
|
||||
- [ ] [CONCEPT: 记忆激活] 实现用户、部门、企业记忆优先级、冲突解释、时间衰减和最小样本要求。
|
||||
- [x] [CONCEPT: 记忆与学习] 新增租户化个人记忆与证据链接迁移,唯一键保证同一 Expense Case 对同一候选最多计一票。
|
||||
证据:记忆、证据、Decision、Feedback、Outcome、Expense Case 和 Claim 采用租户复合外键;证据同时校验 actor、员工和 Case/单据 owner,跨租户或跨主体关系不能计票。
|
||||
- [x] [CONCEPT: 记忆激活] 为常用出行方式实现隐式激活门槛:3 个不同 Case 的一致服务端纠正、至少 2 次审批通过、证据跨 7 天;草稿、client_observed、accepted 和重试不激活。
|
||||
证据:只有当前有效的 `server_verified` 编辑、`application_submitted` 结果和最新审批状态参与计算;提交事件还必须绑定对应 `expense_claim` 与 Claim ID,invalidated/reversed 事实、同 Case 重放和旧请求均被排除。
|
||||
- [x] [CONCEPT: 记忆与学习] 在服务端申请预览签发前只为空白出行方式应用 active 个人记忆,并返回 memory id、证据数与来源;当前输入、主数据和企业规则优先。
|
||||
证据:`expense_application_preview_workflow.py` 应用记忆后重新执行规则测算和签名;仅缺出行方式时前端仍请求服务端,命中记忆后可直接生成完整核对表。
|
||||
- [x] [CONCEPT: AI 记忆与自动化设置] 提供当前用户记忆查询与“忘记此偏好”接口;撤销后清除可恢复值并在后续预览中不再应用。
|
||||
证据:`GET /api/v1/expense-application-memories/me` 与 `DELETE /api/v1/expense-application-memories/{id}` 均绑定当前租户和主体,越权以 404 隐藏资源存在性。
|
||||
- [ ] [CONCEPT: 记忆与学习] 当规则中心新增按职级、路线或金额禁用交通方式的制度维度时,在个人记忆应用前接入显式允许性判定、冲突抑制原因和回归测试。
|
||||
- [x] [CONCEPT: 记忆与学习] 为 AI 申请预填记录用户原样采纳、显式字段修改和草稿/提交结果证据。
|
||||
证据:`expenseApplicationDecisionFeedback.js`、`useApplicationPreviewEditor.js`、`expense_application_learning.py`、`expense_application_preview_decisions.py`;改回原建议会清除字段差异,日期联动同步记录天数,最终值由服务端 facts 重建。旧预览保持 `client_observed`;服务端签发预览由版本化 HMAC 快照与最终 facts 逐字段比对,字段新增、删除或改值都标记为 `server_verified` 编辑。两者均保持 `training_eligible=false`,尚不直接训练模型或激活记忆。
|
||||
- [x] [CONCEPT: 记忆与学习] 将小财管家、Steward 与通用 Orchestrator 的申请预览切换到认证签发与消费链路,并把结构化预览失败策略收口为 fail-closed。
|
||||
@@ -134,6 +145,8 @@
|
||||
- [ ] [CONCEPT: 审批例外工作台] 补齐批量审批、委托、转交、加签、会签和超时升级交互。
|
||||
- [ ] [CONCEPT: 审批例外工作台] 接入真实企微/钉钉/邮件触达和处理结果回写。
|
||||
- [ ] [CONCEPT: AI 记忆与自动化设置] 新增“我的 AI 记忆”,支持来源解释、修改、忘记和关闭个性化。
|
||||
- [x] [CONCEPT: AI 记忆与自动化设置] 在申请核对表展示常用出行方式的记忆来源、证据数量和“忘记此偏好”,并在保存/提交后区分候选记录与已应用回执。
|
||||
证据:`TravelReimbursementMemoryPanel.vue` 与独立样式分片承载记忆解释、学习回执和可访问的忘记入口;会话快照可跨刷新恢复已应用记忆。
|
||||
- [ ] [CONCEPT: AI 记忆与自动化设置] 新增企业记忆、保留策略、敏感等级和自动化上限管理。
|
||||
- [ ] [CONCEPT: 前端] 展示自动化动作、执行依据、撤销入口、抽检状态和版本信息。
|
||||
|
||||
@@ -176,7 +189,8 @@
|
||||
证据:`test_alembic_migrations.py` 默认无显式 URL 时跳过,主机和库名必须带 disposable 标记;tmpfs PostgreSQL 17 中 4 项通过,覆盖空库升级、重复升级、关键约束/索引、外键级联、base 降级、legacy 哨兵保留、漂移拒绝和再次升级;持久化开发库未被修改。完整 legacy baseline 仍保留在上一条未完成项中。
|
||||
- [ ] [CONCEPT: 测试方案] 为连接器幂等、重试、回执、失败恢复、重复付款和对账补充测试。
|
||||
- [ ] [CONCEPT: 测试方案] 跑通申请 → 票据 → 报销 → 预审 → 审批 → 付款 → 入账 → 归档端到端。
|
||||
- [ ] [CONCEPT: 测试方案] 跑通 AI 建议 → 用户修改 → 工作流结果 → 记忆激活 → 下次建议变化闭环。
|
||||
- [x] [CONCEPT: 测试方案] 跑通首个个人出行方式切片的 AI 建议 → 用户修改 → 工作流结果 → 记忆激活 → 下次建议变化闭环。
|
||||
证据:容器内记忆、预览决策、迁移与所有权组合回归 56 项通过、1 项条件跳过;一次性 PostgreSQL 迁移循环 1 项通过;前端申请快速预览、个人记忆、Steward 与会话恢复组合 83 项通过,Vite 生产构建通过,Python Ruff F/I 与 `git diff --check` 通过。
|
||||
- [x] [CONCEPT: 测试方案] 跑通首个行为采集切片:AI 申请预填 → 用户接受/显式修改 → 草稿或提交结果同事务落账。
|
||||
证据:`test_user_agent_application_draft_events.py`、`test_reimbursement_endpoints.py`、`expense-application-decision-feedback.test.mjs`、`expense-application-fast-preview.test.mjs`;覆盖可信入口、模板/详情排除、隐私指纹、同事务事件关联、日期联动及异步乱序响应。容器内学习账本与迁移所有权定向 29 项、一次性 PostgreSQL 迁移 4 项和前端关键场景 5 项通过。
|
||||
- [ ] [CONCEPT: 测试方案] 跑通风险反馈 → few-shot → golden case → Canary → 回滚闭环。
|
||||
|
||||
Reference in New Issue
Block a user