167 Commits

Author SHA1 Message Date
caoxiaozhu
7ced9d93bc chore(rules): 更新公司通信费报销规则表 2026-06-30 11:41:09 +08:00
caoxiaozhu
876cf342ac docs(dev-log): 记录多 task task2 时序缺陷 bug 修复 2026-06-30 11:40:46 +08:00
caoxiaozhu
43779f8f2c fix(web): 多 task 串行推进 task2 不再被预览生成时提前触发
onPreviewReadyForNextTask 在 task1 申请核对表刚生成、用户还没操作时就
提前拉起 task2,与用户后续在 task1 上的保存草稿/提交操作互相打架,导致
task2 完全无反应。移除该提前推进回调,统一由 onApplicationActionCompleted
在 task1 真正完成后再推进 task2。

- useWorkbenchAiApplicationPreviewFlow: 删除预览生成时的提前推进分支
- usePersonalWorkbenchAiMode: startModelPlannedApplicationPreview 不再传 onPreviewReadyForNextTask
- useWorkbenchAiActionRouter: 低置信确认按钮分支同步删除该回调
- 新增时序回归测试:预览生成不提前推进、保存草稿后才推进
- 更新两处源码正则断言为 doesNotMatch
2026-06-30 11:40:31 +08:00
caoxiaozhu
08f023243e fix(web): 多 task 草稿自动保存后继续推进下一 task
useWorkbenchAiApplicationPreviewFlow 在自动保存草稿分支透传 onApplicationActionCompleted,
确保草稿/提交完成后仍能按 remaining tasks 推进,修复多 task 报销场景后续步骤不启动。
更新 application-context-submit/intent-planner-model 测试,补充 bug 日志与开发日志。
2026-06-29 20:17:36 +08:00
caoxiaozhu
6bdaeed6d4 chore: 忽略 .zcode 本地目录并更新规则表与开发日志
- .gitignore 新增 .zcode/(ZCode 工具本地配置,不入库)
- 更新交通/通信/差旅等财务规则表
- 补充 2026-06-25/26 开发日志(chat UI SaaS 化、主题企业 AI 风格、bug 日志)
2026-06-26 22:42:46 +08:00
caoxiaozhu
d5a8f84703 refactor(web): 应用外壳/差旅详情/报销创建视图适配主题与多 task
- AppShellRouteView/useAppShell 适配主题皮肤与会话入口
- TravelRequestDetailView/travelRequestDetailSetup 差旅详情适配,travel-request-detail-view.css 调整
- TravelReimbursementCreateView/useTravelReimbursementCreateViewLifecycle 创建视图适配
- 更新 app-shell-financial-assistant-entry/travel-request-detail-risk-advice 测试
2026-06-26 22:42:29 +08:00
caoxiaozhu
c4b5fcc067 feat(web): AI 工作台多 task 串行推进与会话适配
- useWorkbenchAiApplicationPreviewFlow/useWorkbenchAiActionRouter/useWorkbenchAiCommandIntents 支持 task1 完成后自动推进 task2,确认按钮直接拉起申请预览,草稿/提交成功后继续推进下一 task
- workbenchAiIntentPlannerModel/workbenchAiMessageModel/workbenchAiCommandIntentModel 适配多 task 意图规划与消息结构
- aiApplicationPreviewActions/aiApplicationPrecheckModel/aiExpenseDraftModel/aiWorkbenchConversationStore 草稿与会话存储适配
- PersonalWorkbenchAiMode 与样式适配,更新 preview-actions/expense-draft/conversation-store/fast-preview/action-router/command-intent/intent-planner 测试
2026-06-26 22:42:23 +08:00
caoxiaozhu
5753899eb3 feat(web): 主题皮肤系统与 LLM 设置面板重构
- useThemeSkin 重构主题皮肤应用逻辑,支持企业 AI 风格主题切换
- settingsModelHelper 新增主题与模型表字段映射,useSettings 适配
- LlmSettingsPanel/SettingsView 面板重构,支持多模型行编辑与主题区块
- settings-view.css 适配主题样式,新增 settings-theme-section 测试,更新 settings-llm-section 测试
2026-06-26 22:42:00 +08:00
caoxiaozhu
9c3fa80d22 feat(server): 设置持久化新增 LLM 模型表与主题字段
- SettingsLlmForm 新增 models 列表(SettingsModelRow:slot/provider/url/apiKey/modelId/type),支持多模型行持久化
- settings 服务读写模型表与主题相关字段,更新 test_settings_persistence 测试
2026-06-26 22:41:40 +08:00
caoxiaozhu
43c3ff860c fix(web): steward plan 确认按钮直接拉起申请预览,不丢失 remaining tasks
根因:steward plan 的'确认创建申请单'按钮 action_type 是
ASSISTANT_SCOPE_ACTION_SWITCH,handleInlineSuggestedAction 没有匹配分支,
落到 startInlineConversation 重新发起对话,steward_remaining_tasks 完全丢失。

修复:当 payload 有 steward_current_task + session_type=application +
task_type=expense_application 时,直接调 startAiApplicationPreviewFromAction
(会透传 steward_remaining_tasks 到申请预览 message),不走 startInlineConversation。

这样保存草稿成功后,targetMessage 上有 stewardRemainingTasks,
buildApplicationPreviewNextTaskAction 能生成'继续处理费用报销'按钮。
2026-06-26 11:40:44 +08:00
caoxiaozhu
3e4b1e1597 fix(web): 保存草稿/提交成功后也推进到下一个 task
之前多 task 串行推进只在 steward action 执行链(executeInlineStewardAction)
生效,但保存草稿走的是 application preview 流(executeInlineApplicationPreviewAction),
成功后只显示'查看单据',不会提示继续下一个报销 task。

- startAiApplicationPreviewFromAction 透传 steward_remaining_tasks 到 preview message
- startAiApplicationPreview 把 stewardRemainingTasks 存到 message 上
- executeInlineApplicationPreviewAction 成功后:检查 targetMessage.stewardRemainingTasks,
  有剩余 task 则追加'继续处理费用报销'按钮(复用 steward_confirm_flow 分支)
- 新增 buildApplicationPreviewNextTaskAction 辅助函数

现在保存草稿/提交申请成功后,用户会看到:[查看单据] [继续处理费用报销]
2026-06-26 11:21:16 +08:00
caoxiaozhu
3a5664c4da feat(web): 多 task 串行推进 - task1 完成后自动展示 task2 确认按钮
场景:'出差并且报销招待费'→LLM 拆出 2 个 task→先做完出差申请→
完成后自动展示'继续处理费用报销'按钮→用户确认后推进到报销流程。

- 新增 buildNextTaskSuggestedAction:从 actionPayload.steward_remaining_tasks
  取第一个剩余 task,根据 task_type 生成推进按钮(steward_confirm_flow)
- executeInlineStewardAction 成功后:除'查看单据'外,追加'继续处理下一个 task'按钮
- 用户点击推进按钮复用 handleInlineSuggestedAction 的 steward_confirm_flow 分支
- 前端 28 passed 无回归
2026-06-26 10:51:43 +08:00
caoxiaozhu
d139a63e64 refactor(server): 意图识别改 LLM 驱动,规则只做闲聊拦截+resume 兜底
规则不再判断'这是哪个业务场景'——那交给 LLM function call。
规则只保留两个不可替代职责:闲聊拦截(省 LLM 成本)、resume 确定性兜底。

- gate_classify 简化:删掉规则匹配门(94 词 CHOICE 匹配)和 ambiguous 提前判断
- 新增 _is_lightweight_off_topic:只拦 greeting+meaningless,不依赖业务关键词
- HANDLER_ONLY 改为 LLM 输出驱动:LLM 返回 query_travel_standard 后转 handler
- 图拓扑简化:gate_classify 只输出 off_topic|resume|model_intent
- 验证:76 passed;复合场景'出差并且报销招待费'→LLM 返回 2 task
2026-06-26 10:19:04 +08:00
caoxiaozhu
8a2ae6eb75 fix(server): gate_classify 复用 _classify_irrelevant_input 修复 off_topic 误杀
回归问题:P1.3 重构时 gate_classify 的 off_topic 门用了 scene_registry
的 35 个 signal_keywords,丢掉了 legacy 的 73 个关键词(城市名/时间词/金额词/
交通词等),导致'下周去上海''昨天打车30块'等正常业务输入被误判 off_topic,
根本进不了 LLM。

修复:gate_classify 的 off_topic 门改用成熟的 _classify_irrelevant_input
(94 词 + registry 信号词 + greeting/meaningless 细分),scene_registry 的
signal_keywords 只用于规则匹配门(CHOICE 路由)。删除残缺的 _matches_any_signal。

验证:76 passed;实测'下周去上海'→llm_function_call、'昨天打车30块'→
llm_function_call、'你好'→off_topic(正确拦截)。
2026-06-25 16:06:52 +08:00
caoxiaozhu
992cf71fa1 refactor(server): Phase 1 图拓扑重构 - LangGraph 成为唯一编排者
P1.3-P1.7:把 endpoint 补丁搬进图节点,门控收敛到 gate_classify 单一决策点。

- StewardGraphState 扩展:recent_history/steward_state/gate_decision/gate_scene_id/conversation_id
- 新增 5 个图节点:load_context(读历史+state)/gate_classify(统一门控)/execute_scene_handler/resume_recent_task/pending_flow wrapper
- 图拓扑从 5 节点重构为 10 节点:load_context → gate_classify → {off_topic/handler_only/resume/ambiguous/model_intent} → attach_action_steps
- gate_classify 四步裁决:resume门 → off_topic门 → 规则匹配门 → LLM门
- resume 门控优先于 off_topic,避免'再提交'被误判闲聊
- schema 放宽 planning_source/next_action Literal → str,支持 scene_handler:*/context_resume/answer_only
- endpoint 按 planner 类型分发 build_plan(LangGraph 接 db,legacy 不接)
- 76 passed + 4 场景端到端验证(出差申请/再提交/查差旅标准/闲聊)
2026-06-25 15:44:20 +08:00
caoxiaozhu
54356ba81a refactor(server): scene 注册表骨架 + 统一门控管道设计文档
Phase 1 P1.1-P1.2:为后端门控收口提供声明式场景注册基础设施。

- 新建 scenes/ 目录:gate_rules(GateRule/SceneRoute 枚举)、scene_descriptor(SceneDescriptor dataclass)、scene_registry(SceneRegistry 单例)
- 3 个场景迁入 descriptor:expense_application / reimbursement / query_travel_standard
- __init__.py 的 bootstrap_scenes 在 import 时注册 + 运行时绑定 handler/builder/executor(解决循环 import)
- 查询场景 priority=50 优先于 MODEL_ONLY 场景,确保规则匹配先于 LLM
- 落地 UNIFIED_GATE_PIPELINE.md 架构文档:目标架构 / 验收标准(接入 O(1))/ 3 阶段迁移路径
- 76 passed,scene 注册表未破坏现有代码;与 intent_registry 暂时并存,P1.3-P1.8 会统一迁移
2026-06-25 15:09:16 +08:00
caoxiaozhu
e9d7c56d5b feat(server): 会话上下文保留(LLM 历史 + 确定性兜底双保险)
解决用户删除草稿后说'再提交'丢失上下文的问题:

- steward.py 新增 _inject_recent_conversation_history:build_plan 前读最近 10 条对话注入 context_json
- steward_intent_agent.py 的 _build_messages 把 recent_history 暴露给模型,system prompt 加确认类话术引导
- 新建 steward_context_resume.py:should_resume_recent_task 检测'再提交'类话术 + state 有可恢复 flow,attach_resumed_task 从 state 恢复 task
- 两个 plan 入口(/plans 和 /plans/stream)都已接入双保险
- 后端 67 passed,端到端验证'上海出差→再提交'成功恢复 task
2026-06-25 15:08:56 +08:00
caoxiaozhu
2ebc2756bf fix(server): 兼容模型 tasks 输出为 JSON 字符串与 flow_id 误填
- StewardModelPlanBuilder 解析 tasks 时兼容模型把数组序列化为字符串的情况,先反序列化;JSON 截断/语法不完整时用正则抢救 task_type/requested_action/ontology_fields 等关键字段
- task_type 未命中意图时尝试 flow_id→task_type 映射还原,避免模型把 flow_id(如 travel_application)误填为 task_type 导致正确意图被丢弃
2026-06-25 12:25:18 +08:00
caoxiaozhu
606a88c805 chore: stewardPlanModel 适配注册表动作结构并更新规则表与日志
- stewardPlanModel 适配新的意图注册表动作步骤结构
- 更新交通/通信/差旅等财务规则表,补 2026-06-25 work-log
2026-06-25 11:50:11 +08:00
caoxiaozhu
eaada4bc57 refactor(server): steward 意图改用声明式注册表编排
- 新增 steward_intent_registry,IntentDescriptor 统一描述意图的识别关键词、动作步骤构建、字段白名单与副作用集合,替代分散的 if/else
- 新增 steward_intent_bootstrap 注册 expense_application 等意图;新增 steward_query_executors 提供差旅标准查询的无副作用执行与城市/席别标签化输出
- action_contracts/action_executor/graph_planner/intent_agent/model_plan_builder/planner_extraction/fallback 适配注册表,识别与执行分发自动从注册表取数
- 新增 intent_registry/query_executors 测试,更新 intent_agent 测试
2026-06-25 11:50:02 +08:00
caoxiaozhu
d321005044 chore: 更新公司通信费规则表与 AI 意图规划/work-log 文档 2026-06-25 10:56:00 +08:00
caoxiaozhu
59353308a2 feat(web): AI 意图规划置信度阈值与动作策略细化
- workbenchAiIntentPlannerModel 新增 WORKBENCH_AI_INTENT_CONFIDENCE_THRESHOLD 与 isLowConfidenceTravelApplicationPlan,shouldRequestWorkbenchAiIntentPlan 增加业务关键词前置过滤
- resolveExecutableTravelApplicationPlan 区分 requestedSubmit 与提交确认(submitRequiresConfirmation),autoSubmit 不再直接置真
- workbenchIntentActionPolicy 改用 policyDecision 路由(need_confirmation/query_candidates),透传 riskLevel/requiresSelection/requiresConfirmation
- workbenchIntentFrameModel 补充 query 动作识别,usePersonalWorkbenchAiMode/useWorkbenchAiActionRouter/useWorkbenchAiApplicationPreviewFlow 接入低置信度与确认流程
- 更新 intent-planner-model/intent-frame-model/application-gate-model/fast-preview 测试
2026-06-25 10:55:49 +08:00
caoxiaozhu
6b0756a55f chore(logs): split agent change log outputs 2026-06-25 09:35:18 +08:00
caoxiaozhu
4d8a606cd6 chore(skills): date-scope development docs 2026-06-25 09:25:28 +08:00
caoxiaozhu
23f7de6cbf chore(skills): add development docs writer 2026-06-25 09:19:37 +08:00
caoxiaozhu
a12c4bea64 chore: 更新公司通信费规则表、work-log 与 superpowers specs 文档 2026-06-24 22:59:10 +08:00
caoxiaozhu
e5b03c6601 feat(web): 文档查询意图补充风险过滤与 X 天前范围
- aiDocumentQueryIntent 新增风险等级过滤(无/高/中/低/有风险)与 N 天前日期范围解析
- aiDocumentQueryModel/aiConversationHtmlRenderer 渲染适配风险过滤标签
- useWorkbenchAiDocumentQueryFlow/aiWorkbenchConversationStore 会话流转适配命令意图
- 更新 ai-document-query-model/ai-conversation-html-renderer/assistant-session-draft-delete 测试
2026-06-24 22:59:05 +08:00
caoxiaozhu
3eb78d343a feat(web): AI 工作台命令意图解析与动作策略
- 新增 workbenchIntentFrameModel,解析删除/审批/查询/咨询政策等意图帧,含风险等级、目标模式(当前上下文/筛选候选)与日期归一化
- 新增 workbenchIntentActionPolicy,按意图帧路由下一步(直通/拦截批量/上下文确认/查询候选)
- 新增 workbenchAiCommandIntentModel 与 useWorkbenchAiCommandIntents,识别草稿删除意图并解析最近草稿载荷生成引导
- usePersonalWorkbenchAiMode 接入命令意图处理,personal-workbench-ai-mode.css 适配
- 新增 command-intent-model/intent-frame-model 测试
2026-06-24 22:58:59 +08:00
caoxiaozhu
a0f6d9f702 chore: 更新 .env.example、财务规则表与 AI 意图规划开发文档 2026-06-24 21:59:15 +08:00
caoxiaozhu
bb681aa1f3 chore(repo): 移除误跟踪的 egg-info 构建产物并新增忽略规则
server/src/x_financial_server.egg-info/ 为 uv/pip 构建产物,此前被误跟踪。
本次 git rm --cached 移除跟踪(本地保留),.gitignore 新增 *.egg-info/ 规则避免后续误入库。
2026-06-24 21:59:09 +08:00
caoxiaozhu
bc560145a4 feat(web): AI 工作台意图规划与规划思考模型
- 新增 workbenchAiIntentPlannerModel,基于 LLM function_call 解析建单/草稿/提交意图,区分 model 与 rule_fallback 来源
- 新增 workbenchAiPlanningThinkingModel 合并规划思考事件流,按 eventId 去重合并
- application gate/preview 模型接入意图规划,usePersonalWorkbenchAiMode/useWorkbenchAiStewardFlow/useWorkbenchAiActionRouter 链路适配,支持上下文提交
- steward 服务与 stewardPlanModel 适配新动作结构,receipt-folder-view 微调样式
- 新增 intent-planner-model/application-context-submit/steward-actions-service 测试,更新 gate-model/action-router/plan-message-copy/fast-preview 测试
2026-06-24 21:58:46 +08:00
caoxiaozhu
5311c99d69 refactor(server): steward 决策链路改用 LangGraph 编排
- 新增 StewardGraphPlannerService,用 LangGraph 状态图编排意图识别→流程判断→模型/规则分支→兜底,替代原 planner 内线性调用
- 新增 StewardGraphRuntimeService 编排运行时决策与槽位决策;StewardActionContracts/Executor 统一动作合约与执行
- steward_intent_agent/application_fact_resolver/runtime_chat 适配图执行器,config 暴露图相关开关
- pyproject/uv.lock 新增 langgraph 依赖
- 新增 graph_planner/graph_runtime/action_executor 测试,更新 intent_agent/planner/fact_resolver/runtime_chat/reimbursement 测试
2026-06-24 21:58:35 +08:00
caoxiaozhu
545b31d32f chore(env): docker-compose 端口与服务配置微调并更新规则表与日志
- docker-compose(.full).yml 与 start.sh 微调端口/服务配置
- AGENTS.md 同步更新协作规范
- 更新交通/通信/差旅等财务规则表,补 2026-06-24 work-log
2026-06-24 12:36:03 +08:00
caoxiaozhu
8417a9f542 feat(web): 设置中心缓存管理与文件预览资产工具
- 新增 documentPreviewAssets 工具,统一从 URL/Blob/File 推断预览类型(image/pdf/file/unsupported)
- SettingsView/SettingsView.js/settingsModelHelper 新增系统缓存管理区块,调用 /settings/cache/clear 并展示清理结果;useSettings/services 适配
- WorkbenchAiFilePreviewDialog/useWorkbenchAiFilePreview 接入预览资产工具,workbenchAiComposerModel 调整文件处理
- ReceiptFolder/LogDetailView/DigitalEmployeeWorkRecords/travelReimbursementAttachmentModel 配套适配
- 新增 settings-cache-management-section 测试,更新 settings-llm/rendering/receipt-folder-view/composer-components/attachment-association 测试
2026-06-24 12:35:59 +08:00
caoxiaozhu
9a5ed0e94a feat(server): 系统缓存清理接口与 OCR 文本层兜底增强
- 新增 system_cache 模块与 POST /settings/cache/clear,管理员可一键清理 OCR 结果/运行时配置/模型失败冷却/知识库索引/地点语义等进程内缓存
- 各服务暴露 clear_*_cache 方法(ocr/runtime_settings/runtime_chat/knowledge/application_location_semantic),SettingsCacheClearRead 汇总清理项
- OCR 转图片失败时尝试用 PDF 文本层兜底构建识别文档(有效字符≥8),并写结果缓存;OcrService 暴露 clear_result_cache
- receipt_folder 车票过滤补充身份证号关键词,附件文档/操作/展示模块同步适配
- 新增 system_cache_endpoints 测试,更新 openapi_schema/ocr/receipt_folder/attachment_association_jobs 测试
2026-06-24 12:35:51 +08:00
caoxiaozhu
50d2dc579a style(web): 微调 AI 工作台样式 2026-06-24 10:43:08 +08:00
caoxiaozhu
f9553a6a1a docs: 清理过期计划文档并补全 work-log 与开发/用户文档
- 删除已落地的 improvement-roadmap、superpowers 计划与 ui-mockups 参考稿,删除早期 work-log(2026-05-06~08)
- 新增 2026-05-23 起的 work-log 与 attachment-association-background-job、reimbursement-draft-action-branching 等开发文档及用户文档
- docker-compose(.full).yml 微调服务配置
2026-06-24 10:42:57 +08:00
caoxiaozhu
ee730aa31c feat(web): AI 工作台文件预览/附件关联任务与草稿分支
- 新增 WorkbenchAiFilePreviewDialog 附件预览对话框及 useWorkbenchAiFilePreview,附件支持点击预览
- 新增 attachmentAssociationJobs/linkedReimbursementDraftJobs 前端服务与对应 composable,接入后台任务轮询与状态展示
- 新增 travelReimbursementDraftBranchModel 草稿分支模型,报销关联门控支持跳过/选择草稿
- PersonalWorkbenchAiMode 及各 composable(expense/document/steward/application-preview/attachment-association)重构适配,WorkbenchAiComposer/FileStrip 样式与交互完善
- DocumentsCenter/ReceiptFolder/TravelReimbursementCreate 等视图及 scripts 重构,风险/差旅规划/审批等工具适配
- 新增/更新前端测试:application-result-card、reimbursement-list-preview-fetch、guided-flow、composer-components 等
2026-06-24 10:42:50 +08:00
caoxiaozhu
0264a4b5b4 refactor(server): user_agent/steward/ocr 等服务重构并适配关联任务
- user_agent 拆分 application/locations/knowledge/response/review 四个子模块,接入申请位置语义与关联草稿分支
- steward planner/runtime/slot/plan_builder 决策链路重构,travel_reimbursement_calculator/orchestrator_expense_query 适配
- ocr/document_preview/document_intelligence/receipt_folder 复用预览与资产缓存,expense_claim_draft_flow/application_handoff 适配
- pyproject.toml 新增依赖,paddleocr bootstrap 脚本与 server_start.sh 调整
- 更新差旅/交通/通信等财务规则表,同步 document_intelligence/ocr/receipt_folder/user_agent 等测试
2026-06-24 10:42:24 +08:00
caoxiaozhu
332f77389d feat(server): 新增附件关联/关联报销草稿后台任务与申请位置语义
- attachment_association_jobs:从票据夹批量关联附件到报销单,识别城市/日期并创建明细项,内存态 job 跟踪
- linked_reimbursement_draft_jobs:基于申请单异步生成关联报销草稿,调用 Orchestrator 编排,区分 succeeded/failed 终态
- application_location_semantics:抽取差旅出发/到达城市、判断具体地址/业务动作等位置语义,供申请单校验复用
- router 注册两个 job 端点,新增对应 job/语义单元测试
2026-06-24 10:42:05 +08:00
caoxiaozhu
d4ff79f326 chore(agent): 新增变更日志/checkpoint skill 与 post-commit hook
- AGENTS.md 新增变更日志 Skill 规范:变更后增量更新 document/work-log,更新前先做 Git 拉取检查
- 新增 .codex/skills 下 agent-change-log、git-checkpoint-commit 两个 skill
- 新增 .githooks/post-commit 与 tools/agent-change-log 自动化脚本,提供提交后最低限度日志追加
2026-06-24 10:41:56 +08:00
caoxiaozhu
93212600eb chore(skills): add git checkpoint commit loop 2026-06-24 09:47:05 +08:00
caoxiaozhu
73966b3a7b refactor: consolidate finance workflow modules 2026-06-23 11:21:18 +08:00
caoxiaozhu
1f40ce3df3 fix(web): 孤儿申请预览消息触发重新生成可编辑表格
useWorkbenchAiApplicationPreviewFlow 识别仅含表格文案但缺 applicationPreview 载荷的孤儿消息,触发重新生成可编辑表格并提示用户,避免提交动作静默失败。
2026-06-23 09:43:29 +08:00
caoxiaozhu
f17098aa58 chore(repo): 移除误跟踪的 expense_claims 运行时票据文件
server/storage/expense_claims/ 下 30 个用户上传票据/预览图/meta 此前在 gitignore 规则生效前被误提交,运行时会持续产生内容变更。
本次 git rm --cached 移除版本跟踪(本地文件保留),配合已有 server/storage/expense_claims/ 忽略规则,避免后续误入库。
2026-06-23 09:43:07 +08:00
caoxiaozhu
8094333e3b style(web): 通知中心列表行布局重构与时间标签格式化
- TopBar 通知行改为 row-main/row-head/row-foot 结构化布局,标题加粗、分类改为 pill、箭头随标题右侧
- formatNotificationTime 改名 formatNotificationTimeLabel,新增 ISO/短日期直通匹配与超长截断兜底
- 更新 sidebar-document-unread-dot 测试
2026-06-23 09:42:56 +08:00
caoxiaozhu
0122f3b250 chore(rules): 更新交通/通信/差旅/出差等财务规则表 2026-06-23 09:42:43 +08:00
caoxiaozhu
dc4cad2baa chore(env): WEB_PORT 统一回退为 5173 并烟雾检查改为可开关
- .env.example/docker-compose(.full).yml WEB_PORT 默认值 5273→5173(Vite 默认),CORS_ORIGINS 同步
- docker-compose 注入 WEB_PORT/SERVER_PORT 环境变量,健康检查端口随之更新
- start.sh 新增 SERVER_SMOKE_CHECK_ENABLED 开关,默认关闭烟雾检查,仅健康探测
- web/web_start.sh 适配端口
- .gitignore 补充忽略 tmp/ 运行时目录
2026-06-23 09:42:40 +08:00
caoxiaozhu
e725b7f19c feat(web): 票据夹资产缓存接入与 AI 工作台附件流程完善
- ReceiptFolderView 删除票据后提示已关联附件副本保留,接入 useToast;fetchReceiptFolderAsset 加 no-store 避免预览缓存
- PersonalWorkbenchAiMode 附件区/对话气泡适配资产缓存,personal-workbench-ai-mode.css 调整布局
- usePersonalWorkbenchAiMode/useWorkbenchAiApplicationPreviewFlow/useWorkbenchAiAttachmentAssociationFlow/useWorkbenchAiStewardFlow 完善附件草稿选择与关联流程
- travelRequestDetailSmartEntryRecognition 智能识别增强,AppShellRouteView/PersonalWorkbenchView/useApplicationPreviewEditor/useTravelReimbursementSubmitComposer 等配套适配
- 新增 expense-attachment-draft-selection、receipt-folder-asset-cache、travel-request-detail-smart-entry-recognition 测试,更新 attachment-association-confirmation、expense-application-fast-preview、workbench-ai-mode-switch 测试
2026-06-23 09:42:13 +08:00
caoxiaozhu
84a8998e59 feat(server): 票据文件夹资产缓存与文档预览统一生成
- 新增 document_preview 模块,DocumentPreviewAssets 统一处理 data URL 解码、pdftoppm PNG 预览生成(poppler-data 编码)、renderer_id 标识
- receipt_folder 服务复用预览生成,缓存票据资产并提供清理;删除票据时保留已关联报销单的附件副本
- document_intelligence 新增票据预览/资产缓存接入与字段提取增强;ocr 抽取复用预览工具,附件分析/文档/操作/展示四个子模块同步适配
- receipt_folder 端点补充资产缓存头,补/扩 document_intelligence、ocr_endpoints、ocr_service、receipt_folder_service、reimbursement_endpoints 测试,新增 attachment_analysis 回归测试
2026-06-23 09:42:00 +08:00
caoxiaozhu
bc743adef3 chore(rules): 更新公司通信费报销规则表 2026-06-22 15:56:13 +08:00
caoxiaozhu
ded8b39ccb feat(web): 申请单预览编辑器增强与报销流程细节适配
- useApplicationPreviewEditor 扩展字段编辑与校验,useTravelReimbursementApplicationPreviewDateEditor 微调日期处理
- travelReimbursementExpenseQueryModel/reimbursements 服务/expenseApplicationPreview 适配工号/邮箱字段与关联动作
- useWorkbenchAiApplicationPreviewFlow/usePersonalWorkbenchAiMode 接入关联门控后的预览流转
- TravelReimbursementCreateView 调整入口,TravelReimbursementMessageItem 适配
- 新增 expense-application-fast-preview 测试,更新 attachment-association-confirmation、review-drawer-switch 测试
2026-06-22 15:56:06 +08:00
caoxiaozhu
ba444a514f feat(web): 报销单新增关联申请单门控与草稿检测流程
- 新增 travelReimbursementAssociationGateModel,查询可关联申请单/草稿报销单并生成跳过/选择/单独新建动作,区分差旅费与业务招待费类型
- travelReimbursementApplicationLinkModel 补充 buildLinkedApplicationReferenceIndex/buildRequiredApplicationActions 等关联构建逻辑
- useTravelReimbursementSuggestedActions 接入 select_required_application/skip 系列动作,'我要报销'入口改为先走关联门控
- useWorkbenchAiActionRouter 新增 SKIP_REQUIRED_APPLICATION_LINK/SKIP_REIMBURSEMENT_DRAFT_CHECK 动作分发
- useWorkbenchAiExpenseFlow 暴露 startAiReimbursementAssociationGate,stewardPlanModel 待处理流程适配
- 新增 workbench-ai-action-router、workbench-ai-reimbursement-association-gate 测试并更新 guided-flow、steward-plan 测试
2026-06-22 15:55:59 +08:00
caoxiaozhu
aa965da69d feat(server): 报销单输出工号/邮箱并扩展申请人邮箱前缀匹配
- ExpenseClaimRead 新增 employee_no/employee_email 字段,ExpenseClaim 模型补对应只读属性
- expense_claim_access_policy 在姓名匹配未果时,按 candidate@% 邮箱前缀匹配 Employee.email,命中唯一记录即返回
- test_backend_pagination/test_expense_claim_service 补充工号/邮箱字段断言与邮箱前缀匹配用例
- 更新公司通信费报销规则表
2026-06-22 15:55:48 +08:00
caoxiaozhu
1b04ee1c4c fix(web): restore travel detail child component styles 2026-06-22 13:34:12 +08:00
caoxiaozhu
103f225f54 chore(rules): 更新差旅/交通/通信等财务规则表 2026-06-22 12:02:11 +08:00
caoxiaozhu
e42dedaba1 docs: 同步 Docker 编排说明并补充重构计划与 UI 参考
- README 与 docker/README 更新双 compose 文件说明:docker-compose.yml 仅主应用、docker-compose.full.yml 完整栈
- 新增 docs/superpowers/plans 800 行重构实施计划,规划前后端代码体量护栏与按职责拆分路径
- 新增 docs/ui-mockups 附件关联企业版 UI 参考稿
2026-06-22 12:02:08 +08:00
caoxiaozhu
607e127f59 chore(docker): 拆分主应用编排与完整本地栈
- 新增 docker-compose.full.yml:编排 main+postgres+qdrant+onlyoffice 完整本地开发栈,依赖与 DATABASE_URL 由 compose 注入
- docker-compose.yml 精简为仅启动主应用,ONLYOFFICE/QDRANT 相关变量改为空值占位,便于复用外部依赖
- docker-compose.postgres.yml 主应用补充 POSTGRES_*/DATABASE_URL 环境变量
2026-06-22 12:02:03 +08:00
caoxiaozhu
6d33ba5742 refactor: enforce 800 line source limits 2026-06-22 11:58:53 +08:00
caoxiaozhu
08a4fa3577 style(web): AI 工作台附件卡片样式与交互适配
- personal-workbench-ai-mode.css 新增 workbench-ai-file-card 系列样式,file-strip 改为 flex-wrap 左对齐排布卡片,移除按钮样式随卡片重构
- workbench-ai-mode-switch 测试补充附件卡片相关断言
2026-06-21 23:24:36 +08:00
caoxiaozhu
d660a961fb feat(web): AI 工作台附件改为卡片化展示并支持单项移除
- PersonalWorkbenchAiMode 附件区由计数条改为按类型图标/名称/类型标签的卡片列表,支持单项移除(removeAiModeFile),复用 buildFileIdentity 作为 key
- resolveAiComposerFileType 按 pdf/图片/表格/文档/压缩包/文件归类,分别对应图标与色调
- .gitignore 补充忽略 server/storage/receipt_folder/ 运行时票据存储目录
2026-06-21 23:24:16 +08:00
caoxiaozhu
669d22e71f feat(web): 差旅领导意见事件结构化与申请审批信息增强
- applicationApproval 新增按日期/时间/审批角色拆分格式化,buildLeaderApprovalEvents 补充 dateLabel/timeLabel/roleLabel 字段
- TravelRequestDetailView 领导意见事件改为日期+时间+审批人结构化展示,travel-request-detail-view.css 重构对应样式
- travelReimbursementAttachmentModel 微调附件标识,同步更新 application-approval-info、travel-request-detail-leader-approval、attachment-association-confirmation 测试
- 更新公司通信费报销规则表
2026-06-21 23:24:09 +08:00
caoxiaozhu
88e91a5900 feat(ocr): PDF 文本层可用时跳过 worker 调用并补装 poppler-data
- OcrService 提取 PDF 文本层后若有效字符达到阈值,直接构建文档并写入结果缓存,不再触发 OCR worker,仅无文本层时才解析 python_bin/worker_path 调用 worker
- _build_text_layer_document 复用 AggregatedOcrDocument 聚合文本层片段,_has_usable_pdf_text_layer 基于 meaningful_char_count 判定
- docker-compose 与 paddleocr bootstrap 脚本补装 poppler-data,保证 PDF 文本层抽取的中文编码正确
- 新增文本层直取与运行时依赖两项 ocr_service 单测
2026-06-21 23:23:59 +08:00
caoxiaozhu
1986b0d945 style(web): 移除顶栏 AI 快捷操作区并优化差旅领导意见事件样式
- TopBar 移除 AI 模式下的公司切换/AI 模式切换快捷操作块及 showAiModeUtilityActions 计算属性,清理 top-bar.css 对应样式
- TravelRequestDetailView 领导意见事件重构为状态/意见/审批人结构化布局,travel-request-detail-view.css 补充对应样式
- 同步更新 topbar-ai-mode-switch、ai-sidebar-rail-mode、travel-request-detail-leader-approval 测试
2026-06-21 22:56:34 +08:00
caoxiaozhu
24b5b71b0f feat(web): 差旅申请详情进度 viewer 与审批/加载态组件增强
- 新增 requestProgressViewer,申请单在直属领导审批视角下将当前步骤展示为'等待批复',travel-request-detail/app-shell/useRequests 接入
- TravelRequestApprovalDialog 增强审批交互,TableLoadingState 补充表格加载占位,ConfirmDialog 扩展确认对话框能力
- useAppShell/useRequests/AppShellRouteView 配套适配申请详情跳转与会话状态
- 同步更新 requestProgressSteps、travel-request-detail-leader-approval、assistant-session-draft-delete、documents-center-status-filter、app-shell-financial-assistant-entry、request-progress-viewer 等测试
2026-06-21 22:49:58 +08:00
caoxiaozhu
8b3495455b feat(web): AI 文档详情引用解析与查询卡片增强
- 新增 aiDocumentDetailReference,统一解析 #ai-open-document-detail / #ai-open-application-detail 引用,兼容 A/R/D 短格式与 AP-/RE-/AD- 旧格式单号,提供 isBusinessDocumentReference 判定
- aiDocumentQueryModel 文档卡片接入详情引用,按申请单/报销单生成对应 href,HTML 渲染器识别单据记录表格并生成卡片链接
- PersonalWorkbenchAiMode 处理文档详情点击跳转,卡片样式重构为结构化布局并更新背景资源
- expenseApplicationPreview 补充事由字段,同步新增/更新 ai-document-detail-reference、document-query-model、html-renderer、workbench-ai-mode 等测试
- 更新公司通信费报销规则表
2026-06-21 22:49:53 +08:00
caoxiaozhu
3b74a330a3 feat(web): AI 文档查询卡片重构与单号判定统一
- documentClassification 抽出 isApplicationDocumentNo,统一兼容 AP-/APP- 旧格式与 A+8 新格式,aiDocumentQueryModel 复用
- aiDocumentQueryModel 文档卡片改为结构化字段布局(单据类型/金额/申请人/编号/操作),新增查询范围摘要区,渲染走 HTML 信任块
- AppShellRouteView/useAppShell/useRequests/detailAlerts/riskVisibility 等差旅详情模型适配单号判定
- 同步更新 ai-document-query-model/workbench-ai-mode-switch 测试,新增 document-classification 测试
2026-06-20 22:04:37 +08:00
caoxiaozhu
8158716e23 test(server): 适配 A/R/D 紧凑单号格式
- approval_routing/service/user_agent 测试中报销单查询统一兼容 RE- 旧格式与 R+8 新格式,申请单单号断言改为短格式
- generate_claim_no 用例重命名为短前缀校验,正则改为 R[A-HJ-NP-Z2-9]{8}
- 同步更新差旅/交通/通信等财务规则表
2026-06-20 22:04:31 +08:00
caoxiaozhu
0cda750ff0 feat(web): AI 工作台会话与文档卡片渲染增强
- aiConversationHtmlRenderer 识别单据记录类表格并渲染为卡片列表,新增删除申请单详情的禁用占位链接
- aiWorkbenchConversationStore 增加草稿删除后会话链接失效处理,避免点击已删除单据跳转
- aiApplicationPreviewActions 调整提交/草稿调用路径,PersonalWorkbenchAiMode 接入新的会话存储与渲染
- ConfirmDialog/TravelRequestDeleteDialog/useAppShell/AppShellRouteView 配套适配,同步更新相关前端测试
2026-06-20 21:44:16 +08:00
caoxiaozhu
81e990ab72 feat(server): 申请单支持草稿保存并统一删除权限口径
- user_agent_application 新增草稿分支:识别'保存草稿/存草稿/先保存'等意图,复用可编辑记录更新或建草稿,提交前单据重叠仍拦截
- 草稿态返回单号与待提交提示,submit 仅在确认提交分支触发,避免草稿进入审批流
- reimbursements 删除接口文案与判定统一为系统管理员可删、申请人删自有草稿/退回单,申请单判定改用 is_application_claim_no
- 更新财务规则表与 reimbursement 端点测试
2026-06-20 21:44:12 +08:00
caoxiaozhu
47c6a4bb73 refactor(server): 单号规则收紧为 A/R/D+8 位紧凑格式
- DOCUMENT_NUMBER_PREFIXES 改为 A/R/D,新增短格式与旧格式正则并存识别,提取正则加边界锚定避免误匹配
- build_document_number 去掉时间戳段,统一生成 A+token 等紧凑单号,is_application_claim_no 兼容旧 AP-/APP- 前缀
- access_policy/status_registry/reimbursements/expense_claims/budget_support 统一复用 is_application_claim_no 判定申请单
- 同步 document_numbering 单元测试覆盖新旧两种格式
2026-06-20 21:44:06 +08:00
caoxiaozhu
96c2e1099a feat(web): 统一平台管理员判定与 AI 工作台申请预览动作接入
- authUser 抽出 resolveAuthUserAdminFlag,统一 isAdmin 解析(含 superadmin、role_codes、中英文角色名),accessControl 复用同一逻辑
- 登录态、应用外壳路由、系统状态接入统一管理员判定,LoginView 与相关 composable 配套调整
- AI 工作台申请提交改为调用新的 /application-preview-action 接口,草稿保存仍走 orchestrator;预审模型补充重叠冲突提示与阻断判断
- 同步更新 accessControl/api-request/ai 预览动作等前端测试
2026-06-20 14:42:04 +08:00
caoxiaozhu
729d833edb feat(server): 新增申请核对预览快速建单接口与平台管理员判定统一
- reimbursements 新增 POST /application-preview-action,AI 工作台表格核对后直接走 UserAgentService 建单/提交,免去通用 Orchestrator 编排
- 平台管理员判定统一抽取 PLATFORM_ADMIN_IDENTITIES 常量,identity 与 role_codes 均支持 admin/superadmin,含 header 开关
- docker-compose 镜像补装 openssh-server
- 同步更新差旅/交通/通信等财务规则表与 reimbursements 端点测试
2026-06-20 14:41:59 +08:00
caoxiaozhu
304bbe1fd4 feat(web): 工作台 AI 模式报销预审与文档查询模型拆分
- 新增 aiApplicationPrecheckModel/aiDocumentQueryModel/aiApplicationPreviewActions/aiConversationHtmlRenderer 四个独立模型与服务,按职责从主组件拆出
- PersonalWorkbenchAiMode 接入拆分后的预审、文档查询与 HTML 渲染逻辑,配合 markdown 工具增强结构化展示
- 文档中心与归档筛选、风险可见性、申请预览等工具同步适配,补充对应单元测试
- 新增 AI 文档卡片背景资源
2026-06-20 10:17:37 +08:00
caoxiaozhu
3d69f8501f feat(risk): 申请单阶段风险可见性细化与规则表更新
- 申请单阶段将 policy/trip/amount 类风险对申请人可见、可自行修正,画像/审批流程类仍走领导可见
- 平台风险标记与语义推断统一采用该策略,更新对应单元测试
- 风险规则中 city_mismatch 等城市匹配规则移除 expense_application 阶段,仅保留 reimbursement
- 同步更新交通/通信/差旅/出差等财务规则表
2026-06-20 10:17:18 +08:00
caoxiaozhu
4d04f4e7af chore(gitignore): 忽略 .env 防止敏感配置入库
将 .env 从版本库移除(本地文件保留),并补充 .env.local 等本地变体忽略规则,
避免数据库密码、密钥等敏感配置进入 git 历史。
2026-06-18 22:14:53 +08:00
caoxiaozhu
3131112952 style(web): 调整 AI 模式用户消息气泡布局与引用图标
- 用户消息气泡的操作区与时间右对齐
- 引用按钮图标由 mdi-reply 改为 mdi-format-quote-open
2026-06-18 22:13:09 +08:00
caoxiaozhu
a2f67af13e docs: 新增 X-Financial 改进路线图 2026-06-18 22:12:38 +08:00
caoxiaozhu
0cde1f8990 feat(web): 工作台 AI 模式与差旅/风险建议交互优化
- 新增 PersonalWorkbenchAiMode 组件、AI 侧边栏与 orb 机器人视觉资源
- 新增 aiApplicationDraftModel / aiExpenseDraftModel / aiWorkbenchConversationStore
  及业务准入 aiSidebarBusinessAccess,支撑 AI 模式下的申请与报销草稿
- 顶栏、侧边栏、工作台样式重构,适配 AI 模式切换与响应式布局
- 同步 steward plan/off_topic、差旅报销引导流、风险建议卡片等测试
2026-06-18 22:12:24 +08:00
caoxiaozhu
a6674a1e76 feat(steward): off_topic 场景细分与引导回复
- 将业务无关输入细分为 greeting / meaningless / off_business 三类场景
- 新增 StewardOffTopicAgent,用 function calling 生成管家语气引导回复
- steward endpoint 与 user_agent_application 串联 off_topic 引导话术
- 补充 planner 与 user agent 的 off_topic 覆盖测试
2026-06-18 22:12:10 +08:00
caoxiaozhu
127d603e7d feat(ontology): 仅放行财务业务相关问题的信号校验
- 新增 _has_supported_business_signal,在加载目录前拦截非财务问题并抛错
- 同步重构 ontology 服务测试覆盖业务信号判定分支
2026-06-18 22:12:00 +08:00
caoxiaozhu
3f17619e0c fix(auth): 登录目录就绪幂等化与并发控制
- employee/settings/user_session_metrics 的 ensure_*_ready 改为按 bind 缓存 + 锁,
  避免每次登录重复建表与并发场景下的竞态
- auth 登录链路先查员工再降级触发目录就绪,并吞掉查询期 SQLAlchemy 异常
- 默认管理员账号由 superadmin 迁移为 admin,兼容历史账号回填
- 补充登录降级与设置持久化相关测试
2026-06-18 22:11:53 +08:00
caoxiaozhu
59ba76c74a feat(startup): 服务端启动 bootstrap 与缓存预热
- 新增 STARTUP_BOOTSTRAP_ENABLED / STARTUP_CACHE_WARMUP_ENABLED 配置开关
- lifespan 拆分 bootstrap 步骤并后台线程预热缓存,失败可降级继续启动
- server_start.sh / web_start.sh 扩展 SERVER_PORT、启动与调度开关的 env 覆盖
- bootstrap_paddleocr_mobile.sh 改用 python3 并补充 poppler-utils 依赖
- 补充启动 bootstrap 与 env 覆盖优先级测试
2026-06-18 22:11:37 +08:00
caoxiaozhu
35372c6661 feat(rules): 更新差旅与通信费用等财务规则表 2026-06-18 22:11:13 +08:00
caoxiaozhu
38653fa365 chore(storage): 清理用户历史报销票据附件
移除测试期残留的 receipt_folder 附件与预览文件,后续通过归档目录维护。
2026-06-18 22:11:10 +08:00
caoxiaozhu
c28e99b714 chore(gitignore): 忽略 .nezha/ 与 .omo/ 本地工具目录 2026-06-18 22:11:06 +08:00
caoxiaozhu
43432534d8 feat(steward): 前端支持 off_topic 与引导话术
- assistantSessionScope.js:新增 ASSISTANT_SCOPE_ACTION_FILL_COMPOSER 常量
- assistantSuggestedActionPrefill.js:识别 fill_composer 与 payload.fill_text
- stewardPlanModel.js:normalizeStewardPlan 透传 suggestedPrompts;
  buildStewardPlanMessageText / buildStewardSuggestedActions
  新增 off_topic 分支,按钮填充输入框不提交
- useStewardPlanFlow.js:isPendingStewardActionMessage 排除 off_topic
- steward-plan-off-topic.test.mjs:覆盖 normalize/文案/按钮/兼容路径
2026-06-18 14:15:30 +08:00
caoxiaozhu
cce19e4c40 feat(steward): 拦截业务无关输入返回 off_topic 计划
- schemas/steward.py:StewardPlanResponse 新增 suggested_prompts 字段
- steward_planner.py:新增 STEWARD_BUSINESS_SIGNAL_KEYWORDS 与
  _is_business_irrelevant_input 守卫,在 build_plan 入口前置;
  新增 _build_off_topic_plan 构造 plan_status=off_topic 的引导计划
- steward_intent_agent.py:system prompt 追加业务无关约束
- test_steward_planner.py:覆盖 123/你好/纯标点走 off_topic,
  并验证正常业务输入不受守卫影响
2026-06-18 14:15:20 +08:00
caoxiaozhu
b8915a29c0 chore(storage): 归档用户报销票据附件 2026-06-17 14:39:41 +08:00
caoxiaozhu
4199feb681 test: 同步报销审批流与预算分析测试
- 新增预算审批合并、风险标记去重与占位条目校验用例
- 补充预算分析对当前审核人与财务的可见性断言
- 调整单据删除权限测试以匹配 admin 限制
2026-06-17 14:39:26 +08:00
caoxiaozhu
0fac8b615f feat(web): 优化差旅详情、风险建议卡片与文档中心交互
- 拆分阶段风险建议卡片样式到独立文件
- 完善差旅申请审批对话框与详情视图交互
- 调整文档中心列表共享样式与状态筛选
- 同步应用外壳、视图初始化与系统状态 composables
2026-06-17 14:39:12 +08:00
caoxiaozhu
a3e5295915 feat(rules): 更新财务差旅与通信费用规则表 2026-06-17 14:38:51 +08:00
caoxiaozhu
1f4681f486 feat(claim): 重构报销审批流并收敛风险标记
- 直属领导兼任部门 P8 预算审批人时合并预算审批,直接流转至财务审批
- 预算超过警戒值时强制要求预算管理者填写审批意见
- 新增风险标记去重工具,消除各审核阶段重复风险卡片
- 新增工作流修复 Mixin,纠正重复预算审批阶段的历史数据
- 收紧单据删除权限至 admin,放宽预算分析可见范围至当前审核人
- 提交校验放宽已上传票据条目的 OCR 字段缺失并忽略尾部占位条目
2026-06-17 14:38:07 +08:00
caoxiaozhu
09a66c72cb chore: 将 web 端口由 5173 调整为 5273 2026-06-17 14:37:50 +08:00
caoxiaozhu
0d525fa64c chore: 忽略 .codex-temp 工具临时目录 2026-06-17 14:34:36 +08:00
caoxiaozhu
470f343b29 fix(expense): narrow travel route risk indicators 2026-06-17 09:36:24 +08:00
caoxiaozhu
9f7b8b46a3 Refine travel reimbursement steward flow
Align planner, runtime rules, and policy assets so travel guidance
matches the updated reimbursement workflow.
2026-06-15 22:55:18 +08:00
caoxiaozhu
792741709a fix(claim): align risk advice with expense rows 2026-06-15 20:53:48 +08:00
caoxiaozhu
5747e85acf fix(risk): restore upload-time rule center review 2026-06-15 20:20:55 +08:00
Codex
8b952c9a26 refactor(travel): split reimbursement create workflow
完整修改内容:

- 拆分 TravelReimbursementCreateView:提取审核面板纯模型、消息操作、建议动作处理、生命周期 watcher/UI 映射、小财管家运行时、续办流程和运行时文本模型,减少主组件继续堆叠业务分支。
- 调整申请预览链路:新增本地申请意图 gate,完善复杂差旅申请的大模型复核判断、交通方式缺失/候选识别、规则中心交通费用预估合并和申请冲突处理。
- 优化小财管家流程:抽出 steward typewriter 分段策略,避免 Markdown 表格逐字闪烁;补齐跨助手 carry、字段补齐续办、文本确认提交和行程规划推荐动作。
- 调整消息与样式:移除申请预览日期 chip 样式,收敛申请卡片/报销草稿消息的展示与复制、朗读、反馈入口逻辑。
- 更新测试:将源码锚点迁移到新模块,覆盖申请预览、提交确认、小财管家续办、引导流和审核抽屉相关断言。

验证:

- node --check web/src/views/scripts/TravelReimbursementCreateView.js 及新增拆分模块
- npm --prefix web run build
- node --test web/tests/expense-application-fast-preview.test.mjs web/tests/expense-application-submit-rich-confirm.test.mjs web/tests/travel-reimbursement-guided-flow.test.mjs

说明:

- 后端/规则/容器配置/Audit 页面等工作区已有改动未纳入本提交。
- 容器内后端定向 pytest 曾运行 timeout 180s /tmp/x-financial-server-venv/bin/pytest -q <相关后端测试>,180 秒超时且超时前已有失败标记,未作为通过项记录。
- TravelReimbursementCreateView 当前仍超过 800 行,后续仍需继续拆分;本提交先把新增职责模块控制在 800 行内,阻止主类/主模块继续膨胀。
2026-06-13 14:53:23 +00:00
336fee9d93 chore: 忽略 .superpowers 工具缓存目录 2026-06-12 09:43:53 +08:00
caoxiaozhu
25724c354f feat: 同步报销流程与工作台改动 2026-06-09 08:32:00 +00:00
caoxiaozhu
e124e4bbcb feat: 报销审批流重构与管家计划全链路贯通
- 重构报销状态注册表、审批流路由与平台风险标记
- 完善管家意图规划器与模型计划构建器全链路
- 新增 OCR Worker 脚本、数据库会话管理与通知状态
- 优化文档中心、日志视图、预算中心与员工管理交互
- 增强工作台摘要、图标资源与全局主题样式
- 补充审批路由、状态注册、OCR 服务与管家规划器测试覆盖
2026-06-06 17:19:07 +08:00
caoxiaozhu
f60cebadb8 feat: 小财管家意图规划与报销提交编排增强
- 完善管家意图识别、模型计划构建与规划器调度
- 重构差旅报销提交编排器与管家计划流程前端交互
- 优化报销消息项样式与文档中心视图
- 新增小财管家与附件上传风险前置复核设计文档
- 补充管家规划器与文档中心测试覆盖
2026-06-04 14:25:14 +08:00
caoxiaozhu
1cbf3fee44 feat: 报销预审会话状态管理与工作台交互增强
- 新增差旅报销会话状态管理与对话模型重构
- 增强风险观测服务与运行时聊天上下文作用域
- 优化工作台图标资源、助理意图识别与摘要工具
- 完善报销创建视图样式与差旅详情页标准调整交互
- 补充风险观测、运行时聊天与报销端点测试覆盖
2026-06-04 11:03:29 +08:00
caoxiaozhu
87da5df91b feat: 风险可见性控制与差旅详情页交互优化
- 新增风险可见性工具函数与风险日趋势图表组件
- 优化差旅请求详情页费用模型与视图交互
- 完善顶部导航栏样式与应用壳路由逻辑
- 补充风险可见性、风险看板与差旅详情测试覆盖
2026-06-03 22:15:45 +08:00
caoxiaozhu
75d5c178e1 feat(workbench): persist topbar notification state 2026-06-03 21:43:35 +08:00
caoxiaozhu
b9826a1985 fix: keep adjusted risks visible to reviewers 2026-06-03 19:14:40 +08:00
caoxiaozhu
0f8bc4071a fix: preserve reviewer risk notice after standard adjustment 2026-06-03 19:10:29 +08:00
caoxiaozhu
cb36d78fa2 fix: 优化顶部导航栏布局与工作台摘要展示并清理旧票据数据 2026-06-03 17:40:52 +08:00
caoxiaozhu
8e2477587f fix: handle risk explanation standard adjustment 2026-06-03 17:31:40 +08:00
caoxiaozhu
67b81a1bd8 fix(workbench): replay profile radar animation 2026-06-03 17:31:12 +08:00
caoxiaozhu
9c24a852e7 fix(workbench): remount expense stats chart on reopen 2026-06-03 17:22:48 +08:00
caoxiaozhu
95956afbc6 fix(notifications): refine bell notification center 2026-06-03 17:16:09 +08:00
caoxiaozhu
c73178b65d fix(documents): move unread notice into bell 2026-06-03 17:05:34 +08:00
caoxiaozhu
8c2f301d85 fix(documents): sort newest rows first 2026-06-03 16:52:49 +08:00
caoxiaozhu
4717ee6086 fix(documents): refine unread badges and mark all read 2026-06-03 16:46:13 +08:00
caoxiaozhu
513ff909f9 fix: remove manual expense detail add action 2026-06-03 16:44:06 +08:00
caoxiaozhu
92198549f6 fix: require explicit transport mode for applications 2026-06-03 16:36:02 +08:00
caoxiaozhu
59d3bf0f00 fix(auth): keep admin out of personal workbench 2026-06-03 16:31:27 +08:00
caoxiaozhu
04f0951b3d fix: restrict application linking for reimbursement drafts 2026-06-03 16:28:09 +08:00
caoxiaozhu
8887cf5a27 fix(workbench): stretch profile tag card 2026-06-03 15:53:30 +08:00
caoxiaozhu
34457f9c3e feat: 本体字段治理与风险规则模板执行器重构
- 新增本体字段注册表与字段治理审计脚本
- 重构风险规则模板执行器、DSL 验证与清单分类器
- 完善票据夹服务与差旅请求详情页交互
- 优化趋势图表与总览页数据展示
- 增强报销平台风险分级与模拟公司筛选
- 补充本体字段、风险规则生成与票据夹服务测试覆盖
2026-06-03 15:46:56 +08:00
caoxiaozhu
e12b140508 fix(workbench): show single expense distribution chart 2026-06-03 15:46:51 +08:00
caoxiaozhu
18d716bc6b feat(workbench): show expense distribution as donut chart 2026-06-03 15:31:09 +08:00
caoxiaozhu
74d488adfa fix(workbench): center progress expense type 2026-06-03 15:21:38 +08:00
caoxiaozhu
31052d0b98 feat(workbench): keep progress detail return context 2026-06-03 15:14:44 +08:00
caoxiaozhu
20cb60e247 feat(workbench): add expense stats detail modal 2026-06-03 14:59:55 +08:00
caoxiaozhu
3130c42d76 feat(workbench): separate stale progress items 2026-06-03 12:38:17 +08:00
caoxiaozhu
6fc5e66ea1 feat(workbench): show progress update time first 2026-06-03 12:28:21 +08:00
caoxiaozhu
27dd2f0a0d feat(dashboard): reorganize budget and risk cards 2026-06-03 10:47:11 +08:00
caoxiaozhu
faa39e6c06 test(dashboard): cover shared loading overlay 2026-06-03 09:45:06 +08:00
caoxiaozhu
d060f89d30 style(dashboard): reuse shared loading overlay 2026-06-03 09:43:36 +08:00
caoxiaozhu
0d6327a990 feat(dashboard): polish risk and digital employee boards 2026-06-03 09:41:32 +08:00
caoxiaozhu
15006a05a7 feat: 数字员工财务报告体系与定时提醒及看板快照调度
- 新增数字员工财务报告生成、邮件投递与渲染调度器
- 引入员工画像扫描调度与定时提醒任务
- 完善财务看板快照、排行口径与部门人员占比计算
- 优化数字员工工作看板仪表盘与技能目录
- 增强前端总览页图表、工作台摘要与顶部导航栏交互
- 新增差旅申请规划推动提醒与报销创建会话状态管理
- 补充财务报告、看板调度、数字员工工作记录测试覆盖
2026-06-03 09:25:23 +08:00
caoxiaozhu
0c74b4ab4a feat: 财务看板口径重构与半年模拟数据及报销状态注册表
- 重构 finance_dashboard 口径计算,新增模拟公司画像数据生成与筛选
- 引入 expense_claim_status_registry 统一报销状态流转
- 完善报销草稿流程、Item Sync 与本体解析器
- 优化总览页趋势图、分页组件与请求进度步骤
- 增强报销申请快速预览、本体工具与详情展示
- 新增半年报销模拟数据种子脚本与状态审计工具
- 补充财务看板、报销状态注册与模拟数据测试覆盖
2026-06-02 16:22:59 +08:00
caoxiaozhu
ca691f3ee0 feat: 优化差旅报销预审流程与个人工作台 UI 体系
- 完善 user_agent_application 申请差旅报销预审槽位与消息组装
- 增强预算助理报告与风险建议卡片交互
- 重构登录页视觉样式与移动端响应式适配
- 优化个人工作台、文档中心、政策中心、员工管理等页面布局
- 拆分 travelRequestDetailPreReviewModel 为 advice/submit 模型
- 补充报销草稿、风险复核、Item Sync 与模板执行器测试覆盖
2026-06-02 14:01:51 +08:00
caoxiaozhu
92444e7eae feat: 扩展风险规则体系、审批动态路由与预算中心列表化改造
- 新增 25+ 条风险规则(预算/报销/申请/通用类),完善风险规则模拟与反馈发布机制
- 引入费用审批动态路由、平台风险分级、预审与风险阶段管理
- 预算中心列表化改造,优化票据夹仪表盘与数字员工工作看板
- 新增 Hermes 风险线索收集器、Agent 链路追踪中心
- 扩展数字员工能力库(18 个领域 Skill)与交通费用自动预估
- 完善报销申请快速预览、权限控制与前端测试覆盖
2026-06-01 17:07:14 +08:00
caoxiaozhu
7989f3a159 feat: 新增风险图谱算法与系统仪表盘及操作反馈体系
后端新增风险图谱算法模块、风险观察与反馈服务、规则 DSL
校验器和可解释性引擎,完善系统仪表盘和财务仪表盘统计,
优化 agent 运行和编排执行链路,清理旧开发文档,前端新增
系统趋势、负载热力图等多种仪表盘图表组件,完善操作反馈
对话框和工作台日期选择器,优化报销创建和审批详情交互,
补充单元测试覆盖。
2026-05-30 15:46:51 +08:00
caoxiaozhu
4c59941ec6 feat: 新增票据夹模块并优化 OCR 与员工画像服务
后端新增票据夹端点、数据模型和服务模块,优化 OCR 端点
Schema 和附件操作逻辑,完善员工行为画像服务和辅助函数,
前端新增票据夹视图和服务层,优化文档中心样式和侧边栏导
航,完善员工画像详情弹窗和权限控制,补充单元测试。
2026-05-29 14:51:18 +08:00
caoxiaozhu
678f64d772 feat: 统一后端分页查询与前端服务层适配
后端新增通用分页模块,为报销单、员工、预算、agent 资产等
端点统一接入分页参数和游标查询,优化 repository 层分页实
现,前端服务层适配分页响应结构,完善预算图表和全局样式,
优化侧边栏和企业选择器组件,引入 Element Plus 插件注册。
2026-05-29 14:11:06 +08:00
caoxiaozhu
e080105f9f feat(ui): finalize shared shells and loading states 2026-05-29 13:17:39 +08:00
caoxiaozhu
64cc76c970 refactor(audit): reuse list shells and split models 2026-05-29 10:13:49 +08:00
caoxiaozhu
99e90798d2 refactor(audit): split list detail flows 2026-05-29 09:44:03 +08:00
caoxiaozhu
064eeb614f refactor(ui): introduce shared list detail shells 2026-05-28 22:49:58 +08:00
caoxiaozhu
b383244a29 chore: backup workspace before list detail shell refactor 2026-05-28 22:33:53 +08:00
caoxiaozhu
e384318046 feat: 引入 ECharts 统一图表并完善员工画像标签分页
后端优化员工行为画像服务和辅助函数,完善系统设置模型和
配置持久化,前端引入 ECharts 替换所有图表组件实现统一
渲染,新增员工画像标签分页器和数字员工工作记录组件,优
化工作台响应式布局和登录页过渡动画,完善预算中心和数字
员工页面样式细节。
2026-05-28 16:24:59 +08:00
caoxiaozhu
8a4a777be7 feat: 新增员工行为画像算法与费用风险标签体系
后端新增员工行为画像算法模块,支持标签规则引擎和评分计算,
完善员工模型、银行信息、序列化和导入逻辑,优化报销审批流
和工作流常量,增强 Hermes 同步和知识同步能力,前端新增费
用画像详情弹窗、雷达图和风险卡片组件,完善登录页和工作台
样式,优化文档中心和归档中心交互,补充单元测试。
2026-05-28 12:09:49 +08:00
caoxiaozhu
04cd6d0f81 feat: 新增数字员工管理页面与工作台首页重构
后端优化 agent 资产种子初始化和常量配置,前端新增数字员工
视图和调度对话框组件,重构个人工作台首页布局和洞察面板,
完善审计页面数字员工详情和运行时模型,优化侧边栏导航和图
标配置,新增工作台摘要和工作台数据模块,补充单元测试。
2026-05-28 09:30:34 +08:00
caoxiaozhu
d4d5d40569 feat: 新增预算费控模型与报销审批流引擎
后端新增预算费控服务和报销单审批流模块,引入申请人费用画像
算法,优化知识库 RAG 运行时和同步逻辑,完善报销单工作流常
量和明细同步,更新差旅报销规则电子表格,前端新增预算分析
组件和数字员工模型,完善审批对话框和洞察面板交互,优化侧
边栏和顶栏样式,补充单元测试。
2026-05-27 17:31:27 +08:00
caoxiaozhu
cbb98f4469 feat: 完善审批退回流程与报销申请关联
后端优化报销单访问策略和常量定义,增强退回原因和审批状态
流转,前端完善退回对话框和审批交互组件,新增报销申请关联
模型,优化文档中心行数据和审批收件箱工具函数,增强引导
流程和会话模型,补充单元测试覆盖。
2026-05-27 14:35:17 +08:00
caoxiaozhu
7d32eae74e feat: 新增预算助手报告组件并优化报销交互细节
新增预算助手报告视图模型和组件,优化报销洞察面板和消息项
样式细节,完善预算中心页面布局和文档中心视图,增强报销创
建会话管理和提交编排器,调整 Vite 构建配置,补充单元测试。
2026-05-27 12:27:17 +08:00
caoxiaozhu
b1a9c8a194 fix: 优化报销创建页面样式与洞察面板交互
修复侧边栏和审计视图样式细节,完善差旅报销洞察面板和消息
组件布局,优化报销创建页面会话管理和流程状态持久化,增强
申请预览工具函数和导航图标,补充单元测试。
2026-05-27 10:32:08 +08:00
caoxiaozhu
2dcc72102d style: 全局 UI 主题皮肤重构与样式模块化
引入 Element Plus 主题定制和主题皮肤 composable,将全局
样式拆分为组件级独立 CSS 文件(侧边栏、顶栏、工作台等),
统一色彩变量和间距规范,重构所有视图和组件样式以适配新
主题系统,优化图表和知识图谱组件视觉表现,提取审计和差
旅报销相关子组件。
2026-05-27 09:17:57 +08:00
caoxiaozhu
df49103f23 feat: 完善预算中心图表与确认对话框交互
后端预算服务增加汇总查询和辅助计算,前端预算中心优化趋
势图组件和数据展示,增强确认对话框通用性和样式,完善预
算编辑对话框布局,补充预算端点单元测试。
2026-05-26 20:07:56 +08:00
caoxiaozhu
e7bef0883d feat: 新增预算后端服务与差旅风险规则库
后端新增预算模型、端点和服务模块,支持预算 CRUD 和余额
查询,清理旧生成规则文件并替换为按严重等级分类的差旅风
险规则库,优化认证权限和报销单访问策略,新增财务规则目
录和演示数据构建脚本,前端预算中心增加对话框交互,完善
审计页面运行时模型和元数据展示,补充单元测试。
2026-05-26 17:29:35 +08:00
caoxiaozhu
e1e515ecae feat: 新增预算中心本体与风险规则评分回填
后端新增预算本体解析模块和风险规则评分回填服务,优化规则
生成本体对齐和提示词构建,增强费用类型关键词和本体验证,
完善报销查询和审计接口,前端预算中心页面增加对话框和本
体工具函数,重构审计页面元数据和视图模型,补充单元测试。
2026-05-26 12:16:20 +08:00
caoxiaozhu
0e861d8fa6 feat: 增强风险规则生成引擎与预算中心页面
后端拆分风险规则生成为解释器、语义分析、本体对齐等子模块,
优化模板执行和流程图生成,完善员工种子数据和导入逻辑,增强
报销单权限策略和草稿持久化,前端新增预算中心视图和趋势图
组件,重构审计页面和风险规则测试对话框交互,完善文档中心
和报销创建页面细节,补充单元测试覆盖。
2026-05-26 09:15:14 +08:00
caoxiaozhu
d0e946cf47 feat: 完善文档中心与报销申请交互及侧边栏重构
后端优化编排器报销查询和本体检测精度,增强报销单草稿保
存和附件回填逻辑,前端重构侧边栏组件支持折叠和图标导
航,完善文档中心状态筛选和详情提示,报销创建和审批详情
页优化会话管理和费用明细交互,新增助手应用服务和预设动
作工具函数,补充单元测试覆盖。
2026-05-25 13:35:39 +08:00
caoxiaozhu
50b1c3f9a9 feat: 增强规则资产管理与审计页面运行时调试
后端新增规则资产版本管理和规则文件 CRUD 接口,优化风险
规则生成模板执行和员工数据模型字段,知识库 RAG 增强本
地回退和文档提取能力,清理旧风险规则文件统一由生成引擎
管理,前端审计页面增加运行时调试面板和规则资产编辑交互,
补充单元测试覆盖。
2026-05-24 21:44:17 +08:00
caoxiaozhu
575f093c74 feat: 新增风险规则生成引擎与知识图谱可视化
后端新增风险规则自动生成和模板执行服务,支持从规则资产
批量生成并持久化风险规则文件;知识库入库日志增强图谱
查询和本地 RAG 回退,前端审计页面增加风险规则模型和流
程图组件,知识入库面板拆分为图谱可视化子组件,报销创
建页面增加引导式流程模型,更新知识库索引数据。
2026-05-23 19:54:42 +08:00
caoxiaozhu
5b388d08c0 feat: 增强知识库索引与设置页面模块化拆分
扩展知识库索引任务和 RAG 检索支持增量入库和文档去重,优
化本体检测和规则匹配精度,前端设置页面拆分为 LLM、邮件
和 Hermes 员工同步子面板并重构样式,新增日志详情组件和
知识入库日志模型,补充单元测试覆盖。
2026-05-22 23:47:28 +08:00
caoxiaozhu
88ff04bef8 feat: 新增归档中心页面并完善知识库与报销查询能力
新增前端归档中心视图及相关工具函数,扩充知识库文档分类和
提取器支持多种格式,增强编排器报销查询的多维度检索,优
化本体规则和用户代理审核消息,前端完善报销创建和审批详
情交互细节,补充单元测试覆盖。
2026-05-22 16:00:19 +08:00
caoxiaozhu
1f15699013 feat(mobile): track mobile app scaffold 2026-05-22 12:41:45 +08:00
caoxiaozhu
222ba0bfdc refactor(server): split oversized backend services 2026-05-22 10:42:31 +08:00
caoxiaozhu
2e57702638 docs: add agent code size standards 2026-05-22 10:42:19 +08:00
caoxiaozhu
5fe3b201d9 feat: 重构报销单服务并完善前端提交与审核交互
重构 expense_claims 服务模块结构并优化差旅票据审核逻辑,
增强用户代理服务的票据类型识别,前端报销创建页面拆分为
附件模型和会话模型模块,重构提交编排器和草稿关联确认流
程,更新知识库索引,补充单元测试。
2026-05-22 08:58:59 +08:00
1430 changed files with 330954 additions and 74186 deletions

View File

@@ -0,0 +1,160 @@
---
name: agent-change-log
description: Use when working in X-Financial after bug fixes that need a split dev log, when maintaining document/development/YYYY-MM-DD/dev-logs/bugs, or when generating the daily 17:00 combined work-logs.med from same-day feature docs and bug logs.
---
# Agent Change Log
## Overview
This skill keeps split development logs for X-Financial. Bug fixes are recorded under the same-day `dev-logs/bugs` folder. Daily summaries combine same-day feature documents and bug records into one `work-logs.med`.
The log should sound like a careful teammate writing for tomorrow's teammate: concrete, warm, and honest.
## When To Use
- After fixing a bug.
- When a post-commit hook detects a bug-like commit.
- At the daily 17:00 summary pass.
- Before updating the log in a branch where other agents may have pushed commits.
- After verification, so the entry can include what was actually checked.
- When a failed attempt changed files, generated artifacts, or revealed a risk worth preserving.
Do not create legacy `document/work-log/YYYY-MM-DD.md` entries for new work.
## Log Location
Use the same date root as development documents:
```text
document/development/YYYY-MM-DD/
├── feature/<feature-point>/CONCEPT.md + TODO.md
├── dev-logs/bugs/<bug-slug>.md
└── work-logs.med
```
If the date folder exists, reuse it. If not, create it.
## Bug Log Structure
For bug fixes, create or update one file per bug:
```text
document/development/YYYY-MM-DD/dev-logs/bugs/<bug-slug>.md
```
The file must contain `## 修复记录` and timestamped bullets similar to the old `当日工作内容`.
Do not add `遗留问题` or `TODO` sections to bug logs.
Use the helper when possible:
```bash
python3 tools/agent-change-log/update_change_log.py \
--kind bug \
--bug-title "<bug 名称>" \
--bug-slug <bug-slug>
```
## Required Git Check
Before writing or updating a bug log, manually check Git for upstream and local-ahead commits from other agents.
Run:
```bash
date '+%Y-%m-%d %H:%M:%S %Z'
git fetch --all --prune
git status -sb
git rev-parse --abbrev-ref --symbolic-full-name @{u}
git log --oneline --decorate --max-count=20 HEAD..@{u}
git log --oneline --decorate --max-count=20 @{u}..HEAD
```
Rules:
- Treat `git fetch --all --prune` as the default safe "pull check"; it updates remote refs without merging into a dirty worktree.
- Treat `HEAD..@{u}` as upstream commits not yet in local history.
- Treat `@{u}..HEAD` as local commits not yet in upstream history; these may also come from another agent working in the same checkout.
- If the worktree is clean and the branch is only behind upstream, `git pull --ff-only` may be used to fast-forward before analysis.
- If the worktree is dirty, diverged, or likely to conflict, do not merge/rebase automatically. Record the upstream commits from `HEAD..@{u}` in the bug fix entry.
- If there is no upstream branch, record that fact in the bug fix entry and continue with local-only logging.
- When `HEAD..@{u}` has commits, summarize those commits in the bug fix entry before describing local edits. Mention commit hash, subject, and inferred impact.
- When `@{u}..HEAD` has commits that were not created in the current task, summarize them too, because another local agent may have committed without pushing yet.
- When no upstream or local-ahead commits exist, still record "Git 提交检查:未发现 upstream 新提交或本地 ahead 新提交" in the work entry.
## Bug Entry Rules
1. Get the current local time first:
```bash
date '+%Y-%m-%d %H:%M:%S %Z'
```
2. Run the required Git check and capture whether upstream or local-ahead has new commits.
3. Ensure `document/development/YYYY-MM-DD/dev-logs/bugs/` exists.
4. Create or update one `<bug-slug>.md` file for the specific bug.
5. Append a new timestamped bullet under `## 修复记录`.
6. Mention Git commits, changed files or modules, the operation, the intent, and the verification result.
7. Do not add leftover issue or TODO sections.
## Daily Summary
At 17:00 every day, generate the combined work log:
```bash
python3 tools/agent-change-log/update_change_log.py --kind summary
```
This reads:
```text
document/development/YYYY-MM-DD/feature/
document/development/YYYY-MM-DD/dev-logs/bugs/
```
Then writes:
```text
document/development/YYYY-MM-DD/work-logs.med
```
The summary should cover:
- Today's feature points from `feature/*/CONCEPT.md` and `TODO.md`.
- Today's bug fixes from `dev-logs/bugs/*.md`.
- A concise combined analysis of what changed that day.
## Entry Rules
- For each bug entry, append a new timestamped bullet under `## 修复记录`.
- Mention Git commits, changed files or modules, the operation, the intent, and the verification result.
- Do not write `遗留问题`.
- Do not write `TODO`.
- If the change is a feature rather than a bug, use the development document skill to keep `feature/<feature-point>/CONCEPT.md` and `TODO.md` current instead of writing a bug log.
## Writing Style
- Write in Simplified Chinese.
- Be specific and a little human: "我把...", "这次先...", "还需要留意..." are good.
- Keep the tone factual. Do not turn the log into a victory lap.
- Prefer concise file names and module names in prose, but include enough context to find the change.
- Work content should be detailed enough that a future agent can continue without asking "你到底改了啥?"
## Bug Entry Template
```markdown
- HH:MM记录 bug 修复:<bug 名称>。
- Git 提交检查:<git fetch 后 HEAD..upstream 与 upstream..HEAD 的结果;没有就写未发现 upstream 或本地 ahead 新提交>。
- 修改:<文件/模块><做了什么>。
- 操作:<运行了什么命令、迁移了什么状态、重启了什么服务等>。
- 验证:<测试/构建/检查结果;如果没跑,说明原因>。
- 影响:<用户可见变化或工程边界变化>。
```
## Final Response Checklist
Before saying work is complete:
- For bug fixes, today's bug log exists under `document/development/YYYY-MM-DD/dev-logs/bugs/`.
- For non-bug feature work, relevant `feature/<feature-point>` documents are current.
- Git check ran for bug logs, and upstream plus local-ahead commits were summarized or explicitly marked as absent.
- No new legacy `document/work-log/YYYY-MM-DD.md` entry was created.
- The final response mentions whether a bug log, feature document, or daily `work-logs.med` was updated.

View File

@@ -0,0 +1,4 @@
interface:
display_name: "Agent Change Log"
short_description: "Record bug logs and daily work summaries"
default_prompt: "Use $agent-change-log after an X-Financial bug fix or at 17:00 to update document/development/<date>/dev-logs/bugs or work-logs.med."

View File

@@ -0,0 +1,85 @@
---
name: git-checkpoint-commit
description: Use when a coding task finishes a verified bug fix, key feature, risky refactor checkpoint, local backup commit, checkpoint commit, 提交备份, 本地提交, or when an active session has accumulated about five meaningful edit rounds and should create a scoped local git commit without pushing.
---
# Git Checkpoint Commit
## Overview
Use this skill to keep a local git backup loop during active development. The goal is to commit verified, task-scoped progress at meaningful checkpoints without mixing unrelated user changes or pushing remotely.
## Trigger Rules
Create a local checkpoint commit when any condition is true:
- A bug fix is implemented and the targeted regression check passes.
- A key feature slice is implemented and the smallest relevant verification passes.
- A risky refactor reaches a behavior-preserving checkpoint.
- The current session has reached about five meaningful edit rounds since the last commit.
- The user asks for `提交`, `本地提交`, `备份`, `checkpoint`, `commit`, or `形成提交循环`.
Do not use this skill when the user explicitly says not to commit, when the change is exploratory and unverified, or when the only available commit would include unrelated dirty files.
## Workflow
1. Inspect the working tree with `git status --short`.
2. Identify files or hunks owned by the current task.
3. Run the smallest relevant verification first.
- In X-Financial, run backend tests inside `x-financial-main` when backend code is involved.
- Use targeted frontend tests/builds for web-only changes.
4. Commit only the task-owned files.
5. Report the commit hash and verification evidence.
6. Reset the session edit counter to zero after a successful checkpoint.
## Safety Rules
- Never commit unrelated user changes just to make the tree clean.
- Never push as part of this skill.
- Never rewrite history, amend old commits, or run destructive git commands.
- If the same file contains unrelated hunks, split the staging carefully with `git add -p` or a narrower manual patch.
- If the index already contains staged changes, inspect them first; do not mix them into a checkpoint unless they belong to the same current task.
- If verification cannot run, say why in the commit body or final report and prefer a `chore(checkpoint)` message rather than a confident `fix` or `feat`.
## Commit Style
Use normal semantic messages for completed, verified work:
- `fix(workbench): keep application preview after draft save failure`
- `feat(reimbursements): add attachment association job polling`
- `refactor(claims): split draft flow serialization`
Use checkpoint messages for interim backup points:
- `chore(checkpoint): backup attachment association flow`
- `chore(checkpoint): backup after five edit rounds`
Keep the subject concise. Add body lines only when the verification state or scope needs clarity.
## Helper Script
Use `scripts/checkpoint_commit.py` when a path-scoped local commit is enough:
```bash
python3 .codex/skills/git-checkpoint-commit/scripts/checkpoint_commit.py \
--message "chore(checkpoint): backup workbench AI flow" \
web/src/composables/workbenchAiMode/useWorkbenchAiExpenseFlow.js \
web/tests/workbench-ai-mode-switch.test.mjs
```
Preview before committing:
```bash
python3 .codex/skills/git-checkpoint-commit/scripts/checkpoint_commit.py \
--dry-run \
web/src/utils/expenseApplicationPreview.js
```
The script refuses to commit the whole tree unless `--allow-all` is passed. Use `--allow-all` only when the current task truly owns every dirty file.
## Common Mistakes
- Mistaking backup for verification. Verify first, then commit.
- Staging `.` in a dirty worktree. Stage explicit paths or hunks.
- Combining documentation cleanup, feature work, and unrelated local edits in one checkpoint.
- Continuing indefinitely after multiple verified slices. Commit once the counter reaches five meaningful edit rounds.

View File

@@ -0,0 +1,4 @@
interface:
display_name: "Git Checkpoint Commit"
short_description: "Create local backup commits at safe milestones"
default_prompt: "Use $git-checkpoint-commit to checkpoint verified task changes into a local git commit."

View File

@@ -0,0 +1,127 @@
#!/usr/bin/env python3
"""Create a path-scoped local git checkpoint commit."""
from __future__ import annotations
import argparse
import subprocess
import sys
from pathlib import Path
def run_git(args: list[str], cwd: Path, *, check: bool = True) -> subprocess.CompletedProcess[str]:
result = subprocess.run(
["git", *args],
cwd=cwd,
text=True,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
timeout=60,
)
if check and result.returncode != 0:
message = result.stderr.strip() or result.stdout.strip()
raise SystemExit(f"git {' '.join(args)} failed: {message}")
return result
def repo_root() -> Path:
result = subprocess.run(
["git", "rev-parse", "--show-toplevel"],
text=True,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
timeout=60,
)
if result.returncode != 0:
raise SystemExit("Not inside a git repository.")
return Path(result.stdout.strip())
def load_paths(args: argparse.Namespace) -> list[str]:
paths = list(args.paths)
if args.paths_from_file:
raw_lines = Path(args.paths_from_file).read_text(encoding="utf-8").splitlines()
paths.extend(line.strip() for line in raw_lines if line.strip() and not line.startswith("#"))
return paths
def ensure_clean_index(root: Path) -> None:
staged = run_git(["diff", "--cached", "--name-only"], root).stdout.strip()
if staged:
raise SystemExit(
"Refusing to continue because the index already has staged changes:\n"
f"{staged}\n"
"Commit or unstage them before running this checkpoint helper."
)
def status_for(root: Path, paths: list[str], allow_all: bool) -> str:
command = ["status", "--short"]
if not allow_all:
command.extend(["--", *paths])
return run_git(command, root).stdout.strip()
def infer_message(paths: list[str], allow_all: bool) -> str:
if allow_all or not paths:
return "chore(checkpoint): backup current task changes"
first_parts = [Path(item).parts[0] for item in paths if Path(item).parts]
scope = first_parts[0] if first_parts else "task"
return f"chore(checkpoint): backup {scope} changes"
def parse_args() -> argparse.Namespace:
parser = argparse.ArgumentParser(description=__doc__)
parser.add_argument("paths", nargs="*", help="Task-owned paths to stage and commit.")
parser.add_argument("-m", "--message", help="Commit message subject/body.")
parser.add_argument("--paths-from-file", help="Read additional pathspecs from a UTF-8 text file.")
parser.add_argument("--dry-run", action="store_true", help="Show matching changes without staging.")
parser.add_argument("--allow-all", action="store_true", help="Allow committing all dirty files.")
parser.add_argument("--no-verify", action="store_true", help="Pass --no-verify to git commit.")
return parser.parse_args()
def main() -> int:
args = parse_args()
root = repo_root()
paths = load_paths(args)
if not paths and not args.allow_all:
raise SystemExit("Pass explicit paths, or use --allow-all when the current task owns all changes.")
current_status = status_for(root, paths, args.allow_all)
if not current_status:
print("No matching changes to commit.")
return 0
print(current_status)
if args.dry_run:
return 0
ensure_clean_index(root)
# 使用 -A 保留删除/重命名等变更,但只作用于明确传入的 pathspec。
if args.allow_all:
run_git(["add", "-A"], root)
else:
run_git(["add", "-A", "--", *paths], root)
staged_summary = run_git(["diff", "--cached", "--name-status"], root).stdout.strip()
if not staged_summary:
raise SystemExit("No staged changes after git add.")
message = args.message or infer_message(paths, args.allow_all)
commit_command = ["commit"]
if args.no_verify:
commit_command.append("--no-verify")
commit_command.extend(["-m", message])
commit_result = run_git(commit_command, root)
sys.stdout.write(commit_result.stdout)
commit_hash = run_git(["rev-parse", "--short", "HEAD"], root).stdout.strip()
print(f"checkpoint_commit={commit_hash}")
return 0
if __name__ == "__main__":
raise SystemExit(main())

View File

@@ -0,0 +1,125 @@
---
name: write-development-docs
description: Use when working in X-Financial and the user asks to 落文档, 写开发文档, 沉淀方案, 补 concept/todo, or create/update planning documentation under document/development for a feature, refactor, page, algorithm, rule, or business capability.
---
# Write Development Docs
## 目标
把一个功能、重构、算法、页面或业务能力沉淀为项目标准开发文档。
默认落点固定为:
```text
document/development/<YYYY-MM-DD>/feature/<具体功能点目录>/
├── CONCEPT.md
└── TODO.md
```
如果用户说 `concept.md` / `todo.md`,也按仓库现有规范使用大写文件名
`CONCEPT.md``TODO.md`
## 工作流
1. 先读取当前日期,默认使用本地日期 `YYYY-MM-DD` 作为第一层目录。
2. 先阅读 `document/development` 中 2-3 组相邻或同类样例。
3. 再读取本次能力相关的代码、接口、页面、测试或历史文档。
4. 创建或更新 `CONCEPT.md`,先写清业务边界,再写方案和验收。
5. 创建或更新 `TODO.md`,每个任务都要回链到 `CONCEPT.md` 的章节。
6. 已实现或已验证的 TODO 可以勾选 `[x]`,但必须写证据。
7. 交付前检查两份文档互相一致,不额外创建 README、CHANGELOG、SUMMARY。
## 路径规则
- 第一层必须是日期目录,例如 `document/development/2026-06-25/`
- 第二层固定是 `feature/`,表示当天沉淀的功能点集合。
- 第三层是具体功能点目录,每个独立功能点一个目录。
- 每个具体功能点目录内只放 `CONCEPT.md``TODO.md` 两个核心文件。
- 如果一次请求包含多个互不依赖的功能点,拆成多个兄弟目录:
```text
document/development/2026-06-25/feature/
├── receipt-folder-ocr/
│ ├── CONCEPT.md
│ └── TODO.md
└── risk-review-nudge/
├── CONCEPT.md
└── TODO.md
```
- 如果用户明确指定日期,使用用户指定日期;否则使用当前本地日期。
- 如果是更新历史文档,先查找已有目录并原地更新,不自动迁移旧路径。
## 目录命名
- 优先复用用户指定目录名或已有目录名。
- 新增英文目录用小写 kebab-case例如 `receipt-folder`
- 新增中文目录可直接用清晰中文能力名,例如 `费用审批动态路由`
- 同一能力已有目录时更新原目录,不新建近义目录。
## CONCEPT.md 要求
可参考 `assets/CONCEPT.md` 模板。必须包含:
- 标题:`# <功能名> 概念文档`
- `更新时间YYYY-MM-DD`
- `## 功能一句话`
- `## 背景与问题`
- `## 目标与非目标`
- `## 用户与场景`
- `## 功能能力`
- `## 方案设计`
- `## 算法与公式`
- `## 测试方案`
- `## 指标与验收`
- `## 风险与开放问题`
写法要求:
- 先讲业务问题和边界,再讲技术方案。
- 目标与非目标分开写,避免需求无限扩张。
- 方案设计按前端、后端、算法/规则、数据、权限、降级策略分块;
不涉及的块明确写“当前不涉及”。
- 算法与公式必须明确“不涉及”或写出公式、变量说明和适用边界。
- 验收标准必须可验证,不写空泛口号。
## TODO.md 要求
可参考 `assets/TODO.md` 模板。必须包含:
- 标题:`# <功能名> 开发 TODO`
- `更新时间YYYY-MM-DD`
- `## 使用规则`
- 分阶段 checklist
TODO 条目规则:
- 每条用 `- [ ]``- [x]`
- 每条必须包含 `[CONCEPT: <章节名>]`
- 已完成项必须补证据,格式为 `证据:<文件、接口、命令或验证结果>`
- 没有真实证据时不得勾选 `[x]`
建议阶段:
- `## 1. 调研与边界`
- `## 2. 契约与设计`
- `## 3. 后端实现`
- `## 4. 算法/规则实现`
- `## 5. 前端实现`
- `## 6. 测试与验证`
- `## 7. 文档收尾`
## 更新既有文档
- 先读现有 `CONCEPT.md``TODO.md` 全文。
- 新需求先补 `CONCEPT.md`,再补 `TODO.md`
- 实现变化时同步更新“非目标”“风险与开放问题”“本轮实现记录”。
- 不删除历史证据;除非证据明显错误,才替换为新证据。
## 验收检查
- 新建文档路径符合 `document/development/<YYYY-MM-DD>/feature/<具体功能点目录>/`
- `CONCEPT.md``TODO.md` 都存在于同一个具体功能点目录。
- TODO 的 `[CONCEPT: ...]` 都能在 CONCEPT 中找到对应章节或语义段落。
- 已勾选项都有证据。
- 文档没有遗留模板占位符,例如 `<功能名>``<YYYY-MM-DD>``待补充`

View File

@@ -0,0 +1,4 @@
interface:
display_name: "开发文档落地"
short_description: "按日期和功能点生成 CONCEPT/TODO"
default_prompt: "Use $write-development-docs to create CONCEPT.md and TODO.md under document/development/<date>/feature/<feature-point> for an X-Financial feature."

View File

@@ -0,0 +1,132 @@
# <功能名> 概念文档
更新时间:<YYYY-MM-DD>
文档路径document/development/<YYYY-MM-DD>/feature/<具体功能点目录>/CONCEPT.md
## 功能一句话
用一句话说明这个能力解决什么问题、服务谁、交付什么结果。
## 背景与问题
- 当前现状:
- 用户痛点:
- 业务影响:
- 为什么现在需要做:
## 目标与非目标
### 目标
- [G1]
- [G2]
- [G3]
### 非目标
- [NG1] 本轮不做:
- [NG2] 本轮不改变:
- [NG3] 后续再评估:
## 用户与场景
- 目标用户:
- 使用入口:
- 核心场景:
1.
2.
3.
- 异常场景:
-
## 功能能力
- [C1] 输入能力:
- [C2] 处理能力:
- [C3] 输出能力:
- [C4] 状态与权限:
- [C5] 边界与降级:
## 方案设计
### 前端
- 页面/组件:
- 交互状态:
- 展示规则:
- 降级处理:
### 后端
- 接口/服务:
- 权限与校验:
- 持久化:
- 降级处理:
### 算法与规则
- 输入:
- 流程:
- 输出:
- 解释:
### 数据与契约
- 核心字段:
- 状态枚举:
- 兼容策略:
- 版本/审计:
## 算法与公式
当前功能不涉及显式数学公式。
如涉及公式,使用如下格式:
```text
metric = input_a + input_b
```
变量说明:
- metric
- input_a
- input_b
## 测试方案
后端:
-
前端:
-
集成:
-
手工验证:
-
## 指标与验收
- [A1] 功能验收:
- [A2] 性能指标:
- [A3] 质量指标:
- [A4] 安全/权限指标:
- [A5] 可观测性:
## 风险与开放问题
- 风险:
- 已处理依赖:
- 待确认:
- 降级策略:
## 本轮实现记录
-

View File

@@ -0,0 +1,73 @@
# <功能名> 开发 TODO
更新时间:<YYYY-MM-DD>
文档路径document/development/<YYYY-MM-DD>/feature/<具体功能点目录>/TODO.md
## 使用规则
- 每个 TODO 必须对应 `CONCEPT.md` 中的目标、能力、方案或验收点。
- 只有完成并验证后,才能把 `[ ]` 改成 `[x]`
- 勾选时在任务后补充简短证据,例如文件、接口、命令或验证结果。
- 如果需求发生变化,先更新 `CONCEPT.md`,再调整本 TODO。
## 1. 调研与边界
- [ ] [CONCEPT: 背景与问题] 阅读相关页面、接口、服务、测试和历史文档,记录当前实现事实。
证据:
- [ ] [CONCEPT: 目标与非目标] 确认本轮开发范围,写清楚不做项。
证据:
- [ ] [CONCEPT: 风险与开放问题] 标记无法立即确认的依赖、风险和假设。
证据:
## 2. 契约与设计
- [ ] [CONCEPT: 功能能力] 定义输入、输出、状态、权限和边界条件。
证据:
- [ ] [CONCEPT: 方案设计] 明确前端、后端、算法、数据的职责边界。
证据:
- [ ] [CONCEPT: 算法与公式] 补全公式、变量解释或明确当前不涉及公式。
证据:
- [ ] [CONCEPT: 指标与验收] 把验收标准转成可验证的检查点。
证据:
## 3. 后端实现
- [ ] [CONCEPT: 后端] 新增或调整 schema、service、endpoint、权限和持久化逻辑。
证据:
- [ ] [CONCEPT: 数据与契约] 保持响应结构、状态枚举和兼容策略清晰。
证据:
## 4. 算法/规则实现
- [ ] [CONCEPT: 算法与规则] 实现核心处理流程、规则判断或计算逻辑。
证据:
- [ ] [CONCEPT: 结果解释] 输出可读解释、证据链、贡献项或降级原因。
证据:
## 5. 前端实现
- [ ] [CONCEPT: 前端] 新增或调整页面、组件、服务 API 和视图模型。
证据:
- [ ] [CONCEPT: 前端] 实现加载、空态、错误态、权限态和刷新。
证据:
- [ ] [CONCEPT: 前端] 对齐现有企业后台风格,避免营销页或花哨卡片感。
证据:
## 6. 测试与验证
- [ ] [CONCEPT: 测试方案] 补充后端 service/API 定向测试,容器内运行,超时控制在 60s 内。
证据:
- [ ] [CONCEPT: 测试方案] 补充前端视图模型、路由、组件或构建验证。
证据:
- [ ] [CONCEPT: 指标与验收] 记录验证命令、结果和未覆盖风险。
证据:
## 7. 文档收尾
- [ ] [CONCEPT: 指标与验收] 回看所有验收点,确认均有实现或验证证据。
证据:
- [ ] [CONCEPT: 风险与开放问题] 更新剩余风险、后续任务和明确不做项。
证据:
- [ ] [CONCEPT: 功能一句话] 确认最终实现没有偏离原始目标。
证据:

51
.env
View File

@@ -1,51 +0,0 @@
APP_NAME=X-Financial
APP_ENV=local
APP_DEBUG=true
API_V1_PREFIX=/api/v1
SETUP_COMPLETED=true
VITE_SETUP_COMPLETED=true
COMPANY_NAME=YGSOFT
COMPANY_CODE=123
ADMIN_EMAIL='admin@admin.com'
VITE_COMPANY_NAME=YGSOFT
VITE_COMPANY_CODE=123
VITE_ADMIN_EMAIL='admin@admin.com'
# Admin login credentials are stored separately under server/.secrets/
WEB_HOST=10.10.10.122
WEB_PORT=5173
VITE_WEB_HOST=10.10.10.122
VITE_WEB_PORT=5173
SERVER_HOST=0.0.0.0
SERVER_PORT=8000
VITE_SERVER_HOST=0.0.0.0
VITE_SERVER_PORT=8000
SERVER_STARTUP_TIMEOUT=300
SERVER_BLOCKING_STARTUP_TIMEOUT=12
VITE_API_BASE_URL=/api/v1
VITE_AUTH_IDLE_TIMEOUT_MINUTES=30
ONLYOFFICE_ENABLED=true
ONLYOFFICE_PUBLIC_URL=http://10.10.10.122:8082
ONLYOFFICE_BACKEND_URL=http://main:8000
ONLYOFFICE_JWT_SECRET=change-me-onlyoffice
HERMES_AGENT_SHARED_TOKEN=change-me-hermes
POSTGRES_HOST=10.10.10.189
POSTGRES_PORT=5432
POSTGRES_DB=postgres
POSTGRES_USER=root
POSTGRES_PASSWORD=8811614287327Leo
VITE_POSTGRES_HOST=10.10.10.189
VITE_POSTGRES_PORT=5432
VITE_POSTGRES_DB=postgres
VITE_POSTGRES_USER=root
DATABASE_URL='postgresql+psycopg://root:8811614287327Leo@10.10.10.189:5432/postgres'
SQLALCHEMY_ECHO=false
REDIS_URL=
VITE_REDIS_URL=
CORS_ORIGINS='["http://10.10.10.122:5173"]'

View File

@@ -31,6 +31,7 @@ ONLYOFFICE_PUBLIC_URL=http://127.0.0.1:8082
ONLYOFFICE_BACKEND_URL=http://127.0.0.1:8000 ONLYOFFICE_BACKEND_URL=http://127.0.0.1:8000
ONLYOFFICE_JWT_SECRET=change-me-onlyoffice ONLYOFFICE_JWT_SECRET=change-me-onlyoffice
HERMES_AGENT_SHARED_TOKEN=change-me-hermes HERMES_AGENT_SHARED_TOKEN=change-me-hermes
STEWARD_AGENT_RUNTIME=langgraph
POSTGRES_HOST=127.0.0.1 POSTGRES_HOST=127.0.0.1
POSTGRES_PORT=5432 POSTGRES_PORT=5432
@@ -48,4 +49,8 @@ SQLALCHEMY_ECHO=false
REDIS_URL= REDIS_URL=
VITE_REDIS_URL= VITE_REDIS_URL=
OCR_DEVICE=
OCR_TIMEOUT_SECONDS=180
OCR_MAX_CONCURRENT_WORKERS=1
CORS_ORIGINS='["http://127.0.0.1:5173","http://localhost:5173","http://0.0.0.0:5173"]' CORS_ORIGINS='["http://127.0.0.1:5173","http://localhost:5173","http://0.0.0.0:5173"]'

10
.githooks/post-commit Executable file
View File

@@ -0,0 +1,10 @@
#!/bin/sh
# Auto-append a minimal X-Financial agent work-log entry after each commit.
repo_root="$(git rev-parse --show-toplevel 2>/dev/null)" || exit 0
cd "$repo_root" || exit 0
python3 tools/agent-change-log/update_change_log.py \
--kind auto \
--event "post-commit hook" \
>/tmp/x-financial-agent-change-log-hook.log 2>&1 || true

27
.gitignore vendored
View File

@@ -7,7 +7,18 @@ web/.vite/
.omc/ .omc/
.omx/ .omx/
.claude/ .claude/
.codex/ *.egg-info/
.codex/*
!.codex/skills/
.codex/skills/*
!.codex/skills/agent-change-log/
!.codex/skills/agent-change-log/**
!.codex/skills/git-checkpoint-commit/
!.codex/skills/git-checkpoint-commit/**
!.codex/skills/write-development-docs/
!.codex/skills/write-development-docs/**
.codex-temp/
.superpowers/
*.log *.log
.DS_Store .DS_Store
Thumbs.db Thumbs.db
@@ -16,3 +27,17 @@ __pycache__/
server/.venv/ server/.venv/
server/.venv-ocr312 server/.venv-ocr312
server/.secrets/ server/.secrets/
server/logs/
server/storage/expense_claims/
server/storage/finance_reports/
server/storage/receipt_folder/
test-results/
.codex-remote-attachments/
tmp-*.png
tmp/
.zcode/
.nezha/
.omo/
.env
.env.local
.env.*.local

1
.tmp/Yuxi Submodule

Submodule .tmp/Yuxi added at fd6803e477

65
AGENTS.md Normal file
View File

@@ -0,0 +1,65 @@
# X-Financial Agent 协作规范
## 语言规范
- 所有分析、解释、计划、提交说明和最终回复默认使用简体中文。
- 技术结论要直击重点,必要时给出可验证的文件、命令或测试结果。
## 变更日志 Skill 规范
- 每次修复 bug 后,必须调用项目级 Skill `agent-change-log`,并在 `document/development/YYYY-MM-DD/dev-logs/bugs/<bug-slug>.md` 记录该 bug 的修复内容。
- 新增功能、重构、配置或项目文档变更不再写入旧的 `document/work-log/YYYY-MM-DD.md`;功能点默认沉淀到 `document/development/YYYY-MM-DD/feature/<具体功能点>/CONCEPT.md``TODO.md`
- 写 bug 日志前必须先执行 Git 拉取检查:默认运行 `git fetch --all --prune``git status -sb``git log HEAD..@{u}``git log @{u}..HEAD`。发现其他智能体已提交到上游或本地 ahead 提交时,要把这些提交摘要写进 bug 修复记录。
- 自动化触发由 `tools/agent-change-log/update_change_log.py``.githooks/post-commit` 提供;新 checkout 需要执行 `tools/agent-change-log/install_post_commit_hook.sh` 安装到本地 `.git/hooks/post-commit` 后,提交后才会按 `--kind auto` 自动识别 bug-like commit 并写入 `dev-logs/bugs`
- bug 日志只保留 `## 修复记录`,记录具体时间、改了什么、操作了什么、验证了什么和影响;不再写 `遗留问题``TODO` 两块。
- 每天 17:00 生成当天综合日志:读取 `document/development/YYYY-MM-DD/feature/``document/development/YYYY-MM-DD/dev-logs/bugs/`,分析功能点与 bug 修复后写入 `document/development/YYYY-MM-DD/work-logs.med`
## 通用代码拆分规范
无论写前端、后端还是算法代码,都必须主动避免“所有方法堆在一个类里 / 一个组件里 / 一个模块里”的写法。遇到类、组件或核心模块持续变大时,优先按职责拆分,而不是继续追加方法和状态。
### 行数与复杂度目标
- 单个类、核心组件、核心算法模块硬上限为 800 行。
- 普通文件建议控制在 300-600 行。
- 复杂业务文件可以接近 800 行,但必须有清晰职责边界。
- 文件或类超过 800 行必须视为重构预警,不应继续直接追加功能。
- 单个类不应长期承载几十个无关方法,更不应演化成上百个方法的万能类。
### 拆分原则
- 对外 API 尽量保持稳定,先把内部实现拆到小模块。
- 按职责拆分编排、状态管理、持久化、权限、文件存储、OCR/票据分析、规则审核、响应构建、序列化、UI 交互、算法策略、数据转换。
- 新增能力时先判断归属模块;没有合适归属时新增小模块,不要默认塞回主类、主组件或主 Service。
- 拆分必须小步进行,每次提取一个明确职责,并配套运行相关测试。
### X-Financial 重点关注对象
- `ExpenseClaimService`:优先拆分申请单、明细项、附件、票据分析、草稿、规则审核、权限、序列化。
- `UserAgentService`:优先拆分知识库问答、报销预审 payload、Markdown 回复、差旅政策、表单槽位、票据分类、建议动作。
- `OrchestratorService`:优先拆分 agent 路由、工具调用、报销查询、响应构建。
- 前端大型 Vue 页面:优先拆分 composable、view model、样式分片、业务工具函数和子组件。
- 算法/规则模块:优先拆分输入解析、规则匹配、评分策略、结果解释和异常处理。
## 容器与运行环境(必读)
本项目代码是 Docker 容器 `local-x-financial-linux`(镜像 `x-financial-dev:latest`)的源码映射。
- **容器映射**:宿主机 `D:\Code\Project\X-Financial` ↔ 容器内 `/app``docker-compose.yml``volumes: - .:/app``working_dir: /app`)。
- **后端 venv**:容器内位于 `/tmp/x-financial-server-venv`(环境变量 `SERVER_VENV_DIR`),不要假设宿主机上有相同的 venv。
- **外部依赖**Qdrant`x-financial-qdrant`、OnlyOffice`x-financial-onlyoffice`)也在同一 compose 网络里。
## 验证规范(硬性约束)
> 本项目代码与运行环境以容器为唯一事实来源。所有后端测试、集成测试、依赖了 Qdrant / OnlyOffice / venv 的验证,都必须在 `local-x-financial-linux` 容器内执行,**不要在宿主机上直接跑 pytest / pip / python**。
- **进入容器跑命令**(最常用):
```bash
docker exec -w /app -e SERVER_VENV_DIR=/tmp/x-financial-server-venv local-x-financial-linux <cmd>
```
- 跑后端测试:`docker exec -w /app -e SERVER_VENV_DIR=/tmp/x-financial-server-venv local-x-financial-linux /tmp/x-financial-server-venv/bin/pytest -q <path>`
- 交互式排查:`docker exec -it -w /app local-x-financial-linux bash`(登录后默认已在 `/app`
- **容器不可用时**(未启动、健康检查失败、镜像丢失):先 `docker compose up -d main` 恢复,再继续验证;不要绕开容器在宿主机另装 venv。
- **单元测试设置合理超时**避免长时间卡死。涉及外部服务Qdrant / OnlyOffice / LLM的测试要么 mock要么确认 compose 网络中依赖服务在线。
- **每次重构后至少运行对应服务的定向测试**;涉及公共协议时补充端到端或接口测试。
- **修改 docker-compose / start.sh / venv 路径相关代码**时,自己也要回容器里跑一次确认改动生效,不要只改文件就声称完成。

View File

@@ -1,45 +1,50 @@
# X-Financial # X-Financial
项目结构已按前后端拆开: 项目结构已按前后端拆开:
- `web/`:前端工程(当前 Vue + Vite 项目) - `web/`:前端工程(当前 Vue + Vite 项目)
- `server/`:后端工程目录 - `server/`:后端工程目录
- `docs/`:方案和阶段文档 - `docs/`:方案和阶段文档
- `UI/`:界面参考稿 - `UI/`:界面参考稿
- `document/`:业务文档 - `document/`:业务文档
根目录统一环境变量: 根目录统一环境变量:
- `.env` - `.env`
- `.env.example` - `.env.example`
这里集中维护: 这里集中维护:
- 前端启动端口 - 前端启动端口
- 后端启动端口 - 后端启动端口
- PostgreSQL 连接参数 - PostgreSQL 连接参数
- `DATABASE_URL` - `DATABASE_URL`
- `REDIS_URL` - `REDIS_URL`
从根目录统一启动: 从根目录统一启动:
```bash ```bash
./start.sh ./start.sh
``` ```
可选模式: 可选模式:
```bash ```bash
./start.sh web ./start.sh web
./start.sh server ./start.sh server
./start.sh all ./start.sh all
``` ```
根目录 `start.sh` 是统一编排入口;前端和后端的子启动脚本分别是 `web/web_start.sh``server/server_start.sh` 根目录 `start.sh` 是统一编排入口;前端和后端的子启动脚本分别是 `web/web_start.sh``server/server_start.sh`
手动进入前端目录 Docker Compose 运行方式见 `docker/README.md`
```bash - `docker-compose.yml`只启动主应用容器适合复用已有数据库、ONLYOFFICE 等外部依赖。
cd web - `docker-compose.full.yml`启动主应用、PostgreSQL、Qdrant、ONLYOFFICE 的完整本地开发栈。
npm run dev
``` 手动进入前端目录:
```bash
cd web
npm run dev
```

144
docker-compose.full.yml Normal file
View File

@@ -0,0 +1,144 @@
services:
main:
image: x-financial-dev:latest
container_name: local-x-financial-linux
restart: unless-stopped
depends_on:
postgres:
condition: service_healthy
onlyoffice:
condition: service_started
qdrant:
condition: service_started
environment:
WEB_HOST: 0.0.0.0
WEB_PORT: "${WEB_PORT:-5173}"
SERVER_HOST: 0.0.0.0
SERVER_PORT: "${SERVER_PORT:-8000}"
SERVER_RELOAD: "${SERVER_RELOAD:-true}"
SERVER_VENV_DIR: /tmp/x-financial-server-venv
X_FINANCIAL_PREFER_ENV_FILE: "false"
POSTGRES_HOST: postgres
POSTGRES_PORT: "5432"
POSTGRES_DB: "${POSTGRES_DB:-x_financial}"
POSTGRES_USER: "${POSTGRES_USER:-x_financial}"
POSTGRES_PASSWORD: "${POSTGRES_PASSWORD:-x_financial}"
DATABASE_URL: "postgresql+psycopg://${POSTGRES_USER:-x_financial}:${POSTGRES_PASSWORD:-x_financial}@postgres:5432/${POSTGRES_DB:-x_financial}"
ONLYOFFICE_ENABLED: "true"
ONLYOFFICE_PUBLIC_URL: "${LOCAL_ONLYOFFICE_PUBLIC_URL:-http://127.0.0.1:${ONLYOFFICE_PORT:-8082}}"
ONLYOFFICE_BACKEND_URL: "${LOCAL_ONLYOFFICE_BACKEND_URL:-http://main:${SERVER_PORT:-8000}}"
ONLYOFFICE_JWT_SECRET: "${ONLYOFFICE_JWT_SECRET:-x-financial-onlyoffice-dev-secret}"
QDRANT_URL: "http://qdrant:6333"
LIGHTRAG_WORKSPACE: "x_financial_knowledge"
ports:
- "${WEB_PORT:-5173}:${WEB_PORT:-5173}"
- "${SERVER_PORT:-8000}:${SERVER_PORT:-8000}"
- "2223:22"
volumes:
- .:/app
working_dir: /app
command:
- /bin/sh
- -lc
- >
apt-get update &&
DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends
python3 python3-pip python3-venv fontconfig openssh-server poppler-data mupdf-tools &&
if ! fc-match 'Noto Sans CJK SC' | grep -qi 'Noto'; then if ! timeout "${CJK_FONT_INSTALL_TIMEOUT_SECONDS:-45}" sh -lc 'DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends fonts-noto-cjk fonts-noto-cjk-extra'; then printf '%s\n' '[WARN] CJK font installation timed out or failed; continuing startup without blocking the app.'; fi; fi &&
printf '%s\n'
'<?xml version="1.0"?>'
'<!DOCTYPE fontconfig SYSTEM "fonts.dtd">'
'<fontconfig>'
' <alias><family>SimSun</family><prefer><family>Noto Serif CJK SC</family></prefer></alias>'
' <alias><family>NSimSun</family><prefer><family>Noto Serif CJK SC</family></prefer></alias>'
' <alias><family>KaiTi</family><prefer><family>Noto Serif CJK SC</family></prefer></alias>'
' <alias><family>FangSong</family><prefer><family>Noto Serif CJK SC</family></prefer></alias>'
' <alias><family>SimHei</family><prefer><family>Noto Sans CJK SC</family></prefer></alias>'
' <alias><family>DengXian</family><prefer><family>Noto Sans CJK SC</family></prefer></alias>'
' <alias><family>Microsoft YaHei</family><prefer><family>Noto Sans CJK SC</family></prefer></alias>'
'</fontconfig>'
> /etc/fonts/local.conf &&
fc-cache -f &&
mkdir -p /run/sshd && /usr/sbin/sshd &&
printf '%s\n' 'cd /app >/dev/null 2>&1 || true' > /etc/profile.d/zz-x-financial-app-dir.sh &&
chmod 644 /etc/profile.d/zz-x-financial-app-dir.sh &&
touch /root/.bashrc /root/.profile &&
if ! grep -qxF 'cd /app >/dev/null 2>&1 || true' /root/.bashrc; then printf '\ncd /app >/dev/null 2>&1 || true\n' >> /root/.bashrc; fi &&
if ! grep -qxF 'cd /app >/dev/null 2>&1 || true' /root/.profile; then printf '\ncd /app >/dev/null 2>&1 || true\n' >> /root/.profile; fi &&
sed -i 's/\r$//' /app/start.sh /app/web/web_start.sh /app/server/server_start.sh &&
chmod +x /app/start.sh /app/web/web_start.sh /app/server/server_start.sh &&
cd /app &&
./start.sh all
healthcheck:
test: ["CMD-SHELL", "curl -fsS http://127.0.0.1:${WEB_PORT:-5173}/ >/dev/null || exit 1"]
interval: 15s
timeout: 5s
retries: 10
start_period: 180s
networks:
- financial-internal
postgres:
image: pgvector/pgvector:pg17
container_name: x-financial-postgres
restart: unless-stopped
environment:
POSTGRES_DB: "${POSTGRES_DB:-x_financial}"
POSTGRES_USER: "${POSTGRES_USER:-x_financial}"
POSTGRES_PASSWORD: "${POSTGRES_PASSWORD:-x_financial}"
ports:
- "${POSTGRES_HOST_PORT:-55432}:5432"
volumes:
- postgres-data:/var/lib/postgresql/data
healthcheck:
test: ["CMD-SHELL", "pg_isready -U \"$${POSTGRES_USER}\" -d \"$${POSTGRES_DB}\""]
interval: 15s
timeout: 5s
retries: 10
start_period: 30s
networks:
- financial-internal
qdrant:
image: qdrant/qdrant:latest
container_name: x-financial-qdrant
restart: unless-stopped
ports:
- "${QDRANT_HTTP_PORT:-6333}:6333"
- "${QDRANT_GRPC_PORT:-6334}:6334"
volumes:
- qdrant-storage:/qdrant/storage
healthcheck:
test: ["CMD-SHELL", "bash -lc 'exec 3<>/dev/tcp/127.0.0.1/6333' || exit 1"]
interval: 15s
timeout: 5s
retries: 10
start_period: 30s
networks:
- financial-internal
onlyoffice:
image: onlyoffice/documentserver:latest
container_name: x-financial-onlyoffice
restart: unless-stopped
environment:
JWT_ENABLED: "true"
JWT_SECRET: "${ONLYOFFICE_JWT_SECRET:-x-financial-onlyoffice-dev-secret}"
ports:
- "${ONLYOFFICE_PORT:-8082}:80"
healthcheck:
test: ["CMD-SHELL", "curl -fsS http://127.0.0.1/healthcheck >/dev/null || exit 1"]
interval: 15s
timeout: 5s
retries: 10
start_period: 60s
networks:
- financial-internal
networks:
financial-internal:
name: financial-internal
volumes:
postgres-data:
qdrant-storage:

8
docker-compose.gpu.yml Normal file
View File

@@ -0,0 +1,8 @@
services:
main:
gpus: all
shm_size: "8gb"
environment:
NVIDIA_VISIBLE_DEVICES: all
NVIDIA_DRIVER_CAPABILITIES: compute,utility
OCR_DEVICE: "${OCR_DEVICE:-gpu:0}"

View File

@@ -0,0 +1,36 @@
services:
main:
depends_on:
postgres:
condition: service_healthy
environment:
POSTGRES_HOST: postgres
POSTGRES_PORT: "5432"
POSTGRES_DB: "${POSTGRES_DB:-x_financial}"
POSTGRES_USER: "${POSTGRES_USER:-x_financial}"
POSTGRES_PASSWORD: "${POSTGRES_PASSWORD:-x_financial}"
DATABASE_URL: "postgresql+psycopg://${POSTGRES_USER:-x_financial}:${POSTGRES_PASSWORD:-x_financial}@postgres:5432/${POSTGRES_DB:-x_financial}"
postgres:
image: pgvector/pgvector:pg17
container_name: x-financial-postgres
restart: unless-stopped
environment:
POSTGRES_DB: "${POSTGRES_DB:-x_financial}"
POSTGRES_USER: "${POSTGRES_USER:-x_financial}"
POSTGRES_PASSWORD: "${POSTGRES_PASSWORD:-x_financial}"
ports:
- "${POSTGRES_HOST_PORT:-55432}:5432"
volumes:
- postgres-data:/var/lib/postgresql/data
healthcheck:
test: ["CMD-SHELL", "pg_isready -U \"$${POSTGRES_USER}\" -d \"$${POSTGRES_DB}\""]
interval: 15s
timeout: 5s
retries: 10
start_period: 30s
networks:
- financial-internal
volumes:
postgres-data:

View File

@@ -1,38 +1,37 @@
services: services:
main: main:
image: x-financial-dev:latest image: x-financial-dev:latest
container_name: x-financial-main container_name: local-x-financial-linux
restart: unless-stopped restart: unless-stopped
depends_on: environment:
onlyoffice: WEB_HOST: 0.0.0.0
condition: service_started WEB_PORT: "${WEB_PORT:-5173}"
qdrant: SERVER_HOST: 0.0.0.0
condition: service_started SERVER_PORT: "${SERVER_PORT:-8000}"
environment: SERVER_RELOAD: "${SERVER_RELOAD:-true}"
WEB_HOST: 0.0.0.0 SERVER_VENV_DIR: /tmp/x-financial-server-venv
SERVER_HOST: 0.0.0.0 X_FINANCIAL_PREFER_ENV_FILE: "true"
SERVER_VENV_DIR: /tmp/x-financial-server-venv ONLYOFFICE_ENABLED: "${ONLYOFFICE_ENABLED:-false}"
X_FINANCIAL_PREFER_ENV_FILE: "true" ONLYOFFICE_PUBLIC_URL: "${ONLYOFFICE_PUBLIC_URL:-}"
ONLYOFFICE_ENABLED: "${ONLYOFFICE_ENABLED:-true}" ONLYOFFICE_BACKEND_URL: "${ONLYOFFICE_BACKEND_URL:-}"
ONLYOFFICE_PUBLIC_URL: "${ONLYOFFICE_PUBLIC_URL:-http://127.0.0.1:${ONLYOFFICE_PORT:-8082}}" ONLYOFFICE_JWT_SECRET: "${ONLYOFFICE_JWT_SECRET:-x-financial-onlyoffice-dev-secret}"
ONLYOFFICE_BACKEND_URL: "http://main:${SERVER_PORT:-8000}" QDRANT_URL: "${QDRANT_URL:-}"
ONLYOFFICE_JWT_SECRET: "${ONLYOFFICE_JWT_SECRET:-x-financial-onlyoffice-dev-secret}" LIGHTRAG_WORKSPACE: "x_financial_knowledge"
QDRANT_URL: "http://qdrant:6333" ports:
LIGHTRAG_WORKSPACE: "x_financial_knowledge" - "${WEB_PORT:-5173}:${WEB_PORT:-5173}"
ports: - "${SERVER_PORT:-8000}:${SERVER_PORT:-8000}"
- "${WEB_PORT:-5173}:${WEB_PORT:-5173}" - "2223:22"
- "${SERVER_PORT:-8000}:${SERVER_PORT:-8000}" volumes:
- "2223:22" - .:/app
volumes: working_dir: /app
- .:/app command:
working_dir: /app - /bin/sh
command: - -lc
- /bin/sh - >
- -lc
- >
apt-get update && apt-get update &&
DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends
python3 python3-pip python3-venv fontconfig fonts-noto-cjk fonts-noto-cjk-extra && python3 python3-pip python3-venv fontconfig openssh-server poppler-data mupdf-tools &&
if ! fc-match 'Noto Sans CJK SC' | grep -qi 'Noto'; then if ! timeout "${CJK_FONT_INSTALL_TIMEOUT_SECONDS:-45}" sh -lc 'DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends fonts-noto-cjk fonts-noto-cjk-extra'; then printf '%s\n' '[WARN] CJK font installation timed out or failed; continuing startup without blocking the app.'; fi; fi &&
printf '%s\n' printf '%s\n'
'<?xml version="1.0"?>' '<?xml version="1.0"?>'
'<!DOCTYPE fontconfig SYSTEM "fonts.dtd">' '<!DOCTYPE fontconfig SYSTEM "fonts.dtd">'
@@ -48,63 +47,24 @@ services:
> /etc/fonts/local.conf && > /etc/fonts/local.conf &&
fc-cache -f && fc-cache -f &&
mkdir -p /run/sshd && /usr/sbin/sshd && mkdir -p /run/sshd && /usr/sbin/sshd &&
printf '%s\n' 'cd /app >/dev/null 2>&1 || true' > /etc/profile.d/zz-x-financial-app-dir.sh && printf '%s\n' 'cd /app >/dev/null 2>&1 || true' > /etc/profile.d/zz-x-financial-app-dir.sh &&
chmod 644 /etc/profile.d/zz-x-financial-app-dir.sh && chmod 644 /etc/profile.d/zz-x-financial-app-dir.sh &&
touch /root/.bashrc /root/.profile && touch /root/.bashrc /root/.profile &&
if ! grep -qxF 'cd /app >/dev/null 2>&1 || true' /root/.bashrc; then printf '\ncd /app >/dev/null 2>&1 || true\n' >> /root/.bashrc; fi && if ! grep -qxF 'cd /app >/dev/null 2>&1 || true' /root/.bashrc; then printf '\ncd /app >/dev/null 2>&1 || true\n' >> /root/.bashrc; fi &&
if ! grep -qxF 'cd /app >/dev/null 2>&1 || true' /root/.profile; then printf '\ncd /app >/dev/null 2>&1 || true\n' >> /root/.profile; fi && if ! grep -qxF 'cd /app >/dev/null 2>&1 || true' /root/.profile; then printf '\ncd /app >/dev/null 2>&1 || true\n' >> /root/.profile; fi &&
sed -i 's/\r$//' /app/start.sh /app/web/web_start.sh /app/server/server_start.sh && sed -i 's/\r$//' /app/start.sh /app/web/web_start.sh /app/server/server_start.sh &&
chmod +x /app/start.sh /app/web/web_start.sh /app/server/server_start.sh && chmod +x /app/start.sh /app/web/web_start.sh /app/server/server_start.sh &&
cd /app && cd /app &&
./start.sh all ./start.sh all
healthcheck: healthcheck:
test: ["CMD-SHELL", "curl -fsS http://127.0.0.1:${WEB_PORT:-5173}/ >/dev/null || exit 1"] test: ["CMD-SHELL", "curl -fsS http://127.0.0.1:${WEB_PORT:-5173}/ >/dev/null || exit 1"]
interval: 15s interval: 15s
timeout: 5s timeout: 5s
retries: 10 retries: 10
start_period: 180s start_period: 180s
networks: networks:
- financial-internal - financial-internal
qdrant: networks:
image: qdrant/qdrant:latest financial-internal:
container_name: x-financial-qdrant name: financial-internal
restart: unless-stopped
ports:
- "${QDRANT_HTTP_PORT:-6333}:6333"
- "${QDRANT_GRPC_PORT:-6334}:6334"
volumes:
- qdrant-storage:/qdrant/storage
healthcheck:
test: ["CMD-SHELL", "bash -lc 'exec 3<>/dev/tcp/127.0.0.1/6333' || exit 1"]
interval: 15s
timeout: 5s
retries: 10
start_period: 30s
networks:
- financial-internal
onlyoffice:
image: onlyoffice/documentserver:latest
container_name: x-financial-onlyoffice
restart: unless-stopped
environment:
JWT_ENABLED: "true"
JWT_SECRET: "${ONLYOFFICE_JWT_SECRET:-x-financial-onlyoffice-dev-secret}"
ports:
- "${ONLYOFFICE_PORT:-8082}:80"
healthcheck:
test: ["CMD-SHELL", "curl -fsS http://127.0.0.1/healthcheck >/dev/null || exit 1"]
interval: 15s
timeout: 5s
retries: 10
start_period: 60s
networks:
- financial-internal
networks:
financial-internal:
name: financial-internal
volumes:
qdrant-storage:

View File

@@ -1,67 +1,127 @@
# Docker Compose # Docker Compose
This project currently uses the Vite `__setup/*` middleware during the initial setup flow. X-Financial 现在按运行依赖分成两层 Docker Compose
Because of that, the Docker deployment keeps the web frontend and FastAPI startup chain in
the same main container and runs the existing root `start.sh`. - `docker-compose.yml`:只启动主应用容器,适合已经有远端 PostgreSQL、ONLYOFFICE 或 Qdrant 的环境。
- `docker-compose.full.yml`:启动完整本地开发栈,适合没有外部依赖、希望本机一次性跑齐所有服务的环境。
## Start
主应用容器仍然同时启动 Web 前端和 FastAPI 后端,并复用根目录 `start.sh`
```bash 项目根目录会挂载到容器内 `/app`
cp .env.example .env
docker compose up -d ## 轻量启动:只跑主应用
```
适合你已经有数据库和 ONLYOFFICE 的情况。
Open:
```bash
```text cp .env.example .env
http://<your-linux-host>:5173 docker compose up -d
``` ```
## Container Layout 默认只会启动:
- `main`: web + FastAPI main container ```text
- `onlyoffice`: ONLYOFFICE Document Server main
- `postgres`: PostgreSQL database container ```
The project root is mounted directly into the main container: 打开:
```text ```text
.:/app http://<your-linux-host>:5273
``` ```
That means the container reads your existing `.env`, source code, `server/.secrets`, logs, 这条路径不会主动拉起本地 PostgreSQL、Qdrant 或 ONLYOFFICE。
and generated dependency directories directly from the mapped project folder. 数据库、ONLYOFFICE 和 Qdrant 地址都从 `.env` 或外部环境变量读取。
This is a `compose`-only setup. There is no custom `Dockerfile`. 常见外部依赖变量:
The tradeoff is that the `main` container installs the Python runtime packages it needs
when it starts. ```text
DATABASE_URL
## Persistence POSTGRES_HOST
POSTGRES_PORT
The PostgreSQL data directory is stored in the named volume `postgres_data`. ONLYOFFICE_ENABLED
ONLYOFFICE_PUBLIC_URL
## Notes ONLYOFFICE_BACKEND_URL
QDRANT_URL
- Most configuration should be maintained in the project root `.env`. ```
- The first `docker compose up -d` does not require an existing `.env`; the compose file
uses built-in defaults for the PostgreSQL container and the main container database URL. ## 完整启动:本地全栈
- Docker Compose only overrides a few values that must differ inside containers:
- `WEB_HOST=0.0.0.0` 适合没有远端数据库和 ONLYOFFICE 的情况。
- `SERVER_HOST=0.0.0.0`
- `POSTGRES_HOST=postgres` ```bash
- `POSTGRES_PORT=5432` docker compose -f docker-compose.full.yml up -d
- `DATABASE_URL=...@postgres:...` ```
- PostgreSQL is also published to the host by default as `127.0.0.1:55432`.
- ONLYOFFICE is published to the host by default as `127.0.0.1:8082`. 会启动:
- First boot with `SETUP_COMPLETED=false` starts the setup UI only.
- After you complete setup in the browser, the Vite setup bridge will start FastAPI in the ```text
same container using the saved runtime configuration. main
- On later restarts, `start.sh` will detect the saved setup state and start both web and postgres
server automatically. qdrant
- If you access the system from another machine, make sure `CORS_ORIGINS` in `.env` includes onlyoffice
the frontend address you actually use. ```
- For Navicat or any host-side client, use `127.0.0.1:55432`.
- If you need to access ONLYOFFICE from another machine, override `ONLYOFFICE_PUBLIC_URL` 本地服务端口:
so the browser can reach the document server address you actually expose.
- For the setup page, using `127.0.0.1` is acceptable in this Docker layout; the internal ```text
test bridge will resolve that back to the Docker PostgreSQL service. Web: 5273
FastAPI: 8000
PostgreSQL: 55432 -> 5432
Qdrant: 6333 / 6334
ONLYOFFICE: 8082
SSH: 2223
```
完整栈会把主容器内的数据库地址指向 `postgres:5432`
并把 Qdrant 地址指向 `http://qdrant:6333`
ONLYOFFICE 默认使用本机可访问地址:
```text
http://127.0.0.1:8082
```
如果浏览器从另一台机器访问,需要覆盖:
```bash
LOCAL_ONLYOFFICE_PUBLIC_URL=http://<host>:8082 \
docker compose -f docker-compose.full.yml up -d
```
如果 ONLYOFFICE 回调后端也需要外部地址,可以同时覆盖:
```bash
LOCAL_ONLYOFFICE_BACKEND_URL=http://<host>:8000 \
docker compose -f docker-compose.full.yml up -d
```
## 可选:只额外启动本地 PostgreSQL
如果只想在轻量主容器旁边补一个本地 PostgreSQL可以使用覆盖文件
```bash
docker compose -f docker-compose.yml -f docker-compose.postgres.yml up -d
```
这会启动:
```text
main
postgres
```
## 停止与清理
停止当前默认轻量栈:
```bash
docker compose down
```
停止完整本地栈:
```bash
docker compose -f docker-compose.full.yml down
```
如需删除本地数据卷,先确认不再需要其中数据,再手动执行带 `-v` 的清理命令。

View File

@@ -0,0 +1,32 @@
# 附件自动关联后台任务实施计划
## 目标
把小财管家 AI 模式里的附件关联从前端会话内存任务改为后端可查询后台任务,保证用户退出或刷新当前会话后,附件关联仍能继续完成并可恢复状态。
## 执行清单
- [x] 定位当前断链根因:前端依赖 `File` 对象和内存 `Map`
- [x] 确认票据夹已有 `receipt_id`、源文件和关联状态能力。
- [x] 落开发方案文档。
- [x] 实现后端任务 schema 和内存任务池。
- [x] 实现后端任务 API。
- [x] 实现后端票据夹源文件归集到报销单明细。
- [x] 增加后端测试。
- [x] 实现前端任务创建、轮询和恢复。
- [x] 增加前端测试断言。
- [x] 执行容器后端定向测试。
- [x] 执行前端定向测试和构建。
## 验证结果
- 后端定向测试:`6 passed`
- 前端定向测试:`12 passed`
- 前端构建:通过,保留既有 chunk size warning。
- 运行时检查:新任务查询路由已加载,未知任务返回“附件关联任务不存在或已失效。”
## 关键决策
- 第一版使用后端内存任务池和 FastAPI `BackgroundTasks`,解决前端会话断链。
- 第一版不新增数据库任务表,服务重启后的任务恢复作为后续增强。
- 前端消息只保存 `job_id`、状态和票据引用,不再保存附件原件。

View File

@@ -0,0 +1,215 @@
# AI 工作台统一意图识别框架设计
## 背景
AI 工作台当前的输入识别分散在多个前端 flow 中:申请预览、报销草稿、单据查询、草稿删除提示各自判断输入。这样的结构能快速修复单点问题,但会让“删除 3 天前的草稿”“审核合规没有风险的申请”这类组合型请求继续变成关键词补丁。
本设计把自然语言输入先统一解析成结构化 `IntentFrame`,再根据目标是否明确、安全等级和业务边界决定下一步动作。
## 目标
- 让工作台所有自然语言输入先进入统一意图框架,不再在各业务 flow 中散落判断。
- 支持动作、对象、筛选条件、上下文指代、安全等级的组合识别。
- 对删除、审核、驳回等高风险动作固定走“筛选候选 + 详情确认”,禁止自然语言直接执行。
- 保留当前会话内的快速指代能力,例如“删除刚才那个草稿”能定位最近创建的草稿。
- 对带筛选条件的请求,例如“删除 3 天前的草稿”“审核无风险申请”,先展示思考过程和候选列表。
## 非目标
- 第一版不引入 LangGraph也不把前端本地识别迁到后端状态机。
- 第一版不做自然语言直接批量删除、批量审核或批量驳回。
- 第一版不改后端审批、删除接口的权限模型。
- 第一版不重写现有申请预览和报销草稿流程,只把入口识别前置统一。
## 总体架构
统一意图识别分三层:
1. `IntentFrame Parser`:把用户输入解析为结构化意图。
2. `Target Resolver`:结合当前会话、最近动作和筛选条件,判断目标是否唯一。
3. `Action Policy`:根据动作风险决定直接查询、展示候选、要求澄清或阻断。
输入链路应调整为:
```text
用户输入
-> IntentFrame Parser
-> Action Policy
-> Target Resolver
-> 业务 flow
- 查询候选
- 打开详情确认
- 进入申请/报销流程
- 要求补充条件
```
## IntentFrame 数据结构
```js
{
action: 'query' | 'delete' | 'approve' | 'reject' | 'create' | 'update' | 'ask_policy',
objectType: 'draft' | 'application' | 'reimbursement' | 'approval_task' | 'receipt' | 'document',
filters: {
timeRange: null,
status: null,
risk: null,
documentType: null,
amount: null,
keyword: null
},
targetMode: 'current_context' | 'filtered_candidates' | 'ambiguous',
safetyLevel: 'read_only' | 'confirm_required' | 'blocked',
confidence: 0,
normalizedQuery: ''
}
```
### 字段含义
- `action` 表示用户想做什么,例如查、删、审核、驳回、创建或咨询规则。
- `objectType` 表示动作对象,例如草稿、申请单、报销单、待审任务或票据。
- `filters` 表示筛选条件,必须可以复用到单据查询 flow。
- `targetMode` 表示目标定位方式:
- `current_context`:明确指向当前会话最近对象。
- `filtered_candidates`:需要查询候选列表。
- `ambiguous`:条件不足,需要澄清。
- `safetyLevel` 表示动作安全级别:
- `read_only`:可直接查询或解释。
- `confirm_required`:只展示候选或详情入口,不直接执行。
- `blocked`:存在批量破坏性风险或越权风险,必须阻断。
- `normalizedQuery` 是给现有查询 flow 使用的可读查询句,例如“我的 3 天前草稿单据”。
## 识别策略
### 动作识别
- 查询:查、看、列出、有哪些、找一下。
- 删除:删除、删掉、移除、作废、撤销。
- 审核:审核、审批、处理待办、去审批。
- 驳回:驳回、退回、拒绝。
- 创建:新建、发起、申请、我要报销。
- 更新:补充、修改、改成、填入。
- 规则咨询:怎么走、能不能、规则、制度、政策、标准。
### 对象识别
- 草稿:草稿、未提交、刚才保存的单据。
- 申请单:申请、申请单、出差申请、费用申请。
- 报销单:报销、报销单、费用报销。
- 待审任务:待办、待我审核、待审批、审核单。
- 票据:发票、票据、附件、图片。
### 筛选条件识别
- 时间今天、昨天、3 天前、近 7 天、上周、本月、具体日期、日期范围。
- 状态:草稿、审批中、已通过、已驳回、待补充。
- 风险:无风险、低风险、中风险、高风险、合规、异常、超标。
- 金额:超过 1000、500 以下、100 到 300。
- 关键词:地点、事由、人员、部门、单号等自由文本。
## 目标解析规则
### 当前上下文直达
当用户使用“刚才那个”“当前”“这个”“上面那个”这类指代,并且当前会话中能找到最近的可操作对象时,`targetMode``current_context`
例子:
- “删除刚才那个草稿”
- “打开这个申请单”
- “继续刚才的报销草稿”
即便目标唯一,删除、审核、驳回仍然只打开详情页或确认入口。
### 筛选候选
当用户输入包含时间、风险、金额、状态、类型等筛选条件时,`targetMode` 必须为 `filtered_candidates`
例子:
- “删除 3 天前的草稿”
- “审核合规没有风险的申请”
- “找一下上海相关的低风险待审申请”
这类请求必须进入单据查询 flow展示候选结果不能直接套最近草稿。
### 条件不足澄清
当动作高风险但目标既不唯一,也没有足够筛选条件时,`targetMode``ambiguous`
例子:
- “把草稿删了”
- “帮我审核一下”
- “退回这个单”
系统应提示用户选择候选或补充条件。
## Action Policy
| 动作 | 安全等级 | 第一版行为 |
| --- | --- | --- |
| 查询 | `read_only` | 直接查询并展示结果 |
| 规则咨询 | `read_only` | 走政策/规则解释,不进入单据查询 |
| 删除 | `confirm_required` | 展示候选或打开详情页确认,不直接删除 |
| 审核通过 | `confirm_required` | 展示待审候选或打开审核详情,不直接通过 |
| 驳回/退回 | `confirm_required` | 展示待审候选或打开审核详情,不直接驳回 |
| 批量删除/批量审核 | `blocked` | 阻断并要求用户选择具体单据 |
## 用户可见思考过程
筛选型命令必须复用现有查询 thinking events并补充动作意图说明
1. 解析自然语言动作和筛选条件。
2. 判断操作风险和目标定位方式。
3. 查询业务单据接口。
4. 按条件组合筛选候选。
5. 展示候选卡片和下一步入口。
示例:
```text
解析识别到“删除”是高风险动作对象是“草稿”时间条件是“3 天前”。
策略:不会直接删除,将先查询我的草稿候选。
结果:命中 2 张草稿,请打开详情页确认删除目标。
```
## 文件边界
- 新增 `workbenchIntentFrameModel.js`:负责解析用户输入到 `IntentFrame`
- 新增 `workbenchIntentActionPolicy.js`:负责动作安全策略和下一步路由判断。
- 调整 `workbenchAiCommandIntentModel.js`:保留会话内最近草稿解析,但不再单独拥有顶层意图判断。
- 调整 `useWorkbenchAiCommandIntents.js`:基于 `IntentFrame` 分发到当前上下文直达或候选查询。
- 调整 `aiDocumentQueryIntent.js``aiDocumentQueryModel.js`:补充风险筛选、相对日期和筛选摘要。
- 补充前端测试,覆盖组合型输入和安全边界。
## 迁移步骤
1. 先为 `IntentFrame` 解析补测试:
- “删除刚才那个草稿”解析为 `delete + draft + current_context + confirm_required`
- “删除 3 天前的草稿”解析为 `delete + draft + filtered_candidates + confirm_required`
- “审核合规没有风险的申请”解析为 `approve + application + risk:none + filtered_candidates + confirm_required`
- “审批规则怎么走”解析为 `ask_policy`,不进入单据查询。
2. 实现 `workbenchIntentFrameModel.js`,不接入 UI。
3. 实现风险和相对日期筛选能力,让查询 flow 能承接筛选型命令。
4. 接入 `useWorkbenchAiCommandIntents.js`
- 当前上下文直达:生成详情确认入口。
- 筛选候选:调用 `handleAiDocumentQueryIntent(normalizedQuery, pendingMessage)`
- 条件不足:提示补充条件或查询可选候选。
5. 移除或降级旧的散落正则,让顶层输入先走统一框架。
6. 跑定向测试、相邻测试、前端构建和 5173 工作台烟测。
## 验收标准
- 输入“删除刚才那个草稿”时,系统定位当前会话最近草稿,并只打开详情确认入口。
- 输入“删除 3 天前的草稿”时,系统展示筛选思考过程和草稿候选,不使用最近草稿快捷路径。
- 输入“审核合规没有风险的申请”时,系统查询待我审核申请,并筛选无风险候选。
- 输入“审批规则怎么走”时,不进入单据查询。
- 删除、审核、驳回均不通过自然语言直接执行最终动作。
- 新增/调整测试全部通过,前端构建通过,`git diff --check` 无空白错误。
## 后续演进
- 当后端 steward planner 能稳定输出同等 `IntentFrame` 时,可以把 Parser 层迁到后端,前端只保留策略兜底。
- 如果需要跨会话目标记忆,可把最近创建/保存草稿写入会话快照,并附带过期时间和用户确认边界。
- 如果未来引入 LangGraph应把它用于多步状态编排而不是替代 `IntentFrame` schema 本身。

View File

@@ -0,0 +1,12 @@
# AI 工作台审核单二轮审核命令丢失候选上下文
日期2026-06-25
文档路径document/development/2026-06-25/dev-logs/bugs/ai-approval-followup-context.md
## 修复记录
- 16:24记录 bug 修复AI 工作台审核单二轮审核命令丢失候选上下文。bug-log:8a2ae6eb
- Git 提交检查fetch 失败fatal: unable to access 'https://www.caoxiaozhu.com:13002/YG-Soft/X-Financial.git/': LibreSSL SSL_connect: SSL_ERROR_SYSCALL in connection to www.caoxiaozhu.com:13002upstream `origin/main`upstream 新提交:未发现;本地 ahead 提交8a2ae6eb (HEAD -> main) fix(server): gate_classify 复用 _classify_irrelevant_input 修复 off_topic 误杀992cf71f refactor(server): Phase 1 图拓扑重构 - LangGraph 成为唯一编排者54356ba8 refactor(server): scene 注册表骨架 + 统一门控管道设计文档e9d7c56d feat(server): 会话上下文保留LLM 历史 + 确定性兜底双保险)。
- 修改:`workbenchAiCommandIntentModel.js` 新增待审单据候选上下文解析与二轮审批命令提示;`useWorkbenchAiCommandIntents.js``query_candidates` 前优先复用上一轮待审候选;`workbench-ai-command-intent-model.test.mjs` 覆盖“我有哪些审核单”后继续说“审核通过”的候选承接。
- 操作:按 TDD 先补失败用例,再实现最小修复;执行 `tools/agent-change-log/update_change_log.py --kind bug` 创建当天 bug 记录,并手动补全真实修复细节。
- 验证:`node --test web/tests/workbench-ai-command-intent-model.test.mjs` 通过;`node --test web/tests/workbench-ai-command-intent-model.test.mjs web/tests/workbench-intent-frame-model.test.mjs web/tests/ai-document-query-model.test.mjs` 通过31 项前端相关测试全部通过。
- 影响:用户在 AI 工作台先查询待审/审核单后,再说“请帮我审核通过”或类似审批命令时,系统会接上刚才候选并要求进入详情确认,不会把二轮命令当成孤立查询或静默失智;仍保留高风险审批动作不直接执行的安全边界。

View File

@@ -0,0 +1,12 @@
# AI模式企业主题光球出现矩形闪动边框
日期2026-06-25
文档路径document/development/2026-06-25/dev-logs/bugs/ai-enterprise-orb-frame.md
## 修复记录
- 15:02记录 bug 修复AI模式企业主题光球出现矩形闪动边框。bug-log:2ebc2756
- Git 提交检查15:01 执行 `git fetch --all --prune` 成功upstream `origin/main`upstream 新提交:未发现;本地 ahead 提交:未发现。
- 修改:`personal-workbench-ai-mode.css`,把企业主题下 `.workbench-ai-orb` 从白底圆角矩形容器改回透明圆形承载,移除边框与阴影;`settings-theme-section.test.mjs` 增加断言锁定 `border: 0``border-radius: 50%``background: transparent``box-shadow: none`
- 操作:复现时确认企业主题覆盖块把光球容器设置为 `border-radius: 18px`、白底、阴影,导致 GIF 光球外层出现明显闪动方框;修复后用浏览器读取已加载 CSSOM确认企业主题规则已变为透明圆形版本。
- 验证:`node web/tests/settings-theme-section.test.mjs``node web/tests/settings-llm-section.test.mjs``node web/tests/settings-rendering-section.test.mjs``git diff --check``npm --prefix web run build` 均通过;本地工作台页面可加载,光球元素存在,页面无 error浏览器 CSSOM 中企业主题光球规则为 `border: 0px``border-radius: 50%``background: transparent``box-shadow: none`
- 影响:企业沉稳主题下 AI 模式欢迎区光球不再显示矩形闪动边框,动感/专业智能主题保持原有光球表现。

View File

@@ -0,0 +1,27 @@
# 申请详情退回/草稿状态修改申请卡壳
日期2026-06-25
文档路径document/development/2026-06-25/dev-logs/bugs/application-detail-edit-returned-draft.md
## 修复记录
- 16:40记录 bug 修复:申请详情退回/草稿状态修改申请卡壳。bug-log:8a2ae6eb
- Git 提交检查fetch 失败fatal: unable to access 'https://www.caoxiaozhu.com:13002/YG-Soft/X-Financial.git/': LibreSSL SSL_connect: SSL_ERROR_SYSCALL in connection to www.caoxiaozhu.com:13002upstream `origin/main`upstream 新提交:未发现;本地 ahead 提交8a2ae6eb (HEAD -> main) fix(server): gate_classify 复用 _classify_irrelevant_input 修复 off_topic 误杀992cf71f refactor(server): Phase 1 图拓扑重构 - LangGraph 成为唯一编排者54356ba8 refactor(server): scene 注册表骨架 + 统一门控管道设计文档e9d7c56d feat(server): 会话上下文保留LLM 历史 + 确定性兜底双保险)。
- 修改:`travelRequestDetailSetup.js``TravelRequestDetailView.vue` 将“修改申请”入口从仅退回态放宽为申请单草稿/退回归一后的可编辑态,仍要求当前用户是申请人;打开助手时补齐原申请 `draftPayload``applicationEditMode` 和可编辑字段白名单。
- 修改:`useAppShell.js``AppShellRouteView.vue``TravelReimbursementCreateView.js``useTravelReimbursementCreateViewLifecycle.js` 贯通 `initialDraftPayload`,让申请详情带出的核对表首条消息保留原 `claim_id`,保存草稿/直接提交时走已有 `application_edit_claim_id` 更新链路,不再新建或卡在无上下文状态。
- 修改:`expenseApplicationPreview.js` 支持 `editableFields`,在修改申请场景只开放事由、时间、地点、出行方式;`aiApplicationPreviewActions.js` 将白名单写入 `application_editable_fields`,便于后续服务端字段级约束。
- 操作manual 触发 `tools/agent-change-log/update_change_log.py --kind bug` 生成日志后补充真实修复记录;未修改后端接口逻辑,因为 `user_agent_application.py` 已允许 `draft/returned/supplement` 申请按 `application_edit_claim_id` 更新。
- 验证:`node --test web/tests/travel-request-detail-risk-advice.test.mjs` 通过;`node --test --test-name-pattern "application edit prefill opens assistant without auto submit" web/tests/app-shell-financial-assistant-entry.test.mjs` 通过;`node --test --test-name-pattern "application edit preview only allows reason time location and transport changes" web/tests/expense-application-fast-preview.test.mjs` 通过;`node web/tests/ai-application-preview-actions.test.mjs` 通过;`git diff --check` 通过;`npm --prefix web run build` 通过。全量跑 `app-shell-financial-assistant-entry.test.mjs``expense-application-fast-preview.test.mjs` 时仍有既有结构断言漂移,失败点与本次修改无关。
- 影响:用户在申请详情里看到草稿和退回申请都能继续修改;修改面被限制在事由、时间、地点、出行方式,其他职级、负责人、费用标准和金额仍由原单或规则测算带入。
- 16:51补充修复取消底部“修改申请”按钮改为申请详情格子内联铅笔编辑。
- Git 提交检查fetch 仍失败fatal: unable to access 'https://www.caoxiaozhu.com:13002/YG-Soft/X-Financial.git/': LibreSSL SSL_connect: SSL_ERROR_SYSCALL in connection to www.caoxiaozhu.com:13002upstream `origin/main`upstream 新提交:未发现;本地 ahead 提交仍为 8a2ae6eb、992cf71f、54356ba8、e9d7c56d。
- 修改:`TravelRequestDetailView.vue` 移除底部“修改申请”按钮,在申请详情事实格子的值旁显示小铅笔;点击后根据字段类型切换为日期框、下拉框或文本输入,并提供保存/取消按钮。
- 修改:`travelRequestDetailSetup.js` 新增 `applicationDetailEditor` 状态、`canEditApplicationDetailItem``openApplicationDetailEditor``saveApplicationDetailEdit` 等内联编辑流程;保存时复用 `runAiApplicationPreviewAction``save_draft` 路径和 `application_edit_claim_id`,保持更新原申请单。
- 修改:`travel-request-detail-view.css` 收窄申请详情标签选择器,避免内联编辑内部 `span` 被误当字段名,并补充铅笔、确认、取消、编辑控件样式。
- 验证:先运行新增目标断言失败,确认旧按钮仍存在;实现后 `node --test --test-name-pattern "draft or returned application detail edits allowed facts inline" web/tests/travel-request-detail-risk-advice.test.mjs` 通过;`node --test web/tests/travel-request-detail-risk-advice.test.mjs` 62 条通过;`node web/tests/ai-application-preview-actions.test.mjs` 通过;`git diff --check` 通过;`npm --prefix web run build` 通过。本地 `http://[::1]:5173/app/documents` 可达但跳转登录页,因无登录态未继续真实详情点击。
- 影响:草稿/退回申请不再需要先打开 AI 助手才能改,用户可以直接在详情表格中改事由、时间、地点、出行方式;其它字段仍不可编辑,由原单或规则测算带入。
- 17:02补充修复详情页因残留 `handleModifyApplication` 返回项导致 setup 阶段崩溃。
- Git 提交检查fetch 仍失败fatal: unable to access 'https://www.caoxiaozhu.com:13002/YG-Soft/X-Financial.git/': LibreSSL SSL_connect: SSL_ERROR_SYSCALL in connection to www.caoxiaozhu.com:13002upstream `origin/main`upstream 新提交:未发现;本地 ahead 提交仍为 8a2ae6eb、992cf71f、54356ba8、e9d7c56d。
- 修改:`travelRequestDetailSetup.js` 删除 return 对象里已经不存在的 `handleModifyApplication`,避免详情页初始化时抛 `ReferenceError`
- 修改:`travel-request-detail-risk-advice.test.mjs` 为内联编辑回归用例增加 `handleModifyApplication` 不得残留的断言;先运行目标用例确认失败,再删除残留返回项后确认转绿。
- 验证:`node --test --test-name-pattern "draft or returned application detail edits allowed facts inline" web/tests/travel-request-detail-risk-advice.test.mjs` 先失败后通过;`node --test web/tests/travel-request-detail-risk-advice.test.mjs` 62 条通过;`node web/tests/ai-application-preview-actions.test.mjs` 通过;`git diff --check` 通过;`npm --prefix web run build` 通过。真实本地 `[::1]:5173` 以管理员打开 `AG2YUJ9FB` 详情页无控制台错误;切换申请人 `caoxiaozhu@xf.com` 后同页可见 `申请详情` 和单号,铅笔按钮 5 个,点击后出现 1 个编辑控件,取消后无保存副作用。
- 影响:申请/报销详情页 setup 不再因为旧按钮处理函数缺失而白屏,内联铅笔编辑入口保留。

View File

@@ -0,0 +1,116 @@
# 写日志技能拆分 概念文档
更新时间2026-06-25
文档路径document/development/2026-06-25/feature/agent-change-log-split/CONCEPT.md
## 功能一句话
把原来单文件三段式工作日志拆成按日期聚合的功能点文档、bug 修复日志和每日 17:00 综合工作日志。
## 背景与问题
- 当前现状:旧 `agent-change-log` 把所有变更追加到 `document/work-log/YYYY-MM-DD.md`,并固定包含 `当日工作内容``遗留问题``TODO`
- 用户痛点功能点规划、bug 修复和当天综合复盘混在一个日志文件里,后续追溯时难以按功能或问题拆开看。
- 业务影响开发资料会越来越长bug 修复证据和功能点设计边界容易互相干扰。
- 为什么现在需要做:`write-development-docs` 已经改为 `document/development/YYYY-MM-DD/feature/<功能点>/`,日志能力也需要跟随同一日期根目录拆分。
## 目标与非目标
### 目标
- [G1] bug 修复记录落到 `document/development/YYYY-MM-DD/dev-logs/bugs/<bug-slug>.md`
- [G2] bug 日志只保留修复记录,不再写 `遗留问题``TODO` 两块。
- [G3] 每天 17:00 汇总当天 `feature/``dev-logs/bugs/`,生成 `work-logs.med`
- [G4] 保留 Git 双向检查,继续识别 upstream 新提交和本地 ahead 提交。
### 非目标
- [NG1] 本轮不迁移历史 `document/work-log/*.md`
- [NG2] 本轮不删除旧历史日志,避免破坏既有追溯。
- [NG3] 本轮不把非 bug 提交强行写入 bug 日志。
## 用户与场景
- 目标用户:使用 Codex/Agent 维护 X-Financial 的开发者和后续接手的智能体。
- 使用入口:`agent-change-log` Skill、`tools/agent-change-log/update_change_log.py`、post-commit hook、每日 17:00 Codex automation。
- 核心场景:
1. 修复 bug 后写入当天 `dev-logs/bugs/<bug-slug>.md`
2. 非 bug 功能点通过 `feature/<功能点>/CONCEPT.md``TODO.md` 沉淀。
3. 每天 17:00 汇总功能点与 bug生成 `work-logs.med`
- 异常场景:
- 没有 feature 或 bug 时,综合日志明确写“未发现”。
- 提交标题不像 bug 时post-commit 自动日志跳过。
## 功能能力
- [C1] 输入能力:支持 `--kind bug``--kind auto``--kind summary` 三种模式。
- [C2] 处理能力:按日期创建 `dev-logs/bugs`,按 bug slug 记录修复内容。
- [C3] 输出能力:输出 bug 修复记录或每日 `work-logs.med`
- [C4] 状态与权限:沿用 Git fetch/status/log 检查,不主动 merge/rebase。
- [C5] 边界与降级:官方 skill 校验脚本不可用时用脚本单测、frontmatter 和 diff check 兜底。
## 方案设计
### 前端
当前不涉及。
### 后端
当前不涉及业务后端;只修改仓库级 Skill、脚本和 hook。
### 算法与规则
- 输入commit subject、用户传入的 bug title/slug、当天 feature 和 bug 文档。
- 流程bug 模式写入 bug 文件auto 模式识别 bug-like commitsummary 模式扫描 `feature/``dev-logs/bugs/` 后生成综合日志。
- 输出:`dev-logs/bugs/*.md``work-logs.med`
- 解释summary 中保留来源目录和综合分析,便于复盘追溯。
### 数据与契约
- 核心字段日期、bug slug、bug title、Git 提交检查、修改、操作、验证、影响。
- 状态枚举:`auto``bug``summary`
- 兼容策略:保留旧 `document/work-log` 历史,不新增旧格式。
- 版本/审计:本轮变更通过本地 checkpoint commit 保留。
## 算法与公式
当前功能不涉及显式数学公式。
## 测试方案
后端:
- 当前不涉及后端服务。
前端:
- 当前不涉及前端构建。
集成:
- 运行 `python3 tools/agent-change-log/test_update_change_log.py`,覆盖 bug 日志、非 bug 自动跳过、每日综合日志聚合。
手工验证:
- 运行 `update_change_log.py --kind bug --dry-run``--kind summary --dry-run` 检查目标路径和输出内容。
## 指标与验收
- [A1] 功能验收bug 日志路径为 `document/development/YYYY-MM-DD/dev-logs/bugs/<bug-slug>.md`
- [A2] 性能指标:脚本单测在 60s 内完成。
- [A3] 质量指标:不再为新日志写入旧三段式 `document/work-log/YYYY-MM-DD.md`
- [A4] 安全/权限指标:脚本不做 merge/rebase不删除历史日志。
- [A5] 可观测性17:00 automation 生成 `work-logs.med` 后报告路径和是否发现 feature/bug。
## 风险与开放问题
- 风险:`work-logs.med` 是按用户原文保留的扩展名,可能与常见 `.md` 扩展名不一致。
- 已处理依赖:已创建 Codex automation 执行每日 17:00 summary。
- 待确认:后续是否需要迁移历史 `document/work-log`
- 降级策略automation 不可用时可手动运行 `python3 tools/agent-change-log/update_change_log.py --kind summary`
## 本轮实现记录
- 2026-06-25重写 `agent-change-log` Skill 和脚本,新增 split log 测试,创建每日 17:00 Codex automation。

View File

@@ -0,0 +1,61 @@
# 写日志技能拆分 开发 TODO
更新时间2026-06-25
文档路径document/development/2026-06-25/feature/agent-change-log-split/TODO.md
## 使用规则
- 每个 TODO 必须对应 `CONCEPT.md` 中的目标、能力、方案或验收点。
- 只有完成并验证后,才能把 `[ ]` 改成 `[x]`
- 勾选时在任务后补充简短证据,例如文件、接口、命令或验证结果。
- 如果需求发生变化,先更新 `CONCEPT.md`,再调整本 TODO。
## 1. 调研与边界
- [x] [CONCEPT: 背景与问题] 确认旧日志 Skill、脚本、hook 和 AGENTS 仍指向 `document/work-log/YYYY-MM-DD.md`
证据:`rg -n "document/work-log|当日工作内容|遗留问题|TODO" AGENTS.md .codex/skills/agent-change-log tools/agent-change-log .githooks/post-commit`
- [x] [CONCEPT: 目标与非目标] 明确本轮不迁移历史 `document/work-log/*.md`
证据:`CONCEPT.md` 非目标已列明历史不迁移。
## 2. 契约与设计
- [x] [CONCEPT: 功能能力] 定义 `auto``bug``summary` 三种脚本模式。
证据:`tools/agent-change-log/update_change_log.py``--kind` 参数。
- [x] [CONCEPT: 数据与契约] 固定新路径 `document/development/YYYY-MM-DD/dev-logs/bugs``work-logs.med`
证据:`agent-change-log` Skill、AGENTS 和脚本常量。
## 3. 后端实现
- [x] [CONCEPT: 后端] 重写日志脚本,支持 bug 记录、auto 跳过非 bug、summary 聚合。
证据:`tools/agent-change-log/update_change_log.py`
- [x] [CONCEPT: 后端] 更新 post-commit hook改为 `--kind auto`
证据:`.githooks/post-commit`
## 4. 算法/规则实现
- [x] [CONCEPT: 算法与规则] 实现 bug-like commit 识别规则。
证据:`looks_like_bug()` 覆盖 `fix``bugfix``修复``失败``异常` 等关键词。
- [x] [CONCEPT: 算法与规则] 实现 feature 和 bug 汇总生成 `work-logs.med`
证据:`build_daily_summary()`
## 5. 前端实现
- [x] [CONCEPT: 前端] 当前不涉及前端页面。
证据:本轮只修改仓库 Skill、脚本、hook、文档和 automation。
## 6. 测试与验证
- [x] [CONCEPT: 测试方案] 补充脚本回归测试。
证据:`tools/agent-change-log/test_update_change_log.py`
- [x] [CONCEPT: 测试方案] 运行脚本单测。
证据:`python3 tools/agent-change-log/test_update_change_log.py`3 tests OK。
- [x] [CONCEPT: 测试方案] dry-run 验证 bug 路径和 summary 路径。
证据:`--kind bug --dry-run` 输出 `document/development/2026-06-25/dev-logs/bugs/draft-preview-disappears.md``--kind summary --dry-run` 输出 `document/development/2026-06-25/work-logs.med`
## 7. 文档收尾
- [x] [CONCEPT: 指标与验收] 更新 `agent-change-log` Skill、AGENTS 和 README。
证据:`.codex/skills/agent-change-log/SKILL.md``AGENTS.md``tools/agent-change-log/README.md`
- [x] [CONCEPT: 指标与验收] 创建每日 17:00 Codex automation。
证据automation id `x-financial-daily-split-work-log`

View File

@@ -0,0 +1,31 @@
# AI 对话 UI 样式重构与 SaaS 化设计方案
为了让 X-Financial AI 助手的对话界面展现更专业的金融与 SaaS 企业化视觉,我们对前端全局的 Markdown 渲染样式进行了重构。
## 设计目标
- **中性色打底**:对话块背景、边框移除饱和偏色,统一采用 Slate/Neutral 冷灰色调(如 `#f8fafc``#cbd5e1`)。
- **降低色彩冗余**:将非必须的高亮蓝色改为中性灰色,各单据卡片仅在状态字样与极淡头部透明底中体现状态点缀,避免彩色杂乱堆积。
- **界面扁平微阴影**:移除带有斜向彩色发光的阴影与复杂的背景图案,采用 1px 实线描边配合微阴影,契合 Stripe, Jira 等现代 SaaS 产品规范。
## 详细参数定义
- **引用块 (`blockquote` / `.ai-html-callout`)**
- 边框:`3px solid #cbd5e1`
- 背景:`#f8fafc`
- 文字:`#334155`
- **信息网格 (`.ai-html-focus-grid`)**
- 边框:`3px solid #cbd5e1`
- 标题颜色:`#475569` (Slate-600)
- **单据卡片 (`.ai-document-card`)**
- 描边:`1px solid #e2e8f0`
- 投影:`0 1px 2px 0 rgba(15, 23, 42, 0.05)`
- 头部默认背景:`rgba(241, 245, 249, 0.5)`
- 状态点缀色:
- `is-success` (Teal-700): `#0f766e`
- `is-warning` (Amber-700): `#b45309`
- `is-danger` (Red-700): `#b91c1c`
- is-pending (Blue-600): `#2563eb`
## 消息排版格式规范
- **限制 Alert 引用块为单条**:在警示/阻塞状态下,只允许包含一条 `>` 引用块用作 Alert 提示。
- **列表扁平化**:发起前核对结果等普通多维状态信息,一律不使用 `>` 引用块,合并为标准的无序列表展示,保持界面视觉扁平、整洁。
- **常规表单数据平铺**:时间、单据编号等字段,均采用扁平加粗文本平铺,不再触发 focus-grid 等具有边框线的额外容器。

View File

@@ -0,0 +1,9 @@
# 任务计划 (SaaS 风格视觉优化)
- [x] 优化全局 `blockquote``.ai-html-callout` 的色彩饱和度,改用 Slate 灰蓝色系打底。
- [x] 优化 `.ai-html-focus-grid` 信息网格与竖线的亮蓝色调。
- [x] 移除单据卡片上的 `ai-document-card-bg.png` 渐变背景图。
- [x] 扁平化单据卡片的描边与中性阴影。
- [x] 优化卡片语义状态角标与操作链接的 SaaS 蓝及点缀。
- [x] 优化原生 Markdown 列表 `li::marker` 与表格外包边框的色彩层级。
- [x] 重构预审与冲突消息的 Markdown 输出格式,消除不必要的 `>` 引用块,攻克“三条大竖杠”的排版痛点。

View File

@@ -0,0 +1,207 @@
# 主题设置与企业沉稳 AI 模式 概念文档
更新时间2026-06-25
文档路径document/development/2026-06-25/feature/theme-settings-enterprise-ai-style/CONCEPT.md
## 功能一句话
将系统设置中的“界面皮肤”升级为“主题设置”,从单纯色板选择扩展为产品体验风格选择,并让 AI 模式在“企业沉稳”主题下呈现更符合企业级 SaaS 的低噪声、结构化、克制风格。
## 背景与问题
当前系统设置里的外观入口仍偏向“界面皮肤”语义,主要表达颜色和视觉皮肤选择。这个命名过窄,无法承载用户希望配置的完整体验风格。
现有 AI 模式默认更接近动感活泼风格,使用较多渐变、明亮色块和活跃视觉标识。它适合演示和助手化体验,但在企业级财务、审批、风控、报销场景中,容易显得色彩过重,不够沉稳。
用户希望在系统设置中明确提供主题类型,至少覆盖:
1. 动感活泼:保留当前这种更有活力、更有 AI 助手感的主题。
2. 企业沉稳:符合企业 SaaS 风格,尤其 AI 模式下的对话图标、样式和整体风格需要克制、稳定,减少颜色渲染。
3. 专业智能:作为第三类默认方案,介于前两者之间,保留少量智能化识别感,但整体更收敛。
## 目标与非目标
目标:
- 将“界面皮肤”入口重命名为“主题设置”,让用户理解这里配置的是整体体验风格。
- 将主题从一组颜色选项收敛成三类可理解的主题类型。
- 在“企业沉稳”主题下,让 AI 模式呈现企业后台应用的专业感。
- 保持现有设置保存链路稳定,优先复用当前 appearance 配置和主题变量机制。
- 为后续进一步扩展租户品牌色、暗色模式、组件密度预留结构边界。
非目标:
- 不重做整个系统设置信息架构。
- 不一次性重写所有业务页面的视觉风格。
- 不改变 AI 意图识别、报销流程、审批逻辑和后端业务规则。
- 不新增复杂的租户级主题发布、审批或版本管理能力。
- 不引入新的前端主题框架或额外依赖。
## 用户与场景
管理员在系统设置中进入“主题设置”,选择适合当前组织的产品体验风格。
演示、培训、轻量工作台场景可以使用“动感活泼”,保留当前更有活力的 AI 交互表达。
企业正式生产环境可以使用“企业沉稳”,让财务、审批、风控和 AI 对话看起来像成熟的企业应用,而不是营销页或玩具化助手。
希望保留智能化识别但又不希望过度活泼的组织,可以使用“专业智能”。
## 功能能力
主题设置页面需要提供三类主题:
- 动感活泼:当前风格延续,允许渐变、轻动效和更明显的 AI 识别色。
- 企业沉稳:低饱和色、白灰底、轻描边、少阴影、少渐变,强调信息层级和业务可信度。
- 专业智能:更克制的智能风格,允许小面积蓝灰、紫灰或品牌色点缀,但避免大面积彩色渲染。
页面文案调整:
- 左侧菜单从“界面皮肤”调整为“主题设置”。
- 页面标题从“界面皮肤与企业主色”调整为“主题风格与界面体验”。
- 保存反馈从“界面皮肤已保存”调整为“主题设置已保存”。
- 说明文案从“皮肤/配色”改为“主题/体验风格”。
AI 模式联动:
- 动感活泼:保留当前 AI 模式视觉语言。
- 企业沉稳:对 AI 对话区、消息气泡、工具调用状态、思考过程、图标、卡片、提示块做克制化覆写。
- 专业智能:保留轻量 AI 识别感,但降低渐变、发光、背景装饰和高饱和强调色。
## 方案设计
配置模型优先沿用当前系统设置外观配置,避免为了命名调整引入后端迁移风险。
首期可以继续复用 `appearanceForm.themeSkin` 作为持久化字段,将值从原先色板语义逐步映射为主题语义:
- `vivid`:动感活泼。
- `enterprise`:企业沉稳。
- `intelligent`:专业智能。
为了减少现有 CSS 变量和本地存储影响,前端可以在兼容期保留 `themeSkin` 字段,同时在 DOM 上补充更清晰的主题标识:
```text
document.documentElement.dataset.themeSkin = value
document.documentElement.dataset.themeMode = value
```
旧值兼容策略:
- 旧的 `sky``blue``emerald` 等明亮主题默认映射到“动感活泼”。
- 旧的 `navy``slate` 等偏稳重主题默认映射到“企业沉稳”。
- 无法识别的值回退到“企业沉稳”,保证生产环境默认更克制。
设置页结构:
- 保留现有表单保存机制。
- 将原色板卡片改为三张主题选项卡。
- 每个主题卡展示名称、适用场景、视觉关键词和小型预览。
- 当前选中主题需要有明确选中态,但避免大面积彩色边框。
企业沉稳 AI 模式样式:
- 通过 `[data-theme-mode="enterprise"]``[data-theme-skin="enterprise"]` 覆写 `personal-workbench-ai-mode.css` 中的 AI 模式变量。
- 背景从多层 radial-gradient 收敛为白灰底或极轻线性渐变。
- 对话气泡使用白底、浅灰描边和稳定文字层级。
- AI 图标使用低饱和单色或品牌主色的小面积点缀。
- 思考过程、工具调用、风险提示等区域使用结构化信息块,减少发光、彩色渐变和装饰性元素。
- 风险、成功、警告等语义色保留,但只在图标、状态条或小面积标签上表达。
专业智能主题样式:
- 保留少量 AI 识别色,例如主色强调、轻量渐变按钮或小面积状态标识。
- 背景和卡片仍以企业应用的可读性为主。
- 避免全屏强背景、过多彩色阴影和过密装饰。
## 算法与公式
本功能不涉及复杂算法。
需要定义稳定的主题值映射函数:
```text
normalizeThemeMode(rawTheme):
if rawTheme in ["vivid", "sky", "blue", "emerald", "purple"]:
return "vivid"
if rawTheme in ["enterprise", "navy", "slate", "gray"]:
return "enterprise"
if rawTheme in ["intelligent"]:
return "intelligent"
return "enterprise"
```
主题应用顺序:
```text
后端保存值 / 本地缓存值
-> normalizeThemeMode
-> 写入 appearanceForm.themeSkin
-> 写入 root dataset
-> 应用 CSS 变量
-> AI 模式按 data-theme-mode 覆写组件样式
```
## 测试方案
前端单元和静态测试:
- 断言系统设置外观入口显示为“主题设置”。
- 断言页面标题显示为“主题风格与界面体验”。
- 断言三类主题均可见:动感活泼、企业沉稳、专业智能。
- 断言企业沉稳主题保存后写入稳定主题值。
- 断言旧主题值能通过 normalize 逻辑回退到可识别主题。
- 断言 AI 模式存在企业沉稳主题 CSS 钩子。
构建验证:
- 运行前端构建,确保主题设置改动不破坏现有页面。
- 运行已有设置相关测试,确保系统设置保存链路不回归。
真实页面验收:
- 打开 `/app/settings?section=appearance`,确认左侧菜单、页面标题、三类主题和保存反馈符合预期。
- 切换到“企业沉稳”后打开 AI 工作台,确认对话区域、图标、消息、思考过程和提示块明显减少彩色渲染。
- 切回“动感活泼”,确认现有风格仍可正常展示。
- 切到“专业智能”,确认介于两者之间,不退化为纯色板换色。
## 指标与验收
功能验收:
- “界面皮肤”在设置入口和页面主标题中完成改名。
- 用户可以选择三类主题,而不是面对一堆颜色皮肤。
- 选择主题后刷新页面仍保持选中态。
- 企业沉稳主题下AI 模式整体视觉明显更接近企业 SaaS。
- 动感活泼主题不丢失现有活力风格。
- 专业智能主题具备独立视觉边界。
设计验收:
- 企业沉稳主题下不出现大面积高饱和渐变背景。
- AI 对话图标和卡片不依赖强发光、强阴影或多彩背景表达层级。
- 风险、审批、单据、工具调用等业务信息优先使用结构化排版。
- 主题卡片文字不溢出,不在移动端产生拥挤或重叠。
工程验收:
- 不新增前端依赖。
- 不引入后端表结构迁移。
- 旧主题值有明确兼容策略。
- 相关测试、构建和真实页面验收通过。
## 风险与开放问题
第三类主题默认命名为“专业智能”。如果后续用户指定更贴合业务的名称,可以只替换展示文案,不影响主题值和实现结构。
仅靠全局 CSS 变量可能无法完全消除 AI 模式的活泼感。企业沉稳主题需要对 AI 模式局部样式做有针对性的覆写。
旧色板值如果直接隐藏,可能让已有用户困惑。首期需要在兼容层处理旧值,并保证保存一次后落到新的三类主题值。
如果后续需要租户品牌色和主题组合,应该把“主题模式”和“品牌主色”拆成两个独立配置,避免再次把体验风格退化成颜色选择。
## 本轮文档记录
本轮已完成主题设置功能的前端实现:系统设置入口改名为“主题设置”,主题选项收敛为“动感活泼 / 企业沉稳 / 专业智能”三类,并通过主题归一化兼容旧色板值。
企业沉稳主题已联动 AI 工作台样式:根节点写入 `data-theme-mode="enterprise"`AI 模式背景、图标容器、输入框、消息、思考过程和建议动作改为低饱和、轻描边、少渲染的企业 SaaS 风格。

View File

@@ -0,0 +1,69 @@
# 主题设置与企业沉稳 AI 模式 开发 TODO
更新时间2026-06-25
文档路径document/development/2026-06-25/feature/theme-settings-enterprise-ai-style/TODO.md
## 使用规则
- 每个任务都需要关联 `CONCEPT.md` 中的章节,格式为 `[CONCEPT: 章节名]`
- 完成实现后再勾选对应任务,不用文档勾选代替代码验证。
- 涉及真实页面效果的任务,需要在 5173 页面完成验收后再标记完成。
## 1. 调研与边界
- [x] [CONCEPT: 背景与问题] 确认当前设置外观入口仍使用“界面皮肤”语义,后续需要改为“主题设置”。
- [x] [CONCEPT: 方案设计] 确认当前主题能力主要依赖 `appearanceForm.themeSkin`、主题选项和根节点 dataset。
- [x] [CONCEPT: 方案设计] 确认企业沉稳 AI 模式主要需要覆写 `personal-workbench-ai-mode.css` 中的背景、对话、图标和提示块样式。
- [x] [CONCEPT: 风险与开放问题] 梳理旧色板值到三类主题值的完整映射清单。
- [x] [CONCEPT: 用户与场景] 确认三类主题在设置页中的展示顺序和说明文案。
## 2. 契约与设计
- [x] [CONCEPT: 功能能力] 将主题枚举收敛为 `vivid``enterprise``intelligent`
- [x] [CONCEPT: 功能能力] 明确三类主题的中文名称、适用场景和视觉关键词。
- [x] [CONCEPT: 方案设计] 设计 `normalizeThemeMode` 兼容函数,保证旧值和未知值都有稳定回退。
- [x] [CONCEPT: 方案设计] 决定是否新增 `themeMode` 前端概念,并保持与 `themeSkin` 字段兼容。
- [x] [CONCEPT: 指标与验收] 定义企业沉稳 AI 模式的视觉验收标准。
## 3. 后端实现
- [x] [CONCEPT: 方案设计] 评估后端 settings schema 是否需要补充主题枚举校验。
- [x] [CONCEPT: 方案设计] 若继续复用 `themeSkin`,确保后端允许新主题值保存。
- [ ] [CONCEPT: 测试方案] 补充或更新设置持久化测试,覆盖三类主题值。
- [x] [CONCEPT: 风险与开放问题] 确认不需要数据库结构迁移,并在实现说明中记录。
## 4. 算法/规则实现
- [x] [CONCEPT: 算法与公式] 实现旧主题值到新主题值的 normalize 逻辑。
- [x] [CONCEPT: 算法与公式] 为未知值设置默认回退策略,优先回退到“企业沉稳”。
- [x] [CONCEPT: 算法与公式] 确保本地缓存、后端返回值和根节点 dataset 使用同一套归一化结果。
## 5. 前端实现
- [x] [CONCEPT: 功能能力] 将设置左侧菜单“界面皮肤”改为“主题设置”。
- [x] [CONCEPT: 功能能力] 将页面标题改为“主题风格与界面体验”。
- [x] [CONCEPT: 功能能力] 将保存反馈和说明文案从“皮肤”语义调整为“主题”语义。
- [x] [CONCEPT: 功能能力] 将原色板式选项调整为三类主题卡片。
- [x] [CONCEPT: 功能能力] 为“动感活泼”保留当前视觉风格。
- [x] [CONCEPT: 方案设计] 为“企业沉稳”新增 AI 模式样式覆写。
- [x] [CONCEPT: 方案设计] 为“专业智能”新增介于活泼和沉稳之间的样式边界。
- [x] [CONCEPT: 指标与验收] 检查主题卡片、按钮和说明文字在移动端不溢出、不重叠。
- [x] [CONCEPT: 方案设计] 保证刷新页面后主题选择和 AI 模式样式仍然一致。
## 6. 测试与验证
- [x] [CONCEPT: 测试方案] 更新设置页相关前端测试,断言“主题设置”和三类主题选项。
- [x] [CONCEPT: 测试方案] 补充 normalize 逻辑测试,覆盖旧值、未知值和三类新值。
- [x] [CONCEPT: 测试方案] 补充 AI 模式企业沉稳 CSS 钩子测试或静态断言。
- [x] [CONCEPT: 测试方案] 运行前端设置相关定向测试。
- [x] [CONCEPT: 测试方案] 运行 `npm --prefix web run build`
- [x] [CONCEPT: 测试方案] 运行 `git diff --check`
- [x] [CONCEPT: 测试方案] 在真实 5173 页面验收 `/app/settings?section=appearance`
- [ ] [CONCEPT: 测试方案] 在真实 5173 页面验收 AI 工作台三类主题切换效果。
## 7. 文档收尾
- [x] [CONCEPT: 本轮文档记录] 实现完成后更新本文勾选状态。
- [x] [CONCEPT: 指标与验收] 在最终交付说明中记录测试、构建和真实页面验收结果。
- [ ] [CONCEPT: 风险与开放问题] 若第三类主题命名发生变化,同步更新概念文档和测试描述。

View File

@@ -0,0 +1,37 @@
# 多 task 串行推进时 task2(业务招待费报销)无法启动
## 修复记录
- 12:14记录 bug 修复:多 task 串行推进时task1出差申请做完后点击"继续处理费用报销"task2业务招待费报销根本无法启动报销草稿交互不起来task2 语义(招待费/2000元/昨天)全部丢失。
- Git 提交检查:`git fetch --all --prune` 因远端 SSL 连接失败未拉到新内容;`HEAD..@{u}` 为空(无 upstream 新提交);`@{u}..HEAD` 本地领先 8 个提交,其中与本 bug 相关的前置提交为 `3a5664c4 feat(web): 多 task 串行推进``3e4b1e15 fix(web): 保存草稿/提交成功后也推进到下一个 task``43c3ff86 fix(web): steward plan 确认按钮直接拉起申请预览,不丢失 remaining tasks`
- 修改:
- `web/src/composables/workbenchAiMode/useWorkbenchAiActionRouter.js``travel_reimbursement` 分支不再硬编码 `requiresApplicationBeforeReimbursement=true`,改为从 `steward_current_task.ontology_fields` 解析费用类型并调 `requiresApplicationBeforeReimbursement(expenseType)` 判断;用 `buildAiExpenseDraftPrefillValues` 把 task 语义(金额/时间/事由/地点)预填进报销草稿;透传 `steward_remaining_tasks``ai_application_start_inline` 分支也透传 `prefill_values``steward_remaining_tasks`,让"查不到申请单→发起申请单"后能回到 task2。`buildNextTaskSuggestedAction` payload 补 `steward_remaining_tasks: remainingTasks.slice(1)`,防 3+ task 断链。
- `web/src/composables/workbenchAiMode/useWorkbenchAiExpenseFlow.js``startAiExpenseDraft` 扩展第 4 参 `options``prefillValues`/`stewardRemainingTasks``resolveAiExpenseApplicationLink` 接收 options查不到申请单时按费用类型动态生成"确认发起业务招待申请"按钮(不再写死"出差申请"),并透传 `prefill_values`/`steward_remaining_tasks`;新增 `attachStewardRemainingTasks`/`resolveStewardRemainingTasks`/`resolveRequiredApplicationLabel`/`buildExpenseDraftNextTaskAction` helper把 remaining tasks 上下文挂在 draft 上贯穿报销→关联申请单→pollLinkedDraftJob 全流程;`advanceAiExpenseDraft``linkAiExpenseApplication``replaceInlineAssistantMessage``resumePendingLinkedReimbursementDraftJobs` 均补 remaining tasks 透传。
- `web/src/composables/workbenchAiMode/useWorkbenchAiApplicationPreviewFlow.js``buildApplicationPreviewNextTaskAction` payload 补 `steward_remaining_tasks: remainingTasks.slice(1)`
- `web/src/utils/aiExpenseDraftModel.js``createAiExpenseDraft` 新增第三参 `prefillValues`,按已填值推进 `stepKey` 到第一个未填字段;新增 `buildAiExpenseDraftPrefillValues` 把 task ontology 映射到草稿字段。
- `web/src/composables/workbenchAiMode/workbenchAiMessageModel.js``createInlineMessage`/`normalizeRuntimeMessage`/`serializeRuntimeMessage` 三处补 `stewardRemainingTasks` 字段读写,避免消息重建/刷新丢失推进上下文。
- `web/src/utils/aiWorkbenchConversationStore.js``normalizeMessage` 持久化时保留 `stewardRemainingTasks`
- 操作:未提交(工作区有大量预先存在的未提交改动,未自动提交)。容器 `local-x-financial-linux` 此前未运行,已 `docker start` 恢复。
- 验证在容器内node v22.22.3)跑 `node --test tests/ai-expense-draft-model.test.mjs tests/ai-workbench-conversation-store.test.mjs tests/workbench-ai-action-router.test.mjs`16 个测试全部通过(含新增的 `buildAiExpenseDraftPrefillValues``createAiExpenseDraft` 预填、`stewardRemainingTasks` 持久化、`travel_reimbursement` 分支预填+透传 4 个用例。其余前端测试失败为基线已存在git stash 对比确认,与本次改动无关,多为正则匹配源码文本的断言因工作区其他未提交改动而失败)。
- 影响:用户一次提问含"出差申请 + 招待费报销"等多 task 时task1 完成后 task2 现在能正常启动招待费类型、2000元金额、时间、事由会预填到报销草稿招待费需要前置招待申请单业务规则保留查不到时按钮文案按类型动态展示并承接语义发起申请单后能回到 task23+ task 不再断链;刷新会话后推进上下文不丢失。
- 12:23继续修复同一 bug模型计划已经返回“出差申请 + 业务招待费报销”两个 task 时AI 工作台入口只消费第一个申请 task第二个 task 没有自动开始。
- Git 提交检查:`git fetch --all --prune` 仍因 `LibreSSL SSL_connect: SSL_ERROR_SYSCALL` 失败;`HEAD..@{u}` 为空,未发现可见 upstream 新提交;`@{u}..HEAD` 本地领先 8 个提交:`43c3ff86 fix(web): steward plan 确认按钮直接拉起申请预览,不丢失 remaining tasks``3e4b1e15 fix(web): 保存草稿/提交成功后也推进到下一个 task``3a5664c4 feat(web): 多 task 串行推进 - task1 完成后自动展示 task2 确认按钮``d139a63e refactor(server): 意图识别改 LLM 驱动,规则只做闲聊拦截+resume 兜底``8a2ae6eb fix(server): gate_classify 复用 _classify_irrelevant_input 修复 off_topic 误杀``992cf71f refactor(server): Phase 1 图拓扑重构 - LangGraph 成为唯一编排者``54356ba8 refactor(server): scene 注册表骨架 + 统一门控管道设计文档``e9d7c56d feat(server): 会话上下文保留LLM 历史 + 确定性兜底双保险)`
- 修改:`workbenchAiIntentPlannerModel.js` 在归一化模型计划时保留 application task 后面的 `stewardRemainingTasks`,并只在存在剩余 task 时放进可执行申请请求;`usePersonalWorkbenchAiMode.js` 把 remaining tasks 传入申请预览,并在预览生成后通过现有 `steward_continue_next_task` 路由自动启动下一个 task低置信确认按钮 payload 也继续携带队列;`useWorkbenchAiApplicationPreviewFlow.js` 在普通申请预览完成后调用 `onPreviewReadyForNextTask``useWorkbenchAiActionRouter.js``ai_application_confirm_intent` 分支同样透传 remaining tasks 并注册自动续跑回调。
- 操作:新增回归测试覆盖“模型返回申请 task + 业务招待报销 task 时,前端可执行请求保留第二个 task”以及“低置信确认按钮不丢队列并提供自动续跑回调”保留既有未提交工作区改动没有回滚或提交其他文件。
- 验证:先看到新增测试红灯(`plan.stewardRemainingTasks``undefined`,确认按钮 options 也没有 remaining tasks修复后 `node --test web/tests/workbench-ai-intent-planner-model.test.mjs web/tests/workbench-ai-action-router.test.mjs` 通过 24/24`git diff --check` 通过;`docker exec -w /app -e SERVER_VENV_DIR=/tmp/x-financial-server-venv x-financial-local-linux timeout 60s /tmp/x-financial-server-venv/bin/pytest -q server/tests/test_steward_planner.py -k 'future_travel_without_apply_word_as_application or uses_llm_for_multi_financial_demands'` 通过 2/2同命令在 `local-x-financial-linux` 收集阶段因该容器缺 `langgraph` 失败,已改用当前映射 5173 的 `x-financial-local-linux` 验证;`npm --prefix web run build` 通过;真实 `http://localhost:5173/api/v1/steward/plans` 采样确认该用户句子返回 `expense_application``reimbursement` 两个 task。
- 影响用户输入“2月20-23日去上海出差3天服务国网服务器部署并且报销昨天的业务招待费2000元”时前端不再在第一个申请预览处截断队列申请预览生成后会自动把第二个业务招待费报销 task 交给现有报销流程继续处理,同时刷新/低置信确认路径也不丢 task 队列。
- 22:30继续修复同一 bug用户点击“保存草稿”后task1 已经完成,但界面仍只展示“继续处理费用报销”按钮,没有自动开始 task2。
- Git 提交检查:`git fetch --all --prune` 仍因 `LibreSSL SSL_connect: SSL_ERROR_SYSCALL` 失败;`HEAD..@{u}` 为空,未发现可见 upstream 新提交;`@{u}..HEAD` 本地仍领先 8 个提交:`43c3ff86``3e4b1e15``3a5664c4``d139a63e``8a2ae6eb``992cf71f``54356ba8``e9d7c56d`
- 修改:`useWorkbenchAiApplicationPreviewFlow.js` 在保存草稿/提交申请成功后,如果当前申请消息还有 `stewardRemainingTasks`,就调用 `onApplicationActionCompleted` 自动续跑下一项;自动续跑时结果消息只保留查看详情动作,不再额外保留“继续处理”按钮,避免重复触发同一个 task。`usePersonalWorkbenchAiMode.js` 将该回调接到 `startModelPlannedNextTask``useWorkbenchAiActionRouter.js` 的低置信确认路径也同步传入保存/提交成功回调。
- 操作:先补红灯断言,要求工作台入口向申请预览流传 `onApplicationActionCompleted`,且申请预览流在保存/提交成功分支调用该回调;然后按同一条 `steward_continue_next_task` 路由复用原有报销启动逻辑。
- 验证:红灯阶段 `node --test web/tests/workbench-ai-intent-planner-model.test.mjs` 失败在缺少 `onApplicationActionCompleted`;修复后 `node --test web/tests/workbench-ai-intent-planner-model.test.mjs` 17/17 通过,`node --test web/tests/workbench-ai-action-router.test.mjs` 7/7 通过;`git diff --check` 通过;`npm --prefix web run build` 通过。
- 影响:复合任务里用户保存第一张出差申请草稿后,系统会立即进入第二个业务招待费报销任务,不再要求用户手动点击“继续处理费用报销”;低置信确认后再保存草稿也保持同样行为。
- 22:45继续修复同一 bug真实页面已经显示“申请草稿已保存”但保存动作结束后没有继续拉起第二个业务招待费报销 task。
- Git 提交检查:`git fetch --all --prune` 仍因 `LibreSSL SSL_connect: SSL_ERROR_SYSCALL` 失败;`HEAD..@{u}` 为空,未发现可见 upstream 新提交;`@{u}..HEAD` 本地领先 13 个提交:`6bdaeed6 chore: 忽略 .zcode 本地目录并更新规则表与开发日志``d5a8f847 refactor(web): 应用外壳/差旅详情/报销创建视图适配主题与多 task``c4b5fcc0 feat(web): AI 工作台多 task 串行推进与会话适配``5753899e feat(web): 主题皮肤系统与 LLM 设置面板重构``9c3fa80d feat(server): 设置持久化新增 LLM 模型表与主题字段`,以及前面记录过的 8 个本地 ahead 提交。
- 修改:`useWorkbenchAiApplicationPreviewFlow.js` 在保存草稿/提交申请成功分支新增 `actionCompletedHandler`,优先使用本次 `executeInlineApplicationPreviewAction` / `startAiApplicationPreview` options 传入的 `onApplicationActionCompleted`,没有时再回落到 composable 初始化回调;自动保存草稿时同步把 `options.onApplicationActionCompleted` 透传给保存动作。`workbench-ai-application-context-submit.test.mjs` 新增“自动保存申请草稿后继续剩余 steward task”的行为测试`workbench-ai-intent-planner-model.test.mjs` 更新结构断言,锁住 options 回调优先和自动保存透传契约。
- 操作:先用新增测试复现红灯:自动保存时确实只触发初始化回调,`options` 里的续跑回调没有被使用;再做最小修复,让保存动作按本次调用上下文续跑下一任务。
- 验证:红灯阶段 `node --test web/tests/workbench-ai-application-context-submit.test.mjs` 失败在 `fromOptions``undefined`;修复后该测试 2/2 通过;`node --test web/tests/workbench-ai-intent-planner-model.test.mjs` 17/17 通过;`node --test web/tests/workbench-ai-action-router.test.mjs` 7/7 通过;真实 `http://127.0.0.1:5173/api/v1/steward/plans` 采样确认该用户句子仍返回 `expense_application` + `reimbursement` 两个 task`npm --prefix web run build` 通过;`git diff --check` 通过。
- 影响:保存草稿结果消息到达后,前端会使用当前任务链路传下来的续跑回调立即处理剩余 task用户截图里的“申请草稿已保存”不再是终点后续业务招待费报销会自动进入现有报销流程。

View File

@@ -0,0 +1,17 @@
# 2026-06-26 综合工作日志
生成时间2026-06-26 17:45:36 CST
来源:`feature/` 功能点文档与 `dev-logs/bugs/` bug 记录
## 今日功能点
- 今日未发现功能点文档。
## 今日 Bugs
- 多 task 串行推进时 task2(业务招待费报销)无法启动影响用户输入“2月20-23日去上海出差3天服务国网服务器部署并且报销昨天的业务招待费2000元”时前端不再在第一个申请预览处截断队列申请预览生成后会自动把第二个业务招待费报销 task 交给现有报销流程继续处理,同时刷新/低置信确认路径也不丢 task 队列。(文件:`multi-task-reimbursement-not-starting.md`
## 综合分析
- 问题侧记录了 1 个 bug 修复。
- 后续复盘优先看本文件,再回到对应功能点或 bug 文件追溯证据。

View File

@@ -0,0 +1,17 @@
# 2026-06-27 综合工作日志
生成时间2026-06-27 17:43:24 CST
来源:`feature/` 功能点文档与 `dev-logs/bugs/` bug 记录
## 今日功能点
- 今日未发现功能点文档。
## 今日 Bugs
- 今日未发现 bug 修复记录。
## 综合分析
- 今日目录下暂无功能点或 bug 记录。
- 后续复盘优先看本文件,再回到对应功能点或 bug 文件追溯证据。

View File

@@ -0,0 +1,17 @@
# 2026-06-28 综合工作日志
生成时间2026-06-28 18:30:35 CST
来源:`feature/` 功能点文档与 `dev-logs/bugs/` bug 记录
## 今日功能点
- 今日未发现功能点文档。
## 今日 Bugs
- 今日未发现 bug 修复记录。
## 综合分析
- 今日目录下暂无功能点或 bug 记录。
- 后续复盘优先看本文件,再回到对应功能点或 bug 文件追溯证据。

View File

@@ -0,0 +1,16 @@
# 多 task 串行推进时 task2 无法启动onPreviewReadyForNextTask 时序缺陷)
日期2026-06-30
文档路径document/development/2026-06-30/dev-logs/bugs/multi-task-next-task-blocked-by-preview-ready-timing.md
## 修复记录
- 11:18记录 bug 修复:用户在 AI 工作台输入"出差申请 + 招待费报销"等多 task 时task1出差申请保存草稿/提交成功后task2招待费报销完全无法启动界面停在"申请草稿已保存"。
- Git 提交检查:`git fetch --all --prune` 成功upstream `origin/main``HEAD..@{u}` 未发现 upstream 新提交;`@{u}..HEAD` 未发现本地 ahead 提交。工作区改动仅为本次 3 个源文件 + 2 个测试文件(另有一个预先存在的未提交改动 `server/rules/finance-rules/公司通信费报销规则.xlsx`,与本次无关)。
- 根因:`onPreviewReadyForNextTask` 回调在 task1 申请核对表**刚生成、用户还没看、还没点保存草稿**时就立刻触发 `startModelPlannedNextTask`,提前把 task2 招待费报销拉起(`startAiExpenseDraft` 会 push 一条"选择费用报销"用户消息 + 报销 prompt。两条流程的消息和状态互相打架用户再在 task1 上点保存草稿时 `onApplicationActionCompleted` 又试图拉起 task2但 task2 状态已被前面 `onPreviewReadyForNextTask` 搞乱,最终表现为"完全无反应"。运行时复现脚本时序铁证:预览生成后立即出现 `!!! onPreviewReadyForNextTask 触发(task1预览刚生成,用户还没操作)`与串行推进的正确语义task1 完成后才推进 task2冲突。这是早期实现的残留——引入 `onApplicationActionCompleted`task1 完成后触发)后,`onPreviewReadyForNextTask` 职责重叠且时序错误。
- 修改(前端 web3 个源文件):
- `web/src/composables/workbenchAiMode/useWorkbenchAiApplicationPreviewFlow.js`:删除 `startAiApplicationPreview` 预览生成后的 `else if (onPreviewReadyForNextTask ...)` 提前推进分支(原 L622-L628并加注释说明 task2 推进统一交给 `onApplicationActionCompleted` 在 task1 真正完成后触发。`executeInlineApplicationPreviewAction` 里 L466 的 `actionCompletedHandler` 回落逻辑保留不动(手动点保存草稿走 actionRouter 不传 options 回调,回落到模块级 `startModelPlannedNextTask`,这是正确的续跑路径)。
- `web/src/composables/workbenchAiMode/usePersonalWorkbenchAiMode.js``startModelPlannedApplicationPreview` 调用 `startAiApplicationPreview` 时删除 `onPreviewReadyForNextTask: startModelPlannedNextTask` 一行,只保留 `onApplicationActionCompleted: startModelPlannedNextTask`(原 L769
- `web/src/composables/workbenchAiMode/useWorkbenchAiActionRouter.js``ai_application_confirm_intent`(低置信确认按钮)分支删除 `onPreviewReadyForNextTask` 回调,只保留 `onApplicationActionCompleted`(原 L99-L104消除低置信路径的同样时序缺陷。
- 操作:先写复现脚本 `/tmp/repro-timing.mjs`applicationFlow + 两个回调)锁定时序根因——修复前预览生成后立即触发推进回调,修复后无提前触发;再按计划小步改 3 个源文件 + 2 个测试文件;未提交(工作区有预先存在的无关 xlsx 改动,未自动提交)。
- 验证:宿主机 node v22.22.3 跑 `node --test web/tests/workbench-ai-intent-planner-model.test.mjs web/tests/workbench-ai-action-router.test.mjs web/tests/workbench-ai-application-context-submit.test.mjs` 通过 27/27含新增的时序回归用例 `workbench application preview does not continue next task until draft is saved or submitted`:断言预览生成时 `continuedTasks.length === 0`、保存草稿后才推进 task2 且走模块级续跑回调、自动续跑时不展示重复的"继续处理"按钮);`npm --prefix web run build` 通过3.97s);复现脚本 `/tmp/repro-timing.mjs` 修复后事件序列只剩用户消息、无提前推进;真实 `http://localhost:5173/api/v1/steward/plans``/api/v1/steward/plans/stream` 采样确认该句子仍返回 `expense_application` + `reimbursement` 两个 task后端拆分正确本次未动后端
- 影响:用户输入框提交"2月20-23日去上海出差辅助国网仿生产服务器部署并且报销昨天的上午招待费2000元"等多 task 时task1 出差申请核对表生成后干净停下等用户操作,用户点保存草稿/直接提交成功后自动进入 task2 招待费报销(预填金额/时间/事由),不再出现两条流程打架导致 task2 完全无反应的问题。不影响后端、单 task 场景、autoSaveDraft 路径(它走 `executeInlineApplicationPreviewAction` 完成后触发 `onApplicationActionCompleted`,链路不变);低置信确认按钮路径也同步修复。

View File

@@ -0,0 +1,243 @@
# 统一门控管道Unified Gate Pipeline
> 状态:**设计定稿,待实施**
> 创建2026-06-25
> 关联:`CONCEPT.md`、`LANGGRAPH_RUNTIME_MIGRATION.md`
## 1. 为什么要做这件事
### 1.1 现状的致命问题
小财管家的门控(决定用户输入走哪条路)目前散落在 **7 个位置**,互相不知道对方的结论,每加一个场景要找 n 个地方改:
| # | 位置 | 文件 | 做的门控 |
|---|---|---|---|
| 1 | 前端 7 层 if/else | `usePersonalWorkbenchAiMode.js:858-913` `startInlineConversation` | 命令→文本动作→草稿→模型规划→报销→闲聊,每层各自 return |
| 2 | 前端业务词预筛 | `workbenchAiIntentPlannerModel.js:shouldRequestWorkbenchAiIntentPlan` | 不含业务词的输入不发给后端 |
| 3 | 后端 endpoint 补丁群 | `steward.py:create_steward_plan` | `_hydrate_required_application_gate` / `_inject_recent_conversation_history` / `_apply_context_resume` 三个补丁串在 `build_plan` 前后 |
| 4 | 图条件边路由 | `steward_graph_planner.py:_route_after_prepare_context` | off_topic / model / fallback 三路 |
| 5 | off_topic 关键词 | `steward_planner_fallback.py:_classify_irrelevant_input` + `STEWARD_BUSINESS_SIGNAL_KEYWORDS` | 写死的信号词元组 |
| 6 | 候选流程歧义 | `steward_planner_extraction.py:_looks_like_ambiguous_travel_flow` | 独立的正则判定 |
| 7 | 图后意图处理 | `usePersonalWorkbenchAiMode.js:813-835` `executeModelPlannedWorkbenchIntent` | 前端再判一遍 task_type 决定渲染申请预览还是报销 |
**根因:没有单一的决策点。** LangGraph 图只承担了"意图识别"这一个职责,控制流泄漏到了 endpoint 层和前端 composable形成两个影子编排器。
### 1.2 不持久的判据
加一个场景(如"查报销进度")的成本是 **O(n)**——必须同步改前端门控、后端补丁、图条件边、off_topic 关键词、候选流程判定等多处,漏一处就静默出错。本次会话已经在不断验证这个痛点:每个新场景(查询、低置信度、上下文恢复)都是往不同位置打补丁。
## 2. 目标:接入成本 O(1)
加一个新场景,**全文改动只有一处**
```python
# server/src/app/services/scenes/scene_query_reimbursement_progress.py
register_scene(SceneDescriptor(
scene_id="query_reimbursement_progress",
label="报销进度查询",
signal_keywords=("报销进度", "报销状态", "审批进度", "审批到哪了"),
ontology_fields=("claim_no", "time_range"),
gate=GateRule.CHOICE, # 不走候选流程、不走 off_topic
can_resume=False, # 不参与上下文恢复
route=SceneRoute.HANDLER_ONLY, # 不走 LLM,直接执行 handler
handler=execute_progress_query, # 纯函数:检索 + 拼装
prompt_fragment="用户询问报销审批进度/状态时,识别为 query_reimbursement_progress。",
))
```
**不改图、不改 endpoint、不改前端门控、不改 extraction。** 判断规则、路由、执行、槽位、恢复能力在同一个 descriptor 里声明,不会割裂。
## 3. 目标架构
### 3.1 后端:图成为唯一编排者
```
POST /api/v1/steward/plans
endpoint: 纯 IO (收请求 → graph.invoke → 返响应,零编排)
LangGraph StateGraph (唯一编排者):
START
→ load_context 读最近10条历史 + steward_state + hydrate
→ gate_classify 统一门控:按 registry 规则裁决 scene + route
→ route 分支
├─ off_topic → off_topic_reply
├─ handler_only → execute_scene_handler (查询/命令类,不走 LLM)
├─ resume → resume_recent_task ("再提交"确定性恢复)
├─ ambiguous_flow → pending_flow_confirmation
└─ model_intent → detect_model_intent → {done | fallback}
→ attach_action_steps
→ persist_state 写 message + steward_state
→ END
```
**endpoint 层只剩 3 行**`planner = build(db); plan = planner.build_plan(payload); return plan`。所有 hydrate/inject/resume 全部搬进图节点。
### 3.2 前端:退化为纯渲染
```
用户输入
前端: 不再自己决策,统一发给后端
POST /steward/plans { message, conversation_id }
后端返回 StewardPlanResponse:
- plan.next_action 告诉前端该渲染什么
- plan.tasks[].task_type 告诉前端该用哪个渲染器
- plan.suggested_actions 告诉前端该显示哪些按钮
前端: 按 response 的指令渲染(申请预览/报销预览/查询结果/纯文本回复)
```
前端的 7 层 if/else **全部移除**,替换为:
```js
async function startInlineConversation(prompt) {
const plan = await fetchStewardPlan({ message: prompt, conversation_id: conversationId.value })
renderPlanResponse(plan) // 按 plan.next_action / task_type 分发到对应渲染器
}
```
### 3.3 SceneDescriptor场景的唯一声明
```python
@dataclass(frozen=True)
class SceneDescriptor:
scene_id: str # 唯一标识,等同 task_type
label: str # 中文标签
signal_keywords: tuple[str, ...] # 规则识别的关键词(聚合进 off_topic 信号池)
ontology_fields: tuple[str, ...] # 该场景允许的槽位
gate: GateRule # 门控规则(见 3.4)
route: SceneRoute # 路由策略(见 3.5)
handler: Callable | None # 执行函数(handler_only 路由用)
can_resume: bool = False # 是否参与"再提交"上下文恢复
action_steps_builder: Callable = ... # 动作步骤生成
prompt_fragment: str = "" # 注入 LLM system prompt 的识别指引
priority: int = 100 # gate_classify 的匹配优先级(小优先)
flow_id: str | None = None # 候选流程用;查询/命令类为 None
```
### 3.4 GateRule门控规则枚举
```python
class GateRule(Enum):
OFF_TOPIC = "off_topic" # 非业务输入,走 off_topic_reply
CHOICE = "choice" # 明确的业务选择,走 handler/model
AMBIGUOUS_FLOW = "ambiguous_flow" # 话术歧义,走候选流程确认
MODEL_ONLY = "model_only" # 只走 LLM function call,不参与规则匹配
```
### 3.5 SceneRoute路由策略枚举
```python
class SceneRoute(Enum):
HANDLER_ONLY = "handler_only" # 不走 LLM,直接执行 handler(查询/命令类)
MODEL_INTENT = "model_intent" # 走 LLM function call(申请/报销类)
OFF_TOPIC = "off_topic" # 走 off_topic 回复
RESUME = "resume" # 走确定性上下文恢复
AMBIGUOUS = "ambiguous" # 走候选流程确认
```
## 4. gate_classify 节点的裁决逻辑(唯一决策点)
```python
def gate_classify(state) -> dict:
"""统一门控:按优先级遍历 registry,输出 scene_id + route。"""
message = state["message"]
steward_state = state["steward_state"]
history = state["recent_history"]
# ① off_topic 门:聚合所有场景的 signal_keywords,无命中 → off_topic
if not _matches_any_signal(message):
return {"scene_id": "off_topic", "route": SceneRoute.OFF_TOPIC}
# ② resume 门:用户说"再提交"+ state 有可恢复 flow
resume_scene = _check_resume(message, steward_state)
if resume_scene:
return {"scene_id": resume_scene, "route": SceneRoute.RESUME}
# ③ 规则匹配门:按 priority 遍历,命中 signal_keywords 的场景
for scene in registry.scenes_sorted_by_priority():
if scene.gate == GateRule.CHOICE and _matches_keywords(message, scene.signal_keywords):
return {"scene_id": scene.scene_id, "route": scene.route}
# ④ LLM 门:规则未命中,走 model function call
return {"scene_id": None, "route": SceneRoute.MODEL_INTENT}
```
**所有门控收敛到这一个函数。** off_topic 信号词、resume 判断、规则匹配、LLM 兜底,全部在这里按固定顺序裁决。
## 5. 文件结构
```
server/src/app/services/
scenes/ # 场景声明(每个场景一个文件)
__init__.py # 注册所有场景
scene_registry.py # SceneRegistry 单例 + 查询方法
scene_descriptor.py # SceneDescriptor dataclass
scene_expense_application.py # 出差申请场景
scene_reimbursement.py # 报销场景
scene_query_travel_standard.py# 差旅标准查询场景
gate_rules.py # GateRule / SceneRoute 枚举
steward_graph_planner.py # 图:load_context/gate_classify/.../persist_state
steward_scene_handlers.py # 各场景的 handler 纯函数
```
## 6. 迁移路径(分阶段,每阶段可独立验证)
### Phase 1建场景注册表 + 收口后端门控(后端自闭环)
**目标**:后端 endpoint 零编排,图成为唯一编排者。
1. 新建 `scenes/` 目录,实现 `SceneDescriptor` / `SceneRegistry` / `GateRule` / `SceneRoute`
2. 把现有 3 个场景expense_application / reimbursement / query_travel_standard迁入 descriptor
3. 新增图节点:`load_context``gate_classify``resume_recent_task``persist_state`
4. 把 endpoint 的 4 个补丁函数搬进图节点
5. endpoint 退化为 3 行
**验证**:后端全量测试绿 + 端到端(上海出差/再提交/查差旅标准)通过
### Phase 2前端退化为纯渲染
**目标**:前端移除 7 层 if/else统一发给后端。
1. `startInlineConversation` 改为:`fetchStewardPlan → renderPlanResponse`
2.`plan.next_action` / `task_type` 分发到渲染器(申请预览/报销预览/查询结果/纯文本)
3. 移除 `shouldRequestWorkbenchAiIntentPlan``isReimbursementCreationIntent``isLowConfidenceTravelApplicationPlan` 等前端门控函数
4. 保留并复用现有渲染组件applicationPreview、stewardPlan 渲染逻辑不重写)
**验证**:前端测试绿 + 人工验证各场景渲染正确
### Phase 3清理冗余
1. 删除 `steward_planner_fallback.py``_classify_irrelevant_input` 独立门控
2. 删除 `_looks_like_ambiguous_travel_flow` 独立判定(收进 gate_classify
3. 统一 signal_keywords 来源registry 唯一)
4. 删除旧的 endpoint 补丁函数
## 7. 验证标准(持久性的可衡量判据)
接入一个新场景(如"查报销进度")时,**改动文件清单必须且仅限于**
| 文件 | 改动 |
|---|---|
| `scenes/scene_query_reimbursement_progress.py` | 新建1 个 SceneDescriptor + 1 个 handler 函数 |
| `scenes/__init__.py` | 加 1 行 import + register |
**如果接入时需要动 `steward_graph_planner.py` / `steward.py` / 前端 composable / extraction.py / fallback.py 中任何一个,说明架构没有收口成功。** 这是验收的硬标准。
## 8. 不改变的东西
- `RuntimeChatService`(模型供应商抽象):不动
- `StewardActionExecutor`(执行分发):已在 registry 驱动,不动
- `AgentConversationService`(消息持久化):不动,只是调用点从 endpoint 搬进图节点
- LangGraph 的 `StateGraph` / `interrupt` / checkpoint继续用只是节点职责更完整
- 现有渲染组件applicationPreview 表格、stewardPlan 消息):复用,不重写
## 9. 风险与对策
| 风险 | 对策 |
|---|---|
| 图重构引入回归 | Phase 1 每搬一个节点跑一次全量测试 |
| 前端去掉门控后某些场景渲染不出 | Phase 2 先保留渲染器映射,只改"谁决策"不改"怎么渲染" |
| gate_classify 性能(遍历 registry | 场景数 <20关键词正则匹配 O(1),无性能问题 |
| LLM 历史注入搬进图后 token 超限 | 保持 limit=10 不变 |

View File

@@ -1,58 +0,0 @@
# Agent Plan 文档索引
本目录描述 X-Financial 后续要建设的双 Agent 财务智能架构。
核心目标:
- 建立一套共享的语义本体协议,统一理解用户问题、定时任务和规则触发上下文。
- 建设两套职责边界清晰的 Agent
- Hermes后台数字员工负责内循环定时任务、风险巡检、统计、知识维护。
- 自建 Agent用户流程助手负责用户交互、流程操作、解释、查询、草稿生成。
- 建设 Agent Orchestrator统一负责路由、权限、工具调用、审计和失败处理。
- 让规则中心、MCP、知识库、数据库查询和任务系统使用同一套语义协议。
## 与一周计划的关系
`document/development/agent week plan` 是一周开发路线图,只描述每天要完成的大方向和交付结果。
本目录是具体架构与实现依据,包含:
- 架构设计。
- 数据协议。
- Agent 职责。
- Orchestrator 流程。
- OCR、知识库、规则生命周期。
- 每天 daily 文档会引用到的设计依据。
执行时按这个顺序阅读:
1. 先看 `document/development/agent week plan/MASTER_TODO.md`,确认今天做什么。
2. 再看本目录的架构文档,理解为什么这样做。
3. 最后进入 `document/development/agent week plan/` 对应 Day 文档,在同一份文档中按详细执行清单开发。
推荐阅读顺序:
1. [01_overall_architecture.md](./01_overall_architecture.md)
2. [02_semantic_ontology.md](./02_semantic_ontology.md)
3. [03_agent_responsibilities.md](./03_agent_responsibilities.md)
4. [04_orchestrator_and_runtime_flow.md](./04_orchestrator_and_runtime_flow.md)
5. [05_development_roadmap.md](./05_development_roadmap.md)
6. [06_data_contracts_and_governance.md](./06_data_contracts_and_governance.md)
7. [07_capability_registry.md](./07_capability_registry.md)
8. [08_permission_confirmation.md](./08_permission_confirmation.md)
9. [09_observability_and_trace.md](./09_observability_and_trace.md)
10. [10_evaluation_and_testset.md](./10_evaluation_and_testset.md)
11. [11_ocr_invoice_architecture.md](./11_ocr_invoice_architecture.md)
12. [12_llm_wiki_knowledge_architecture.md](./12_llm_wiki_knowledge_architecture.md)
13. [13_rule_formation_lifecycle.md](./13_rule_formation_lifecycle.md)
14. [14_financial_document_canonical_model.md](./14_financial_document_canonical_model.md)
15. [15_feedback_learning_loop.md](./15_feedback_learning_loop.md)
16. [../agent week plan/00_README.md](<../agent week plan/00_README.md>)
开发原则:
- 先语义协议,后 Agent 能力。
- 先只读和建议,后写入和流程动作。
- 先人工确认,后有限自动化。
- 所有财务关键动作必须可审计、可回滚、可追责。
- 所有 Agent 能力必须注册、分级、可评测、可追踪。

View File

@@ -1,163 +0,0 @@
# 双 Agent 总体架构
## 1. 背景
X-Financial 后续需要同时支持两类智能化能力:
1. 用户主动发起的交互式流程操作。
2. 系统后台自动运行的定时巡检、统计、预警和知识维护。
如果用一个万能 Agent 同时处理这两类任务,风险会很高:
- 用户流程操作需要权限、确认、上下文追问。
- 定时巡检需要稳定批处理、失败重试、审计记录。
- 财务系统不能让大模型直接决定审批、付款、规则上线。
因此建议建设双 Agent 架构:
```text
Hermes Agent
后台数字员工
面向系统内循环
定时、批量、巡检、统计、预警、知识候选
User Agent
自建用户流程助手
面向用户交互
查询、解释、创建草稿、流程操作、审批辅助
```
两套 Agent 共享一套语义本体协议,由 Agent Orchestrator 统一调度。
## 2. 总体架构图
```text
┌──────────────────────┐
│ 用户自然语言 / 定时任务 │
└───────────┬──────────┘
┌──────────────────────┐
│ Semantic Ontology │
│ 语义本体解析层 │
└───────────┬──────────┘
┌──────────────────────┐
│ Agent Orchestrator │
│ 路由 / 权限 / 审计 / 调度 │
└───────┬─────────┬────┘
│ │
┌─────────────▼─┐ ┌─▼──────────────┐
│ Hermes Agent │ │ User Agent │
│ 后台数字员工 │ │ 用户流程助手 │
└───────┬───────┘ └───────┬────────┘
│ │
└──────────┬──────────┘
┌────────────┬───────────┼───────────┬────────────┐
▼ ▼ ▼ ▼ ▼
规则中心 MCP 服务 业务数据库 知识库 任务系统
```
## 3. 核心分层
### 3.1 语义本体层
负责把自然语言或任务配置转成结构化 JSON。
输出不是最终答案,而是统一协议:
```json
{
"domain": "reimbursement",
"scenario": "invoice_validation",
"intent": "explain_risk",
"entities": [],
"time_range": {},
"constraints": {},
"risk_signals": [],
"next_step": "run_rule"
}
```
### 3.2 编排层
Agent Orchestrator 负责:
- 判断应该由 Hermes 还是 User Agent 处理。
- 判断是否需要查数据库、跑规则、调 MCP、检索知识库。
- 检查用户权限。
- 记录审计日志。
- 控制失败重试。
- 对高风险动作要求用户或管理员确认。
### 3.3 Agent 层
Hermes 和 User Agent 不直接决定财务关键状态。
它们负责:
- 理解任务。
- 组织工具调用。
- 汇总工具结果。
- 生成建议、解释、报告、草稿。
### 3.4 能力层
能力层包括:
- 规则中心:管理 `.md` 规则文件、审核、版本。
- MCP封装外部服务如发票验真、银行流水、OCR、差旅平台。
- 数据库查询:查询报销、报账、应收、应付、账款数据。
- 知识库制度文档、FAQ、历史解释、规则说明。
- 任务系统:定时任务、批量任务、重试、运行日志。
## 4. 关键边界
Hermes 可以:
- 定时读取数据。
- 执行规则检查。
- 调 MCP 查询外部状态。
- 生成风险报告。
- 生成知识候选。
- 生成待处理工单。
Hermes 不可以:
- 自动提交报销。
- 自动发起付款。
- 自动审批通过。
- 自动发布知识库正式内容。
- 自动上线规则。
User Agent 可以:
- 帮用户查询状态。
- 帮用户解释风险。
- 帮用户创建报销或付款草稿。
- 帮审批人生成审批意见。
- 在用户确认后调用流程 API。
User Agent 不可以:
- 绕过权限。
- 未确认直接提交关键动作。
- 自动最终审批。
- 自动付款。
- 修改规则审核状态。
## 5. 推荐建设顺序
```text
Step 1: 建立语义本体 JSON 协议
Step 2: 建立规则中心的规则/技能/MCP/任务目录
Step 3: 建立 Orchestrator 路由和审计
Step 4: 建立 User Agent 的只读查询和解释能力
Step 5: 建立 Hermes 的定时任务和报告能力
Step 6: 接入 MCP 和业务数据库
Step 7: 增加用户确认后的流程写入能力
Step 8: 增加知识候选和规则优化闭环
```

View File

@@ -1,457 +0,0 @@
# 语义本体协议设计
## 1. 定位
语义本体协议是用户问题、定时任务、规则中心、MCP、数据库查询和 Agent 之间的统一中间层。
它解决的问题是:
- 用户到底在问哪个业务域?
- 这属于什么场景?
- 用户想做什么?
- 问题中涉及哪些对象?
- 有没有时间、金额、状态、部门等过滤条件?
- 是否涉及风险?
- 下一步应该查知识库、查数据库、跑规则、调 MCP还是追问
## 2. 第一版核心字段
第一版建议只强制落 8 个字段。
```json
{
"domain": "",
"scenario": "",
"intent": "",
"entities": [],
"time_range": {},
"constraints": {},
"risk_signals": [],
"next_step": ""
}
```
### 2.1 domain
一级业务域。
建议枚举:
```text
reimbursement
accounts_receivable
accounts_payable
general_finance
system_operation
```
含义:
- `reimbursement`:报销、差旅、发票、补件。
- `accounts_receivable`:应收账款、客户开票、收款、账龄。
- `accounts_payable`:应付账款、供应商发票、付款、对账。
- `general_finance`:通用财务知识、制度、统计。
- `system_operation`系统巡检、任务运行、规则维护、MCP 健康检查。
### 2.2 scenario
细分场景。
报销:
```text
travel_reimbursement
daily_expense
invoice_validation
attachment_review
policy_overrun
reimbursement_audit
```
应收:
```text
customer_invoice
collection_followup
receivable_aging
payment_matching
bad_debt_risk
contract_receivable
```
应付:
```text
vendor_invoice
payment_request
payable_aging
vendor_reconciliation
invoice_matching
cash_outflow_forecast
```
系统运营:
```text
daily_risk_scan
daily_finance_statistics
knowledge_accumulation
mcp_health_check
rule_quality_review
```
### 2.3 intent
用户或任务的意图。
建议枚举:
```text
query
explain
create
validate
summarize
reconcile
monitor
predict
remind
generate
optimize
```
### 2.4 entities
识别出的业务对象。
统一结构:
```json
{
"type": "invoice",
"value": "INV-202605001",
"normalized_value": "INV-202605001",
"role": "target",
"confidence": 0.92
}
```
常见实体:
```text
employee
department
customer
vendor
invoice
contract
reimbursement_request
payment_order
receipt
bank_transaction
cost_center
project
policy
approval_node
rule
task
```
### 2.5 time_range
统一描述时间。
```json
{
"raw": "上个月",
"start": "2026-04-01",
"end": "2026-04-30",
"granularity": "month"
}
```
Hermes 定时任务也使用同一字段。
例如每日风险巡检:
```json
{
"raw": "昨日",
"start": "2026-05-09",
"end": "2026-05-09",
"granularity": "day"
}
```
### 2.6 constraints
查询、判断或执行条件。
```json
{
"status": "overdue",
"aging_days": ">30",
"amount": {
"operator": ">",
"value": 50000,
"currency": "CNY"
},
"department": "销售部",
"risk_level": ["medium", "high"]
}
```
### 2.7 risk_signals
风险信号。
建议枚举:
```text
duplicate_invoice
missing_attachment
policy_overrun
over_budget
overdue_receivable
bad_debt_risk
vendor_payment_risk
payment_mismatch
contract_mismatch
cashflow_pressure
mcp_unavailable
rule_quality_issue
```
### 2.8 next_step
下一步动作。
建议枚举:
```text
answer
ask_clarification
query_database
run_rule
call_mcp
search_knowledge
create_draft
create_task
generate_report
notify_user
escalate_to_human
```
## 3. 扩展字段
后续可以增加:
```json
{
"schema_version": "1.1",
"confidence": 0.86,
"ambiguity": [],
"missing_slots": [],
"required_capabilities": [],
"normalized_query": "",
"permission_scope": {},
"audit_tags": []
}
```
## 4. 混合语义解析架构
第一版可上线实现不应只依赖关键词和正则。
推荐采用:
```text
输入上下文装配
用户文本 + 页面上下文 + 附件名称 + OCR/VLM 摘要
预抽取
时间、金额、单号、显式对象
LLM 结构化解析
输出 scenario / intent / entities / missing_slots / ambiguity
Schema 校验
JSON 解析、字段枚举、必填校验、类型归一化
规则兜底
模型失败、低置信度或字段缺失时回退到规则解析
澄清追问
低置信度、歧义、缺槽位时不允许直接查库
```
设计原则:
- 模型优先负责“理解意图和场景”。
- 规则优先负责“校验、补全和兜底”。
- 附件名称、OCR、VLM 结果只能作为证据,不等于已确认事实。
- 所有语义输出都必须标记置信度和来源。
## 5. 推荐新增字段
为支持模型优先解析,建议在扩展字段中至少增加:
```json
{
"missing_slots": [],
"ambiguity": [],
"field_confidence": {},
"field_source": {},
"attachment_context": [],
"parse_strategy": "llm_primary_with_rule_fallback"
}
```
字段说明:
- `missing_slots`:还缺哪些关键字段,例如费用类型、单据号、客户单位。
- `ambiguity`:当前可能混淆的理解结果。
- `field_confidence`:字段级置信度,而不是只给整体分数。
- `field_source`:字段来自 `llm``rule``ocr``vlm` 还是 `user_context`
- `attachment_context`:本次可供语义解析使用的附件摘要。
- `parse_strategy`:标记本次是模型主解析还是规则回退。
## 6. 叙述型财务输入
语义层必须支持“不是查询句”的自然叙述。
典型样例:
```text
我今天去客户现场招待了客户花销了1000元
我垫付了打车费和餐费,帮我看看怎么报
上传了三张票,帮我整理成报销草稿
```
这类输入不能默认识别成 `query`
建议默认策略:
- 优先识别为 `reimbursement` 域。
- 场景优先落到 `daily_expense``travel_reimbursement``attachment_review`
- 意图优先落到 `create``generate``validate`
- 缺失关键字段时返回 `ask_clarification`,而不是直接查数据库。
## 7. 模糊短句与澄清规则
以下输入应优先追问:
```text
我要报销
这个为什么还没处理
帮我看一下这个
上传好了,下一步呢
```
处理原则:
- 不允许直接执行工具。
- 不允许直接落到应收、应付查询。
- 必须生成澄清问题。
- 必须在审计中记录触发追问的原因。
扩展原则:
- 先不要把所有字段都做成数据库列。
- 语义结果建议存 JSONB。
- 使用 `schema_version` 管理版本。
- Orchestrator 只依赖稳定字段。
- 新字段以可选方式加入,不影响老任务。
## 4. 示例
### 4.1 用户查询应收账龄
用户问:
```text
上个月哪些客户应收逾期超过 30 天?
```
解析:
```json
{
"domain": "accounts_receivable",
"scenario": "receivable_aging",
"intent": "query",
"entities": [
{
"type": "customer",
"value": "客户",
"role": "group_by"
}
],
"time_range": {
"raw": "上个月",
"start": "2026-04-01",
"end": "2026-04-30",
"granularity": "month"
},
"constraints": {
"aging_days": ">30",
"status": "overdue"
},
"risk_signals": ["overdue_receivable"],
"next_step": "query_database"
}
```
### 4.2 用户解释发票拦截
用户问:
```text
这张发票为什么报销被拦截?
```
解析:
```json
{
"domain": "reimbursement",
"scenario": "invoice_validation",
"intent": "explain",
"entities": [
{
"type": "invoice",
"value": "这张发票",
"role": "target"
}
],
"time_range": {},
"constraints": {},
"risk_signals": ["unknown"],
"next_step": "run_rule"
}
```
### 4.3 Hermes 每日风险巡检
任务配置:
```json
{
"domain": "reimbursement",
"scenario": "daily_risk_scan",
"intent": "monitor",
"entities": [],
"time_range": {
"raw": "昨日"
},
"constraints": {
"risk_level": ["medium", "high"]
},
"risk_signals": [
"duplicate_invoice",
"missing_attachment",
"policy_overrun"
],
"next_step": "run_rule"
}
```

View File

@@ -1,178 +0,0 @@
# Hermes 与自建 Agent 职责边界
## 1. 两套 Agent 的定位
### 1.1 Hermes
Hermes 定位为后台数字员工。
它不直接面向用户聊天,而是在系统后台做内循环工作。
关键词:
```text
定时
批量
巡检
统计
预警
知识维护
规则质量复盘
```
### 1.2 自建 Agent
自建 Agent 定位为用户流程助手。
它直接面对员工、财务人员、审批人和管理员。
关键词:
```text
用户触发
会话式
流程操作
查询解释
草稿生成
审批辅助
用户确认
```
## 2. Hermes 职责
Hermes 负责:
1. 每日风险巡检。
2. 每日报销、报账、账款统计。
3. 应收逾期预警。
4. 应付付款风险预警。
5. 规则命中质量复盘。
6. MCP 健康检查。
7. 知识库候选内容生成。
8. 高风险工单生成。
9. 任务运行报告生成。
Hermes 输出的内容包括:
```text
risk_report
risk_work_items
daily_finance_snapshot
knowledge_candidates
rule_improvement_items
mcp_health_report
task_run_log
```
Hermes 不允许:
1. 自动审批通过。
2. 自动发起付款。
3. 自动提交用户申请。
4. 自动发布正式知识库。
5. 自动上线规则。
6. 直接修改核心财务状态。
## 3. 自建 Agent 职责
自建 Agent 负责:
1. 查询报销单进度。
2. 创建报销或付款草稿。
3. 解释规则拦截原因。
4. 生成审批意见。
5. 检索制度知识。
6. 查询应收应付数据。
7. 帮用户对账。
8. 引导用户补充缺失信息。
9. 在用户确认后调用流程 API。
自建 Agent 输出的内容包括:
```text
natural_language_answer
form_draft
approval_opinion_draft
clarification_question
query_result_summary
next_action_suggestion
```
自建 Agent 不允许:
1. 未经用户确认提交关键动作。
2. 跳过权限校验。
3. 自动最终审批。
4. 自动付款。
5. 修改规则上线状态。
## 4. 权限边界
| 动作 | Hermes | 自建 Agent |
|---|---|---|
| 查询制度知识 | 可以 | 可以 |
| 查询业务数据 | 可以,按任务权限 | 可以,按用户权限 |
| 跑规则 | 可以 | 可以 |
| 调 MCP | 可以 | 可以 |
| 生成报告 | 可以 | 可以 |
| 生成草稿 | 不建议 | 可以 |
| 提交流程 | 不可以 | 用户确认后可以 |
| 审批通过 | 不可以 | 不可以直接做 |
| 发起付款 | 不可以 | 高权限确认后才可做草稿 |
| 发布知识 | 不可以 | 不可以 |
| 上线规则 | 不可以 | 不可以 |
## 5. 共享能力
两套 Agent 共享:
- 语义本体协议。
- 规则中心。
- MCP 服务。
- 知识库。
- 数据库查询服务。
- 审计日志。
- 权限系统。
不共享:
- 运行队列。
- 调度策略。
- 用户会话状态。
- 任务重试状态。
## 6. 示例
### 6.1 Hermes 场景
每日 02:00 自动运行:
```text
每日风险巡检
读取昨日报销、报账、发票、账款数据
执行规则
调用发票验真 MCP
调用账款流水 MCP
生成风险报告
生成风险工单
```
### 6.2 自建 Agent 场景
用户问:
```text
帮我看一下这张差旅报销为什么没通过。
```
处理:
```text
解析语义
查询报销单
读取规则命中
检索制度条款
组织解释
给出补件建议
```

View File

@@ -1,385 +0,0 @@
# Agent Orchestrator 与运行流程
## 1. Orchestrator 定位
Agent Orchestrator 是双 Agent 架构的调度中心。
它不负责生成最终答案,而是负责:
- 接收用户请求或定时任务。
- 调用语义解析。
- 判断处理方。
- 选择工具。
- 检查权限。
- 记录审计。
- 管理失败重试。
- 控制高风险动作确认。
## 2. 运行主流程
```text
输入
用户消息 / 页面按钮 / 定时任务 / 系统事件
上下文装配
页面对象 / 附件名称 / OCR 摘要 / VLM 摘要 / 用户角色 / conversation_id / draft_claim_id
语义解析
LLM 主解析 + 规则兜底,输出 ontology_json
语义校验
confidence / missing_slots / ambiguity / permission 初判
Orchestrator 决策
判断 agent = hermes | user_agent
判断 tool = rule | mcp | db | knowledge | task
权限检查
用户权限 / 任务权限 / 数据范围
业务写入
报销草稿创建 / 报销草稿更新 / 用户确认后提交
工具执行
规则中心 / MCP / 数据库 / 知识库 / 任务系统
Agent 汇总
Hermes 报告 / User Agent 回答
审计记录
保存输入、语义、工具、结果、动作
```
## 3. 路由规则
### 3.1 Hermes 路由
满足以下条件之一,进入 Hermes
```text
source = schedule
source = system_event
intent = monitor
intent = summarize and no active user session
next_step = generate_report and task_type is batch
scenario in daily_risk_scan / knowledge_accumulation / mcp_health_check
```
补充约束:
- 这里的 Hermes 指系统后台真实 Hermes 进程或 Hermes CLI不是前端概念上的 “Hermes 模式”。
- Orchestrator 负责路由、权限、审计和 Trace不负责替代 Hermes 自身执行。
- 当前阶段允许保留本地 fallback但必须预留真实 Hermes 进程调用入口。
### 3.2 User Agent 路由
满足以下条件之一,进入自建 Agent
```text
source = user_message
source = page_action
intent = query / explain / create / validate / reconcile
requires_user_context = true
next_step = ask_clarification
next_step = create_draft
```
### 3.3 工具路由
```text
next_step = query_database
调用数据库查询服务
next_step = run_rule
调用规则中心
next_step = call_mcp
调用 MCP 服务
next_step = search_knowledge
调用知识库检索
next_step = create_task
调用任务系统
next_step = create_expense_claim_draft
创建 expense_claims / expense_claim_items 草稿
next_step = update_expense_claim_draft
回写报销主表、明细和附件关联
next_step = submit_expense_claim
用户确认后更新 expense_claims.status = submitted
next_step = ask_clarification
返回追问
```
### 3.4 低置信度与缺槽位保护
当满足以下任一条件时不允许直接进入数据库、MCP 或高风险流程:
```text
confidence < threshold
missing_slots 非空
ambiguity 非空
输入为叙述型报销,但缺少关键报销信息
```
处理方式:
```text
next_step = ask_clarification
selected_agent = user_agent
tool_count = 0
```
### 3.5 叙述型报销输入保护
像下面这类文本:
```text
我今天去客户现场招待了客户花销了1000元
我垫付了交通费和午餐费
我上传了票据,帮我整理一下
```
不能因为出现“客户”就落到应收查询。
Orchestrator 应依赖语义层返回的 `scenario + intent + missing_slots` 做决策,而不是二次猜测文本关键词。
### 3.6 报销建单与状态流转边界
`scenario = expense` 且已满足最小建单槽位时:
```text
next_step = create_expense_claim_draft
status = draft
```
当用户继续补充金额、地点、客户、参与人、附件时:
```text
next_step = update_expense_claim_draft
status 保持 draft
```
当用户明确说“提交报销”并完成确认时:
```text
next_step = submit_expense_claim
status = submitted
requires_confirmation = true
```
以下状态不应由 User Agent 直接改写:
```text
approved
rejected
paid
```
这些状态应由审批流、财务支付流或受控后台同步更新。
### 3.7 结构化核对回路
`scenario = expense` 且当前仍存在缺槽位、附件待核对或票据需拆单时,不直接返回一段自由文本,而是返回结构化核对结果:
```text
result.review_payload
intent_summary
body_message
slot_cards
risk_briefs
document_cards
claim_groups
confirmation_actions = 取消 / 修改 / 保存草稿或下一步
edit_fields
```
前端正文区只展示简洁提示,右侧展示字段、风险、票据与分单明细。
### 3.8 会话续接与重识别
用户对话不是无状态调用。Orchestrator 需要携带以下会话字段继续当前报销流程:
```text
conversation_id
draft_claim_id
conversation_history
review_action
review_form_values
```
其中:
```text
review_action = edit_review
表示用户基于结构化模板修改识别结果,需要重新进入语义识别
review_action = save_draft
表示信息未补齐,但允许先保存报销草稿
review_action = next_step
表示用户确认当前识别结果,可进入下一步流转
```
## 4. 用户流程示例
用户输入:
```text
上个月哪些客户应收逾期超过 30 天?
```
流程:
```text
Step 1: User Agent 接收消息
Step 2: semantic_parser 输出 ontology_json
Step 3: Orchestrator 识别 domain = accounts_receivable
Step 4: next_step = query_database
Step 5: 权限检查用户是否可看应收数据
Step 6: 查询应收账龄表
Step 7: User Agent 汇总结果
Step 8: 返回客户清单、金额、逾期天数、风险说明
```
## 5. Hermes 任务示例
任务:
```text
每日风险巡检
```
流程:
```text
Step 1: 任务调度器在 02:00 触发
Step 2: Orchestrator 构造 ontology_json
Step 3: 路由给 Hermes
Step 4: Hermes 拉取昨日业务快照
Step 5: 执行规则中心规则
Step 6: 调用 MCP 验真、账款流水
Step 7: 生成风险报告
Step 8: 写入风险工单
Step 9: 记录任务日志
Step 10: 通知财务风控组
```
### 5.1 Hermes 后台执行方式
推荐最小形态:
```text
任务系统 / 手动触发 API
Orchestrator 生成 run_id、任务上下文、权限信息
后端调用系统 Hermes CLI 或 Hermes 后台进程
Hermes 执行知识同步 / 风险巡检 / 规则草稿形成
结果回写 AgentRun / ToolCall / 审计日志
```
约束:
- Hermes 运行使用系统级配置,不在任务代码里再写一套模型配置。
- Hermes 运行失败要记录 stderr 或等价错误摘要。
- Hermes 输出的知识候选和规则草稿必须回写为结构化结果,不只保留终端文本。
## 5A. 用户报销建单示例
用户输入:
```text
我今天去客户现场招待了客户花销了1000元
```
流程:
```text
Step 1: User Agent 接收消息
Step 2: semantic_parser 输出 ontology_json
Step 3: Orchestrator 判断 scenario = expense, intent = draft
Step 4: 若缺客户、参与人、附件,则 next_step = ask_clarification
Step 5: 补齐最小槽位后next_step = create_expense_claim_draft
Step 6: 创建 expense_claims / expense_claim_items
Step 7: 若有附件,则挂接 document_assets / expense_item_documents
Step 8: 用户确认提交后next_step = submit_expense_claim
Step 9: 更新 expense_claims.status = submitted
Step 10: 写入 AgentRun、ToolCall、AuditLog
```
## 6. 审计日志
每次 Agent 运行都应该写入审计。
建议字段:
```json
{
"id": "",
"source": "user_message | schedule | system_event",
"agent": "hermes | user_agent",
"user_id": "",
"task_id": "",
"ontology_json": {},
"tools_called": [],
"permission_scope": {},
"result_summary": "",
"action_taken": "",
"requires_confirmation": false,
"created_at": ""
}
```
建议补充 Trace 字段:
```json
{
"semantic_provider": "",
"semantic_model": "",
"semantic_prompt_version": "",
"semantic_parse_strategy": "llm_primary | rule_fallback",
"semantic_fallback_reason": "",
"semantic_latency_ms": 0
}
```
## 7. 失败处理
### 7.1 用户交互失败
```text
数据库查询失败
返回“暂时无法查询”,记录错误
缺少关键字段
返回追问
权限不足
返回无权限说明
MCP 不可用
返回降级说明,必要时生成待处理项
```
### 7.2 Hermes 任务失败
```text
任务失败
自动重试 3 次
部分 MCP 失败
标记 partial_success
数据不完整
生成异常任务日志
连续失败
通知管理员
```

View File

@@ -1,458 +0,0 @@
# 分阶段开发计划
## Phase 0准备阶段
目标:统一概念和边界,不写复杂功能。
### Step 0.1 明确术语
产出:
- 规则:`.md` 审查规则文件。
- 技能:可复用的 Agent 能力,如审批意见生成、风险解释。
- MCP外部服务连接。
- 任务:定时或批量运行的后台作业。
- Hermes后台数字员工。
- User Agent用户流程助手。
- Orchestrator调度和路由层。
- Ontology语义本体协议。
### Step 0.2 冻结第一版语义字段
第一版只强制 8 个字段:
```text
domain
scenario
intent
entities
time_range
constraints
risk_signals
next_step
```
### Step 0.3 建立设计文档
产出:
- 本目录所有文档。
- 后续数据库表设计草案。
- API 合同草案。
## Phase 1任务规则中心基础建设
目标:先把管理后台搭起来。
### Step 1.1 完成前端信息架构
页签:
```text
规则 / 技能 / MCP / 任务
```
规则详情:
- Markdown 编辑器。
- 审核人。
- 审核状态。
- 版本列表。
- 版本切换确认。
技能详情:
- 技能配置。
- 输入上下文。
- 输出契约。
- 测试样例。
- 依赖能力。
MCP 详情:
- 服务地址。
- 鉴权方式。
- 权限范围。
- 健康检查。
- 调用记录。
任务详情:
- Cron。
- 运行窗口。
- 输入范围。
- 产出对象。
- 最近运行。
### Step 1.2 建立后端基础模型
建议表:
```text
agent_rules
agent_skills
agent_mcp_services
agent_tasks
agent_asset_versions
agent_asset_reviews
```
第一阶段可以先不做完整执行,只做 CRUD。
### Step 1.3 规则版本与审核
规则上线流程:
```text
草稿
提交审核
审核通过
上线
```
关键约束:
- 没有审核人不能上线。
- 没有审核通过不能上线。
- 上线必须生成新版本。
- 历史版本只读。
## Phase 2OCR 与财务单据标准模型
目标:让发票、附件、报销单和账款流水先标准化。
### Step 2.1 附件上传与文件分类
识别:
- 发票。
- 行程单。
- 合同。
- 付款凭证。
- 审批截图。
### Step 2.2 OCR MCP 接入
把附件转成结构化字段。
### Step 2.3 Invoice 标准模型
统一 OCR、MCP、用户填写和业务系统字段。
### Step 2.4 人工修正
允许财务人员修正 OCR 字段,并写入反馈池。
### Step 2.5 规则中心接入 OCR 结果
重复发票、附件完整性、金额不一致等规则开始使用标准模型。
## Phase 3语义本体服务
目标:用户问题和任务配置都能转成 ontology_json。
### Step 3.1 建立 semantic_parser API
接口:
```text
POST /api/v1/semantic/parse
```
输入:
```json
{
"source": "user_message",
"text": "上个月哪些客户应收逾期超过 30 天?",
"context": {}
}
```
输出:
```json
{
"domain": "accounts_receivable",
"scenario": "receivable_aging",
"intent": "query",
"entities": [],
"time_range": {},
"constraints": {},
"risk_signals": [],
"next_step": "query_database"
}
```
### Step 3.2 建立模型优先解析器
要求:
- 使用运行时模型配置,而不是写死单一 provider。
- 输入包括文本、上下文、附件摘要和预抽取字段。
- 输出必须是结构化 JSON而不是自由文本。
- 输出必须经过 Schema 校验。
- 模型失败时必须回退到规则解析。
### Step 3.3 建立 ontology schema 表
建议表:
```text
semantic_ontology_schemas
semantic_parse_logs
```
字段:
```text
id
schema_version
schema_json
status
created_at
updated_at
```
### Step 3.4 建立字段级校验与澄清策略
至少支持:
- 缺少费用类型时追问。
- 缺少业务对象时追问。
- 短句或模糊句时追问。
- 叙述型报销输入默认走 create/generate而不是 query。
- 低置信度时禁止工具执行。
### Step 3.5 建立解析测试集
至少覆盖:
- 报销规则解释。
- 差旅报销创建。
- 叙述型报销创建。
- 发票验真。
- 应收逾期查询。
- 应付付款状态。
- 每日风险巡检。
- 知识库维护。
- 模糊短句追问。
- 附件输入解析。
## Phase 4LLM Wiki 知识库
目标让制度文档、FAQ、审批经验可被 Agent 检索和引用。
### Step 4.1 文档解析与分块
上传 PDF、Word、Excel 后抽取正文并 chunk。
### Step 4.2 元数据与向量索引
为知识块打 domain、scenario、tags、版本。
### Step 4.3 知识检索 API
User Agent 可以基于语义本体查询知识。
### Step 4.4 知识候选审核
Hermes 生成 FAQ 或条款候选,人工审核后发布。
## Phase 5Orchestrator 基础版
目标:基于 ontology_json 做确定性路由。
### Step 5.1 建立路由规则
输入:
```text
source
domain
scenario
intent
next_step
```
输出:
```text
agent = hermes | user_agent
tools = []
permission_required = []
```
### Step 5.2 建立工具网关
第一批工具:
```text
rule_engine.run
knowledge.search
database.query
mcp.call
task.create
```
### Step 5.3 建立审计日志
所有请求都记录:
- 原始输入。
- 语义 JSON。
- 路由结果。
- 工具调用。
- 输出摘要。
- 错误信息。
## Phase 6User Agent 第一版
目标:先做只读和解释,不做强写入。
### Step 6.1 支持制度问答
流程:
```text
用户问题
-> semantic_parse
-> search_knowledge
-> User Agent 生成回答
```
### Step 6.2 支持规则解释
流程:
```text
用户问为什么被拦截
-> semantic_parse
-> run_rule
-> search_knowledge
-> User Agent 解释风险原因
```
### Step 6.3 支持业务查询
先支持:
- 报销单状态查询。
- 应收账龄查询。
- 应付付款状态查询。
### Step 6.4 支持草稿生成
只生成草稿,不直接提交。
```text
用户确认前不写核心状态
```
## Phase 7Hermes 第一版
目标:让后台数字员工开始跑任务。
### Step 7.1 每日风险巡检
输入:
- 昨日单据。
- 发票。
- 附件。
- 付款流水。
输出:
- 风险报告。
- 风险工单。
- 风险统计。
### Step 7.2 每日财务统计
统计:
- 报销金额。
- 报账金额。
- 应收账龄。
- 应付账龄。
- 付款状态。
- 账款异常。
### Step 7.3 知识候选积累
来源:
- 审批意见。
- 驳回原因。
- 高频问答。
- 规则误报反馈。
输出:
- FAQ 候选。
- 规则优化建议。
- 制度变更摘要。
## Phase 8MCP 接入
目标:让 Agent 能安全调用外部系统。
优先接入:
1. 发票验真 MCP。
2. 附件 OCR MCP。
3. 银行流水 MCP。
4. 差旅平台 MCP。
5. ERP/付款状态 MCP。
每个 MCP 必须有:
- 服务地址。
- 鉴权方式。
- 权限范围。
- 超时设置。
- 降级策略。
- 健康检查。
- 调用日志。
## Phase 9规则形成与反馈闭环
目标:让系统持续变聪明,但不失控。
闭环:
```text
Hermes 发现问题
-> 生成规则优化建议
-> 管理员审核
-> 更新规则
-> User Agent 使用新规则解释
-> 反馈继续进入 Hermes
```
关键限制:
- Hermes 只生成候选。
- 管理员审核后才能发布。
- 所有规则变更有版本。
- 所有上线动作有审核人。
### Step 9.1 规则候选池
Hermes 从制度、风险案例、反馈中生成规则候选。
### Step 9.2 规则测试样例
每条规则上线前必须有测试样例。
### Step 9.3 反馈池
收集 OCR 修正、规则误报、Agent 回答反馈。
### Step 9.4 质量看板
统计误报率、修正率、回答满意度、MCP 失败率。

View File

@@ -1,445 +0,0 @@
# 数据契约与治理要求
## 1. 推荐数据表
### 1.1 语义本体
```text
semantic_ontology_schemas
```
字段:
```text
id
schema_version
schema_json
status
created_by
created_at
updated_at
```
```text
semantic_parse_logs
```
字段:
```text
id
source
user_id
raw_text
ontology_json
confidence
parse_strategy
created_at
```
### 1.2 Agent 资产
```text
agent_rules
agent_skills
agent_mcp_services
agent_tasks
```
通用字段:
```text
id
code
name
description
status
owner
reviewer
config_json
created_at
updated_at
```
### 1.3 版本与审核
```text
agent_asset_versions
```
字段:
```text
id
asset_type
asset_id
version
content
change_note
created_by
created_at
```
```text
agent_asset_reviews
```
字段:
```text
id
asset_type
asset_id
version
reviewer
review_status
review_note
reviewed_at
```
### 1.4 运行日志
```text
agent_runs
```
字段:
```text
id
agent
source
task_id
user_id
ontology_json
status
started_at
finished_at
result_summary
error_message
```
```text
agent_tool_calls
```
字段:
```text
id
run_id
tool_type
tool_name
request_json
response_json
status
duration_ms
created_at
```
### 1.5 财务业务主表
```text
expense_claims
expense_claim_items
accounts_receivable
accounts_payable
approval_records
```
治理要求:
- `expense_claims` 作为报销主表,不再继续扩张 `reimbursement_requests`
- `expense_claim_items` 作为报销明细最小粒度OCR 匹配、风险识别、票据挂接都优先挂到该粒度。
- `accounts_receivable``accounts_payable` 保持独立,避免因为 Agent 语义层接入而混用口径。
### 1.6 票据与文件资产表
```text
document_assets
document_asset_versions
document_derivatives
expense_item_documents
document_access_logs
```
职责:
- `document_assets`:原始附件主索引
- `document_asset_versions`:原件版本留痕
- `document_derivatives`:预览件、缩略图、脱敏件、逐页图片
- `expense_item_documents`:报销明细与票据关联
- `document_access_logs`:预览、下载、导出审计
### 1.7 OCR、验真与风险表
```text
document_ocr_results
invoice_structured_records
invoice_verification_records
risk_events
risk_actions
```
职责:
- `document_ocr_results`:每次 OCR 执行快照
- `invoice_structured_records`:标准化发票字段
- `invoice_verification_records`:发票验真结果留痕
- `risk_events`:风险命中事实
- `risk_actions`:风险处置动作
## 2. API 契约
### 2.1 语义解析
```text
POST /api/v1/semantic/parse
```
请求:
```json
{
"source": "user_message",
"text": "这张发票为什么被拦截?",
"context": {
"user_id": "emp_001",
"current_page": "reimbursement_detail"
}
}
```
响应:
```json
{
"domain": "reimbursement",
"scenario": "invoice_validation",
"intent": "explain",
"entities": [],
"time_range": {},
"constraints": {},
"risk_signals": ["unknown"],
"parse_strategy": "llm_primary",
"next_step": "run_rule"
}
```
### 2.2 Orchestrator 执行
```text
POST /api/v1/agent/orchestrate
```
请求:
```json
{
"source": "user_message",
"ontology": {},
"context": {}
}
```
响应:
```json
{
"agent": "user_agent",
"tools_called": [],
"answer": "",
"requires_confirmation": false,
"audit_id": ""
}
```
### 2.3 文件上传契约
```text
POST /api/v1/documents/upload
```
请求:
```json
{
"biz_domain": "expense",
"biz_object_type": "expense_claim",
"biz_object_id": "claim_001",
"upload_source": "user_workbench",
"files": [
{
"filename": "invoice.jpg",
"mime_type": "image/jpeg"
}
]
}
```
响应:
```json
{
"documents": [
{
"document_id": "",
"version_no": 1,
"storage_status": "stored",
"ocr_status": "pending"
}
]
}
```
### 2.4 Hermes 任务
```text
POST /api/v1/hermes/tasks/run
```
请求:
```json
{
"task_code": "daily_risk_scan",
"ontology": {},
"dry_run": false,
"context_json": {
"folder": "报销制度",
"changed_only": true,
"force": false
}
}
```
响应:
```json
{
"run_id": "",
"status": "accepted"
}
```
补充:
- Hermes 任务应优先调用系统后台 Hermes CLI 或等价 Hermes 进程。
- `changed_only=true` 时,只处理知识库中发生变化的文档。
- 文档变化判断至少包含 `original_name``stored_name``sha256``version_number``updated_at`
- 若文档无变化,应返回 `unchanged_skipped`,而不是重新形成 LLM Wiki。
## 3. 安全原则
### 3.1 最小权限
Agent 调工具时不能使用超级权限。
权限来源:
- 用户权限
- 任务权限
- 服务账号权限
### 3.2 高风险动作确认
以下动作必须确认:
- 提交报销
- 发起付款
- 生成正式审批意见
- 发布规则
- 发布知识库
- 创建外部通知
### 3.3 审计不可省略
必须记录:
- 谁触发
- 输入是什么
- 解析结果是什么
- 调了哪些工具
- 输出是什么
- 是否确认
### 3.4 文件存储治理
必须遵守:
- 原始文件二进制不落业务主表,不存入大字段 blob。
- 所有文件必须有 `storage_provider``storage_key``sha256``file_size_bytes``mime_type`
- 原件不可覆盖,只能新增版本。
- 删除默认是解除业务关联或逻辑删除,物理删除必须走审计流程。
- 对象存储访问必须使用签名 URL 或后端代理,不直接暴露固定公网地址。
### 3.5 敏感数据治理
对于发票、行程单、合同、付款凭证中的敏感信息:
- 应支持脱敏衍生件
- 应记录查看与下载行为
- 应区分申请人、审批人、财务、管理员可见范围
- 应支持争议单据 `legal_hold` 保留策略
### 3.6 AI 证据治理
Agent 和 OCR 相关能力必须遵守:
- 未经 OCR/VLM 实际解析,不得假设附件内容已知。
- Agent 输出若引用发票金额、号码、日期,必须能追溯到 `invoice_structured_records` 或人工修正记录。
- 风险解释若引用“重复报销”“金额不一致”等判断,必须能追溯到 `risk_events.evidence_json`
## 4. 数据质量要求
### 4.1 关键唯一性
- `expense_claims.claim_no` 唯一
- `document_assets.sha256` 可重复但必须可检索
- `document_asset_versions(document_id, version_no)` 唯一
- `invoice_structured_records.duplicate_fingerprint` 必须可索引
### 4.2 时间与状态字段
- 所有业务主表必须有 `created_at``updated_at`
- 文件上传、OCR、验真、风控、处置必须有独立时间戳
- 状态字段应使用受控枚举,不允许前端自由拼写
### 4.3 可追溯性
任一笔报销单、发票或风险结论,至少应能追到:
- 原始输入文本
- 原始附件
- 结构化结果
- 规则或模型判断
- 人工修正动作
## 5. 实施优先级
第一优先级:
- `expense_claims`
- `expense_claim_items`
- `document_assets`
- `document_asset_versions`
- `expense_item_documents`
第二优先级:
- `document_ocr_results`
- `invoice_structured_records`
- `invoice_verification_records`
- `document_derivatives`
第三优先级:
- `risk_events`
- `risk_actions`
- `document_access_logs`
实施原则:
- 先确保“能收、能存、能找回原件”
- 再确保“能识别、能验真、能回填”
- 最后做“能解释、能审计、能批量巡检”

View File

@@ -1,198 +0,0 @@
# Capability Registry 能力注册中心
## 1. 为什么需要能力注册中心
双 Agent 架构里会出现很多能力:
- 规则文件。
- 技能。
- MCP 服务。
- 数据库查询。
- 知识库检索。
- 定时任务。
- 报告生成。
如果 Orchestrator 直接在代码里硬编码这些能力,会导致:
- 能力越来越多后难维护。
- 无法统一权限。
- 无法统一版本。
- 无法统一输入输出格式。
- Hermes 和 User Agent 复用困难。
因此建议建立 Capability Registry。
它的定位是:
```text
所有可被 Agent 调用的能力目录
```
## 2. 能力类型
建议第一版支持:
```text
rule
skill
mcp
task
database_query
knowledge_search
report_generator
notification
```
含义:
- `rule`:审查规则,通常是 `.md` 文件或规则配置。
- `skill`:智能能力,如审批意见生成、风险解释。
- `mcp`:外部服务连接。
- `task`:定时或批量任务。
- `database_query`:受控数据库查询能力。
- `knowledge_search`:知识库检索能力。
- `report_generator`:报告生成能力。
- `notification`:通知能力。
## 3. 能力注册结构
建议结构:
```json
{
"id": "cap_rule_duplicate_invoice",
"code": "duplicate_invoice_rule",
"name": "重复报销识别规则",
"capability_type": "rule",
"domain": "reimbursement",
"scenarios": ["invoice_validation", "reimbursement_audit"],
"intents": ["validate", "explain", "monitor"],
"input_schema": {},
"output_schema": {},
"permission_required": ["reimbursement:read", "risk:write"],
"risk_level": "high",
"owner": "财务风控组",
"version": "v1.9",
"status": "active",
"requires_confirmation": false,
"created_at": "",
"updated_at": ""
}
```
## 4. 与语义本体的匹配关系
Orchestrator 根据 ontology_json 匹配能力。
示例:
```json
{
"domain": "reimbursement",
"scenario": "invoice_validation",
"intent": "explain",
"risk_signals": ["duplicate_invoice"],
"next_step": "run_rule"
}
```
可以匹配:
```text
重复报销识别规则
发票验真 MCP
风险解释技能
制度知识库检索
```
## 5. 能力匹配优先级
建议顺序:
```text
Step 1: next_step 决定能力大类
Step 2: domain 限定业务域
Step 3: scenario 限定场景
Step 4: risk_signals 匹配具体规则
Step 5: intent 匹配技能
Step 6: permission_required 校验权限
Step 7: status 必须 active
Step 8: version 使用当前上线版本
```
## 6. 数据表建议
```text
agent_capabilities
```
字段:
```text
id
code
name
capability_type
domain
scenario_json
intent_json
input_schema_json
output_schema_json
permission_json
risk_level
owner
current_version
status
requires_confirmation
config_json
created_at
updated_at
```
## 7. 开发步骤
### Step 1: 先注册静态能力
先把现有规则、技能、MCP、任务写入 Registry。
不需要一开始做复杂 UI。
### Step 2: Orchestrator 改为查 Registry
从:
```text
if next_step = run_rule then call duplicate_invoice_rule
```
改为:
```text
query capabilities where type = rule and scenario = invoice_validation
```
### Step 3: 加权限过滤
只返回当前用户或任务有权限调用的能力。
### Step 4: 加版本选择
默认使用 active 版本。
历史版本只用于回放和调试。
### Step 5: 加健康状态
MCP、任务、数据库查询能力应有健康状态。
不可用时 Orchestrator 走降级策略。
## 8. 治理要求
- 所有能力必须有 owner。
- 高风险能力必须有 reviewer。
- 所有能力必须有输入输出 schema。
- 所有能力必须有状态。
- 下线能力不能被 Orchestrator 调用。
- 能力版本变更必须写入审计。

View File

@@ -1,214 +0,0 @@
# 权限与确认引擎
## 1. 目标
Agent 不能只靠提示词判断能不能执行动作。
财务系统需要独立的权限与确认引擎:
```text
Permission Engine
Confirmation Engine
```
它们负责:
- 判断用户是否能看某类数据。
- 判断任务是否能调用某个能力。
- 判断动作是否需要确认。
- 判断动作是否禁止自动执行。
## 2. 动作风险分级
建议按 L0-L5 分级。
### L0 只读查询
例子:
- 查询制度。
- 查询单据状态。
- 查询规则说明。
- 查询任务运行记录。
要求:
- 需要权限。
- 不需要确认。
### L1 生成建议
例子:
- 生成审批意见建议。
- 生成风险解释。
- 生成规则优化建议。
要求:
- 需要权限。
- 不写业务状态。
- 不需要确认,但要标记为建议。
### L2 生成草稿
例子:
- 生成报销草稿。
- 生成付款申请草稿。
- 生成知识库候选。
要求:
- 需要权限。
- 写入草稿区。
- 不进入正式流程。
### L3 用户确认后提交
例子:
- 用户确认后提交报销。
- 审批人确认后写入审批意见。
- 用户确认后发起补件。
要求:
- 必须二次确认。
- 必须记录确认人。
- 必须记录确认前后内容。
### L4 管理员确认后发布
例子:
- 发布规则。
- 发布知识库。
- 启用 MCP。
- 启用任务。
要求:
- 必须管理员确认。
- 必须有审核记录。
- 必须有版本。
### L5 禁止自动执行
例子:
- 自动最终审批。
- 自动付款。
- 自动绕过风控。
- 自动修改核心财务状态。
要求:
- Agent 永远不能直接执行。
## 3. 权限判断输入
```json
{
"user_id": "emp_001",
"agent": "user_agent",
"source": "user_message",
"action": "create_reimbursement_draft",
"domain": "reimbursement",
"resource": {
"type": "reimbursement_request",
"id": ""
},
"capability": "travel_reimbursement_create"
}
```
## 4. 权限判断输出
```json
{
"allowed": true,
"risk_level": "L2",
"requires_confirmation": false,
"reason": "",
"permission_scope": {
"departments": ["current_user"],
"data_masking": false
}
}
```
## 5. 确认弹窗策略
需要确认的动作必须显示:
- 动作名称。
- 影响对象。
- 关键字段。
- 执行后果。
- 是否可撤销。
- 确认人。
示例:
```json
{
"title": "确认提交报销申请",
"action": "submit_reimbursement",
"summary": "将提交差旅报销单 TR-202605001金额 ¥3,280。",
"risk_level": "L3",
"confirm_button": "确认提交"
}
```
## 6. Hermes 权限
Hermes 使用服务账号,不使用个人账号。
建议拆分权限:
```text
hermes:risk_scan
hermes:finance_statistics
hermes:knowledge_candidate
hermes:mcp_health_check
```
Hermes 默认只允许:
- 读脱敏快照。
- 跑规则。
- 调只读 MCP。
- 写报告、候选、工单。
Hermes 不允许:
- 写正式审批状态。
- 写正式付款状态。
- 发布规则。
- 发布知识。
## 7. User Agent 权限
User Agent 继承当前用户权限。
例如:
- 员工只能看自己的报销。
- 部门负责人可以看本部门。
- 财务可以看授权范围内数据。
- 管理员可以管理规则、任务、MCP。
User Agent 不能扩大用户权限。
## 8. 开发步骤
```text
Step 1: 定义 action risk level
Step 2: 建立 Permission Engine 接口
Step 3: 所有工具调用前接入权限判断
Step 4: L3/L4 动作接入确认弹窗
Step 5: 审计记录确认内容
Step 6: 增加权限测试用例
```

View File

@@ -1,186 +0,0 @@
# 可观测性与 Agent Run Trace
## 1. 目标
Agent 系统必须可追踪、可回放、可解释。
财务系统中尤其需要回答:
- 为什么 Agent 得出这个结论?
- 用了哪个模型?
- 用了哪个规则版本?
- 调用了哪些 MCP
- 查了哪些数据?
- 谁确认了动作?
- 失败在哪里?
## 2. Agent Run Trace
每次 Agent 运行都生成一个 run_id。
建议结构:
```json
{
"run_id": "",
"source": "user_message",
"agent": "user_agent",
"user_id": "emp_001",
"raw_input": "",
"ontology_json": {},
"route_decision": {},
"permission_result": {},
"tool_calls": [],
"final_output": "",
"status": "success",
"started_at": "",
"finished_at": ""
}
```
## 3. 需要记录的版本
每次运行都要记录:
```text
ontology_schema_version
semantic_parser_prompt_version
model_name
model_version
rule_version
skill_version
mcp_version
knowledge_snapshot_version
orchestrator_version
```
原因:
用户可能问:
```text
为什么昨天和今天的结论不一样?
```
只有记录版本,才能解释。
## 4. Tool Call Trace
每个工具调用都记录:
```json
{
"tool_call_id": "",
"run_id": "",
"tool_type": "mcp",
"tool_name": "invoice_verify",
"request_json": {},
"response_json": {},
"status": "success",
"duration_ms": 820,
"error_message": ""
}
```
敏感字段应脱敏。
## 5. 运行状态
建议枚举:
```text
pending
running
success
partial_success
failed
cancelled
waiting_confirmation
```
## 6. Hermes 可观测性
Hermes 任务需要额外记录:
```text
task_code
schedule_time
data_snapshot_id
records_scanned
rules_executed
mcp_calls
risk_items_generated
knowledge_candidates_generated
retry_count
```
示例:
```json
{
"task_code": "daily_risk_scan",
"records_scanned": 2146,
"rules_executed": 8,
"mcp_calls": 436,
"risk_items_generated": 19,
"status": "success"
}
```
## 7. User Agent 可观测性
User Agent 需要额外记录:
```text
conversation_id
page_context
user_confirmation
draft_created
business_object_id
```
## 8. 前端审计视图
建议后续增加“Agent 运行记录”页面。
展示:
- 运行时间。
- Agent 类型。
- 用户或任务。
- 语义解析结果。
- 调用工具。
- 运行状态。
- 耗时。
- 错误。
详情页展示:
- 原始输入。
- 本体 JSON。
- 路由决策。
- 工具调用链。
- 最终输出。
## 9. 告警
需要告警的情况:
- Hermes 任务连续失败。
- MCP 健康检查失败。
- 语义解析低置信度比例过高。
- 某规则误报率过高。
- Agent 调用耗时异常。
- 权限拒绝次数异常。
## 10. 开发步骤
```text
Step 1: 增加 agent_runs 表
Step 2: 增加 agent_tool_calls 表
Step 3: Orchestrator 每次执行创建 run_id
Step 4: 工具网关记录 tool call
Step 5: 前端增加运行记录页面
Step 6: 增加异常告警规则
```

View File

@@ -1,198 +0,0 @@
# 评测集与质量控制
## 1. 为什么需要评测集
语义解析、本体字段、Agent 路由、规则命中都不能只靠人工感觉。
每次修改 prompt、模型、规则或路由逻辑都应该运行评测集。
目标:
- 检查 domain 是否识别正确。
- 检查 scenario 是否识别正确。
- 检查 intent 是否识别正确。
- 检查 next_step 是否正确。
- 检查是否应该追问。
- 检查是否错误调用高风险工具。
## 2. 第一版评测集规模
建议第一版至少 300 条。
```text
报销问题80 条
应收问题60 条
应付问题60 条
制度问答40 条
风险解释30 条
定时任务20 条
模糊问题10 条
叙述型报销20 条
附件输入10 条
```
## 3. 评测样例结构
```json
{
"id": "eval_001",
"input": "上个月哪些客户应收逾期超过 30 天?",
"expected": {
"domain": "accounts_receivable",
"scenario": "receivable_aging",
"intent": "query",
"next_step": "query_database"
},
"required_entities": ["customer"],
"notes": "应识别为应收账龄查询"
}
```
## 4. 评测指标
### 4.1 字段准确率
```text
domain_accuracy
scenario_accuracy
intent_accuracy
next_step_accuracy
field_level_f1
clarification_accuracy
```
### 4.2 工具路由准确率
```text
tool_route_accuracy
permission_decision_accuracy
confirmation_decision_accuracy
narrative_misroute_rate
```
### 4.3 安全指标
```text
unsafe_action_rate
missing_confirmation_rate
permission_bypass_rate
low_confidence_unsafe_tool_rate
```
这些指标必须接近 0。
## 5. 低置信度处理
语义解析输出应包含:
```json
{
"confidence": 0.62,
"missing_slots": ["time_range"],
"ambiguity": ["应收逾期还是审批逾期"]
}
```
当置信度低于阈值:
```text
confidence < 0.75
不执行工具
返回追问
```
## 6. 模糊问题样例
用户问:
```text
这个为什么还没处理?
```
不能直接执行查询。
应该追问:
```text
你是想查询报销单、应收款还是付款申请的处理状态?
```
叙述型报销样例:
```json
{
"id": "eval_reimbursement_narrative_001",
"input": "我今天去客户现场招待了客户花销了1000元",
"expected": {
"domain": "reimbursement",
"scenario": "daily_expense",
"intent": "create",
"next_step": "ask_clarification"
},
"required_entities": ["amount"],
"notes": "不能错误路由到应收查询"
}
```
## 7. 回归测试流程
每次改动以下内容都要跑评测:
- semantic parser 模型或 provider。
- semantic parser prompt。
- ontology schema。
- Orchestrator 路由。
- 规则中心匹配逻辑。
- MCP 能力注册。
- 模型版本。
流程:
```text
Step 1: 加载评测集
Step 2: 批量调用 semantic_parse
Step 3: 批量调用 route_decision
Step 4: 对比 expected
Step 5: 输出准确率报告
Step 6: 阻止低于阈值的发布
```
## 8. 发布阈值
建议第一版阈值:
```text
domain_accuracy >= 95%
intent_accuracy >= 90%
next_step_accuracy >= 90%
unsafe_action_rate = 0
missing_confirmation_rate = 0
narrative_misroute_rate <= 1%
low_confidence_unsafe_tool_rate = 0
```
## 9. 评测数据管理
建议文件结构:
```text
server/tests/fixtures/semantic_eval/
reimbursement.jsonl
accounts_receivable.jsonl
accounts_payable.jsonl
risk_explain.jsonl
scheduled_tasks.jsonl
```
每行一个样例。
## 10. 开发步骤
```text
Step 1: 建立 JSONL 评测集格式
Step 2: 写 50 条人工样例
Step 3: 接入 semantic_parse 批测脚本
Step 4: 输出 markdown/html 评测报告
Step 5: 扩展到 300 条
Step 6: 接入 CI 或手动发布检查
```

View File

@@ -1,376 +0,0 @@
# OCR 票据识别架构
## 1. 定位
OCR 票据识别不是一个简单的图片转文字功能。
它在 X-Financial 中承担四件事:
1. 把用户上传的附件变成结构化票据信息。
2. 为规则中心提供可判断的字段。
3. 为 User Agent 和 Hermes 提供可解释的证据。
4. 为后续审计、复核、争议处理保留可回溯原件。
因此 OCR 应作为独立能力纳入 Capability Registry。
```text
capability_type = mcp | document_processor
capability_code = invoice_ocr
```
## 2. 总体链路
```text
附件上传
文件落盘 / 对象存储
文件分类
OCR 识别
字段结构化
票据类型归一化
发票验真 MCP
与报销明细匹配
规则中心检查
人工修正
修正结果沉淀
```
关键原则:
- 文件先持久化,再做 OCR不允许只在内存里跑完就丢。
- 原件不可覆盖,只能新增版本。
- Agent 不得假设图片内容已知;只有 OCR/VLM 实际解析后才能引用附件内容。
## 3. 阶段拆分
### Phase A附件接入与文件分类
目标:先识别上传的是什么。
输入:
- 图片
- PDF
- Excel
- Word
- 压缩包
输出:
```json
{
"document_type": "invoice",
"mime_type": "image/png",
"page_count": 1,
"confidence": 0.91
}
```
分类结果:
```text
invoice
itinerary
contract
payment_receipt
approval_screenshot
other
```
### Phase BOCR 字段提取
目标:从图片或 PDF 中提取票据字段。
结构:
```json
{
"invoice_code": "",
"invoice_number": "",
"seller_name": "",
"seller_tax_no": "",
"buyer_name": "",
"buyer_tax_no": "",
"issue_date": "",
"total_amount": 0,
"tax_amount": 0,
"currency": "CNY",
"ocr_confidence": 0.88
}
```
### Phase C字段归一化
目标:不同 OCR 服务返回不同字段名,必须统一。
示例:
```text
发票号码 / invoiceNo / invoice_number
-> invoice_number
```
金额统一:
```json
{
"raw": "¥1,280.00",
"value": 1280.00,
"currency": "CNY"
}
```
### Phase D验真与状态检查
调用发票验真 MCP。
输出:
```json
{
"verify_status": "verified",
"voided": false,
"red_reversed": false,
"verified_at": ""
}
```
### Phase E与报销明细匹配
对比:
- 发票金额 vs 报销金额
- 开票日期 vs 费用日期
- 销售方 vs 商户
- 发票类型 vs 费用类型
输出:
```json
{
"match_status": "matched",
"mismatch_fields": [],
"match_confidence": 0.94
}
```
### Phase F人工修正与回流
OCR 结果必须允许人工修正。
修正内容进入反馈池:
```json
{
"field": "invoice_number",
"before": "12345B",
"after": "123456",
"corrected_by": "finance_user",
"corrected_at": ""
}
```
## 4. 文件存储策略
### 4.1 为什么不能直接把文件塞进数据库
- 原始票据、合同、行程单体积大,数据库行膨胀明显。
- 预览件、缩略图、逐页图片、脱敏件都属于衍生文件,不适合和业务行混存。
- 财务原件需要版本留痕和不可变追溯,文件系统或对象存储更适合。
结论:
- 文件二进制存文件系统或对象存储。
- 数据库仅保存元数据、索引、版本、OCR 结果、验真结果、访问审计和业务关联。
### 4.2 开发环境目录方案
根目录使用后端配置中的 `STORAGE_ROOT_DIR`
建议目录:
```text
<STORAGE_ROOT_DIR>/
finance-documents/
expense_claim/
2026/
05/
<claim_id>/
<document_id>/
v1/
original/
source.jpg
preview/
preview.pdf
pages/
page-1.png
thumbs/
thumb.webp
ocr/
ocr-1.json
verify/
verify-1.json
```
说明:
- `claim_id` 为空时,可先挂到 `draft/<conversation_id>/<document_id>/...`,待正式建单后再回填业务关联。
- `v1``v2` 表示文件版本,不允许直接覆盖 `v1`
- 原始文件名用于展示,真实定位依赖 `storage_key``sha256`
### 4.3 生产环境存储方案
生产环境建议使用:
- MinIO
- S3
- 阿里云 OSS
- 腾讯云 COS
对象存储推荐键名:
```text
finance-documents/expense_claim/2026/05/<claim_id>/<document_id>/v1/original/source.jpg
finance-documents/expense_claim/2026/05/<claim_id>/<document_id>/v1/preview/preview.pdf
finance-documents/expense_claim/2026/05/<claim_id>/<document_id>/v1/thumbs/thumb.webp
```
数据库必须保存:
```text
storage_provider
storage_bucket
storage_key
sha256
file_size_bytes
mime_type
current_version_no
```
### 4.4 原件、版本与衍生件规则
- 原件不可变:上传后不得覆盖。
- 替换附件只能新增 `document_asset_versions` 记录。
- OCR 原始输出、验真响应、预览件、缩略图都作为衍生件管理。
- 删除操作默认只允许逻辑删除业务关联,不允许物理删除原件。
- 命中审计或争议流程的单据可切换到 `legal_hold` 保留策略,暂停清理。
### 4.5 去重与追溯
- 每个原始文件必须计算 `sha256`
- 同一个 `sha256` 可提示重复上传,但不能自动覆盖旧版本。
- 发票查重不能只靠文件哈希,还要结合 `invoice_code + invoice_number + issue_date + total_amount`
## 5. 数据模型建议
推荐配套表:
```text
document_assets
document_asset_versions
document_derivatives
document_ocr_results
invoice_structured_records
invoice_verification_records
expense_item_documents
document_access_logs
```
各表职责:
- `document_assets`:文件主索引
- `document_asset_versions`:原件版本
- `document_derivatives`:缩略图、预览、逐页图片、脱敏件
- `document_ocr_results`:每次 OCR 执行结果
- `invoice_structured_records`:标准化票据字段
- `invoice_verification_records`:验真结果
- `expense_item_documents`:报销明细与票据挂接
- `document_access_logs`:文件查看、下载、导出审计
## 6. 与规则中心关系
OCR 输出供规则使用:
```text
重复报销识别规则
作废发票检查规则
发票抬头异常规则
附件完整性规则
金额不一致规则
OCR 低置信度补录规则
```
规则读取原则:
- 读标准化字段,不直接依赖某个 OCR 服务的原始字段名。
- 需要追证时,从 `document_assets``document_asset_versions` 找原件。
- 需要解释时,从 `document_ocr_results``invoice_verification_records` 给证据。
## 7. 与 Agent 关系
User Agent 使用 OCR
- 解释发票为什么被拦截
- 帮用户补充发票信息
- 提醒上传清晰附件
- 根据 OCR 结果自动回填报销草稿
Hermes 使用 OCR
- 夜间批量验真
- 扫描重复票据
- 统计发票异常趋势
- 回刷历史低置信度票据
## 8. 安全与审计要求
### 8.1 访问控制
- 原始票据预览、下载应按用户角色控制。
- 财务、审批人、申请人看到的文件范围可以不同。
- 对象存储不要暴露永久公网链接,统一走签名 URL 或后端代理下载。
### 8.2 敏感信息处理
- 身份证、银行卡、手机号等敏感字段如被识别,应支持脱敏预览件。
- 对外展示尽量用衍生件,不直接暴露原件。
### 8.3 审计要求
必须记录:
- 谁上传了原件
- 谁触发了 OCR
- 谁查看或下载了原件
- 谁修正了 OCR 结果
- 谁发起了验真
- 哪次风险判断引用了哪些票据
## 9. 开发阶段建议
```text
Step 1: 附件上传与 document_assets / document_asset_versions 落库
Step 2: 本地文件目录方案打通
Step 3: 接入 OCR MCP 或 OCR 服务
Step 4: 结构化字段归一化
Step 5: 发票验真 MCP
Step 6: 与 expense_claim_items 匹配
Step 7: 风险规则中心接入
Step 8: 人工修正界面
Step 9: Hermes 夜间批量 OCR 与验真巡检
```
当前阶段优先级:
- 先把“文件原件可存、可找、可追溯”做实。
- 再把 OCR 和验真接进来。
- 最后再做大规模自动巡检和脱敏导出。

View File

@@ -1,221 +0,0 @@
# LLM Wiki 知识库架构
## 1. 定位
LLM Wiki 不是简单的文件库。
它是给 Agent 使用的知识底座负责把制度、FAQ、审批经验、规则说明转成可检索、可引用、可版本化的知识。
## 2. 总体链路
```text
文档上传
格式解析
正文抽取
分块 Chunking
元数据标注
向量索引
条款抽取
知识候选
人工审核
发布 Wiki
Agent 检索引用
```
## 2.1 目录约束
LLM Wiki 解析产物不能与原始制度文件混放。
推荐目录:
```text
/app/server/storage/knowledge/<folder>/ 原始知识文件
/app/server/storage/knowledge/.llm_wiki/ 解析产物根目录
/app/server/storage/knowledge/.llm_wiki/documents/<document_id>/
document.json
text.md
chunks.json
clauses.json
knowledge_candidates.json
rule_candidates.json
/app/server/storage/knowledge/.llm_wiki/index.json
/app/server/storage/knowledge/.llm_wiki/sync_runs.json
```
约束:
- 原始文件目录只存原件,不存解析碎片。
- LLM Wiki 目录只存结构化产物,不反向覆盖原件。
- 所有解析产物必须能按 `document_id` 回溯到原始文件。
## 3. 知识类型
```text
policy_document
faq
rule_explanation
approval_case
risk_case
operation_manual
system_notice
```
## 4. 知识块结构
```json
{
"chunk_id": "",
"document_id": "",
"title": "",
"content": "",
"domain": "reimbursement",
"scenario": "travel_reimbursement",
"tags": ["差旅", "住宿标准"],
"effective_date": "",
"version": "v1.0",
"source_page": 4,
"embedding_id": "",
"status": "published"
}
```
## 5. 条款抽取
Hermes 可以从制度文档中抽取条款候选。
示例:
```json
{
"clause_type": "amount_limit",
"domain": "reimbursement",
"scenario": "travel_reimbursement",
"condition": {
"city_tier": "一线城市",
"employee_grade": "P5"
},
"limit": {
"amount": 800,
"currency": "CNY",
"period": "night"
},
"source": "差旅制度 2026 第 4 页"
}
```
该结果不直接变成规则,先进入规则候选池。
## 5.1 增量形成策略
LLM Wiki 不应按天无脑全量重建。
每个文档都应维护签名:
```json
{
"document_id": "",
"original_name": "",
"stored_name": "",
"sha256": "",
"version_number": 1,
"updated_at": ""
}
```
只有在以下任一条件发生时,才重建对应文档的 LLM Wiki
- `original_name` 变更。
- `stored_name` 变更。
- `sha256` 变更。
- `version_number` 变更。
- `updated_at` 变更,视为人工修改。
如果以上均未变化:
- 本次文档状态应记为 `unchanged_skipped`
- 不重新抽取正文。
- 不重新分块。
- 不重新生成知识候选或规则候选。
## 6. Wiki 发布流程
```text
草稿知识
Hermes 生成候选
知识管理员审核
发布
Agent 可检索
```
## 7. 与 User Agent 的关系
User Agent 用 Wiki
- 回答制度问题。
- 给风险解释提供条款依据。
- 给审批意见生成引用。
- 帮用户理解流程。
## 8. 与 Hermes 的关系
Hermes 用 Wiki
- 每日知识候选生成。
- 发现制度与规则不一致。
- 生成规则优化建议。
- 生成 FAQ 候选。
补充要求:
- Hermes 对制度文档的处理默认是增量同步,不是每日全量重建。
- Hermes 应先检查知识库签名,再决定是否需要重建某个文档的 Wiki。
- Hermes 形成的是候选与草稿,不是正式发布内容。
## 9. 数据模型建议
```text
knowledge_documents
knowledge_chunks
knowledge_embeddings
knowledge_candidates
knowledge_reviews
knowledge_versions
```
当前最小落地允许先以文件索引实现:
```text
.llm_wiki/index.json
.llm_wiki/sync_runs.json
.llm_wiki/documents/<document_id>/document.json
```
后续再平滑迁移到数据库或向量库。
## 10. 开发阶段建议
```text
Step 1: 文档上传和文件管理
Step 2: 文本抽取和分块
Step 3: 元数据标注
Step 4: 向量索引
Step 5: 知识检索 API
Step 6: User Agent 问答引用
Step 7: Hermes 知识候选生成
Step 8: 人工审核发布
Step 9: 条款抽取和规则候选
```

View File

@@ -1,194 +0,0 @@
# 规则形成生命周期
## 1. 定位
规则不是凭空写出来的。
它应来自:
- 制度文档。
- 历史审批。
- 风险案例。
- OCR 识别结果。
- MCP 验真结果。
- 用户反馈。
- Hermes 分析。
## 2. 总体闭环
```text
制度文档 / 历史审批 / 风险案例 / 用户反馈
Hermes 分析
规则候选
人工审核
规则 .md
测试样例
版本发布
规则执行
命中反馈
规则优化
```
## 3. 规则候选结构
```json
{
"candidate_id": "",
"source_type": "policy_document",
"domain": "reimbursement",
"scenario": "invoice_validation",
"risk_signal": "duplicate_invoice",
"suggested_rule_name": "重复报销识别规则",
"rule_markdown_draft": "",
"evidence": [],
"confidence": 0.86,
"created_by": "hermes"
}
```
补充约束:
- `rule_markdown_draft` 不能是任意自由文本,必须符合固定模板。
- 规则候选应同时携带机器可读 JSON 草稿,例如 `runtime_rule`
- JSON 草稿只能从受控模板族中选择,不允许 Hermes 自创字段结构后直接进入规则中心。
## 4. 规则 Markdown 推荐结构
```markdown
# 规则名称
## 目标
## 适用范围
## 输入字段
## 判断规则
## 输出
## 测试样例
## 管理员备注
```
推荐再补一段模板元信息:
```markdown
## 模板信息
- 模板键:`travel_standard_v1`
- 来源文档公司支出管理办法2024
- Hermes 置信度0.86
- 审核人:张三
```
## 4.1 规则 JSON 推荐结构
规则中心不应只有 Markdown。
应同时提供可执行 JSON 编辑区,至少支持:
```json
{
"kind": "policy_rule_draft",
"version": 1,
"template_key": "travel_standard_v1",
"rule_name": "差旅住宿标准草稿规则",
"scenario": "travel_reimbursement",
"review_required": true,
"conditions": {},
"actions": {},
"source_document_name": "公司支出管理办法2024"
}
```
治理要求:
- Markdown 负责给人看。
- JSON 负责给运行时和规则引擎看。
- 两者必须成对维护,不能只改其中一份。
- JSON 变更也必须走版本和审核。
## 4.2 模板族约束
Hermes 只能从白名单模板中选,不允许自由生成任意规则结构。
第一版建议模板:
```text
travel_standard_v1
expense_amount_limit_v1
attachment_requirement_v1
general_policy_v1
```
如果制度条款不适合自动规则化:
- 允许只生成 `knowledge_candidate`
- 或只生成 `general_policy_v1` 草稿并要求人工补齐
- 不能为了“有结果”而编造可执行规则
## 5. 审核要求
规则上线必须满足:
- 有审核人。
- 有版本。
- 有测试样例。
- 有来源依据。
- 有回滚方案。
补充:
- Hermes 生成规则默认只能是 `draft`
- Hermes 不能直接覆盖当前 `active` 线上规则。
- Hermes 如发现制度更新,应优先生成新的候选或草稿版本,仍需人工审核后再上线。
## 6. 规则执行反馈
每次规则运行应记录:
```text
rule_id
rule_version
input_snapshot
hit_result
risk_level
operator_feedback
false_positive
false_negative
```
## 7. 规则优化来源
```text
误报反馈
漏报反馈
审批人修改意见
Hermes 每日复盘
制度文档更新
MCP 新字段可用
```
## 8. 开发阶段建议
```text
Step 1: 规则 .md 编辑和版本
Step 2: 规则审核上线
Step 3: 规则运行日志
Step 4: 人工反馈误报/漏报
Step 5: Hermes 生成规则候选
Step 6: 规则候选审核
Step 7: 规则测试样例管理
Step 8: 规则质量看板
```

View File

@@ -1,646 +0,0 @@
# 财务单据标准模型
## 1. 为什么需要标准模型
OCR、MCP、用户填写、业务数据库可能都描述同一张发票但字段名和格式不同。
如果没有标准模型:
- 规则无法复用。
- Agent 难以解释。
- Hermes 难以批量统计。
- MCP 返回结果难以合并。
这里要区分三层:
- 标准模型:定义 Agent、规则、MCP、OCR、数据库之间统一交换的数据结构。
- 业务数据库表:定义 MVP 阶段真正落库存储、查询和统计所依赖的业务表。
- 文件存储对象定义原始票据、预览件、OCR 中间产物、验真结果附件的存储位置与版本规则。
如果只有标准模型没有业务表和文件资产表User Agent 无法真正发起报销如果只有数据库表没有统一标准模型语义解析、规则解释、OCR 回填和 Hermes 巡检会越来越混乱。
## 2. 标准对象
第一版建议定义这些对象:
```text
Invoice
Receipt
ExpenseClaim
PaymentRequest
AccountsReceivableRecord
AccountsPayableRecord
BankTransaction
Contract
Customer
Vendor
Employee
CostCenter
DocumentAsset
RiskEvent
```
说明:
- 对外语义层建议统一使用 `ExpenseClaim` 概念,不再把“报销申请”和“报销单据”拆成两个平行主概念。
- 现有代码中仍有 `reimbursement_requests`MVP 阶段不建议再继续扩张该表,而应以 `expense_claims` 作为报销主表。
- `reimbursement_requests` 可保留用于兼容旧页面或审批联动,但新能力默认挂到 `expense_claims`
## 3. Invoice 标准模型
```json
{
"invoice_id": "",
"invoice_code": "",
"invoice_number": "",
"invoice_type": "",
"seller_name": "",
"seller_tax_no": "",
"buyer_name": "",
"buyer_tax_no": "",
"issue_date": "",
"total_amount": 0,
"tax_amount": 0,
"currency": "CNY",
"verify_status": "",
"ocr_confidence": 0,
"source_document_id": ""
}
```
## 4. ExpenseClaim 标准模型
```json
{
"claim_id": "",
"claim_no": "",
"employee_id": "",
"employee_name": "",
"department_id": "",
"department_name": "",
"cost_center_code": "",
"project_code": "",
"expense_type": "",
"reason": "",
"location": "",
"amount": 0,
"currency": "CNY",
"status": "",
"occurred_at": "",
"submitted_at": "",
"approval_stage": "",
"items": [],
"attachments": [],
"risk_flags": []
}
```
说明:
- `reason``location``occurred_at` 是报销语义判断、规则解释、风险识别的最小必要字段。
- 一张报销单通常包含多条费用明细,标准模型中允许聚合,数据库层必须拆到明细表。
- `attachments` 指向文件资产,不直接嵌入二进制文件。
## 5. AccountsReceivableRecord 标准模型
```json
{
"ar_id": "",
"document_no": "",
"customer_id": "",
"customer_name": "",
"contract_no": "",
"invoice_no": "",
"amount_receivable": 0,
"amount_received": 0,
"amount_outstanding": 0,
"currency": "CNY",
"due_date": "",
"posting_date": "",
"status": "",
"aging_days": 0,
"risk_flags": []
}
```
## 6. AccountsPayableRecord 标准模型
```json
{
"ap_id": "",
"document_no": "",
"vendor_id": "",
"vendor_name": "",
"invoice_no": "",
"amount_payable": 0,
"amount_paid": 0,
"amount_outstanding": 0,
"currency": "CNY",
"due_date": "",
"posting_date": "",
"status": "",
"aging_days": 0,
"risk_flags": []
}
```
## 7. BankTransaction 标准模型
```json
{
"transaction_id": "",
"bank_account": "",
"transaction_date": "",
"amount": 0,
"currency": "CNY",
"counterparty_name": "",
"summary": "",
"matched_object_type": "",
"matched_object_id": "",
"match_status": ""
}
```
## 8. MVP 真实业务表设计
标准模型不等于数据库表,但 MVP 至少要有以下真实表,才能支撑 Day 5 用户报销对话、Day 6 风险巡检和后续审批/验真闭环。
### 8.1 设计原则
- 报销主数据统一落在 `expense_claims`,不再新建第三套“报销主表”。
- 原始票据文件二进制不进数据库,只存元数据和关联信息。
- OCR 结果、发票结构化结果、验真结果、风险事件要分表存,避免把所有字段塞进一个 JSON。
- 所有表都要能被 Agent 解释,也要能被 Hermes 批量扫表。
- `reimbursement_requests` 进入兼容态,不作为新能力主干表继续扩展。
### 8.2 报销主表 `expense_claims`
用途:
- 作为用户报销会话最终落单的主业务对象。
- 承接语义层补槽后的草稿、提交、审批、打回、归档状态。
建议字段:
```text
id string(36) PK
claim_no string(50) UK, 报销单号
source string(30) 来源: agent/web/import/api
title string(200) 报销标题
employee_id string(64) 申请人 ID
employee_name string(100) 申请人姓名
department_id string(64) 部门 ID
department_name string(100) 部门名
company_code string(50) 公司编码
cost_center_code string(50) 成本中心
project_code string(50) 项目编码
expense_type string(50) 费用大类
reason text 事由
location string(100) 地点
amount numeric(12,2) 报销总金额
currency string(10) 币种
invoice_count int 附件票据数
attachment_count int 附件总数
occurred_start_at timestamptz 发生开始时间
occurred_end_at timestamptz 发生结束时间
submitted_at timestamptz 提交时间
status string(30) draft/submitted/approved/rejected/paid
status_changed_at timestamptz 最近状态变更时间
status_changed_by string(64) 最近状态变更人
status_change_note text 状态变更备注
approval_stage string(50) 当前审批节点
risk_level string(20) none/low/medium/high
risk_flags_json json 风险标记快照
conversation_id string(64) 对话会话 ID
created_by string(64) 创建人
updated_by string(64) 更新人
created_at timestamptz
updated_at timestamptz
```
说明:
- 现有模型已有一部分字段,后续只做增量扩展即可。
- `occurred_start_at``occurred_end_at` 比单一 `occurred_at` 更适合差旅、接待等跨时段报销。
### 8.2.1 报销状态流转建议
建议状态:
```text
draft
submitted
approved
rejected
paid
```
建议流转:
```text
语义补槽完成
-> 创建 expense_claims 草稿
-> status = draft
用户继续补充字段 / 上传附件
-> 更新 expense_claims / expense_claim_items / expense_item_documents
-> status 仍为 draft
用户明确确认提交
-> status = submitted
-> 写入 submitted_at / status_changed_at / status_changed_by
审批流结果回写
-> status = approved 或 rejected
付款完成回写
-> status = paid
```
边界:
- User Agent 可以创建 `draft`,也可以在用户确认后提交到 `submitted`
- User Agent 不应直接把状态改为 `approved``rejected``paid`
- 所有状态变化都应写审计日志,必要时保留 `status_change_note`
### 8.3 报销明细表 `expense_claim_items`
用途:
- 表达一单多明细。
- 作为 OCR 发票比对、重复报销识别、风险定位的最小粒度。
建议字段:
```text
id string(36) PK
claim_id string(36) FK -> expense_claims.id
line_no int 明细序号
item_date date 费用发生日期
item_type string(50) 费用小类
item_reason text 明细事由
item_location string(100) 明细地点
merchant_name string(200) 商户/酒店/餐厅
customer_name string(200) 客户单位
participants_json json 参与人员
transport_type string(50) 交通方式
item_amount numeric(12,2) 明细金额
tax_amount numeric(12,2) 税额
currency string(10)
invoice_match_status string(30) unmatched/partial/matched
risk_level string(20)
risk_flags_json json
remark text
created_at timestamptz
updated_at timestamptz
```
说明:
- 现有 `invoice_id` 单字段不足以覆盖多张附件挂同一明细的情况,后续应改为关联表。
### 8.4 票据资产主表 `document_assets`
用途:
- 作为所有原始附件的主索引表。
- 支持报销单、报销明细、审批、验真、风控证据等多对象挂载。
建议字段:
```text
id string(36) PK
biz_domain string(30) expense/ap/ar/common
biz_object_type string(50) expense_claim/expense_item/approval_record
biz_object_id string(36) 业务对象 ID
document_type string(50) invoice/receipt/itinerary/contract/other
document_subtype string(50) vat_special/taxi/train/hotel/meal 等
source string(30) upload/agent/import/system
original_filename string(255)
mime_type string(100)
file_ext string(20)
page_count int
file_size_bytes bigint
sha256 string(64) 去重与追溯
storage_provider string(30) local/minio/s3/oss/cos
storage_bucket string(100) 本地模式可为空
storage_key string(500) 指向当前有效版本原件
current_version_no int
classification_status string(30) pending/success/failed
ocr_status string(30) pending/running/success/failed
virus_scan_status string(30) pending/clean/infected
retention_policy string(30) finance_default/legal_hold/manual
uploaded_by string(64)
uploaded_at timestamptz
created_at timestamptz
updated_at timestamptz
```
### 8.5 票据版本表 `document_asset_versions`
用途:
- 保留原始文件和后续重新上传版本。
- 允许“修正”但不允许覆盖原始证据。
建议字段:
```text
id string(36) PK
document_id string(36) FK -> document_assets.id
version_no int 1,2,3...
is_current bool
change_reason string(100) replace/rotate/desensitize/reupload
original_filename string(255)
mime_type string(100)
file_size_bytes bigint
sha256 string(64)
storage_provider string(30)
storage_bucket string(100)
storage_key string(500)
uploaded_by string(64)
uploaded_at timestamptz
created_at timestamptz
```
### 8.6 衍生文件表 `document_derivatives`
用途:
- 存储缩略图、预览 PDF、逐页图片、脱敏件等衍生产物。
建议字段:
```text
id string(36) PK
document_version_id string(36) FK -> document_asset_versions.id
derivative_type string(50) thumb/preview/page_image/desensitized
page_no int 可空
mime_type string(100)
file_size_bytes bigint
storage_provider string(30)
storage_bucket string(100)
storage_key string(500)
created_by string(64)
created_at timestamptz
```
### 8.7 OCR 结果表 `document_ocr_results`
用途:
- 保留每次 OCR 原始结果、模型版本、置信度和错误信息。
- 支持后续重跑 OCR 与人工纠错对比。
建议字段:
```text
id string(36) PK
document_id string(36) FK -> document_assets.id
document_version_id string(36) FK -> document_asset_versions.id
ocr_engine string(50) paddle/aliyun/tencent/openai 等
ocr_model string(100)
run_no int 第几次 OCR
status string(30) success/failed/partial
language string(20)
raw_text text
raw_result_json json
structured_result_json json
confidence numeric(5,4)
error_message text
started_at timestamptz
finished_at timestamptz
created_at timestamptz
```
### 8.8 发票结构化表 `invoice_structured_records`
用途:
- 将发票核心字段标准化后独立存储,便于查重、验真、规则计算。
建议字段:
```text
id string(36) PK
document_id string(36) FK -> document_assets.id
ocr_result_id string(36) FK -> document_ocr_results.id
invoice_code string(50)
invoice_number string(50)
invoice_type string(50)
seller_name string(200)
seller_tax_no string(50)
buyer_name string(200)
buyer_tax_no string(50)
issue_date date
total_amount numeric(12,2)
tax_amount numeric(12,2)
currency string(10)
check_code string(100)
is_red_invoice bool
is_electronic bool
ocr_confidence numeric(5,4)
normalized_status string(30) normalized/manual_corrected
duplicate_fingerprint string(100) 发票号+代码+金额+日期
created_at timestamptz
updated_at timestamptz
```
### 8.9 发票验真记录表 `invoice_verification_records`
用途:
- 保留每次调用税局/第三方验真服务的结果,支持追溯。
建议字段:
```text
id string(36) PK
invoice_record_id string(36) FK -> invoice_structured_records.id
verification_channel string(50) tax_mcp/third_party/manual
request_payload_json json
response_payload_json json
verify_status string(30) verified/unverified/voided/error
voided bool
red_reversed bool
verified_amount numeric(12,2)
verified_issue_date date
error_code string(50)
error_message text
verified_by string(64)
verified_at timestamptz
created_at timestamptz
```
### 8.10 明细与票据关联表 `expense_item_documents`
用途:
- 解决一条明细可关联多张票据、一张票据也可能支撑多条拆分明细的场景。
建议字段:
```text
id string(36) PK
claim_id string(36) FK -> expense_claims.id
claim_item_id string(36) FK -> expense_claim_items.id
document_id string(36) FK -> document_assets.id
relation_type string(30) evidence/invoice/boarding_pass/receipt
allocated_amount numeric(12,2) 分摊到该明细的金额
match_status string(30) unmatched/partial/matched
match_confidence numeric(5,4)
created_at timestamptz
updated_at timestamptz
```
### 8.11 风险事件表 `risk_events`
用途:
- 记录风险命中,而不是只在主表里塞一个 `risk_flags_json`
- 作为 Agent 解释“为什么拦截”的核心依据。
建议字段:
```text
id string(36) PK
biz_domain string(30) expense/ap/ar
biz_object_type string(50) expense_claim/expense_item/invoice
biz_object_id string(36)
risk_code string(50) duplicate_invoice/amount_mismatch 等
risk_name string(100)
risk_level string(20) low/medium/high
hit_source string(30) rule/agent/hermes/manual
evidence_json json
status string(30) open/confirmed/resolved/ignored
detected_at timestamptz
detected_by string(64)
resolved_at timestamptz
resolved_by string(64)
resolution_note text
created_at timestamptz
updated_at timestamptz
```
### 8.12 风险处置表 `risk_actions`
用途:
- 记录每次人工确认、驳回、忽略、要求补件等处置动作。
建议字段:
```text
id string(36) PK
risk_event_id string(36) FK -> risk_events.id
action_type string(30) confirm/reject/ignore/request_more
action_note text
operator_id string(64)
operator_name string(100)
created_at timestamptz
```
### 8.13 文件访问审计表 `document_access_logs`
用途:
- 记录谁看过、下载过、导出过原始票据。
- 支撑财务审计和数据安全追溯。
建议字段:
```text
id string(36) PK
document_id string(36) FK -> document_assets.id
document_version_id string(36) FK -> document_asset_versions.id
action string(30) preview/download/export/delete
operator_id string(64)
operator_name string(100)
operator_role string(50)
client_ip string(64)
user_agent string(255)
trace_id string(64)
created_at timestamptz
```
## 9. 表关系建议
```text
expense_claims
└─ expense_claim_items
└─ expense_item_documents
└─ document_assets
└─ document_asset_versions
└─ document_derivatives
└─ document_ocr_results
└─ invoice_structured_records
└─ invoice_verification_records
risk_events -> 可指向 expense_claims / expense_claim_items / invoice_structured_records
risk_actions -> risk_events
document_access_logs -> document_assets / document_asset_versions
```
原则:
- 主业务对象和文件资产解耦。
- OCR、验真、风险都挂在文件资产或业务对象之上不把责任塞到一个巨表。
- 文件版本和业务关系分离,避免替换附件时把历史证据冲掉。
## 10. 与现有表的衔接策略
当前代码中已经存在:
- `expense_claims`
- `expense_claim_items`
- `reimbursement_requests`
建议策略:
- `expense_claims` 继续作为未来报销主表。
- `expense_claim_items` 增量扩字段并替换当前单一 `invoice_id` 直连方式。
- `reimbursement_requests` 暂不删除,但冻结扩表。
- 如旧流程仍引用 `reimbursement_requests`,可在过渡期建立:
- `request_no -> claim_no` 对照字段
- 或由 `approval_records` 同时支持两类来源对象
不建议做法:
- 再新建第四张“报销申请主表”。
- 把原始发票图片以 blob 方式存进 `expense_claims`
- 把 OCR、验真、风控结果全塞进一个 JSON 大字段。
## 11. 实施顺序建议
Phase 1
- 扩展 `expense_claims`
- 扩展 `expense_claim_items`
- 新增 `document_assets`
- 新增 `document_asset_versions`
- 新增 `expense_item_documents`
Phase 2
- 新增 `document_ocr_results`
- 新增 `invoice_structured_records`
- 新增 `invoice_verification_records`
- 新增 `document_derivatives`
Phase 3
- 新增 `risk_events`
- 新增 `risk_actions`
- 新增 `document_access_logs`
Phase 4
- 逐步弱化 `reimbursement_requests`
- 将 Agent 草稿、审批、OCR、验真、风控全收敛到 `expense_claims` 体系
## 12. 对 Agent 的直接收益
- 用户说“我要报销”时Agent 能先创建 `expense_claims` 草稿,再持续补槽。
- 用户上传票据后,系统有明确的 `document_assets``expense_item_documents` 可挂载。
- OCR 和验真结果不是一次性临时输出,而是可追溯、可回放、可审计的长期资产。
- Agent 回答“为什么被拦截”时,可以直接引用 `risk_events` 和票据证据,不再靠拼字符串解释。

View File

@@ -1,119 +0,0 @@
# 反馈闭环与持续学习
## 1. 定位
Agent 系统必须能从人工反馈中持续变好。
反馈来源:
- OCR 人工修正。
- 规则误报/漏报。
- 审批人修改意见。
- 用户对回答的反馈。
- Hermes 风险复盘。
- MCP 调用失败和降级。
## 2. 反馈类型
```text
ocr_correction
rule_false_positive
rule_false_negative
agent_answer_feedback
approval_opinion_edit
knowledge_answer_feedback
mcp_failure_feedback
task_result_feedback
```
## 3. 反馈结构
```json
{
"feedback_id": "",
"feedback_type": "rule_false_positive",
"source_object_type": "rule_run",
"source_object_id": "",
"before": {},
"after": {},
"comment": "",
"created_by": "",
"created_at": ""
}
```
## 4. 反馈流向
```text
人工反馈
反馈池
Hermes 聚类分析
候选改进项
人工审核
更新规则 / 知识 / OCR 映射 / Prompt
```
## 5. 反馈不直接自动生效
反馈只能生成候选,不直接修改线上规则。
必须人工审核:
- 规则修改。
- 知识发布。
- Prompt 修改。
- OCR 字段映射调整。
## 6. Hermes 每日反馈复盘
Hermes 每日任务:
```text
读取昨日反馈
聚类相似问题
统计误报高发规则
统计低评分回答
生成优化候选
```
输出:
```text
rule_improvement_candidates
knowledge_update_candidates
ocr_mapping_candidates
prompt_improvement_notes
```
## 7. 质量指标
建议监控:
```text
ocr_correction_rate
rule_false_positive_rate
rule_false_negative_rate
agent_answer_like_rate
agent_answer_rewrite_rate
knowledge_no_hit_rate
mcp_failure_rate
```
## 8. 开发阶段建议
```text
Step 1: 增加反馈按钮和反馈表
Step 2: OCR 修正写入反馈池
Step 3: 规则误报/漏报反馈
Step 4: Agent 回答反馈
Step 5: Hermes 每日反馈聚类
Step 6: 生成优化候选
Step 7: 人工审核发布
Step 8: 建立质量看板
```

View File

@@ -1,77 +0,0 @@
# Agent Week Plan 一周开发路线图
本目录现在同时承接:
- 一周路线图
- 每天 daily 文档
- 每天的详细执行清单
原独立执行细则目录已合并进各 Day 文档,不再单独维护。
## 文档分工
| 目录 | 职责 | 读者 |
| --- | --- | --- |
| `agent week plan` | 一周节奏、每天目标、验收门槛、详细执行清单、阻塞记录、日终交接 | 产品、架构、Codex、开发、验收 |
| `agent plan` | 架构设计、协议、流程、治理、标准模型、能力边界 | 架构、开发、评审 |
## 使用方式
1. 先读 [MASTER_TODO.md](./MASTER_TODO.md),确认 7 天节奏和当前状态。
2. 打开当天 daily 文档。
3. 在同一份 daily 文档里按顺序阅读:
今天的大开发点 -> 当前完成情况 -> 当天验收门槛 -> 详细执行清单 -> 阻塞记录 -> 日终交接。
4. 如需设计依据,再跳到 `agent plan` 对应架构文档。
5. 完成一个最小项后,再把该项改成完成态,而不是代码写完就直接算过。
## 完成标记规则
未完成:
```md
- [ ] 建立 AgentAsset 数据模型
```
完成后:
```md
- [x] ~~建立 AgentAsset 数据模型~~
```
执行要求:
- [ ] 每次只处理一个最小 TODO。
- [ ] 完成后先自测,再改成 `[x]`
- [ ] 改成 `[x]` 时,同时用 `~~` 画线。
- [ ] 不能因为代码写完就标完成,必须满足该 TODO 的验收证据。
- [ ] 遇到阻塞时,在当天文档的“阻塞记录”下新增说明。
- [ ] 每天收尾时更新当天文档的“日终交接”。
## 一周总体目标
- Day 1先把资产、版本、审核、运行日志、审计日志等基础地基建好。
- Day 2把任务规则中心和后端资产体系打通。
- Day 3建立语义本体 MVP让用户问题能变成稳定结构。
- Day 4建立 Orchestrator让请求能被统一路由、审计、降级。
- Day 5建立 User Agent MVP处理用户查询、解释和草稿生成。
- Day 6建立 Hermes MVP处理定时巡检、统计、知识和规则草稿。
- Day 7做加固、测试、演示、验收和下一阶段交接。
## 一周暂不完成
- 完整 OCR 生产识别引擎。
- 完整发票验真 MCP 深度接入。
- 完整 LLM Wiki 向量检索。
- 全量财务域数据打通。
- 规则自动上线。
- 完整 CI/CD 质量门禁。
## 生产底线
- 所有写操作必须有审计日志。
- 所有 Agent 执行必须生成 `run_id`
- 所有规则必须有版本。
- 未审核规则不能上线。
- 高风险动作只能生成草稿或建议,不能自动提交。
- 外部能力失败必须有降级结果。
- 语义解析结果必须可回放。

View File

@@ -1,73 +0,0 @@
# Agent Week Plan 总控
本文件是本周总览和执行索引。
每个 Day 文档现在同时包含:
- 路线图
- 当前完成情况
- 验收门槛
- 详细执行清单
不再跳转独立执行细则目录。
## 快速浏览
- HTML 总览:[agent_week_plan_html/index.html](<../agent_week_plan_html/index.html>)
- Day 1 HTML[agent_week_plan_html/day-1.html](<../agent_week_plan_html/day-1.html>)
## 执行方式
1. 先看本文件,确认今天做哪一天、当前状态和依赖顺序。
2. 再打开当天 daily 文档,直接在同一份文档里推进开发。
3. 完成一个最小 TODO 后,再改成 `[x] ~~...~~`
4. 每天结束时回填阻塞记录、验收结果和日终交接。
## 一周节奏
| Day | 状态 | 主题 | 主要交付 | Markdown | HTML |
| --- | --- | --- | --- | --- | --- |
| Day 1 | 已完成2026-05-11 | 基础模型与工程骨架 | 资产、版本、审核、运行日志、审计日志、基础 API、最小财务数据源 | [Day 1](./day_1_foundation_models.md) | [HTML](<../agent_week_plan_html/day-1.html>) |
| Day 2 | 已完成,待补浏览器走查记录 | 任务规则中心联调 | 规则/技能/MCP/任务列表与详情、Markdown、版本、审核 | [Day 2](./day_2_rule_center_integration.md) | [HTML](<../agent_week_plan_html/day-2.html>) |
| Day 3 | 已完成主体功能,待补评测样本扩充 | 语义本体 MVP | 8 字段语义解析、日志、评测入口、OCR 摘要与最小会话上下文带入 | [Day 3](./day_3_semantic_ontology_mvp.md) | [HTML](<../agent_week_plan_html/day-3.html>) |
| Day 4 | 已完成主干与会话串联,待接通提交/附件持久化链路 | Orchestrator 运行时 | 统一入口、路由、权限、工具调用、报销单写入路由、会话 Trace | [Day 4](./day_4_orchestrator_runtime.md) | [HTML](<../agent_week_plan_html/day-4.html>) |
| Day 5 | 已完成问答主链路、草稿创建/补全与会话上下文,待接通提交状态流转 | User Agent MVP | 用户问答、报销单草稿创建/补全/提交、财务查询、规则解释、附件/OCR 带入 | [Day 5](./day_5_user_agent_mvp.md) | [HTML](<../agent_week_plan_html/day-5.html>) |
| Day 6 | 未开始 | Hermes MVP | 定时任务、风险巡检、日报、知识候选、规则草稿 | [Day 6](./day_6_hermes_mvp.md) | [HTML](<../agent_week_plan_html/day-6.html>) |
| Day 7 | 未开始 | 加固、演示和验收 | 回归、测试、演示脚本、交付说明 | [Day 7](./day_7_hardening_demo_acceptance.md) | [HTML](<../agent_week_plan_html/day-7.html>) |
## 当前完成情况
- Day 1 已完成,后端基础模型、审计和最小财务数据源已可供后续能力复用。
- Day 2 已完成主要前后端联调,当前仅剩浏览器人工走查记录待补。
- Day 3 主体已完成,`/api/v1/ontology/parse`、8 字段返回、缺槽位追问、权限判断和前端调试入口均已落地OCR 摘要、附件上下文和最小会话历史已进入语义层,前端浏览器时间上下文也已接入相对时间换算,当前主要剩叙述型报销、附件/OCR 带入样本和模糊追问样本继续扩充。
- Day 4 主干已完成Orchestrator 已具备统一入口、User Agent / Hermes 路由、权限阻断、ToolCall 记录、Trace、降级和 `conversation_id` 会话串联;`expense_claims` 草稿建单/改单与 ToolCall / Audit 已接通,但提交、附件持久化和更细的 ToolCall Trace 仍未接通。
- Day 5 问答主链路已完成个人工作台和报销对话框已能把文本、附件名称、OCR 摘要、页面上下文和会话 ID 带入 Orchestrator并返回回答、规则引用、风险说明、结构化草稿和识别核对面板核对 UI 已调整为“右侧只看识别结果、主对话负责待补与风险、底部负责动作”,但附件 / OCR 结果落库及 `draft -> submitted` 仍未完成。
## Day 1 - Day 5 未完成补齐清单
- Day 1当前周计划范围内无新增遗留项基础资产、日志、审计和最小财务表已完成文件资产、OCR 结果表和风险事件表作为 Day 5 真落库前置底座,设计已完成但代码未落地。
- Day 2仍缺一轮浏览器人工走查记录需补充规则中心真实页面联调截图或缺陷清单。
- Day 3仍需补充叙述型报销长句样本、附件/OCR 摘要带入样本、模糊短句追问样本,并把这些样本纳入自动评测。
- Day 4仍需接通 `submit_expense_claim` 真服务补齐附件挂接服务注册、ToolCall 更细粒度记录和前端 Trace 展示。
- Day 5仍需把附件和 OCR 识别结果真正落到 `document_assets``document_asset_versions``expense_item_documents``document_ocr_results`,并完成 `draft -> submitted` 状态流转、前端确认动作回写和提交流程确认。
## 关键依赖顺序
1. Day 1 必须先完成,因为后面所有能力都依赖资产、版本、审核、日志。
2. Day 2 必须在 Day 3 前完成,因为语义和 Agent 需要读取规则、技能、MCP、任务资产。
3. Day 3 必须在 Day 4 前完成,因为 Orchestrator 依赖语义本体做路由。
4. Day 4 必须在 Day 5 / Day 6 前完成,因为 User Agent 和 Hermes 都应该由 Orchestrator 调用。
5. Day 5 和 Day 6 可以部分并行但都必须遵守权限、审计、Trace。
6. Day 7 不新增大功能,只做加固、验收和交接。
## 最终验收
- 任务规则中心能看到规则、技能、MCP、任务。
- 规则详情能编辑 Markdown、查看最近 5 个版本、切换版本。
- 未审核规则不能上线。
- 用户问题能解析出语义本体 8 字段。
- Orchestrator 能路由到 User Agent 和 Hermes。
- User Agent 能完成查询、解释、报销单草稿创建、字段补全和提交前确认。
- Hermes 能执行一次风险巡检或日报任务。
- AgentRun、ToolCall、AuditLog 都能追溯。
- 有演示脚本和下一阶段交接文档。

View File

@@ -1,221 +0,0 @@
# Day 1基础模型与工程骨架
## 当前状态
- [x] ~~Day 1 已完成2026-05-11。~~
- [x] ~~后端基础模型、API 骨架、种子数据、审计能力和 Day 2 联调入口均已落地。~~
## 今天的大开发点
Day 1 只做地基,不做复杂 Agent 智能。
核心是把后面 6 天都会用到的基础对象建出来:资产、版本、审核、运行日志、工具调用日志、语义解析日志、审计日志,以及最小财务业务数据来源。
## 为什么第一天做这个
如果没有稳定的数据模型后面的任务规则中心、语义本体、Orchestrator、User Agent、Hermes 都会各自临时造结构,后期会很难合并。
## 今天主要交付
- [x] ~~统一资产模型规则、技能、MCP、任务。~~
- [x] ~~版本模型:规则 Markdown 和其他资产配置快照。~~
- [x] ~~审核模型:未审核不能上线。~~
- [x] ~~Agent 运行日志:所有 Agent 执行都有 `run_id`。~~
- [x] ~~工具调用日志MCP、数据库、LLM、OCR、规则引擎调用都可追踪。~~
- [x] ~~语义解析日志:后续语义本体结果可回放。~~
- [x] ~~审计日志:所有写操作可追责。~~
- [x] ~~最小财务业务数据来源:报销、应收、应付。~~
## 实际落地结果
- [x] ~~新增 `AgentAsset`、`AgentAssetVersion`、`AgentAssetReview`、`AgentRun`、`AgentToolCall`、`SemanticParseLog`、`AuditLog`、`ExpenseClaim`、`ExpenseClaimItem`、`AccountsReceivableRecord`、`AccountsPayableRecord`。~~
- [x] ~~新增 `/api/v1/agent-assets`、`/api/v1/agent-runs`、`/api/v1/audit-logs` 相关接口。~~
- [x] ~~种子数据已覆盖 3 条规则、2 条技能、2 条 MCP、3 条任务,以及报销 / 应收 / 应付示例数据。~~
- [x] ~~旧开发库启动时会自动补齐新增资产和版本,不需要手动清库。~~
相关架构文档:
- [整体架构](<../agent plan/01_overall_architecture.md>)
- [语义本体](<../agent plan/02_semantic_ontology.md>)
- [数据契约与治理](<../agent plan/06_data_contracts_and_governance.md>)
- [能力注册](<../agent plan/07_capability_registry.md>)
- [权限与确认](<../agent plan/08_permission_confirmation.md>)
- [观测与 Trace](<../agent plan/09_observability_and_trace.md>)
- [财务单据标准模型](<../agent plan/14_financial_document_canonical_model.md>)
## 当天验收门槛
- [x] ~~数据库或等价存储能创建基础对象。~~
- [x] ~~API 服务能启动。~~
- [x] ~~资产列表能返回规则、技能、MCP、任务。~~
- [x] ~~规则资产能关联 Markdown 当前版本。~~
- [x] ~~未审核规则不能上线。~~
- [x] ~~AgentRun 能保存一条运行记录。~~
- [x] ~~AuditLog 能保存一条写操作记录。~~
## Day 2 联调入口
- `GET /api/v1/agent-assets`
- `GET /api/v1/agent-assets/{asset_id}`
- `GET /api/v1/agent-assets/{asset_id}/versions?limit=5`
- `POST /api/v1/agent-assets/{asset_id}/reviews`
- `POST /api/v1/agent-assets/{asset_id}/activate`
- `GET /api/v1/audit-logs`
## 今天不做
- 不做完整 Agent 对话。
- 不做完整 Hermes 调度。
- 不做真实 OCR。
- 不做复杂规则推理。
## 详细执行清单
以下内容为合并后的详细执行清单。
## 0. 开始前检查
- [x] ~~确认后端目录为 `/app/server`,模型、路由、启动入口和测试目录已定位。~~
- [x] ~~确认本次改动以增量方式落到现有 FastAPI + SQLAlchemy 工程,不回退无关文件。~~
验收证据:
- [x] ~~模型注册位于 `server/src/app/db/base.py`,路由注册位于 `server/src/app/api/v1/router.py`,启动入口位于 `server/src/app/main.py`,测试位于 `server/tests`。~~
## 1. 统一命名和边界
- [x] ~~统一枚举:`rule | skill | mcp | task`、`draft | review | active | disabled`、`pending | approved | rejected`、`orchestrator | user_agent | hermes`。~~
- [x] ~~统一运行来源、权限级别、内容类型、运行状态和工具类型命名,避免出现第二套并行语义。~~
验收证据:
- [x] ~~`server/src/app/core/agent_enums.py` 已成为模型、Schema 和服务层的统一枚举入口。~~
## 2. 设计最小财务业务数据模型
- [x] ~~建立 `expense_claims`、`expense_claim_items`、`accounts_receivable`、`accounts_payable`。~~
- [x] ~~字段覆盖时间、地点、理由、金额、员工、部门、状态,以及应收 / 应付的金额、到期日、账龄、风险标记。~~
验收证据:
- [x] ~~`server/src/app/models/financial_record.py` 与 `document/development/agent plan/14_financial_document_canonical_model.md` 形成直接映射。~~
## 3. 建立 AgentAsset 模型
- [x] ~~建立 `AgentAsset`,包含 `asset_type`、`code`、`name`、`description`、`domain`、`scenario_json`、`owner`、`reviewer`、`status`、`current_version`、`config_json` 等核心字段。~~
- [x] ~~对 `code`、`asset_type`、`status`、`domain` 建立唯一约束或索引。~~
验收证据:
- [x] ~~资产列表可按 `rule`、`skill`、`mcp`、`task` 四类过滤返回。~~
## 4. 建立 AgentAssetVersion 模型
- [x] ~~建立 `AgentAssetVersion`,规则版本保存 Markdown其余资产版本保存 JSON 快照。~~
- [x] ~~对 `asset_id + version` 建立唯一约束,并支持按资产读取最近版本列表。~~
验收证据:
- [x] ~~规则详情接口可返回 `current_version_content` 和 `recent_versions`。~~
## 5. 建立 AgentAssetReview 模型
- [x] ~~建立 `AgentAssetReview`,保存版本、审核人、审核状态、审核备注和审核时间。~~
- [x] ~~服务层实现规则版本未 `approved` 时禁止上线。~~
验收证据:
- [x] ~~`POST /api/v1/agent-assets/{asset_id}/activate` 对待审规则返回 400 拦截。~~
## 6. 建立 AgentRun 模型
- [x] ~~建立 `AgentRun`,包含 `run_id`、`agent`、`source`、`ontology_json`、`route_json`、`permission_level`、`status`、`result_summary`、`error_message` 等字段。~~
- [x] ~~所有运行记录统一生成 `run_id`,并允许失败态保存错误信息。~~
验收证据:
- [x] ~~`AgentRunService.create_run()` 会自动生成 `run_` 前缀标识,并可回读失败摘要。~~
## 7. 建立 AgentToolCall 模型
- [x] ~~建立 `AgentToolCall`,可记录工具类型、工具名、请求 / 响应 JSON、耗时和错误信息。~~
- [x] ~~同一个 `run_id` 下支持多次工具调用追踪。~~
验收证据:
- [x] ~~种子运行数据已覆盖数据库查询、MCP 调用和权限规则引擎调用。~~
## 8. 建立 SemanticParseLog 模型
- [x] ~~建立 `SemanticParseLog`,覆盖场景、意图、实体、时间范围、指标、约束、风险、权限和置信度。~~
- [x] ~~支持按 `run_id` 回放 Day 3 语义结果。~~
验收证据:
- [x] ~~`GET /api/v1/agent-runs/{run_id}` 已能携带 `semantic_parse` 返回。~~
## 9. 建立 AuditLog 模型
- [x] ~~建立 `AuditLog` 和统一 `AuditLogService`。~~
- [x] ~~资产创建、版本保存、审核、上线等写操作都会留下审计记录。~~
验收证据:
- [x] ~~`GET /api/v1/audit-logs` 可返回种子审计日志,服务层新建资产也会落审计。~~
## 10. 建立 Schema / DTO
- [x] ~~建立 `AgentAssetCreate / Update / Read / ListItem`、`AgentAssetVersionRead`、`AgentAssetReviewRead`、`RuleMarkdownUpdate`、`AgentRunRead`、`AgentToolCallRead`、`SemanticParseRead`。~~
- [x] ~~所有 JSON 字段以结构化对象返回,不回传字符串化 JSON。~~
验收证据:
- [x] ~~列表 DTO 不返回大块 Markdown详情 DTO 返回当前版本正文和最近版本。~~
## 11. 建立 API 骨架
- [x] ~~建立 `GET/POST/PATCH /api/v1/agent-assets`、`GET /api/v1/agent-assets/{asset_id}`、`GET/POST /api/v1/agent-assets/{asset_id}/versions`、`POST /api/v1/agent-assets/{asset_id}/reviews`、`POST /api/v1/agent-assets/{asset_id}/activate`。~~
- [x] ~~建立 `GET /api/v1/agent-runs`、`GET /api/v1/agent-runs/{run_id}`、`GET /api/v1/audit-logs`。~~
验收证据:
- [x] ~~所有接口已挂到 `server/src/app/api/v1/router.py`,并通过 `create_app()` 自动暴露。~~
## 12. 建立种子数据
- [x] ~~种子资产补齐到 3 条规则、2 条技能、2 条 MCP、3 条任务。~~
- [x] ~~三条规则都具备至少 2 个版本,并覆盖 `approved / pending / rejected` 三种审核样本。~~
- [x] ~~旧开发数据库启动时会自动增量补齐新增资产和版本,不要求手动清库。~~
验收证据:
- [x] ~~Smoke`GET /api/v1/agent-assets` 返回 10 条资产,`GET /api/v1/agent-runs` 返回 3 条运行日志,`GET /api/v1/audit-logs` 返回 4 条审计日志。~~
## 13. 最小测试
- [x] ~~新增 Day 1 服务层与接口层测试,覆盖种子完整性、版本历史、未审核不能上线、运行日志生成和审计日志写入。~~
- [x] ~~Ruff 校验通过Day 1 新增文件保持可检查状态。~~
验收证据:
- [x] ~~`/app/server/.venv/bin/pytest -q /app/server/tests/test_agent_asset_service.py /app/server/tests/test_agent_foundation_endpoints.py` -> `11 passed`。~~
- [x] ~~`/app/server/.venv/bin/pytest -q tests` 已通过全量后端测试。~~
## 14. Day 1 验收
- [x] ~~数据库能创建所有新增表或等价结构。~~
- [x] ~~API 服务能启动OpenAPI 能看到新增接口。~~
- [x] ~~资产列表接口返回规则、技能、MCP、任务规则详情带 Markdown 当前版本和最近版本列表。~~
- [x] ~~未审核规则不能上线AgentRun 和 AuditLog 均可保存记录。~~
- [x] ~~所有 Day 1 TODO 已改为完成态。~~
## 阻塞记录
- [x] ~~暂无阻塞。~~
## 日终交接
- [x] ~~已完成模型:资产、版本、审核、运行日志、工具调用、语义解析、审计、报销、应收、应付。~~
- [x] ~~已完成 API`/api/v1/agent-assets`、`/api/v1/agent-runs`、`/api/v1/audit-logs`。~~
- [x] ~~Day 2 前端联调应优先使用 `GET /api/v1/agent-assets`、`GET /api/v1/agent-assets/{asset_id}`、`GET /api/v1/agent-assets/{asset_id}/versions?limit=5`、`POST /api/v1/agent-assets/{asset_id}/reviews`、`POST /api/v1/agent-assets/{asset_id}/activate`。~~
- [x] ~~后续 Day 4 及以后运行时方向按用户要求转向 `LangChain + LangGraph`Hermes 继续作为内部数字员工入口Day 1 保留为数据与治理底座。~~

View File

@@ -1,296 +0,0 @@
# Day 2任务规则中心联调
## 今天的大开发点
把任务规则中心从静态页面改成可和后端资产体系联动的生产形态。
重点是规则、技能、MCP、任务四类资产的列表和详情以及规则 Markdown、版本、审核、上线约束。
## 为什么第二天做这个
任务规则中心是业务人员管理 Agent 能力的入口。后续语义本体、Orchestrator、User Agent、Hermes 都要读取这里注册的规则、技能、MCP 和任务。
## 今天主要交付
- 规则、技能、MCP、任务四个页签对接资产 API。
- 列表支持搜索、筛选、状态展示。
- 规则详情展示 Markdown 内容。
- 管理员可编辑规则 Markdown。
- 规则版本展示最近 5 个版本。
- 版本切换需要弹窗确认。
- 审核者信息放在标题区域。
- 右侧只保留版本信息。
- 未审核规则上线时被后端拦截。
## 当前完成情况
- [x] ~~四个页签已切到真实资产 API。~~
- [x] ~~规则 Markdown、版本切换、审核、上线动作已联调。~~
- [x] ~~前端构建已通过。~~
- [ ] 浏览器手动走查记录待补。
相关架构文档:
- [能力注册](<../agent plan/07_capability_registry.md>)
- [规则形成生命周期](<../agent plan/13_rule_formation_lifecycle.md>)
- [数据契约与治理](<../agent plan/06_data_contracts_and_governance.md>)
## 当天验收门槛
- 四个页签可切换并有真实 API 或 Mock API 数据。
- 规则详情可编辑 Markdown。
- Markdown 保存后刷新不丢失。
- 版本卡片可切换版本。
- 未审核规则不能上线。
- 前端构建通过。
## 今天不做
- 不做规则自动生成。
- 不做完整 MCP 真实调用。
- 不做复杂权限矩阵。
- 不重做 UI 风格,只在现有风格上微调。
## 详细执行清单
以下内容为合并后的详细执行清单。
## 0. 开始前检查
- [x] ~~确认 Day 1 API 已可访问。~~
- [x] ~~确认前端任务规则中心文件位置。~~
- [x] ~~确认现有路由名称和导航名称。~~
- [x] ~~确认现有 UI 风格,不重新做大改版。~~
- [x] ~~确认当前页面已有页签规则、技能、MCP、任务。~~
- [x] ~~确认详情页隐藏顶部 title bar 的逻辑仍然有效。~~
- [x] ~~确认返回列表栏高度没有被重新拉高。~~
## 1. API Client
- [x] ~~新增或扩展资产列表请求函数。~~
- [x] ~~新增资产详情请求函数。~~
- [x] ~~新增版本列表请求函数。~~
- [x] ~~新增规则 Markdown 保存请求函数。~~
- [x] ~~新增审核请求函数。~~
- [x] ~~新增上线请求函数。~~
- [x] ~~新增运行日志请求函数。~~
- [x] ~~给所有请求增加加载态。~~
- [x] ~~给所有请求增加错误态。~~
- [x] ~~给所有写请求增加成功提示。~~
验收证据:
- [x] ~~前端不再只依赖本地硬编码资产数据。~~
- [x] ~~后端不可用时页面有明确错误提示。~~
## 2. 列表页数据接入
- [x] ~~规则页签请求 `asset_type=rule`。~~
- [x] ~~技能页签请求 `asset_type=skill`。~~
- [x] ~~MCP 页签请求 `asset_type=mcp`。~~
- [x] ~~任务页签请求 `asset_type=task`。~~
- [x] ~~搜索框传递关键词或本地过滤。~~
- [x] ~~类型下拉和搜索框可以同时生效。~~
- [x] ~~状态筛选可以过滤 `draft | review | active | disabled`。~~
- [x] ~~列表卡片展示名称。~~
- [x] ~~列表卡片展示摘要。~~
- [x] ~~列表卡片展示状态。~~
- [x] ~~列表卡片展示负责人。~~
- [x] ~~列表卡片展示最近更新时间。~~
- [x] ~~空数据时展示空态。~~
- [x] ~~加载中时展示骨架或加载状态。~~
验收证据:
- [x] ~~四个页签都能切换。~~
- [x] ~~四个页签都有数据或空态。~~
- [x] ~~搜索和筛选不会互相覆盖。~~
## 3. 规则详情页主信息
- [x] ~~打开规则资产时请求详情 API。~~
- [x] ~~Hero title 展示规则名称。~~
- [x] ~~Hero title 下方展示审核者。~~
- [x] ~~Hero title 下方展示审核状态。~~
- [x] ~~Hero title 下方展示上线条件。~~
- [x] ~~Hero title 高度保持紧凑。~~
- [x] ~~详情页不显示外层顶部 title bar。~~
- [x] ~~返回列表栏高度保持原有紧凑高度。~~
验收证据:
- [x] ~~用户能一眼看到该规则是否已审核。~~
- [x] ~~用户不会看到两层 title。~~
## 4. Markdown 编辑器
- [x] ~~从当前版本读取 Markdown 内容。~~
- [x] ~~Markdown 编辑框高度和右侧版本卡片底部对齐。~~
- [x] ~~Markdown 编辑框支持长内容滚动。~~
- [x] ~~Markdown 编辑框保存时调用 API。~~
- [x] ~~保存后创建新版本或更新草稿版本,按后端约定执行。~~
- [x] ~~保存成功后刷新版本列表。~~
- [x] ~~保存失败时保留用户输入。~~
- [x] ~~编辑器禁用态覆盖 `active` 且无编辑权限的情况。~~
- [x] ~~编辑器底部展示最后保存时间。~~
验收证据:
- [x] ~~编辑 Markdown 后刷新页面内容仍存在。~~
- [x] ~~保存失败不会丢内容。~~
- [x] ~~左右卡片底部视觉对齐。~~
## 5. 版本卡片
- [x] ~~右侧只保留版本信息卡片。~~
- [x] ~~版本卡片宽度足够展示版本号、日期、状态。~~
- [x] ~~展示最近 5 个版本。~~
- [x] ~~当前版本有明显但不突兀的标识。~~
- [x] ~~当前版本标识居中显示。~~
- [x] ~~选中状态只变色,不改变内容对齐。~~
- [x] ~~日期列和其他版本日期对齐。~~
- [x] ~~点击非当前版本时弹出确认弹窗。~~
- [x] ~~弹窗展示目标版本号。~~
- [x] ~~弹窗展示切换风险提示。~~
- [x] ~~确认后切换当前展示内容。~~
- [x] ~~取消后不改变当前版本。~~
验收证据:
- [x] ~~版本切换不会造成列表文字位移。~~
- [x] ~~当前版本背景能完全覆盖内容区域。~~
- [x] ~~版本卡片不贴右侧边界。~~
## 6. 审核与上线
- [x] ~~详情中展示审核者姓名。~~
- [x] ~~详情中展示审核时间。~~
- [x] ~~详情中展示审核意见。~~
- [x] ~~未审核规则显示不能上线原因。~~
- [x] ~~点击上线时调用后端上线接口。~~
- [x] ~~后端拒绝时展示拒绝原因。~~
- [x] ~~审核通过后上线按钮可用。~~
- [x] ~~审核动作写入审计日志。~~
- [x] ~~上线动作写入审计日志。~~
验收证据:
- [x] ~~pending 规则无法上线。~~
- [x] ~~approved 规则可以上线。~~
- [x] ~~rejected 规则无法上线。~~
## 7. 技能详情
- [x] ~~技能页签列表展示能力名称。~~
- [x] ~~技能详情展示能力说明。~~
- [x] ~~技能详情展示输入参数。~~
- [x] ~~技能详情展示输出参数。~~
- [x] ~~技能详情展示依赖能力。~~
- [x] ~~技能详情展示适用场景。~~
- [x] ~~技能详情展示负责人。~~
- [x] ~~技能详情展示版本。~~
- [x] ~~技能详情不使用规则 Markdown 编辑器。~~
验收证据:
- [x] ~~技能和规则详情不会混用 UI。~~
## 8. MCP 详情
- [x] ~~MCP 页签列表展示外部服务名称。~~
- [x] ~~MCP 详情展示服务类型。~~
- [x] ~~MCP 详情展示调用地址或能力名。~~
- [x] ~~MCP 详情展示鉴权方式。~~
- [x] ~~MCP 详情展示超时配置。~~
- [x] ~~MCP 详情展示降级策略。~~
- [x] ~~MCP 详情展示最近调用状态。~~
- [x] ~~MCP 详情展示负责人。~~
验收证据:
- [x] ~~MCP 被定义为外部服务,而不是技能规则。~~
## 9. 任务详情
- [x] ~~任务页签展示定时任务名称。~~
- [x] ~~任务详情展示 cron 或调度周期。~~
- [x] ~~任务详情展示执行 Agent默认 Hermes。~~
- [x] ~~任务详情展示任务目标。~~
- [x] ~~任务详情展示风险等级。~~
- [x] ~~任务详情展示最近执行时间。~~
- [x] ~~任务详情展示最近执行结果。~~
- [x] ~~任务详情展示启停状态。~~
验收证据:
- [x] ~~定时任务用户可见名称为“任务”。~~
- [x] ~~技术字段可保留 `schedule`,但 UI 不显示“定时任务”。~~
## 10. 前端质量
- [x] ~~页面在 1366 宽度下无横向滚动。~~
- [x] ~~页面在 1920 宽度下右侧卡片不过宽。~~
- [x] ~~页面在窄屏下详情区域可滚动。~~
- [x] ~~所有按钮有禁用态。~~
- [x] ~~所有弹窗有取消按钮。~~
- [x] ~~所有表单错误有提示。~~
- [x] ~~所有日期格式统一。~~
- [x] ~~状态颜色和现有系统一致。~~
验收证据:
- [x] ~~`npm run build` 通过。~~
- [ ] 任务规则中心手动走查通过。
## 11. Day 2 验收
- [x] ~~规则、技能、MCP、任务四个页签可用。~~
- [x] ~~搜索框和筛选下拉可用。~~
- [x] ~~规则详情展示 Markdown。~~
- [x] ~~规则 Markdown 可保存。~~
- [x] ~~右侧只保留版本信息。~~
- [x] ~~版本可切换且有弹窗确认。~~
- [x] ~~审核者信息在标题下方。~~
- [x] ~~未审核规则不能上线。~~
- [x] ~~前端构建通过。~~
- [x] ~~所有完成项已按完成态标记。~~
## 阻塞记录
- [x] ~~暂无。~~
## 日终交接
- [x] ~~写明已接入的 API。~~
- [x] ~~写明仍然使用 Mock 的字段。~~
- [x] ~~写明 UI 未完成项。~~
- [x] ~~写明 Day 3 语义本体需要复用的资产数据。~~
已接入的 API
- `GET /api/v1/agent-assets?asset_type=rule|skill|mcp|task`
- `GET /api/v1/agent-assets/{asset_id}`
- `GET /api/v1/agent-assets/{asset_id}/versions`
- `POST /api/v1/agent-assets/{asset_id}/versions`
- `POST /api/v1/agent-assets/{asset_id}/reviews`
- `POST /api/v1/agent-assets/{asset_id}/activate`
- `GET /api/v1/agent-runs`
仍然使用 Mock / 种子数据的字段:
- MCP 服务地址仍是 `mock://...` 种子地址,用于占位联调。
- MCP 最近调用状态、任务最近执行结果来自 Day 1 注入的 `AgentRun` 种子数据。
- 技能、MCP、任务详情仍以只读方式展示未开放编辑表单。
UI 未完成项:
- 未做浏览器内人工走查记录,当前仅完成构建验证与代码层联调。
- 技能、MCP、任务的编辑能力仍留待后续 Day 3 / Day 4 之后按权限开放。
Day 3 语义本体需要复用的资产数据:
- 资产主键与编码:`id``code``asset_type`
- 业务归类:`domain``scenario_json`
- 当前生效版本:`current_version``current_version_content``current_version_content_type`
- 治理状态:`status``latest_review``recent_versions`
- 运行关联:`config_json.agent``config_json.cron``AgentRun.task_id``tool_calls`

View File

@@ -1,304 +0,0 @@
# Day 3语义本体 MVP
## 今天的大开发点
建立模型优先的语义解析层,把自然语言问题转换成统一的 8 个核心字段。
这一天的目标不是继续堆关键词,而是先把真实模型接入语义层,让报销、应收、应付、知识和风险相关问题进入稳定结构,再由规则做兜底和校验。
## 为什么第三天做这个
Orchestrator 不能直接根据原始文本做可靠路由。它需要先拿到结构化语义,再决定调用 User Agent、Hermes、规则、MCP 或知识库。
## 今天主要交付
- 语义本体 8 字段结构。
- 场景识别:报销、应收、应付、知识、未知。
- 意图识别:查询、解释、对比、风险检查、草稿、操作。
- 业务对象提取:员工、客户、供应商、部门、项目、单据、金额。
- 时间范围解析。
- 指标和约束解析。
- 风险信号和权限级别判断。
- LLM 结构化解析 Prompt。
- Schema 校验与 JSON 清洗。
- 规则回退解析。
- 低置信度追问和缺槽位追问。
- 语义解析 API。
- 解析日志和最小评测集。
## 当前完成情况
- [x] ~~`/api/v1/ontology/parse` 已上线8 字段语义结构、缺槽位、歧义、权限和澄清问题均可返回。~~
- [x] ~~语义层已切到“模型优先 + 规则回退”,并把结果写入 `AgentRun` / `SemanticParseLog`。~~
- [x] ~~附件名称、附件数量、OCR 摘要和 OCR 文档摘要已能作为上下文带入语义层。~~
- [x] ~~最小会话历史、上一轮场景/意图和 `draft_claim_id` 已能作为上下文带入语义层,用于识别“改成 800”“继续补充”这类追问。~~
- [x] ~~叙述型报销语义已补强:`客户 + 吃饭/请客/宴请/招待` 优先归类为业务招待费,不再误打到应收查询。~~
- [x] ~~相对时间已支持标准化展示:前端会透传浏览器本地时间上下文,`今天 / 昨天 / 本月 / 4 月` 会换算成绝对日期;展示层默认优先显示绝对日期,原始表达仅作为辅助信息。~~
- [x] ~~前端调试入口与核心评测测试已完成并通过。~~
- [ ] 叙述型报销样本、附件/OCR 带入样本和模糊短句追问样本仍需继续扩充。
相关架构文档:
- [语义本体](<../agent plan/02_semantic_ontology.md>)
- [财务单据标准模型](<../agent plan/14_financial_document_canonical_model.md>)
- [数据契约与治理](<../agent plan/06_data_contracts_and_governance.md>)
## 当天验收门槛
- 输入自然语言问题能返回 8 个字段。
- 模型解析失败时能自动回退到规则解析。
- 低置信度问题能返回澄清问题。
- 越权动作不会被标记为可直接执行。
- 解析结果能写入日志。
- 至少覆盖报销、应收、应付三个场景。
- 叙述型报销输入不会被错误路由到应收或应付。
## 今天不做
- 不做复杂多轮对话记忆。
- 不做完整 Agent 自主规划。
- 不做自动执行业务流程。
## 详细执行清单
以下内容为合并后的详细执行清单。
## 0. 开始前检查
- [x] ~~确认 Day 1 的 `SemanticParseLog` 可用。~~
- [x] ~~确认 Day 1 的 `AgentRun` 可用。~~
- [x] ~~确认 Day 2 的资产 API 可用。~~
- [x] ~~找到后端服务层目录。~~
- [x] ~~找到现有 LLM 调用或 Mock 调用方式。~~
- [x] ~~确认当前是否允许真实调用 LLM。~~
- [x] ~~确认当前运行时模型槽位可用于语义解析。~~
- [x] ~~如果真实模型不可用,已准备规则解析回退路径。~~
## 1. 定义 8 个核心字段
- [x] ~~定义字段 `scenario`,表示业务场景。~~
- [x] ~~定义字段 `intent`,表示用户意图。~~
- [x] ~~定义字段 `entities`,表示业务对象。~~
- [x] ~~定义字段 `time_range`,表示时间范围。~~
- [x] ~~定义字段 `metrics`,表示指标或金额口径。~~
- [x] ~~定义字段 `constraints`,表示过滤条件。~~
- [x] ~~定义字段 `risk_flags`,表示风险信号。~~
- [x] ~~定义字段 `permission`,表示动作权限。~~
- [x] ~~为每个字段写清楚类型。~~
- [x] ~~为每个字段写清楚是否必填。~~
- [x] ~~为每个字段写清楚默认值。~~
- [x] ~~为每个字段写清楚示例。~~
验收证据:
- [x] ~~8 个字段在 Schema、服务层、日志中名字一致。~~
## 2. 设计字段枚举
- [x] ~~`scenario` 支持 `expense`。~~
- [x] ~~`scenario` 支持 `accounts_receivable`。~~
- [x] ~~`scenario` 支持 `accounts_payable`。~~
- [x] ~~`scenario` 支持 `knowledge`。~~
- [x] ~~`scenario` 支持 `unknown`。~~
- [x] ~~`intent` 支持 `query`。~~
- [x] ~~`intent` 支持 `explain`。~~
- [x] ~~`intent` 支持 `compare`。~~
- [x] ~~`intent` 支持 `risk_check`。~~
- [x] ~~`intent` 支持 `draft`。~~
- [x] ~~`intent` 支持 `operate`。~~
- [x] ~~`permission.level` 支持 `read`。~~
- [x] ~~`permission.level` 支持 `draft_write`。~~
- [x] ~~`permission.level` 支持 `approval_required`。~~
- [x] ~~`permission.level` 支持 `forbidden`。~~
验收证据:
- [x] ~~未识别的问题不会抛异常,返回 `unknown`。~~
## 3. 建立 Schema
- [x] ~~定义 `OntologyParseRequest`。~~
- [x] ~~`OntologyParseRequest` 包含 `query`。~~
- [x] ~~`OntologyParseRequest` 包含 `user_id`。~~
- [x] ~~`OntologyParseRequest` 包含 `context_json`。~~
- [x] ~~定义 `OntologyParseResult`。~~
- [x] ~~`OntologyParseResult` 包含 8 个核心字段。~~
- [x] ~~`OntologyParseResult` 包含 `confidence`。~~
- [x] ~~`OntologyParseResult` 包含 `clarification_required`。~~
- [x] ~~`OntologyParseResult` 包含 `clarification_question`。~~
- [x] ~~`OntologyParseResult` 包含 `run_id`。~~
- [x] ~~定义字段级错误结构。~~
验收证据:
- [x] ~~OpenAPI 中可以看到语义解析请求和响应。~~
## 4. 实现解析服务
- [x] ~~新增 `SemanticOntologyService` 或同等服务。~~
- [x] ~~实现 `parse(query, user_context)` 主函数。~~
- [x] ~~增加上下文装配层,输入文本、页面上下文、附件摘要和预抽取字段。~~
- [x] ~~实现模型优先的结构化语义解析。~~
- [x] ~~约束模型只输出 JSON。~~
- [x] ~~对模型输出做清洗、提取和 Schema 校验。~~
- [x] ~~模型失败时自动回退到规则解析。~~
- [x] ~~在结果中记录本次使用了 `llm_primary` 还是 `rule_fallback`。~~
- [x] ~~报销关键词映射到 `expense`。~~
- [x] ~~应收、回款、客户欠款映射到 `accounts_receivable`。~~
- [x] ~~应付、供应商、付款映射到 `accounts_payable`。~~
- [x] ~~风险、异常、重复、超标映射到 `risk_check`。~~
- [x] ~~为什么、依据、规则映射到 `explain`。~~
- [x] ~~统计、汇总、多少映射到 `query`。~~
- [x] ~~生成、创建、发起映射到 `draft` 或 `operate`。~~
- [x] ~~无法识别时返回低置信度和澄清问题。~~
- [x] ~~叙述型报销输入优先识别为创建/草稿,而不是查询。~~
验收证据:
- [x] ~~“查一下本周报销超标风险”能识别为 expense + risk_check。~~
- [x] ~~“客户 A 这个月还有多少应收”能识别为 accounts_receivable + query。~~
- [x] ~~“供应商 B 明天要付多少钱”能识别为 accounts_payable + query。~~
- [x] ~~“我今天去客户现场招待了客户花销了1000元”不会错误识别为应收查询。~~
- [x] ~~“昨天请客户吃饭花了 200 元”会优先识别为报销草稿语义,并把“昨天”换算为用户本地日期下的绝对日期。~~
## 5. 解析业务对象
- [x] ~~从问题中提取员工姓名。~~
- [x] ~~从问题中提取部门。~~
- [x] ~~从问题中提取客户。~~
- [x] ~~从问题中提取供应商。~~
- [x] ~~从问题中提取项目。~~
- [x] ~~从问题中提取单据号。~~
- [x] ~~从问题中提取金额。~~
- [x] ~~从问题中提取费用类型。~~
- [x] ~~无法提取时返回空数组,不返回 null。~~
验收证据:
- [x] ~~“张三 4 月差旅报销”能提取员工、月份、费用类型。~~
## 6. 解析时间范围
- [x] ~~支持今天。~~
- [x] ~~支持昨天。~~
- [x] ~~支持本周。~~
- [x] ~~支持上周。~~
- [x] ~~支持本月。~~
- [x] ~~支持上月。~~
- [x] ~~支持本季度。~~
- [x] ~~支持今年。~~
- [x] ~~支持明确日期。~~
- [x] ~~支持日期区间。~~
- [x] ~~解析结果包含 `start_date` 和 `end_date`。~~
- [x] ~~日期使用 ISO 格式。~~
验收证据:
- [x] ~~“本周”能解析为当前周起止日期。~~
- [x] ~~“2026 年 4 月”能解析为 `2026-04-01` 到 `2026-04-30`。~~
## 7. 解析指标与约束
- [x] ~~识别金额指标。~~
- [x] ~~识别数量指标。~~
- [x] ~~识别超标指标。~~
- [x] ~~识别逾期指标。~~
- [x] ~~识别重复报销指标。~~
- [x] ~~识别部门过滤条件。~~
- [x] ~~识别状态过滤条件。~~
- [x] ~~识别金额阈值过滤条件。~~
- [x] ~~识别排序要求。~~
- [x] ~~识别 Top N 要求。~~
验收证据:
- [x] ~~“列出金额最高的 10 笔报销”能识别排序和 Top 10。~~
## 8. 解析风险与权限
- [x] ~~重复报销映射到 `duplicate_expense`。~~
- [x] ~~发票异常映射到 `invoice_anomaly`。~~
- [x] ~~金额超标映射到 `amount_over_limit`。~~
- [x] ~~逾期应收映射到 `ar_overdue`。~~
- [x] ~~逾期应付映射到 `ap_overdue`。~~
- [x] ~~查询类问题权限为 `read`。~~
- [x] ~~生成草稿权限为 `draft_write`。~~
- [x] ~~审批、上线、付款类动作权限为 `approval_required`。~~
- [x] ~~越权动作权限为 `forbidden`。~~
验收证据:
- [x] ~~“帮我直接付款”不能被标为可直接执行。~~
## 9. API 接口
- [x] ~~新增 `POST /api/v1/ontology/parse`。~~
- [x] ~~请求参数包含用户问题。~~
- [x] ~~请求参数包含用户上下文。~~
- [x] ~~响应包含 8 个字段。~~
- [x] ~~响应包含 `run_id`。~~
- [x] ~~响应包含置信度。~~
- [x] ~~响应包含澄清问题。~~
- [x] ~~每次调用写入 `SemanticParseLog`。~~
- [x] ~~每次调用写入 `AgentRun` 或关联已有 `AgentRun`。~~
验收证据:
- [x] ~~连续调用多次都能在日志中查到。~~
## 10. 前端调试入口
- [x] ~~在合适页面增加语义解析调试入口。~~
- [x] ~~输入框支持自然语言问题。~~
- [x] ~~点击解析后调用 API。~~
- [x] ~~展示 8 个字段。~~
- [x] ~~展示 JSON 原始结果。~~
- [x] ~~展示置信度。~~
- [x] ~~展示澄清问题。~~
- [x] ~~展示 `run_id`。~~
- [x] ~~错误时展示错误信息。~~
验收证据:
- [x] ~~产品和开发可以直接在页面验证解析结果。~~
## 11. 评测集
- [x] ~~创建至少 5 条报销问题。~~
- [ ] 创建至少 5 条叙述型报销问题。
- [ ] 创建至少 3 条附件 / OCR 摘要带入的报销问题。
- [x] ~~创建至少 5 条应收问题。~~
- [x] ~~创建至少 5 条应付问题。~~
- [x] ~~创建至少 3 条知识库问题。~~
- [x] ~~创建至少 3 条越权操作问题。~~
- [ ] 创建至少 3 条模糊短句追问问题。
- [x] ~~为每条问题写期望 `scenario`。~~
- [x] ~~为每条问题写期望 `intent`。~~
- [x] ~~为每条问题写期望权限级别。~~
- [x] ~~编写评测脚本或测试。~~
验收证据:
- [x] ~~当前评测样本集已通过,覆盖样本准确率达到当天设定阈值。~~
## 12. Day 3 验收
- [x] ~~语义解析 API 可用。~~
- [x] ~~8 个核心字段完整返回。~~
- [x] ~~解析日志可查询。~~
- [x] ~~低置信度问题有澄清问题。~~
- [x] ~~越权动作不会被标为可执行。~~
- [x] ~~前端调试入口可用。~~
- [x] ~~评测集可运行。~~
- [x] ~~所有完成项已用 `[x] ~~...~~` 标记。~~
## 阻塞记录
- [x] ~~暂无。~~
## 日终交接
- [x] ~~已支持报销 / 应收 / 应付 / 知识 / 风险 / 草稿 / 越权动作等核心场景关键词、实体与权限解析。~~
- [x] ~~语义层已可接收附件名称、附件数量和 OCR 摘要上下文,但这些样本仍需继续扩到评测集。~~
- [x] ~~当前仍需继续扩充的弱样本主要是叙述型报销长句、附件/OCR 带入和模糊短句追问。~~
- [x] ~~Day 4 可直接复用 `scenario / intent / entities / time_range / metrics / constraints / risk_flags / permission / confidence / missing_slots / ambiguity / parse_strategy / clarification_required / clarification_question / run_id`。~~

View File

@@ -1,254 +0,0 @@
# Day 4Orchestrator 运行时
## 今天的大开发点
建立统一调度层。用户请求和系统任务都先进入 Orchestrator由它完成语义解析、权限判断、能力选择、Agent 路由、工具调用记录和失败降级。
## 为什么第四天做这个
没有 OrchestratorUser Agent 和 Hermes 会各自直接调用能力权限、审计、降级、Trace 都会分散。生产系统必须有统一入口。
## 今天主要交付
- Orchestrator 请求和响应结构。
- 用户请求路由到 User Agent。
- 定时任务路由到 Hermes。
- 权限级别判断。
- 语义补槽完成后的报销草稿创建、草稿更新、提交动作路由。
- 高风险动作确认机制。
- 能力注册查询。
- 工具调用封装。
- AgentRun Trace 查询。
- 失败降级返回。
## 当前完成情况
- [x] ~~`/api/v1/orchestrator/run`、统一路由、权限阻断、ToolCall 记录、Trace 和降级结果已经可用。~~
- [x] ~~用户消息已能路由到 User Agent占位 Hermes 任务也能由定时入口触发。~~
- [x] ~~附件名称、页面上下文和 OCR 摘要已能随 Orchestrator 请求透传到语义层和 User Agent。~~
- [x] ~~Orchestrator 已开始向前端返回结构化 `review_payload`,用于右侧预审面板展示识别意图、槽位、票据和分单建议。~~
- [x] ~~`conversation_id`、会话消息历史和 `draft_claim_id` 已接入 Orchestrator会话内追问可继续落到同一张报销草稿。~~
- [x] ~~已新增最近会话恢复与用户级会话清空接口,个人工作台可显式继续旧会话或删除旧会话后新建。~~
- [x] ~~`clarification_required` 的报销请求已改为返回结构化核对结果,而不是只回一句追问文案。~~
- [x] ~~`review_action`、`review_form_values` 已能透传到 User Agent / 报销草稿服务,用于结构化修改后重识别和保存草稿。~~
- [ ] 真实 `expense_claims` 提交链路尚未接通;草稿建单 / 改单已接到真实落库,附件与 OCR 持久化仍未完成。
- [ ] 报销附件持久化服务、OCR 结果落库服务和前端 ToolCall 细粒度 Trace 展示尚未接通。
相关架构文档:
- [Orchestrator 与运行流程](<../agent plan/04_orchestrator_and_runtime_flow.md>)
- [能力注册](<../agent plan/07_capability_registry.md>)
- [权限与确认](<../agent plan/08_permission_confirmation.md>)
- [观测与 Trace](<../agent plan/09_observability_and_trace.md>)
## 当天验收门槛
- Orchestrator API 可用。
- 用户消息能路由到 User Agent 占位实现。
- 定时任务能路由到 Hermes 占位实现。
- forbidden 请求不会调用下游 Agent。
- 每次运行都有 `run_id` 和 Trace。
- 工具调用失败能记录并返回降级结果。
- 叙述型报销输入在满足最小槽位后能进入建单或改单流程。
## 今天不做
- 不做复杂任务编排 DAG。
- 不做多 Agent 协商。
- 不做自动高风险动作。
## 详细执行清单
以下内容为合并后的详细执行清单。
## 0. 开始前检查
- [x] ~~确认 Day 3 `POST /api/v1/ontology/parse` 可用。~~
- [x] ~~确认 `AgentRun` 可创建。~~
- [x] ~~确认 `AgentToolCall` 可创建。~~
- [x] ~~确认资产列表能查询技能、MCP、任务。~~
- [x] ~~确认权限级别枚举已稳定。~~
- [x] ~~找到后端服务层适合放 Orchestrator 的位置。~~
## 1. Orchestrator 输入输出
- [x] ~~定义 `OrchestratorRequest`。~~
- [x] ~~请求包含 `source`。~~
- [x] ~~请求包含 `user_id`。~~
- [x] ~~请求包含 `message`。~~
- [x] ~~请求包含 `task_id`。~~
- [x] ~~请求包含 `context_json`。~~
- [x] ~~定义 `OrchestratorResponse`。~~
- [x] ~~响应包含 `run_id`。~~
- [x] ~~响应包含 `selected_agent`。~~
- [x] ~~响应包含 `route_reason`。~~
- [x] ~~响应包含 `permission_level`。~~
- [x] ~~响应包含 `status`。~~
- [x] ~~响应包含 `result`。~~
- [x] ~~响应包含 `requires_confirmation`。~~
- [x] ~~响应包含 `trace_summary`。~~
验收证据:
- [x] ~~Orchestrator 响应能直接被前端展示。~~
## 2. 建立 Orchestrator 服务
- [x] ~~新增 `OrchestratorService`。~~
- [x] ~~实现 `run(request)` 主入口。~~
- [x] ~~主入口第一步创建 `AgentRun`。~~
- [x] ~~主入口第二步调用语义解析。~~
- [x] ~~主入口第三步执行权限判断。~~
- [x] ~~主入口第四步选择 Agent。~~
- [x] ~~主入口第五步调用目标 Agent 或返回阻断结果。~~
- [x] ~~主入口第六步更新 `AgentRun` 状态。~~
- [x] ~~所有异常都写入 `AgentRun.error_message`。~~
验收证据:
- [x] ~~正常请求状态为 `succeeded`。~~
- [x] ~~被权限拦截请求状态为 `blocked`。~~
- [x] ~~异常请求状态为 `failed`。~~
## 3. 路由规则
- [x] ~~`source=user_message` 默认路由到 User Agent。~~
- [x] ~~`source=schedule` 默认路由到 Hermes。~~
- [x] ~~`intent=risk_check` 且来源为 schedule 时路由到 Hermes。~~
- [x] ~~`intent=query` 且来源为 user_message 时路由到 User Agent。~~
- [x] ~~`intent=explain` 路由到 User Agent。~~
- [x] ~~`intent=draft` 路由到 User Agent并可返回结构化核对结果、草稿结果或草稿更新结果。~~
- [x] ~~`scenario=expense` 且最小建单槽位完整时,允许进入 `create_expense_claim_draft`。~~
- [x] ~~`scenario=expense` 且已有 `claim_id` 或会话内 `draft_claim_id` 时,允许进入 `update_expense_claim_draft`。~~
- [ ] `scenario=expense` 且用户明确确认提交时,允许进入 `submit_expense_claim`
- [x] ~~`permission.level=approval_required` 时设置 `requires_confirmation=true`。~~
- [x] ~~`permission.level=forbidden` 时不调用下游 Agent。~~
- [x] ~~无法识别或信息不足时返回澄清问题。~~
验收证据:
- [x] ~~同一句风险检查,在用户入口和任务入口有不同路由结果。~~
## 4. 权限判断
- [x] ~~新增权限判断服务或函数。~~
- [x] ~~查询类请求返回 `read`。~~
- [x] ~~草稿类请求返回 `draft_write`。~~
- [ ] 报销草稿字段补全、附件挂接返回 `draft_write`
- [ ] 报销单提交返回 `approval_required`,并要求显式用户确认。
- [ ] 审批、上线、付款类请求返回 `approval_required`
- [x] ~~用户无权限时返回 `forbidden`。~~
- [x] ~~高风险动作不允许自动执行。~~
- [x] ~~需要确认的动作返回确认提示。~~
- [x] ~~权限判断结果写入 `AgentRun.permission_level`。~~
验收证据:
- [x] ~~“直接上线规则”不会被自动执行。~~
- [x] ~~“直接付款”不会被自动执行。~~
## 5. 能力注册查询
- [x] ~~从 `AgentAsset` 查询 active 技能。~~
- [x] ~~从 `AgentAsset` 查询 active MCP。~~
- [x] ~~从 `AgentAsset` 查询 active 任务。~~
- [ ] 查询可用的报销单写入服务和附件挂接服务。
- [ ] 查询可用的 OCR 结果持久化服务和票据文件回溯服务。
- [x] ~~过滤 disabled 能力。~~
- [x] ~~过滤未审核 active 条件不满足的规则。~~
- [x] ~~为每次能力选择记录 `route_json`。~~
- [x] ~~找不到能力时返回降级说明。~~
验收证据:
- [x] ~~禁用 MCP 不会被 Orchestrator 调用。~~
## 6. 工具调用封装
- [x] ~~定义统一工具调用接口。~~
- [ ] 工具请求前写入 `AgentToolCall` running 或准备记录。
- [x] ~~工具成功后写入响应和耗时。~~
- [x] ~~工具失败后写入错误。~~
- [ ] 报销草稿更新、提交也按工具调用或等价服务调用记录。
- [x] ~~报销草稿创建按工具调用或等价服务调用记录。~~
- [ ] 附件挂接、OCR 结果落库、票据回溯查询也按工具调用或等价服务调用记录。
- [x] ~~外部 MCP 调用失败时返回降级结果。~~
- [x] ~~数据库查询失败时返回明确错误。~~
- [x] ~~LLM 调用失败时返回可读提示。~~
验收证据:
- [x] ~~每次 Orchestrator 运行至少可以看到 0 到多条工具调用记录。~~
## 7. API 接口
- [x] ~~新增 `POST /api/v1/orchestrator/run`。~~
- [x] ~~请求支持用户消息。~~
- [x] ~~请求支持任务触发。~~
- [x] ~~响应返回 `run_id`。~~
- [x] ~~响应返回路由结果。~~
- [x] ~~响应返回权限结果。~~
- [x] ~~复用 `GET /api/v1/agent-runs/{run_id}` 查看 Trace。~~
- [x] ~~Trace 接口返回语义解析、路由、工具调用、最终结果。~~
- [x] ~~`POST /api/v1/orchestrator/run` 返回的 `result` 已可携带 `review_payload`。~~
验收证据:
- [x] ~~前端或 curl 可以完整看到一次运行链路。~~
## 8. 前端最小 Trace 查看
- [ ] 在合适位置展示最近运行记录。
- [x] ~~点击当前对话结果可查看 `run_id`。~~
- [x] ~~展示 selected_agent。~~
- [x] ~~展示 route_reason。~~
- [x] ~~展示 permission_level。~~
- [ ] 展示工具调用列表。
- [x] ~~展示错误信息。~~
- [ ] 展示耗时。
- [ ] 展示报销写链路中的 claim_id / claim_no / status 变化。
验收证据:
- [x] ~~开发调试时不需要直接查数据库才能理解主要路由结果。~~
## 9. 测试
- [x] ~~测试用户查询路由到 User Agent。~~
- [x] ~~测试定时任务路由到 Hermes。~~
- [x] ~~测试叙述型报销输入可路由到报销建单服务。~~
- [x] ~~测试同一 `conversation_id` 下的追问会继续更新已有报销草稿。~~
- [ ] 测试报销单提交前必须显式确认。
- [x] ~~测试 forbidden 不调用下游 Agent。~~
- [x] ~~测试 approval_required 返回确认。~~
- [x] ~~测试工具失败写入 ToolCall。~~
- [x] ~~测试 Orchestrator 异常写入 AgentRun。~~
验收证据:
- [x] ~~Orchestrator 核心测试通过。~~
## 10. Day 4 验收
- [x] ~~Orchestrator API 可用。~~
- [x] ~~用户请求能路由到 User Agent 占位实现。~~
- [x] ~~定时任务能路由到 Hermes 占位实现。~~
- [x] ~~语义补槽完成后的报销输入能路由到建单动作。~~
- [x] ~~语义补槽完成后的报销输入能路由到改单动作。~~
- [x] ~~权限阻断有效。~~
- [x] ~~运行 Trace 可查询。~~
- [x] ~~工具调用日志可查询。~~
- [x] ~~降级结果可读。~~
- [x] ~~所有完成项已用 `[x] ~~...~~` 标记。~~
## 阻塞记录
- [x] ~~暂无。~~
## 日终交接
- [x] ~~当前路由规则已稳定为:`user_message -> user_agent`、`schedule -> hermes`、`clarification_required -> blocked`。~~
- [x] ~~当前权限判断已稳定为:`read / draft_write / approval_required / forbidden`,高风险动作默认阻断或要求确认。~~
- [x] ~~Day 5 需承接的接口契约已明确Orchestrator 向 User Agent 传入语义结果、能力码、工具结果,并期待返回 `answer / citations / suggested_actions / draft_payload / risk_flags`。~~
- [x] ~~Day 5 当前已扩展接口契约:除 `answer / citations / suggested_actions / draft_payload / risk_flags` 外,还返回 `review_payload` 用于前端预审工作台。~~
- [x] ~~下一步仍需补齐的运行时写链路是附件持久化、OCR 结果落库和提交状态流转。~~

View File

@@ -1,284 +0,0 @@
# Day 5User Agent MVP
## 今天的大开发点
实现面向用户的自建 Agent。它负责用户提问、流程辅助、规则解释、查询结果解释和草稿生成。
User Agent 只能处理用户侧交互,不负责后台定时内循环,也不能自动执行高风险动作。
## 为什么第五天做这个
Day 1 到 Day 4 已经具备资产、语义、路由和日志基础,此时可以把用户自然语言入口接到真实流程上。
## 今天主要交付
- 用户自然语言入口。
- 对话入口透传首句文本、附件名称和页面上下文。
- 语义识别完整后创建报销单草稿。
- 对话补充字段时更新报销主表、明细和附件关联。
- 用户确认后触发报销单提交和状态变更。
- 报销查询和解释。
- 应收查询和解释。
- 应付查询和解释。
- 规则引用解释。
- 风险原因说明。
- 处理意见草稿。
- 知识库读取骨架。
- 低置信度场景的澄清追问。
- 前端问答或操作入口。
## 当前完成情况
- [x] ~~个人工作台、报销对话框和通用聊天入口已经接通真实 Orchestrator / User Agent 问答链路。~~
- [x] ~~回答、规则引用、风险说明、建议动作和结构化 `draft_payload` 已可返回。~~
- [x] ~~报销对话框已接入 OCR 识别接口附件名称、OCR 摘要和页面上下文已能透传到 Orchestrator / User Agent。~~
- [x] ~~右侧工作台已开始展示结构化 `review_payload`,并已收敛为“识别结果专用区”:核心识别摘要、时间换算说明、逐票据识别结果、可能单据类型、建议归属费用和 OCR 置信度。~~
- [x] ~~个人工作台和报销对话框已接入 `conversation_id` / `draft_claim_id`,同一会话内的连续追问不再按全新请求处理。~~
- [x] ~~个人工作台已支持“继续会话 / 新建会话”,并可恢复最近一次用户会话或清空旧会话后重新开始。~~
- [x] ~~报销核对流已切到产品化交互:正文区负责 AI 式核对提示、待补充信息、风险提醒和底部动作区,右侧只承载识别结果与票据识别明细,动作固定为“取消 / 修改识别信息 / 保存草稿或下一步”。~~
- [ ] 真实 `document_assets` / `document_asset_versions` / `expense_item_documents` / `document_ocr_results` 落库,以及 `draft -> submitted` 状态流转尚未完成;`expense_claims` / `expense_claim_items` 草稿已接通真实落库。
相关架构文档:
- [Agent 职责边界](<../agent plan/03_agent_responsibilities.md>)
- [Orchestrator 与运行流程](<../agent plan/04_orchestrator_and_runtime_flow.md>)
- [LLM Wiki 知识库架构](<../agent plan/12_llm_wiki_knowledge_architecture.md>)
- [规则形成生命周期](<../agent plan/13_rule_formation_lifecycle.md>)
## 当天验收门槛
- 用户能输入自然语言问题。
- 请求必须经过 Orchestrator。
- 至少 3 类财务问题有可读回答。
- 叙述型报销输入在最小槽位满足后能创建 `expense_claims` 草稿。
- 用户确认提交后可把报销单从 `draft` 变更为 `submitted`
- 回答能引用规则或知识。
- 语义低置信度时不会答非所问,而是追问。
- 高风险动作只生成草稿或建议。
- AgentRun Trace 能看到 User Agent 步骤。
## 今天不做
- 不做自动审批。
- 不做自动付款。
- 不做自动上线规则。
- 不做完整知识库检索优化。
- 不假装已读懂未解析的附件内容。
## 详细执行清单
以下内容为合并后的详细执行清单。
## 0. 开始前检查
- [x] ~~确认 Orchestrator 能把用户请求路由到 User Agent。~~
- [x] ~~确认语义本体 8 字段可用。~~
- [x] ~~确认语义层已接入真实模型,而不是仅靠关键词规则。~~
- [x] ~~确认规则资产可查询。~~
- [x] ~~确认 AgentRun 和 ToolCall 可记录。~~
- [x] ~~确认已有现成对话 UI 可复用。~~
- [x] ~~确认财务业务数据已可通过最小真实数据查询。~~
- [x] ~~当前无需额外补最小 Mock 数据服务。~~
## 1. User Agent 输入输出
- [x] ~~定义 `UserAgentRequest`。~~
- [x] ~~请求包含 `run_id`。~~
- [x] ~~请求包含 `user_id`。~~
- [x] ~~请求包含 `message`。~~
- [x] ~~请求包含 `ontology`。~~
- [x] ~~请求包含 `context_json`。~~
- [x] ~~定义 `UserAgentResponse`。~~
- [x] ~~响应包含 `answer`。~~
- [x] ~~响应包含 `citations`。~~
- [x] ~~响应包含 `suggested_actions`。~~
- [x] ~~响应包含 `draft_payload`。~~
- [x] ~~响应包含 `risk_flags`。~~
- [x] ~~响应包含 `requires_confirmation`。~~
验收证据:
- [x] ~~User Agent 响应结构能被 Orchestrator 直接包装返回。~~
## 2. 查询处理
- [x] ~~实现报销查询处理器。~~
- [x] ~~实现应收查询处理器。~~
- [x] ~~实现应付查询处理器。~~
- [ ] 查询前检查权限级别。
- [x] ~~查询时记录 ToolCall。~~
- [x] ~~查询失败时返回可读错误。~~
- [x] ~~查询为空时返回空态解释。~~
- [ ] 查询结果限制返回条数,避免一次返回过大。
验收证据:
- [x] ~~“查本周报销金额”有可读回答。~~
- [x] ~~“客户 A 本月应收多少”有可读回答。~~
- [x] ~~“供应商 B 待付款多少”有可读回答。~~
## 3. 规则解释
- [x] ~~根据语义场景查询相关规则资产。~~
- [x] ~~只引用 active 规则。~~
- [x] ~~读取规则当前版本 Markdown。~~
- [x] ~~从 Markdown 中提取规则摘要。~~
- [x] ~~回答中说明使用了哪些规则。~~
- [x] ~~回答中包含规则版本号。~~
- [x] ~~回答中包含规则更新时间。~~
- [x] ~~没有相关规则时说明缺失。~~
验收证据:
- [x] ~~“为什么这笔报销有风险”能引用规则。~~
## 4. 风险解释
- [x] ~~识别重复报销风险。~~
- [x] ~~识别金额超标风险。~~
- [x] ~~识别发票异常风险。~~
- [x] ~~识别逾期应收风险。~~
- [x] ~~识别逾期应付风险。~~
- [x] ~~风险回答包含风险类型。~~
- [x] ~~风险回答包含触发原因。~~
- [x] ~~风险回答包含建议处理动作。~~
- [x] ~~高风险建议不能变成自动执行。~~
验收证据:
- [x] ~~风险解释结果不是单纯“有风险”,而是有依据。~~
## 5. 草稿生成与单据落库
- [x] ~~支持根据语义结果创建 `expense_claims` 草稿。~~
- [x] ~~报销草稿初始状态写为 `draft`。~~
- [x] ~~支持根据语义结果创建或更新 `expense_claim_items`。~~
- [ ] 支持把用户上传附件挂到 `document_assets``document_asset_versions``expense_item_documents`
- [ ] 支持把 OCR 识别快照写入 `document_ocr_results`,并保留 `ocr_engine``ocr_model``raw_json``confidence`
- [x] ~~对话中补充金额、发生时间、费用类型等已落地字段后,能回写已有草稿而不是只更新内存结果。~~
- [x] ~~支持生成报销处理意见草稿。~~
- [x] ~~支持生成应收催收建议草稿。~~
- [x] ~~支持生成应付付款建议草稿。~~
- [ ] 用户明确确认“提交报销”后,把 `expense_claims.status``draft` 更新为 `submitted`
- [ ] 报销提交时写入 `submitted_at`
- [ ] 报销状态变更写入审计日志。
- [ ] 报销状态变更写入 AgentRun 结果。
- [x] ~~草稿中标明“待人工确认”。~~
- [x] ~~草稿不直接提交业务系统。~~
- [x] ~~草稿生成写入审计日志。~~
- [x] ~~草稿生成写入 AgentRun 结果。~~
- [ ] 草稿创建或更新后向前端返回 `attachment_ids`
- [x] ~~草稿创建或更新后向前端返回 `claim_id`、`claim_no`、`status`。~~
验收证据:
- [ ] “我今天去客户现场招待了客户花销了1000元”在补齐必要字段后可创建报销草稿。
- [ ] “帮我提交这笔报销”在确认后只把状态改到 `submitted`,不会直接改成 `approved``paid`
- [x] ~~“帮我生成处理意见”只返回草稿,不执行审批。~~
## 6. 知识库读取骨架
- [ ] 建立知识条目查询接口或服务。
- [ ] 支持按关键词查询知识条目。
- [ ] 支持按业务场景查询知识条目。
- [ ] User Agent 回答可以引用知识条目。
- [ ] 引用中包含知识标题。
- [ ] 引用中包含更新时间。
- [ ] 知识库不可用时返回降级说明。
验收证据:
- [ ] 知识库失败不会导致整个回答失败。
## 7. 对话或操作入口
- [x] ~~前端增加用户问题输入框。~~
- [x] ~~输入框支持回车或按钮提交。~~
- [x] ~~提交时调用 Orchestrator而不是绕过 Orchestrator。~~
- [x] ~~提交时透传首句文本。~~
- [x] ~~提交时透传附件名称。~~
- [x] ~~提交时透传 OCR 摘要。~~
- [x] ~~提交时透传页面上下文。~~
- [x] ~~提交时透传 `conversation_id` 与 `draft_claim_id`。~~
- [ ] 提交时透传附件 ID。
- [x] ~~展示 Agent 回答。~~
- [x] ~~展示引用规则或知识。~~
- [x] ~~展示建议动作。~~
- [x] ~~展示识别意图摘要、待确认字段和确认动作卡片。~~
- [x] ~~正文区改为简洁核对提示,不再堆叠调度结果或运行明细。~~
- [x] ~~正文区待补充信息和风险提示已改为紧凑高亮样式,避免出现大段冗长说明。~~
- [x] ~~展示逐票据 OCR 识别结果,并支持按 1、2、3… 顺序查看。~~
- [x] ~~右侧逐票据结果已补充“可能单据类型 / 建议归属费用 / 识别置信度”等识别信息。~~
- [x] ~~展示多场景票据的分单建议。~~
- [ ] 展示报销草稿 ID 或 claim_no。
- [ ] 展示当前报销状态。
- [x] ~~展示需要人工确认的提示。~~
- [x] ~~展示 `run_id`。~~
- [x] ~~展示加载态。~~
- [x] ~~展示错误态。~~
验收证据:
- [x] ~~用户可在页面完成一次问答闭环。~~
## 8. 安全边界
- [x] ~~User Agent 不直接修改规则状态。~~
- [x] ~~User Agent 不直接上线规则。~~
- [x] ~~User Agent 不直接审批报销。~~
- [x] ~~User Agent 不直接把报销单改为 `approved` 或 `paid`。~~
- [x] ~~User Agent 不直接付款。~~
- [x] ~~User Agent 不直接删除知识。~~
- [x] ~~所有高风险动作只返回建议或草稿。~~
- [ ] 报销从 `draft` 变更到 `submitted` 之前必须有用户确认。
- [ ] 所有草稿动作标记 `requires_confirmation=true`
- [x] ~~语义低置信度时优先追问,不返回答非所问的查询结果。~~
- [x] ~~没有 OCR/VLM 结果时,不假装读懂图片或票据内容。~~
验收证据:
- [x] ~~提示词要求“直接付款”时仍被阻断。~~
## 9. 测试
- [x] ~~测试报销查询。~~
- [x] ~~测试应收查询。~~
- [ ] 测试应付查询。
- [ ] 测试规则解释。
- [x] ~~测试风险解释。~~
- [ ] 测试 OCR 摘要透传后User Agent 能在回答中正确引用附件语境而不编造内容。
- [x] ~~测试报销草稿创建。~~
- [x] ~~测试报销草稿补槽更新。~~
- [ ] 测试报销状态从 `draft` 变更到 `submitted`
- [x] ~~测试草稿生成。~~
- [ ] 测试越权动作阻断。
- [ ] 测试知识库降级。
验收证据:
- [x] ~~User Agent 核心测试通过。~~
## 10. Day 5 验收
- [x] ~~User Agent 服务可被 Orchestrator 调用。~~
- [x] ~~用户入口可提交自然语言问题。~~
- [x] ~~至少 3 个财务场景有回答。~~
- [x] ~~语义识别完整后的报销输入能创建报销草稿。~~
- [ ] 用户确认后能提交报销并更新状态。
- [x] ~~回答能引用规则或知识。~~
- [x] ~~高风险动作不会自动执行。~~
- [x] ~~AgentRun Trace 能看到 User Agent 步骤。~~
- [x] ~~前端构建通过。~~
- [x] ~~所有完成项已用 `[x] ~~...~~` 标记。~~
## 阻塞记录
- [x] ~~暂无。~~
## 日终交接
- [x] ~~当前已支持报销 / 应收 / 应付查询、规则解释、风险解释、草稿建议与澄清追问。~~
- [x] ~~当前已支持附件名称、OCR 摘要和页面上下文进入对话链路,但这还不是附件真实持久化。~~
- [x] ~~当前已把用户一句话和多票据输入转成结构化预审面板,开始支持字段确认、票据核对和分单建议,而不再只是返回一段文本。~~
- [x] ~~当前仍是占位的主要能力是报销单真实落库、附件持久化、OCR 结果入表和知识库读取,不再是简单静态问答 Mock。~~
- [x] ~~Day 6 Hermes 可直接复用当前的规则检查、风险标签和 Orchestrator Trace / ToolCall 契约。~~

View File

@@ -1,343 +0,0 @@
# Day 6Hermes MVP
## 今天的大开发点
实现 Hermes 数字员工的最小闭环。Hermes 负责后台内循环:定时巡检、统计日报、风险预警、知识维护、规则草稿形成。
## 为什么第六天做这个
Hermes 依赖前几天已经建立的资产、规则、语义、Orchestrator、Trace 和权限体系。放在第六天做,可以避免它变成孤立脚本。
## 今天主要交付
- 任务资产调度入口。
- 手动触发任务 API。
- 系统 Hermes 后台执行入口。
- 每日风险巡检。
- 每日报销、报账、账款统计。
- OCR Mock 接入点。
- 知识候选条目生成。
- 规则草稿生成。
- LLM Wiki 解析目录与增量重建机制。
- Hermes 运行结果展示。
相关架构文档:
- [Agent 职责边界](<../agent plan/03_agent_responsibilities.md>)
- [OCR 票据识别架构](<../agent plan/11_ocr_invoice_architecture.md>)
- [LLM Wiki 知识库架构](<../agent plan/12_llm_wiki_knowledge_architecture.md>)
- [反馈学习闭环](<../agent plan/15_feedback_learning_loop.md>)
## 当天验收门槛
- 至少一个 Hermes 任务可以手动触发。
- 风险巡检有结构化结果。
- 每日统计有结构化结果。
- OCR Mock 调用能记录 ToolCall。
- 知识候选只能是草稿。
- 规则草稿只能是 draft不能自动上线。
## 今天不做
- 不做完整生产调度集群。
- 不做真实 OCR 深度集成。
- 不做自动发布知识。
- 不做自动上线规则。
- 不做每天无差别全量重建 LLM Wiki。
## 本次新增约束
### 1. Hermes 必须是系统后台 Hermes
这次 Hermes 不应继续只是代码里的占位逻辑。
最小可接受形态:
- 后端任务入口能明确区分 `selected_agent=hermes`
- 后端可调用系统安装的 Hermes CLI 或受控 Hermes 进程。
- 即使当前阶段仍允许 Python 内部 fallback也必须保留真实 Hermes 进程接入点。
- Hermes 的模型配置继续由系统设置同步,不允许在任务代码里再写一套模型配置。
- Hermes 执行应记录 `run_id`、ToolCall、错误信息和最终摘要。
### 2. LLM Wiki 必须有独立解析目录
原始知识文件与解析产物必须分离。
推荐目录:
```text
/app/server/storage/knowledge/报销制度 原始制度文件
/app/server/storage/knowledge/.llm_wiki 解析产物根目录
/app/server/storage/knowledge/.llm_wiki/documents/<document_id>/
document.json
text.md
chunks.json
clauses.json
knowledge_candidates.json
rule_candidates.json
/app/server/storage/knowledge/.llm_wiki/index.json
/app/server/storage/knowledge/.llm_wiki/sync_runs.json
```
### 3. LLM Wiki 只能增量形成
不允许每天无脑全量重建。
文档级重建触发条件至少包括:
- 文件名 `original_name` 变更。
- 文件对象 `stored_name` 变更。
- 内容摘要 `sha256` 变更。
- 上传版本 `version_number` 变更。
- 更新时间 `updated_at` 变更,视为人工改动。
如果以上条件都未变化:
- 本次文档应标记为 `unchanged_skipped`
- 不重新抽取文本。
- 不重新生成知识候选。
- 不重新生成规则草稿。
### 4. 规则草稿必须模板化
Hermes 不允许自由生成任意结构的规则。
必须满足:
- 规则 Markdown 使用固定模板。
- 可执行规则 JSON 使用固定模板族,不允许随意拼字段。
- 规则中心要同时展示人类可读的 Markdown 和机器可执行的 JSON。
- Hermes 生成的规则默认 `draft`
- 审核通过前不能 `active`
- Hermes 不能直接覆盖线上 active 规则。
## 详细执行清单
以下内容为合并后的详细执行清单。
## 本轮追加范围2026-05-15
本轮不扩散到新的业务能力,先把已经落地的 LLM Wiki 归纳链路收紧成可运维、可追踪、可持续运行的形态。
本轮目标:
- 把知识管理中的 Hermes 归纳从同步请求改成后台异步任务。
- 用户关闭或切走页面后,归纳任务仍继续执行,不因前端页面生命周期被误判失败。
- 归纳过程中的状态、进度、摘要、异常统一写入 `AgentRun.route_json``result_summary`
- 知识管理页轮询真实任务状态,任务完成后立刻把文档状态从“正归纳”切到最终状态。
- 右侧侧边栏新增“日志管理”入口。
- 日志管理页拆成两类日志:
- Hermes 调用日志查看归纳任务运行状态、当前阶段、文档进度、ToolCall、错误信息。
- 系统运行日志:直接查看 `server/logs` 下的系统日志文本。
本轮边界:
- 仍然使用系统 Hermes CLI 入口,不虚构不存在的 gateway 推理接口。
- 不引入完整消息队列或 Celery 集群,先用后端受控后台任务管理器落地。
- 不把日志页做成审计替代品,重点只覆盖 Hermes 运行日志和系统运行日志。
- 不把普通用户开放为日志管理员,日志查看仍属于管理员能力。
## 0. 开始前检查
- [x] ~~确认任务资产 `asset_type=task` 可查询。~~
- [x] ~~确认 Orchestrator 能处理 `source=schedule`。~~
- [x] ~~确认系统 Hermes CLI 或等价后台 Hermes 进程可被调用。~~
- [x] ~~确认 AgentRun 和 ToolCall 可记录。~~
- [x] ~~确认是否已有后台任务框架。~~
- [ ] 如果没有后台任务框架,先用手动触发 API 模拟定时执行。
## 1. Hermes 输入输出
- [ ] 定义 `HermesTaskRequest`
- [ ] 请求包含 `run_id`
- [ ] 请求包含 `task_asset_id`
- [ ] 请求包含 `task_type`
- [ ] 请求包含 `schedule_time`
- [ ] 请求包含 `context_json`
- [ ] 定义 `HermesTaskResult`
- [ ] 响应包含 `summary`
- [ ] 响应包含 `risk_items`
- [ ] 响应包含 `statistics`
- [ ] 响应包含 `knowledge_updates`
- [ ] 响应包含 `draft_rules`
- [ ] 响应包含 `next_actions`
验收证据:
- [ ] Hermes 响应能被任务详情或运行日志展示。
## 2. 任务调度入口
- [x] ~~新增手动触发任务 API。~~
- [x] ~~API 参数支持任务资产 ID。~~
- [x] ~~API 调用 Orchestratorsource 为 `schedule`。~~
- [x] ~~Orchestrator 路由到 Hermes。~~
- [x] ~~Hermes 执行结果写入 AgentRun。~~
- [ ] 任务执行失败时写入错误。
- [ ] 任务执行结束后更新任务最近执行时间。
- [ ] 任务执行结束后更新任务最近执行状态。
- [x] ~~保留真实 Hermes 进程执行入口,不把 Hermes 固定写死为本地占位函数。~~
验收证据:
- [x] ~~可以手动触发一次 Hermes 任务并看到运行结果。~~
## 3. 每日风险巡检
- [ ] 实现重复报销巡检。
- [ ] 实现金额超标巡检。
- [ ] 实现发票异常巡检占位。
- [ ] 实现应收逾期巡检。
- [ ] 实现应付异常付款巡检。
- [ ] 每个风险项包含风险类型。
- [ ] 每个风险项包含业务对象。
- [ ] 每个风险项包含触发规则。
- [ ] 每个风险项包含建议动作。
- [ ] 每个风险项包含风险等级。
验收证据:
- [ ] 风险巡检结果可以被用户理解和追溯。
## 4. 每日统计
- [ ] 统计当日报销单数量。
- [ ] 统计当日报销金额。
- [ ] 统计当日报账数量。
- [ ] 统计当日报账金额。
- [ ] 统计应收新增金额。
- [ ] 统计应收逾期金额。
- [ ] 统计应付待付金额。
- [ ] 统计应付逾期金额。
- [ ] 输出日报摘要。
验收证据:
- [ ] Hermes 能生成一份每日财务摘要。
## 5. OCR 接入点
- [ ] 原始票据先落 `document_assets``document_asset_versions`,不直接以内存临时文件参与流程。
- [ ] 建立 OCR 识别服务接口。
- [ ] 定义发票识别输入结构。
- [ ] 定义发票识别输出结构。
- [ ] 输出结构包含发票号。
- [ ] 输出结构包含开票日期。
- [ ] 输出结构包含金额。
- [ ] 输出结构包含税额。
- [ ] 输出结构包含销售方。
- [ ] 输出结构包含购买方。
- [ ] 输出结构包含置信度。
- [ ] OCR 输入可通过 `storage_key` 或等价文件定位字段读取原件。
- [ ] 当前阶段允许使用 Mock 结果。
- [ ] OCR 调用写入 ToolCall。
验收证据:
- [ ] Hermes 风险巡检中可以调用 OCR Mock。
## 6. 知识库维护
- [ ] 建立知识条目写入服务。
- [x] ~~建立 `.llm_wiki` 独立解析目录。~~
- [x] ~~原始文档与解析产物物理隔离。~~
- [x] ~~文本抽取结果落 `text.md`。~~
- [x] ~~分块结果落 `chunks.json`。~~
- [x] ~~文档索引落 `index.json`。~~
- [x] ~~同步记录落 `sync_runs.json`。~~
- [x] ~~文档签名包含 `original_name`、`stored_name`、`sha256`、`version_number`、`updated_at`。~~
- [x] ~~未变化文档跳过重建并记录 `unchanged_skipped`。~~
- [x] ~~Hermes 可以生成知识候选条目。~~
- [x] ~~候选条目包含标题。~~
- [x] ~~候选条目包含正文。~~
- [x] ~~候选条目包含来源。~~
- [x] ~~候选条目包含适用场景。~~
- [x] ~~候选条目默认状态为 `draft`。~~
- [x] ~~知识条目不能自动发布。~~
- [ ] 知识条目写入审计日志。
验收证据:
- [x] ~~Hermes 可以生成待审核知识条目。~~
## 7. 规则草稿形成
- [ ] Hermes 可以根据风险巡检结果生成规则草稿。
- [x] ~~规则草稿使用固定 Markdown 模板。~~
- [x] ~~规则草稿生成可执行 JSON 草稿。~~
- [x] ~~规则中心展示 Markdown + JSON 双视图。~~
- [x] ~~JSON 草稿字段受模板约束,不允许自由扩展。~~
- [x] ~~规则草稿保存为 `asset_type=rule`。~~
- [x] ~~规则草稿状态为 `draft`。~~
- [x] ~~规则草稿包含 Markdown 内容。~~
- [x] ~~规则草稿包含 JSON 内容或等价 `runtime_rule` 配置。~~
- [ ] 规则草稿包含生成原因。
- [ ] 规则草稿包含关联风险样例。
- [x] ~~规则草稿不能自动上线。~~
- [x] ~~规则草稿需要审核人。~~
- [x] ~~规则草稿写入审计日志。~~
- [x] ~~Hermes 不直接覆盖线上 active 规则。~~
验收证据:
- [x] ~~Hermes 生成的新规则出现在规则列表中,但不是 active。~~
## 8. Hermes 页面或日志展示
- [x] ~~任务详情能看到最近执行结果。~~
- [ ] 任务详情能手动触发执行。
- [ ] 任务详情能看到风险项数量。
- [ ] 任务详情能看到日报摘要。
- [ ] 任务详情能看到知识候选数量。
- [ ] 任务详情能看到规则草稿数量。
- [ ] 运行 Trace 能看到 Hermes 步骤。
- [x] ~~错误时展示错误原因。~~
- [ ] 日志管理页能查看 Hermes 归纳任务的实时状态。
- [ ] 日志管理页能查看 Hermes ToolCall 请求与结果。
- [ ] 日志管理页能查看系统运行日志文本。
- [ ] 知识管理页能在后台任务完成后自动刷新归纳状态。
验收证据:
- [x] ~~不查数据库也能判断 Hermes 是否执行成功。~~
## 9. 测试
- [x] ~~测试手动触发任务。~~
- [x] ~~测试 Orchestrator 路由到 Hermes。~~
- [ ] 测试风险巡检输出。
- [ ] 测试日报统计输出。
- [ ] 测试 OCR Mock 调用。
- [x] ~~测试知识候选写入。~~
- [x] ~~测试规则草稿生成。~~
- [ ] 测试 Hermes 异常写入 AgentRun。
- [ ] 测试知识归纳异步任务在接口返回后仍能继续执行。
- [ ] 测试归纳进度能持续写入 AgentRun。
- [ ] 测试系统日志读取接口。
验收证据:
- [ ] Hermes 核心测试通过。
## 10. Day 6 验收
- [x] ~~Hermes 可被 Orchestrator 调用。~~
- [x] ~~至少一个任务可以手动触发。~~
- [ ] 风险巡检有结构化结果。
- [ ] 每日统计有结构化结果。
- [ ] OCR Mock 接入点可用。
- [x] ~~知识候选可生成。~~
- [x] ~~规则草稿可生成且不能自动上线。~~
- [x] ~~任务详情或运行日志能展示结果。~~
- [x] ~~所有完成项已用 `[x] ~~...~~` 标记。~~
## 阻塞记录
- [ ] 暂无。
## 日终交接
- [ ] 写明 Hermes 已支持任务类型。
- [ ] 写明 OCR 当前是真实还是 Mock。
- [ ] 写明生成的知识和规则草稿状态。
- [ ] 写明 Day 7 需要重点回归的路径。

View File

@@ -1,260 +0,0 @@
# Day 7加固、演示和验收
## 今天的大开发点
不再大规模扩功能,集中做回归、加固、测试、演示脚本、文档收尾和下一阶段交接。
## 为什么第七天做这个
一周开发不能只停留在“代码写了”。必须能演示、能追溯、能说清楚边界、能交给下一阶段继续开发。
## 今天主要交付
- 核心链路回归。
- 权限和风险边界复查。
- 审计日志补齐。
- AgentRun Trace 补齐。
- 前端体验修补。
- 测试和构建记录。
- 评测集执行记录。
- 演示数据准备。
- 演示脚本。
- 下一阶段开发建议。
相关架构文档:
- [Agent Plan 总览](<../agent plan/00_README.md>)
- [开发路线图](<../agent plan/05_development_roadmap.md>)
- [观测与 Trace](<../agent plan/09_observability_and_trace.md>)
- [评测与测试集](<../agent plan/10_evaluation_and_testset.md>)
## 当天验收门槛
- 任务规则中心核心路径可演示。
- 语义本体、Orchestrator、User Agent、Hermes 都能跑通最小链路。
- 未审核规则、高风险动作、自动付款等边界都被拦截。
- AgentRun、ToolCall、AuditLog 可追溯。
- 有测试记录、演示脚本和交接说明。
## 今天不做
- 不做新大功能。
- 不临时扩大范围。
- 不绕过测试和验收。
## 详细执行清单
以下内容为合并后的详细执行清单。
## 0. 开始前检查
- [ ] 汇总 Day 1 未完成项。
- [ ] 汇总 Day 2 未完成项。
- [ ] 汇总 Day 3 未完成项。
- [ ] 汇总 Day 4 未完成项。
- [ ] 汇总 Day 5 未完成项。
- [ ] 汇总 Day 6 未完成项。
- [ ] 标记必须今天修复的问题。
- [ ] 标记可以进入下一阶段的问题。
- [ ] 冻结新增需求,只处理验收相关问题。
## 1. 核心链路回归
- [ ] 回归资产列表接口。
- [ ] 回归规则详情接口。
- [ ] 回归 Markdown 保存。
- [ ] 回归版本列表。
- [ ] 回归版本切换。
- [ ] 回归审核接口。
- [ ] 回归上线拦截。
- [ ] 回归语义解析接口。
- [ ] 回归 Orchestrator 路由。
- [ ] 回归 User Agent 问答。
- [ ] 回归 Hermes 任务执行。
- [ ] 回归 AgentRun Trace。
- [ ] 回归 ToolCall 日志。
- [ ] 回归 AuditLog 日志。
验收证据:
- [ ] 从前端能完成至少一条端到端演示路径。
## 2. 权限和风险边界
- [ ] 未审核规则不能上线。
- [ ] rejected 规则不能上线。
- [ ] disabled 能力不能被调用。
- [ ] 用户请求付款必须拦截。
- [ ] 用户请求审批必须需要确认。
- [ ] Hermes 生成规则只能是 draft。
- [ ] Hermes 生成知识只能是 draft。
- [ ] User Agent 生成处理意见只能是草稿。
- [ ] 所有高风险动作响应中包含 `requires_confirmation`
验收证据:
- [ ] 不存在 MVP 期间绕过人工审核的路径。
## 3. 审计和 Trace 补齐
- [ ] 规则保存写 AuditLog。
- [ ] 规则审核写 AuditLog。
- [ ] 规则上线写 AuditLog。
- [ ] Hermes 生成规则草稿写 AuditLog。
- [ ] Hermes 生成知识候选写 AuditLog。
- [ ] User Agent 草稿生成写 AuditLog。
- [ ] Orchestrator 每次运行有 AgentRun。
- [ ] 每次工具调用有 ToolCall。
- [ ] Trace 页面或接口能串起 run_id。
- [ ] 错误 Trace 包含 error_message。
验收证据:
- [ ] 任意一条演示链路都能追溯到 run_id。
## 4. 前端体验修补
- [ ] 任务规则中心列表无明显错位。
- [ ] 详情页无双 title。
- [ ] Hero title 高度紧凑。
- [ ] 返回列表栏高度正常。
- [ ] Markdown 编辑器和版本卡片底部对齐。
- [ ] 版本卡片不贴右侧。
- [ ] 当前版本标识不突兀。
- [ ] 日期列对齐。
- [ ] 弹窗文案清楚。
- [ ] 加载态可见。
- [ ] 错误态可见。
- [ ] 空态可见。
- [ ] 按钮禁用态可见。
- [ ] 窄屏不出现内容重叠。
验收证据:
- [ ] 任务规则中心可以给业务用户演示,不需要解释 UI 异常。
## 5. 测试补齐
- [ ] 运行后端现有测试。
- [ ] 运行新增模型测试。
- [ ] 运行新增 API 测试。
- [ ] 运行语义解析测试。
- [ ] 运行 Orchestrator 测试。
- [ ] 运行 User Agent 测试。
- [ ] 运行 Hermes 测试。
- [ ] 运行前端构建。
- [ ] 如果有前端测试,运行前端测试。
- [ ] 记录未能运行的测试和原因。
验收证据:
- [ ] 测试结果写入本文件“测试记录”。
## 6. 评测集
- [ ] 准备 5 条报销问题。
- [ ] 准备 5 条应收问题。
- [ ] 准备 5 条应付问题。
- [ ] 准备 3 条规则解释问题。
- [ ] 准备 3 条越权动作问题。
- [ ] 执行语义解析评测。
- [ ] 执行 User Agent 回答评测。
- [ ] 执行权限拦截评测。
- [ ] 记录失败样例。
- [ ] 为失败样例写下一阶段优化建议。
验收证据:
- [ ] 可以说明 MVP 当前能力边界和准确率风险。
## 7. 演示数据
- [ ] 准备 active 规则。
- [ ] 准备 pending 规则。
- [ ] 准备 rejected 规则。
- [ ] 准备至少一条报销数据。
- [ ] 准备至少一条应收数据。
- [ ] 准备至少一条应付数据。
- [ ] 准备至少一个 Hermes 任务。
- [ ] 准备至少一个 MCP Mock。
- [ ] 准备至少一个知识条目。
- [ ] 准备至少一个风险样例。
验收证据:
- [ ] 演示不会因为没有数据而中断。
## 8. 演示脚本
- [ ] 编写演示步骤 1打开任务规则中心。
- [ ] 编写演示步骤 2查看规则详情。
- [ ] 编写演示步骤 3编辑 Markdown 并保存。
- [ ] 编写演示步骤 4切换版本。
- [ ] 编写演示步骤 5尝试上线未审核规则并被拦截。
- [ ] 编写演示步骤 6输入用户问题。
- [ ] 编写演示步骤 7查看语义本体结果。
- [ ] 编写演示步骤 8查看 User Agent 回答。
- [ ] 编写演示步骤 9手动触发 Hermes 任务。
- [ ] 编写演示步骤 10查看 AgentRun Trace。
- [ ] 编写演示步骤 11查看审计日志。
验收证据:
- [ ] 新开发者按脚本可以复现演示。
## 9. 文档收尾
- [ ] 更新一周计划完成情况。
- [ ] 更新剩余风险。
- [ ] 更新下一阶段开发建议。
- [ ] 更新接口清单。
- [ ] 更新数据模型清单。
- [ ] 更新前端页面清单。
- [ ] 更新评测结果。
- [ ] 更新演示脚本。
- [ ] 更新部署或启动说明。
验收证据:
- [ ] 文档能指导下一周继续开发。
## 10. 最终验收清单
- [ ] 任务规则中心可查看规则、技能、MCP、任务。
- [ ] 规则详情可编辑 Markdown。
- [ ] 规则详情可查看最近 5 个版本。
- [ ] 版本切换有确认弹窗。
- [ ] 审核者信息可见。
- [ ] 未审核规则不能上线。
- [ ] 语义本体 8 字段可返回。
- [ ] Orchestrator 能路由用户请求。
- [ ] Orchestrator 能路由定时任务。
- [ ] User Agent 能回答至少 3 类财务问题。
- [ ] Hermes 能执行至少 1 个任务。
- [ ] OCR Mock 接入点可用。
- [ ] 知识候选可生成。
- [ ] 规则草稿可生成。
- [ ] AgentRun Trace 可查。
- [ ] AuditLog 可查。
- [ ] 前端构建通过。
- [ ] 后端核心测试通过。
- [ ] 演示脚本可执行。
- [ ] 所有完成项已用 `[x] ~~...~~` 标记。
## 测试记录
- [ ] 后端测试:未运行。
- [ ] 前端构建:未运行。
- [ ] 语义评测:未运行。
- [ ] 手动验收:未运行。
## 阻塞记录
- [ ] 暂无。
## 日终交接
- [ ] 写明本周最终完成内容。
- [ ] 写明未完成内容。
- [ ] 写明生产化前必须补齐内容。
- [ ] 写明下一周建议优先级。

View File

@@ -1,137 +0,0 @@
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Day 1 - 基础模型与工程骨架</title>
<link rel="stylesheet" href="./styles.css">
</head>
<body>
<div class="shell">
<div class="topbar">
<a class="brand" href="./index.html"><span class="brand-mark">D1</span><span>Day 1 View</span></a>
<div class="quick-links">
<a class="pill" href="./index.html">返回总览</a>
<a class="pill" href="../agent%20week%20plan/day_1_foundation_models.md">周计划原文</a>
<a class="pill" href="../agent%20week%20plan/day_1_foundation_models.md">合并文档原文</a>
</div>
</div>
<div class="day-nav">
<a class="pill active" href="./day-1.html">Day 1</a>
<a class="pill" href="./day-2.html">Day 2</a>
<a class="pill" href="./day-3.html">Day 3</a>
<a class="pill" href="./day-4.html">Day 4</a>
<a class="pill" href="./day-5.html">Day 5</a>
<a class="pill" href="./day-6.html">Day 6</a>
<a class="pill" href="./day-7.html">Day 7</a>
</div>
<section class="hero">
<div class="hero-badge">Foundation Completed</div>
<h1>Day 1 基础模型与工程骨架</h1>
<p>这一天的任务不是做炫目的业务能力,而是把后面 6 天要反复依赖的模型、版本、审核、run trace、审计日志和最小业务数据源一次定稳。Day 1 做虚了Day 4 到 Day 6 会全部返工。</p>
<div class="hero-meta">
<div class="meta-card"><div class="meta-label">当前状态</div><div class="meta-value">已完成2026-05-11可直接进入 Day 2 联调。</div></div>
<div class="meta-card"><div class="meta-label">上游依赖</div><div class="meta-value">Day 1 是全周底座。</div></div>
<div class="meta-card"><div class="meta-label">下游交接</div><div class="meta-value">Day 2 资产 APIDay 3 解析日志Day 4 run traceDay 5/6 业务数据查询。</div></div>
<div class="meta-card"><div class="meta-label">当天关键</div><div class="meta-value">先确定统一模型,再接 API 骨架和种子数据。</div></div>
</div>
</section>
<div class="section-kicker">Three-Layer Mapping</div>
<h2 class="section-title">三层文档映射</h2>
<div class="grid three">
<section class="card tone-warm">
<h3>路线图</h3>
<p>周计划里定义这一天要完成“工程地基”强调只做稳定模型、API 骨架、种子数据、基础审计和可运行验证。</p>
<div class="card-links"><a class="link-chip" href="../agent%20week%20plan/day_1_foundation_models.md">day_1_foundation_models.md</a></div>
</section>
<section class="card tone-teal">
<h3>执行细则</h3>
<p>执行层把 Day 1 拆成命名边界、最小财务业务数据模型、Agent 资产模型、版本、审核、Run、ToolCall、SemanticParseLog、AuditLog、Schema、API、服务层。</p>
<div class="card-links"><a class="link-chip" href="../agent%20week%20plan/day_1_foundation_models.md">agent week plan/day_1</a></div>
</section>
<section class="card tone-olive">
<h3>架构依据</h3>
<p>主要受总体架构、语义本体、数据契约、能力注册、权限确认、可观测性和财务标准模型约束。</p>
<div class="card-links">
<a class="link-chip" href="../agent%20plan/01_overall_architecture.md">01</a>
<a class="link-chip" href="../agent%20plan/02_semantic_ontology.md">02</a>
<a class="link-chip" href="../agent%20plan/06_data_contracts_and_governance.md">06</a>
<a class="link-chip" href="../agent%20plan/07_capability_registry.md">07</a>
<a class="link-chip" href="../agent%20plan/08_permission_confirmation.md">08</a>
<a class="link-chip" href="../agent%20plan/09_observability_and_trace.md">09</a>
<a class="link-chip" href="../agent%20plan/14_financial_document_canonical_model.md">14</a>
</div>
</section>
</div>
<div class="section-kicker">Build Order</div>
<h2 class="section-title">推荐开发顺序</h2>
<div class="timeline">
<div class="timeline-step"><strong>Step 1</strong>先确认后端目录、ORM、迁移方式、测试目录和不该碰的文件。</div>
<div class="timeline-step"><strong>Step 2</strong>统一命名资产类型、状态、审核状态、Agent、权限级别。</div>
<div class="timeline-step"><strong>Step 3</strong>补最小财务业务数据模型:<code>expense_claims</code><code>accounts_receivable</code><code>accounts_payable</code></div>
<div class="timeline-step"><strong>Step 4</strong>完成 AgentAsset、Version、Review、Run、ToolCall、ParseLog、AuditLog。</div>
<div class="timeline-step"><strong>Step 5</strong>把 Schema、API 骨架、服务层、种子数据接起来。</div>
</div>
<div class="section-kicker">Must Deliver</div>
<h2 class="section-title">今天必须产出的东西</h2>
<div class="grid two">
<section class="card">
<h3>平台底座表</h3>
<ul class="list">
<li><code>AgentAsset</code><code>AgentAssetVersion</code><code>AgentAssetReview</code></li>
<li><code>AgentRun</code><code>AgentToolCall</code><code>SemanticParseLog</code></li>
<li><code>AuditLog</code></li>
</ul>
</section>
<section class="card">
<h3>最小业务数据来源</h3>
<ul class="list">
<li>报销至少有时间、地点、理由、金额、员工、部门、状态。</li>
<li>应收至少有客户、金额、未收金额、到期日、账龄、状态。</li>
<li>应付至少有供应商、金额、未付金额、到期日、账龄、状态。</li>
</ul>
</section>
<section class="card">
<h3>API 骨架</h3>
<ul class="list">
<li>资产列表 / 详情 / 版本 / 审核 / 上线。</li>
<li>运行日志与审计日志查询。</li>
<li>返回真实数据库结果,不用前端硬编码收尾。</li>
</ul>
</section>
<section class="card">
<h3>统一服务边界</h3>
<ul class="list">
<li>上线拦截逻辑在服务层,不堆到路由。</li>
<li>所有写操作要留审计接口。</li>
<li>任何 Agent 执行记录都必须生成 <code>run_id</code></li>
</ul>
</section>
</div>
<div class="section-kicker">Acceptance Snapshot</div>
<h2 class="section-title">验收快照</h2>
<div class="table-like">
<div class="row"><div class="row-label">资产模型</div><div class="row-value">已落地 3 条规则、2 条技能、2 条 MCP、3 条任务,并可通过资产接口返回。</div></div>
<div class="row"><div class="row-label">版本与审核</div><div class="row-value">三条规则都具备版本历史;同一资产版本号不可重复,未审核规则不能上线。</div></div>
<div class="row"><div class="row-label">运行与错误</div><div class="row-value">`GET /api/v1/agent-runs` 可返回 3 条运行日志,任意新建 Run 自动生成 <code>run_id</code></div></div>
<div class="row"><div class="row-label">最小业务表</div><div class="row-value">报销、应收、应付种子数据已就位,后续查询和风险巡检都有明确数据来源。</div></div>
</div>
<div class="section-kicker">Common Misses</div>
<h2 class="section-title">这一天最容易漏掉的点</h2>
<ul class="list">
<li>只建 Agent 表,不建最小财务业务表,导致 User Agent 和 Hermes 后面无数据可查。</li>
<li>把审核拦截塞在 API 路由里,后面很难复用到 Orchestrator 和别的入口。</li>
<li>没有统一 <code>run_id</code> 和审计接口Day 4 到 Day 7 的 Trace 会断链。</li>
</ul>
<div class="footer">Day 1 的判断标准很简单:不是“代码写了多少”,而是“后面 6 天会不会反复回头补地基”。</div>
</div>
</body>
</html>

View File

@@ -1,132 +0,0 @@
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Day 2 - 任务规则中心联调</title>
<link rel="stylesheet" href="./styles.css">
</head>
<body>
<div class="shell">
<div class="topbar">
<a class="brand" href="./index.html"><span class="brand-mark">D2</span><span>Day 2 View</span></a>
<div class="quick-links">
<a class="pill" href="./index.html">返回总览</a>
<a class="pill" href="../agent%20week%20plan/day_2_rule_center_integration.md">周计划原文</a>
<a class="pill" href="../agent%20week%20plan/day_2_rule_center_integration.md">合并文档原文</a>
</div>
</div>
<div class="day-nav">
<a class="pill" href="./day-1.html">Day 1</a>
<a class="pill active" href="./day-2.html">Day 2</a>
<a class="pill" href="./day-3.html">Day 3</a>
<a class="pill" href="./day-4.html">Day 4</a>
<a class="pill" href="./day-5.html">Day 5</a>
<a class="pill" href="./day-6.html">Day 6</a>
<a class="pill" href="./day-7.html">Day 7</a>
</div>
<section class="hero">
<div class="hero-badge">Integration</div>
<h1>Day 2 任务规则中心联调</h1>
<p>Day 2 的核心不是“把页面做漂亮”而是让规则、技能、MCP、任务这四类资产第一次脱离本地假数据真正连到 Day 1 的数据库和 API。最关键的能力是 Markdown、版本、审核和上线约束闭环。</p>
<div class="hero-meta">
<div class="meta-card"><div class="meta-label">上游依赖</div><div class="meta-value">Day 1 的资产模型、版本模型、审核模型、资产 API。</div></div>
<div class="meta-card"><div class="meta-label">下游交接</div><div class="meta-value">Day 3 要复用资产数据Day 4 要查询 active 技能 / MCP / 任务。</div></div>
<div class="meta-card"><div class="meta-label">当天关键</div><div class="meta-value">前端联调不是硬编码演示,而是可对接真实后端。</div></div>
</div>
</section>
<div class="section-kicker">Three-Layer Mapping</div>
<h2 class="section-title">三层文档映射</h2>
<div class="grid three">
<section class="card tone-warm">
<h3>路线图</h3>
<p>周计划要求把任务规则中心从静态 UI 升级到真实数据对接覆盖规则、技能、MCP、任务四类资产。</p>
<div class="card-links"><a class="link-chip" href="../agent%20week%20plan/day_2_rule_center_integration.md">day_2_rule_center_integration.md</a></div>
</section>
<section class="card tone-teal">
<h3>执行细则</h3>
<p>执行层拆成 API Client、四类列表、规则详情、Markdown 编辑、版本卡片、审核与上线、技能详情、MCP 详情、任务详情、前端质量和当天验收。</p>
<div class="card-links"><a class="link-chip" href="../agent%20week%20plan/day_2_rule_center_integration.md">agent week plan/day_2</a></div>
</section>
<section class="card tone-olive">
<h3>架构依据</h3>
<p>这一天主要受能力注册、规则形成生命周期和数据治理约束,重点在四类资产的统一展示方式和规则上线前审核拦截。</p>
<div class="card-links">
<a class="link-chip" href="../agent%20plan/07_capability_registry.md">07</a>
<a class="link-chip" href="../agent%20plan/13_rule_formation_lifecycle.md">13</a>
<a class="link-chip" href="../agent%20plan/06_data_contracts_and_governance.md">06</a>
</div>
</section>
</div>
<div class="section-kicker">Build Order</div>
<h2 class="section-title">推荐开发顺序</h2>
<div class="timeline">
<div class="timeline-step"><strong>Step 1</strong>先补 API Client列表、详情、版本、保存、审核、上线、运行日志。</div>
<div class="timeline-step"><strong>Step 2</strong>把四个页签的真实数据接起来,覆盖筛选、搜索、状态、空态和加载态。</div>
<div class="timeline-step"><strong>Step 3</strong>把规则详情的 Hero 区、Markdown 编辑器、版本卡片和审核信息拉通。</div>
<div class="timeline-step"><strong>Step 4</strong>补技能 / MCP / 任务的差异化详情,不复用规则编辑器。</div>
<div class="timeline-step"><strong>Step 5</strong>最后收 UI 细节、错误态、禁用态、确认弹窗和构建验证。</div>
</div>
<div class="section-kicker">Must Deliver</div>
<h2 class="section-title">今天必须产出的东西</h2>
<div class="grid two">
<section class="card">
<h3>规则中心四页签</h3>
<ul class="list">
<li>规则、技能、MCP、任务都能切换。</li>
<li>每个页签都来自真实接口,不再只读本地常量。</li>
<li>搜索和状态筛选同时生效。</li>
</ul>
</section>
<section class="card">
<h3>规则详情闭环</h3>
<ul class="list">
<li>能读取当前 Markdown。</li>
<li>能保存并刷新版本列表。</li>
<li>能展示审核者、审核状态、上线条件。</li>
</ul>
</section>
<section class="card">
<h3>版本与上线约束</h3>
<ul class="list">
<li>最近 5 个版本可见。</li>
<li>切换旧版本必须弹确认框。</li>
<li>未审核规则不能上线,拒绝原因要可见。</li>
</ul>
</section>
<section class="card">
<h3>详情差异化</h3>
<ul class="list">
<li>技能详情展示输入输出与依赖。</li>
<li>MCP 详情展示服务地址、鉴权、降级策略。</li>
<li>任务详情展示 cron、执行 Agent、最近执行结果。</li>
</ul>
</section>
</div>
<div class="section-kicker">Acceptance Snapshot</div>
<h2 class="section-title">验收快照</h2>
<div class="table-like">
<div class="row"><div class="row-label">真实数据</div><div class="row-value">四个页签都能用真实后端数据渲染,后端不可用时有明确错误提示。</div></div>
<div class="row"><div class="row-label">规则编辑</div><div class="row-value">Markdown 保存后刷新页面仍在,保存失败不丢输入。</div></div>
<div class="row"><div class="row-label">版本卡片</div><div class="row-value">最近 5 个版本可切换,当前版本标识清楚但不造成布局位移。</div></div>
<div class="row"><div class="row-label">审核上线</div><div class="row-value"><code>pending</code> / <code>rejected</code> 规则都无法上线,<code>approved</code> 才能放行。</div></div>
</div>
<div class="section-kicker">Common Misses</div>
<h2 class="section-title">这一天最容易漏掉的点</h2>
<ul class="list">
<li>只把规则页签接成真实数据技能、MCP、任务仍然靠假数据撑场面。</li>
<li>只做版本列表展示,不做确认弹窗和拒绝风险提示。</li>
<li>把任务写成“定时任务”暴露给用户,违背文档里 UI 名称统一成“任务”的约束。</li>
</ul>
<div class="footer">Day 2 的完成标准不是“页面能打开”,而是“规则中心第一次成为真实的资产入口”。</div>
</div>
</body>
</html>

View File

@@ -1,132 +0,0 @@
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Day 3 - 语义本体 MVP</title>
<link rel="stylesheet" href="./styles.css">
</head>
<body>
<div class="shell">
<div class="topbar">
<a class="brand" href="./index.html"><span class="brand-mark">D3</span><span>Day 3 View</span></a>
<div class="quick-links">
<a class="pill" href="./index.html">返回总览</a>
<a class="pill" href="../agent%20week%20plan/day_3_semantic_ontology_mvp.md">周计划原文</a>
<a class="pill" href="../agent%20week%20plan/day_3_semantic_ontology_mvp.md">合并文档原文</a>
</div>
</div>
<div class="day-nav">
<a class="pill" href="./day-1.html">Day 1</a>
<a class="pill" href="./day-2.html">Day 2</a>
<a class="pill active" href="./day-3.html">Day 3</a>
<a class="pill" href="./day-4.html">Day 4</a>
<a class="pill" href="./day-5.html">Day 5</a>
<a class="pill" href="./day-6.html">Day 6</a>
<a class="pill" href="./day-7.html">Day 7</a>
</div>
<section class="hero">
<div class="hero-badge">Ontology</div>
<h1>Day 3 语义本体 MVP</h1>
<p>这一天把自然语言问题统一切成 8 个核心字段。Day 3 不是追求大模型多聪明,而是先让结构稳定、可落日志、可被 Orchestrator、User Agent 和 Hermes 共用。</p>
<div class="hero-meta">
<div class="meta-card"><div class="meta-label">上游依赖</div><div class="meta-value">Day 1 的 <code>SemanticParseLog</code> / <code>AgentRun</code>Day 2 的资产 API。</div></div>
<div class="meta-card"><div class="meta-label">下游交接</div><div class="meta-value">Day 4 路由、Day 5 查询解释、Day 6 风险巡检都直接消费这 8 字段。</div></div>
<div class="meta-card"><div class="meta-label">当天关键</div><div class="meta-value">名字统一、类型统一、日志统一、低置信度有澄清问题。</div></div>
</div>
</section>
<div class="section-kicker">Three-Layer Mapping</div>
<h2 class="section-title">三层文档映射</h2>
<div class="grid three">
<section class="card tone-warm">
<h3>路线图</h3>
<p>周计划要求建立用户问题的统一语义解析层,覆盖场景、意图、对象、时间、指标、约束、风险、权限 8 字段。</p>
<div class="card-links"><a class="link-chip" href="../agent%20week%20plan/day_3_semantic_ontology_mvp.md">day_3_semantic_ontology_mvp.md</a></div>
</section>
<section class="card tone-teal">
<h3>执行细则</h3>
<p>执行层拆成 8 字段定义、字段枚举、Schema、解析服务、对象提取、时间范围、指标约束、风险权限、API、前端调试入口和评测集。</p>
<div class="card-links"><a class="link-chip" href="../agent%20week%20plan/day_3_semantic_ontology_mvp.md">agent week plan/day_3</a></div>
</section>
<section class="card tone-olive">
<h3>架构依据</h3>
<p>主要受语义本体、财务标准模型和数据治理约束。应收、应付、报销的对象语义必须能回到最小业务表和标准对象。</p>
<div class="card-links">
<a class="link-chip" href="../agent%20plan/02_semantic_ontology.md">02</a>
<a class="link-chip" href="../agent%20plan/14_financial_document_canonical_model.md">14</a>
<a class="link-chip" href="../agent%20plan/06_data_contracts_and_governance.md">06</a>
</div>
</section>
</div>
<div class="section-kicker">Build Order</div>
<h2 class="section-title">推荐开发顺序</h2>
<div class="timeline">
<div class="timeline-step"><strong>Step 1</strong>先固定 8 个字段名字、类型、默认值和示例。</div>
<div class="timeline-step"><strong>Step 2</strong><code>scenario</code><code>intent</code><code>permission.level</code> 的枚举定死。</div>
<div class="timeline-step"><strong>Step 3</strong>做请求/响应 Schema再写解析服务。</div>
<div class="timeline-step"><strong>Step 4</strong>补对象提取、时间范围、指标约束、风险和权限映射。</div>
<div class="timeline-step"><strong>Step 5</strong>接 API、日志、调试入口和最小评测集。</div>
</div>
<div class="section-kicker">Must Deliver</div>
<h2 class="section-title">今天必须产出的东西</h2>
<div class="grid two">
<section class="card">
<h3>8 字段统一结构</h3>
<ul class="list">
<li><code>scenario</code><code>intent</code><code>entities</code><code>time_range</code></li>
<li><code>metrics</code><code>constraints</code><code>risk_flags</code><code>permission</code></li>
<li>附带 <code>confidence</code><code>clarification_required</code><code>run_id</code></li>
</ul>
</section>
<section class="card">
<h3>规则解析优先版</h3>
<ul class="list">
<li>先用关键词和规则解析打底。</li>
<li>报销 / 应收 / 应付 / 知识 / unknown 场景都能落到结构。</li>
<li>越权动作能识别为 <code>approval_required</code><code>forbidden</code></li>
</ul>
</section>
<section class="card">
<h3>日志和调试入口</h3>
<ul class="list">
<li>每次解析都要落 <code>SemanticParseLog</code></li>
<li>前端可直接输入一句话看 8 字段结果。</li>
<li>低置信度问题必须给澄清问题。</li>
</ul>
</section>
<section class="card">
<h3>最小评测集</h3>
<ul class="list">
<li>至少覆盖报销、应收、应付、知识、越权动作。</li>
<li>每条样例要写期望 <code>scenario</code><code>intent</code> 和权限级别。</li>
<li>当天目标是可评测,而不是追求完美准确率。</li>
</ul>
</section>
</div>
<div class="section-kicker">Acceptance Snapshot</div>
<h2 class="section-title">验收快照</h2>
<div class="table-like">
<div class="row"><div class="row-label">语义结构</div><div class="row-value">8 字段在 Schema、服务层、日志里名字完全一致。</div></div>
<div class="row"><div class="row-label">关键识别</div><div class="row-value">“本周报销超标风险”“客户 A 本月应收”“供应商 B 明天要付多少钱”都能落到正确场景和意图。</div></div>
<div class="row"><div class="row-label">权限结果</div><div class="row-value">“帮我直接付款”不能被识别成可直接执行动作。</div></div>
<div class="row"><div class="row-label">日志与前端</div><div class="row-value">连续调用多次都能在日志中查到,并能通过调试入口观察结果。</div></div>
</div>
<div class="section-kicker">Common Misses</div>
<h2 class="section-title">这一天最容易漏掉的点</h2>
<ul class="list">
<li>字段结构和日志结构各写一套名字,后面 Trace 很难串。</li>
<li>只做 <code>scenario</code><code>intent</code>,不做 <code>permission</code>Day 4 会直接失去拦截依据。</li>
<li>只在服务里返回结果,不把解析过程落库或落日志,后续无法复盘误判样例。</li>
</ul>
<div class="footer">Day 3 的价值在于把“语义理解”从模糊文本变成稳定协议。后面所有智能能力都站在这层协议上。</div>
</div>
</body>
</html>

View File

@@ -1,133 +0,0 @@
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Day 4 - Orchestrator 运行时</title>
<link rel="stylesheet" href="./styles.css">
</head>
<body>
<div class="shell">
<div class="topbar">
<a class="brand" href="./index.html"><span class="brand-mark">D4</span><span>Day 4 View</span></a>
<div class="quick-links">
<a class="pill" href="./index.html">返回总览</a>
<a class="pill" href="../agent%20week%20plan/day_4_orchestrator_runtime.md">周计划原文</a>
<a class="pill" href="../agent%20week%20plan/day_4_orchestrator_runtime.md">合并文档原文</a>
</div>
</div>
<div class="day-nav">
<a class="pill" href="./day-1.html">Day 1</a>
<a class="pill" href="./day-2.html">Day 2</a>
<a class="pill" href="./day-3.html">Day 3</a>
<a class="pill active" href="./day-4.html">Day 4</a>
<a class="pill" href="./day-5.html">Day 5</a>
<a class="pill" href="./day-6.html">Day 6</a>
<a class="pill" href="./day-7.html">Day 7</a>
</div>
<section class="hero">
<div class="hero-badge">Runtime</div>
<h1>Day 4 Orchestrator 运行时</h1>
<p>Day 4 把整个系统第一次串成“能跑的链”。用户消息和定时任务都先走 Orchestrator由它创建 run、调用语义解析、做权限判断、选择 Agent、记录 ToolCall 和 Trace然后再给下游执行。</p>
<div class="hero-meta">
<div class="meta-card"><div class="meta-label">上游依赖</div><div class="meta-value">Day 3 的语义解析结果Day 1 的 Run / ToolCallDay 2 的 active 资产。</div></div>
<div class="meta-card"><div class="meta-label">下游交接</div><div class="meta-value">Day 5 User Agent 和 Day 6 Hermes 都通过它被调度。</div></div>
<div class="meta-card"><div class="meta-label">当天关键</div><div class="meta-value">权限拦截和 Trace 必须在 Orchestrator 层,而不是散落在各 Agent。</div></div>
</div>
</section>
<div class="section-kicker">Three-Layer Mapping</div>
<h2 class="section-title">三层文档映射</h2>
<div class="grid three">
<section class="card tone-warm">
<h3>路线图</h3>
<p>周计划要求建立统一调度层,让用户请求和系统任务都先进入 Orchestrator再根据语义、权限、能力注册路由到 User Agent、Hermes、MCP 或规则引擎。</p>
<div class="card-links"><a class="link-chip" href="../agent%20week%20plan/day_4_orchestrator_runtime.md">day_4_orchestrator_runtime.md</a></div>
</section>
<section class="card tone-teal">
<h3>执行细则</h3>
<p>执行层拆成输入输出、Orchestrator 服务、路由规则、权限判断、能力查询、工具调用封装、API、最小 Trace 查看和测试。</p>
<div class="card-links"><a class="link-chip" href="../agent%20week%20plan/day_4_orchestrator_runtime.md">agent week plan/day_4</a></div>
</section>
<section class="card tone-olive">
<h3>架构依据</h3>
<p>主要受运行时流程、能力注册、权限确认和可观测性约束。Day 4 的输出要能直接给前端展示,并支持 Day 5/6 的占位实现接入。</p>
<div class="card-links">
<a class="link-chip" href="../agent%20plan/04_orchestrator_and_runtime_flow.md">04</a>
<a class="link-chip" href="../agent%20plan/07_capability_registry.md">07</a>
<a class="link-chip" href="../agent%20plan/08_permission_confirmation.md">08</a>
<a class="link-chip" href="../agent%20plan/09_observability_and_trace.md">09</a>
</div>
</section>
</div>
<div class="section-kicker">Build Order</div>
<h2 class="section-title">推荐开发顺序</h2>
<div class="timeline">
<div class="timeline-step"><strong>Step 1</strong>先定 <code>OrchestratorRequest</code><code>OrchestratorResponse</code></div>
<div class="timeline-step"><strong>Step 2</strong><code>run(request)</code> 主流程:创建 Run、解析语义、判权限、选 Agent、更新状态。</div>
<div class="timeline-step"><strong>Step 3</strong>把用户入口 / 任务入口的路由规则固化下来。</div>
<div class="timeline-step"><strong>Step 4</strong>封装工具调用记录和降级策略。</div>
<div class="timeline-step"><strong>Step 5</strong>暴露 API 和最小 Trace 页面或接口。</div>
</div>
<div class="section-kicker">Must Deliver</div>
<h2 class="section-title">今天必须产出的东西</h2>
<div class="grid two">
<section class="card">
<h3>统一入口</h3>
<ul class="list">
<li><code>source=user_message</code><code>source=schedule</code> 都能进同一入口。</li>
<li>请求返回 <code>run_id</code><code>selected_agent</code><code>route_reason</code><code>permission_level</code></li>
<li>返回结果要能被前端直接展示。</li>
</ul>
</section>
<section class="card">
<h3>权限与路由</h3>
<ul class="list">
<li>查询类走 User Agent定时风险类走 Hermes。</li>
<li><code>approval_required</code> 只返回确认,不直接执行。</li>
<li><code>forbidden</code> 直接阻断,不调下游 Agent。</li>
</ul>
</section>
<section class="card">
<h3>能力与工具调用</h3>
<ul class="list">
<li>只查询 active 技能 / MCP / 任务。</li>
<li>禁用能力不允许被调用。</li>
<li>每次工具调用都能落 <code>AgentToolCall</code></li>
</ul>
</section>
<section class="card">
<h3>Trace 与降级</h3>
<ul class="list">
<li>Trace 能串起语义解析、路由、工具调用和最终结果。</li>
<li>外部 MCP 失败要返回降级说明,不让前端拿到不可读错误。</li>
<li>异常都要写进 <code>AgentRun.error_message</code></li>
</ul>
</section>
</div>
<div class="section-kicker">Acceptance Snapshot</div>
<h2 class="section-title">验收快照</h2>
<div class="table-like">
<div class="row"><div class="row-label">路由结果</div><div class="row-value">同一句风险检查,在用户入口和任务入口会有不同路由结果。</div></div>
<div class="row"><div class="row-label">权限边界</div><div class="row-value">“直接上线规则”和“直接付款”都不会被自动执行。</div></div>
<div class="row"><div class="row-label">日志完整度</div><div class="row-value">每次运行至少有一条 <code>AgentRun</code>,工具调用有 0 到多条 <code>AgentToolCall</code></div></div>
<div class="row"><div class="row-label">可观察性</div><div class="row-value">前端或 curl 可以完整看到一次运行链路,不需要直接查数据库猜过程。</div></div>
</div>
<div class="section-kicker">Common Misses</div>
<h2 class="section-title">这一天最容易漏掉的点</h2>
<ul class="list">
<li>把权限判断放到 User Agent / Hermes 内部,导致系统没有统一边界。</li>
<li>只记录成功 ToolCall不记录失败 ToolCall后面降级和排错会缺证据。</li>
<li>路由能跑,但没有统一 Trace 输出Day 7 演示时会非常难讲清链路。</li>
</ul>
<div class="footer">Day 4 的价值是把系统从“有很多零件”变成“有一条统一运行链”。</div>
</div>
</body>
</html>

View File

@@ -1,133 +0,0 @@
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Day 5 - User Agent MVP</title>
<link rel="stylesheet" href="./styles.css">
</head>
<body>
<div class="shell">
<div class="topbar">
<a class="brand" href="./index.html"><span class="brand-mark">D5</span><span>Day 5 View</span></a>
<div class="quick-links">
<a class="pill" href="./index.html">返回总览</a>
<a class="pill" href="../agent%20week%20plan/day_5_user_agent_mvp.md">周计划原文</a>
<a class="pill" href="../agent%20week%20plan/day_5_user_agent_mvp.md">合并文档原文</a>
</div>
</div>
<div class="day-nav">
<a class="pill" href="./day-1.html">Day 1</a>
<a class="pill" href="./day-2.html">Day 2</a>
<a class="pill" href="./day-3.html">Day 3</a>
<a class="pill" href="./day-4.html">Day 4</a>
<a class="pill active" href="./day-5.html">Day 5</a>
<a class="pill" href="./day-6.html">Day 6</a>
<a class="pill" href="./day-7.html">Day 7</a>
</div>
<section class="hero">
<div class="hero-badge">User Agent</div>
<h1>Day 5 User Agent MVP</h1>
<p>这一天开始让“用户真的能问问题”。但 User Agent 只负责查询、解释、规则引用和草稿生成,绝不绕过权限做审批、付款、上线这类高风险动作。</p>
<div class="hero-meta">
<div class="meta-card"><div class="meta-label">上游依赖</div><div class="meta-value">Day 4 Orchestrator、Day 3 语义结构、Day 1 业务数据与日志模型、Day 2 规则资产。</div></div>
<div class="meta-card"><div class="meta-label">下游交接</div><div class="meta-value">Day 7 要拿它做问答演示、规则解释演示和草稿生成演示。</div></div>
<div class="meta-card"><div class="meta-label">当天关键</div><div class="meta-value">回答可读、引用可追溯、草稿可确认、高风险不自动执行。</div></div>
</div>
</section>
<div class="section-kicker">Three-Layer Mapping</div>
<h2 class="section-title">三层文档映射</h2>
<div class="grid three">
<section class="card tone-warm">
<h3>路线图</h3>
<p>周计划要求做用户自然语言入口、报销 / 应收 / 应付查询解释、规则引用解释、建议草稿和前端入口。</p>
<div class="card-links"><a class="link-chip" href="../agent%20week%20plan/day_5_user_agent_mvp.md">day_5_user_agent_mvp.md</a></div>
</section>
<section class="card tone-teal">
<h3>执行细则</h3>
<p>执行层拆成输入输出、查询处理、规则解释、风险解释、草稿生成、知识库读取骨架、对话入口、安全边界和测试。</p>
<div class="card-links"><a class="link-chip" href="../agent%20week%20plan/day_5_user_agent_mvp.md">agent week plan/day_5</a></div>
</section>
<section class="card tone-olive">
<h3>架构依据</h3>
<p>主要受 Agent 职责划分、运行时流程、知识架构和规则形成生命周期约束。所有高风险动作只能停留在建议或草稿层。</p>
<div class="card-links">
<a class="link-chip" href="../agent%20plan/03_agent_responsibilities.md">03</a>
<a class="link-chip" href="../agent%20plan/04_orchestrator_and_runtime_flow.md">04</a>
<a class="link-chip" href="../agent%20plan/12_llm_wiki_knowledge_architecture.md">12</a>
<a class="link-chip" href="../agent%20plan/13_rule_formation_lifecycle.md">13</a>
</div>
</section>
</div>
<div class="section-kicker">Build Order</div>
<h2 class="section-title">推荐开发顺序</h2>
<div class="timeline">
<div class="timeline-step"><strong>Step 1</strong>先定 <code>UserAgentRequest</code> / <code>UserAgentResponse</code> 协议。</div>
<div class="timeline-step"><strong>Step 2</strong>优先实现报销、应收、应付查询处理器。</div>
<div class="timeline-step"><strong>Step 3</strong>补规则解释和风险解释,让回答有依据而不是只给一句话。</div>
<div class="timeline-step"><strong>Step 4</strong>补草稿生成与知识读取骨架。</div>
<div class="timeline-step"><strong>Step 5</strong>最后接前端问答入口、加载态、错误态和确认提示。</div>
</div>
<div class="section-kicker">Must Deliver</div>
<h2 class="section-title">今天必须产出的东西</h2>
<div class="grid two">
<section class="card">
<h3>三类财务查询</h3>
<ul class="list">
<li>报销查询可读,能查金额、状态或进度。</li>
<li>应收查询可读,能查客户未收金额或账龄。</li>
<li>应付查询可读,能查供应商待付款或付款状态。</li>
</ul>
</section>
<section class="card">
<h3>解释能力</h3>
<ul class="list">
<li>规则解释能引用 active 规则、版本号和更新时间。</li>
<li>风险解释能说明风险类型、原因和建议动作。</li>
<li>知识库不可用时要优雅降级。</li>
</ul>
</section>
<section class="card">
<h3>草稿而非执行</h3>
<ul class="list">
<li>可生成报销处理意见草稿、应收催收建议草稿、应付付款建议草稿。</li>
<li>草稿必须写明“待人工确认”。</li>
<li>草稿行为写入审计日志和 AgentRun 结果。</li>
</ul>
</section>
<section class="card">
<h3>用户入口</h3>
<ul class="list">
<li>前端输入框走 Orchestrator不绕行。</li>
<li>显示回答、引用、建议动作、确认提示和 <code>run_id</code></li>
<li>有加载态和错误态。</li>
</ul>
</section>
</div>
<div class="section-kicker">Acceptance Snapshot</div>
<h2 class="section-title">验收快照</h2>
<div class="table-like">
<div class="row"><div class="row-label">问答闭环</div><div class="row-value">用户在页面上能完成一次自然语言提问、拿到回答、看到引用和 run_id。</div></div>
<div class="row"><div class="row-label">三类场景</div><div class="row-value">至少报销、应收、应付三类财务问题都有结构化回答。</div></div>
<div class="row"><div class="row-label">引用能力</div><div class="row-value">“为什么这笔报销有风险”这类问题能引用规则,而不是只给模糊判断。</div></div>
<div class="row"><div class="row-label">安全边界</div><div class="row-value">“直接付款”“直接审批”类提示不会自动执行,只能变成建议或草稿。</div></div>
</div>
<div class="section-kicker">Common Misses</div>
<h2 class="section-title">这一天最容易漏掉的点</h2>
<ul class="list">
<li>只返回原始查询数据,不把结果翻译成用户可读回答。</li>
<li>只做草稿内容,不做 <code>requires_confirmation</code> 和审计日志。</li>
<li>绕过 Orchestrator 直接从前端打 User Agent导致 Day 4 的统一链路失效。</li>
</ul>
<div class="footer">Day 5 的判断标准是:用户能问、系统能答、回答有依据、动作不越权。</div>
</div>
</body>
</html>

View File

@@ -1,133 +0,0 @@
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Day 6 - Hermes MVP</title>
<link rel="stylesheet" href="./styles.css">
</head>
<body>
<div class="shell">
<div class="topbar">
<a class="brand" href="./index.html"><span class="brand-mark">D6</span><span>Day 6 View</span></a>
<div class="quick-links">
<a class="pill" href="./index.html">返回总览</a>
<a class="pill" href="../agent%20week%20plan/day_6_hermes_mvp.md">周计划原文</a>
<a class="pill" href="../agent%20week%20plan/day_6_hermes_mvp.md">合并文档原文</a>
</div>
</div>
<div class="day-nav">
<a class="pill" href="./day-1.html">Day 1</a>
<a class="pill" href="./day-2.html">Day 2</a>
<a class="pill" href="./day-3.html">Day 3</a>
<a class="pill" href="./day-4.html">Day 4</a>
<a class="pill" href="./day-5.html">Day 5</a>
<a class="pill active" href="./day-6.html">Day 6</a>
<a class="pill" href="./day-7.html">Day 7</a>
</div>
<section class="hero">
<div class="hero-badge">Hermes</div>
<h1>Day 6 Hermes MVP</h1>
<p>Hermes 是后台数字员工,不做即时对话,而是负责定时巡检、风险预警、日报统计、知识候选和规则草稿。它的关键不是“会不会说”,而是“任务能不能跑、结果能不能追”。</p>
<div class="hero-meta">
<div class="meta-card"><div class="meta-label">上游依赖</div><div class="meta-value">Day 4 的 Orchestrator 路由Day 1 的任务与日志表Day 3 的语义结构Day 5 可复用的风险/规则/知识接口。</div></div>
<div class="meta-card"><div class="meta-label">下游交接</div><div class="meta-value">Day 7 要用它做手动触发任务、查看结果、展示规则草稿和知识候选。</div></div>
<div class="meta-card"><div class="meta-label">当天关键</div><div class="meta-value">任务入口、风险项结构、OCR Mock、知识候选和规则草稿都必须可追溯。</div></div>
</div>
</section>
<div class="section-kicker">Three-Layer Mapping</div>
<h2 class="section-title">三层文档映射</h2>
<div class="grid three">
<section class="card tone-warm">
<h3>路线图</h3>
<p>周计划要求实现 Hermes 调度入口、每日风险巡检、统计任务、知识库维护、OCR Mock 和运行结果面板或 API。</p>
<div class="card-links"><a class="link-chip" href="../agent%20week%20plan/day_6_hermes_mvp.md">day_6_hermes_mvp.md</a></div>
</section>
<section class="card tone-teal">
<h3>执行细则</h3>
<p>执行层拆成输入输出、任务调度入口、风险巡检、每日统计、OCR 接入点、知识库维护、规则草稿形成、结果展示和测试。</p>
<div class="card-links"><a class="link-chip" href="../agent%20week%20plan/day_6_hermes_mvp.md">agent week plan/day_6</a></div>
</section>
<section class="card tone-olive">
<h3>架构依据</h3>
<p>主要受 Agent 职责、OCR 架构、知识库架构和反馈学习闭环约束。Hermes 能生成候选和草稿,但不能自动发布正式结果。</p>
<div class="card-links">
<a class="link-chip" href="../agent%20plan/03_agent_responsibilities.md">03</a>
<a class="link-chip" href="../agent%20plan/11_ocr_invoice_architecture.md">11</a>
<a class="link-chip" href="../agent%20plan/12_llm_wiki_knowledge_architecture.md">12</a>
<a class="link-chip" href="../agent%20plan/15_feedback_learning_loop.md">15</a>
</div>
</section>
</div>
<div class="section-kicker">Build Order</div>
<h2 class="section-title">推荐开发顺序</h2>
<div class="timeline">
<div class="timeline-step"><strong>Step 1</strong>先定 <code>HermesTaskRequest</code> / <code>HermesTaskResult</code></div>
<div class="timeline-step"><strong>Step 2</strong>建立手动触发任务 API经 Orchestrator 路由到 Hermes。</div>
<div class="timeline-step"><strong>Step 3</strong>补风险巡检和每日统计的结构化输出。</div>
<div class="timeline-step"><strong>Step 4</strong>接入 OCR Mock、知识候选生成、规则草稿生成。</div>
<div class="timeline-step"><strong>Step 5</strong>补任务详情展示、错误信息和测试。</div>
</div>
<div class="section-kicker">Must Deliver</div>
<h2 class="section-title">今天必须产出的东西</h2>
<div class="grid two">
<section class="card">
<h3>任务调度入口</h3>
<ul class="list">
<li>可手动触发至少一个任务资产。</li>
<li>任务经 Orchestrator 进入 Hermes。</li>
<li>结束后能更新最近执行时间和状态。</li>
</ul>
</section>
<section class="card">
<h3>风险与统计</h3>
<ul class="list">
<li>重复报销、金额超标、应收逾期、应付异常付款等风险有结构化输出。</li>
<li>日报包含报销、报账、应收、应付的关键统计口径。</li>
<li>每个风险项都要能被业务人员理解和追溯。</li>
</ul>
</section>
<section class="card">
<h3>知识候选与规则草稿</h3>
<ul class="list">
<li>知识候选默认是 <code>draft</code>,不能自动发布。</li>
<li>规则草稿保存为 <code>asset_type=rule</code>,状态为 <code>draft</code></li>
<li>两类生成都要写审计日志。</li>
</ul>
</section>
<section class="card">
<h3>OCR Mock 与结果展示</h3>
<ul class="list">
<li>OCR 服务接口和输入输出结构定下来。</li>
<li>当前阶段允许完全使用 Mock 结果。</li>
<li>任务详情或运行日志中能直接看到 Hermes 的执行结果。</li>
</ul>
</section>
</div>
<div class="section-kicker">Acceptance Snapshot</div>
<h2 class="section-title">验收快照</h2>
<div class="table-like">
<div class="row"><div class="row-label">任务可触发</div><div class="row-value">至少一个任务可以手动触发,并能查到结构化结果。</div></div>
<div class="row"><div class="row-label">风险巡检</div><div class="row-value">输出里能看到风险类型、业务对象、触发规则、建议动作和风险等级。</div></div>
<div class="row"><div class="row-label">候选与草稿</div><div class="row-value">知识候选和规则草稿都能生成,但都不是 active / published 正式状态。</div></div>
<div class="row"><div class="row-label">可观察性</div><div class="row-value">不用查数据库,也能从任务详情或运行日志判断 Hermes 是否执行成功。</div></div>
</div>
<div class="section-kicker">Common Misses</div>
<h2 class="section-title">这一天最容易漏掉的点</h2>
<ul class="list">
<li>只做 Hermes 服务逻辑,不做任务入口和结果展示,最后无法演示。</li>
<li>能生成知识或规则,但没把状态锁在 <code>draft</code>,会直接越过人工审核边界。</li>
<li>OCR Mock 只返回一段自由文本,不定义结构字段,后面无法和规则或风险逻辑对接。</li>
</ul>
<div class="footer">Day 6 的价值是让“后台数字员工”第一次具备可触发、可解释、可留痕的闭环。</div>
</div>
</body>
</html>

View File

@@ -1,132 +0,0 @@
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Day 7 - 加固、演示和验收</title>
<link rel="stylesheet" href="./styles.css">
</head>
<body>
<div class="shell">
<div class="topbar">
<a class="brand" href="./index.html"><span class="brand-mark">D7</span><span>Day 7 View</span></a>
<div class="quick-links">
<a class="pill" href="./index.html">返回总览</a>
<a class="pill" href="../agent%20week%20plan/day_7_hardening_demo_acceptance.md">周计划原文</a>
<a class="pill" href="../agent%20week%20plan/day_7_hardening_demo_acceptance.md">合并文档原文</a>
</div>
</div>
<div class="day-nav">
<a class="pill" href="./day-1.html">Day 1</a>
<a class="pill" href="./day-2.html">Day 2</a>
<a class="pill" href="./day-3.html">Day 3</a>
<a class="pill" href="./day-4.html">Day 4</a>
<a class="pill" href="./day-5.html">Day 5</a>
<a class="pill" href="./day-6.html">Day 6</a>
<a class="pill active" href="./day-7.html">Day 7</a>
</div>
<section class="hero">
<div class="hero-badge">Hardening</div>
<h1>Day 7 加固、演示和验收</h1>
<p>Day 7 不再追求新增大功能,而是把 Day 1 到 Day 6 的链路整理成“可演示、可验收、可继续接手”的状态。没有这一层收口,前面做出来的东西很容易停在“只有作者自己懂”的阶段。</p>
<div class="hero-meta">
<div class="meta-card"><div class="meta-label">上游依赖</div><div class="meta-value">Day 1 到 Day 6 的全部核心路径。</div></div>
<div class="meta-card"><div class="meta-label">当天输出</div><div class="meta-value">回归记录、权限边界、审计和 Trace 补齐、测试记录、演示脚本、交接说明。</div></div>
<div class="meta-card"><div class="meta-label">当天关键</div><div class="meta-value">冻结新增需求,只收验收相关缺口。</div></div>
</div>
</section>
<div class="section-kicker">Three-Layer Mapping</div>
<h2 class="section-title">三层文档映射</h2>
<div class="grid three">
<section class="card tone-warm">
<h3>路线图</h3>
<p>周计划要求完成回归、权限补齐、审计补齐、错误态和空态、评测、演示数据、构建和交付说明。</p>
<div class="card-links"><a class="link-chip" href="../agent%20week%20plan/day_7_hardening_demo_acceptance.md">day_7_hardening_demo_acceptance.md</a></div>
</section>
<section class="card tone-teal">
<h3>执行细则</h3>
<p>执行层拆成核心链路回归、权限和风险边界、审计和 Trace、前端体验修补、测试补齐、评测集、演示数据、演示脚本和文档收尾。</p>
<div class="card-links"><a class="link-chip" href="../agent%20week%20plan/day_7_hardening_demo_acceptance.md">agent week plan/day_7</a></div>
</section>
<section class="card tone-olive">
<h3>架构依据</h3>
<p>主要受整体 README、开发路线图、可观测性和评测集约束。Day 7 的本质是把所有边界和证据讲清楚。</p>
<div class="card-links">
<a class="link-chip" href="../agent%20plan/00_README.md">00</a>
<a class="link-chip" href="../agent%20plan/05_development_roadmap.md">05</a>
<a class="link-chip" href="../agent%20plan/09_observability_and_trace.md">09</a>
<a class="link-chip" href="../agent%20plan/10_evaluation_and_testset.md">10</a>
</div>
</section>
</div>
<div class="section-kicker">Build Order</div>
<h2 class="section-title">推荐收口顺序</h2>
<div class="timeline">
<div class="timeline-step"><strong>Step 1</strong>先汇总 Day 1 到 Day 6 未完成项,冻结新增需求。</div>
<div class="timeline-step"><strong>Step 2</strong>回归核心链路资产、规则、语义解析、Orchestrator、User Agent、Hermes、Trace、AuditLog。</div>
<div class="timeline-step"><strong>Step 3</strong>补权限边界与高风险动作拦截。</div>
<div class="timeline-step"><strong>Step 4</strong>补测试、评测、演示数据和前端体验问题。</div>
<div class="timeline-step"><strong>Step 5</strong>写演示脚本和交接说明,形成最终交付。</div>
</div>
<div class="section-kicker">Must Deliver</div>
<h2 class="section-title">今天必须产出的东西</h2>
<div class="grid two">
<section class="card">
<h3>回归与边界</h3>
<ul class="list">
<li>未审核规则不能上线。</li>
<li>付款、审批、上线等高风险动作都不能绕过确认。</li>
<li>disabled 能力不能被调用。</li>
</ul>
</section>
<section class="card">
<h3>审计与 Trace</h3>
<ul class="list">
<li>规则保存、审核、上线都能看到 AuditLog。</li>
<li>Hermes 生成知识候选 / 规则草稿有审计。</li>
<li>任意演示路径都能追到 <code>run_id</code></li>
</ul>
</section>
<section class="card">
<h3>测试、评测、演示数据</h3>
<ul class="list">
<li>后端测试、前端构建、语义评测至少有执行记录。</li>
<li>报销 / 应收 / 应付 / 风险 / 知识都准备好演示数据。</li>
<li>失败样例和已知边界要明确写出。</li>
</ul>
</section>
<section class="card">
<h3>演示脚本与交接</h3>
<ul class="list">
<li>从任务规则中心、规则详情、版本切换、上线拦截,到 User Agent 问答、Hermes 任务、Trace 和审计,都有明确步骤。</li>
<li>新开发者按脚本能走通一遍。</li>
</ul>
</section>
</div>
<div class="section-kicker">Acceptance Snapshot</div>
<h2 class="section-title">最终验收快照</h2>
<div class="table-like">
<div class="row"><div class="row-label">端到端链路</div><div class="row-value">从规则中心到 User Agent再到 Hermes 和 Trace至少有一条完整演示路径可复现。</div></div>
<div class="row"><div class="row-label">证据完整</div><div class="row-value">AgentRun、ToolCall、AuditLog、测试记录、评测结果和演示脚本都存在。</div></div>
<div class="row"><div class="row-label">风险边界</div><div class="row-value">MVP 期间不存在绕过人工审核、自动付款、自动上线的暗门路径。</div></div>
<div class="row"><div class="row-label">可交接性</div><div class="row-value">下一位开发或 Codex 打开文档就能知道已完成、未完成和生产化前必补项。</div></div>
</div>
<div class="section-kicker">Common Misses</div>
<h2 class="section-title">这一天最容易漏掉的点</h2>
<ul class="list">
<li>只验证 Happy Path不回归错误态、空态、禁用态和被权限拦截路径。</li>
<li>能讲演示,但没有测试记录和已知风险说明,交接质量会很差。</li>
<li>前 6 天的 TODO 没回写完成状态,导致页面和 Markdown 脱节。</li>
</ul>
<div class="footer">Day 7 的目标不是继续堆功能,而是把一周产出变成别人也能运行、理解和接手的系统。</div>
</div>
</body>
</html>

View File

@@ -1,181 +0,0 @@
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Agent Week Plan HTML</title>
<link rel="stylesheet" href="./styles.css">
</head>
<body>
<div class="shell">
<div class="topbar">
<a class="brand" href="./index.html">
<span class="brand-mark">A7</span>
<span>Agent Week HTML</span>
</a>
<div class="quick-links">
<a class="pill" href="../agent%20week%20plan/MASTER_TODO.md">周计划总控</a>
<a class="pill" href="../agent%20week%20plan/00_README.md">周计划说明</a>
<a class="pill" href="../agent%20plan/00_README.md">架构目录</a>
</div>
</div>
<section class="hero">
<div class="hero-badge">Static Map</div>
<h1>把 7 天周计划变成可直接浏览的开发视图</h1>
<p>这一套 HTML 页面不是替代 Markdown而是把 <code>agent week plan</code><code>agent plan</code> 的对应关系收成一个稳定入口。每天的路线图和执行清单现在已经并到同一份 daily 文档里。</p>
<div class="hero-meta">
<div class="meta-card">
<div class="meta-label">阅读顺序</div>
<div class="meta-value">先总览,再选 Day再跳转到具体 Markdown 落地执行。</div>
</div>
<div class="meta-card">
<div class="meta-label">核心视图</div>
<div class="meta-value">路线图、执行细则、架构依据三层同时可见。</div>
</div>
<div class="meta-card">
<div class="meta-label">适用对象</div>
<div class="meta-value">Codex 开发、后端开发、前端开发、项目 owner、验收人员。</div>
</div>
</div>
</section>
<div class="section-kicker">How To Use</div>
<h2 class="section-title">怎么用这套页面</h2>
<div class="grid two">
<section class="card tone-teal">
<h3>Codex 开发视角</h3>
<ol class="list">
<li>先看今天在哪一天,确认上游依赖和下游交接。</li>
<li>用“两层映射”定位daily 文档看目标和步骤,架构文档看约束。</li>
<li>按“推荐开发顺序”推进,不跳天,不跨层乱做。</li>
<li>完成后回到原始 Markdown把 TODO、阻塞、交接更新回文档。</li>
</ol>
</section>
<section class="card tone-warm">
<h3>人工开发与验收视角</h3>
<ol class="list">
<li>先看每一天的“今日定位”,知道这一天到底产出什么。</li>
<li>再看“今天必须产出的东西”和“验收快照”,确认完成标准。</li>
<li>最后跳转到对应 Markdown逐条执行或验收。</li>
<li>如果发现跨天阻塞,优先回前一天补地基,而不是在当前天临时兜底。</li>
</ol>
</section>
</div>
<div class="section-kicker">Three Layers</div>
<h2 class="section-title">文档结构一眼看清</h2>
<div class="grid three">
<section class="card">
<h3>1. 周计划路线图</h3>
<p>定义每天的大方向、交付物和验收门槛。用于排期、对齐和验收。核心入口是 <code>MASTER_TODO.md</code> 和 Day 1 到 Day 7 daily 文档。</p>
<div class="card-links">
<a class="link-chip" href="../agent%20week%20plan/00_README.md">00_README</a>
<a class="link-chip" href="../agent%20week%20plan/MASTER_TODO.md">MASTER_TODO</a>
</div>
</section>
<section class="card">
<h3>2. 每日执行清单</h3>
<p>每天的开发目标已经拆到对应 daily 文档中的详细执行清单,直接覆盖模型、字段、接口、服务、前端、测试和验收证据。</p>
<div class="card-links">
<a class="link-chip" href="../agent%20week%20plan/00_README.md">00_README</a>
<a class="link-chip" href="../agent%20week%20plan/MASTER_TODO.md">MASTER_TODO</a>
</div>
</section>
<section class="card">
<h3>3. 架构依据</h3>
<p>提供为什么要这么做、协议怎么定、权限和审计边界是什么。它不直接当 TODO但所有实现都要受它约束。</p>
<div class="card-links">
<a class="link-chip" href="../agent%20plan/01_overall_architecture.md">总体架构</a>
<a class="link-chip" href="../agent%20plan/02_semantic_ontology.md">语义本体</a>
<a class="link-chip" href="../agent%20plan/09_observability_and_trace.md">观测与 Trace</a>
</div>
</section>
</div>
<div class="section-kicker">Seven Days</div>
<h2 class="section-title">7 天总览</h2>
<div class="grid two">
<section class="card tone-olive">
<h3>Day 1 基础模型与工程骨架</h3>
<p><strong>当前状态:</strong>已完成2026-05-11。先把 Agent 资产、版本、审核、运行日志、审计日志,以及报销 / 应收 / 应付的最小业务数据来源定下来。后面所有能力都站在这一天的模型上。</p>
<div class="card-links">
<a class="link-chip" href="./day-1.html">打开日视图</a>
<a class="link-chip" href="../agent%20week%20plan/day_1_foundation_models.md">周计划</a>
<a class="link-chip" href="../agent%20week%20plan/day_1_foundation_models.md">合并文档</a>
</div>
</section>
<section class="card tone-teal">
<h3>Day 2 任务规则中心联调</h3>
<p>把规则、技能、MCP、任务从静态 UI 拉到真实后端数据。重点是规则 Markdown、版本切换、审核和上线拦截。</p>
<div class="card-links">
<a class="link-chip" href="./day-2.html">打开日视图</a>
<a class="link-chip" href="../agent%20week%20plan/day_2_rule_center_integration.md">周计划</a>
<a class="link-chip" href="../agent%20week%20plan/day_2_rule_center_integration.md">合并文档</a>
</div>
</section>
<section class="card tone-warm">
<h3>Day 3 语义本体 MVP</h3>
<p>建立 8 字段语义解析协议,让报销、应收、应付、知识查询进入同一结构,给 Orchestrator、User Agent、Hermes 统一消费。</p>
<div class="card-links">
<a class="link-chip" href="./day-3.html">打开日视图</a>
<a class="link-chip" href="../agent%20week%20plan/day_3_semantic_ontology_mvp.md">周计划</a>
<a class="link-chip" href="../agent%20week%20plan/day_3_semantic_ontology_mvp.md">合并文档</a>
</div>
</section>
<section class="card">
<h3>Day 4 Orchestrator 运行时</h3>
<p>把用户消息和定时任务统一接到 Orchestrator完成 run_id、权限拦截、Agent 路由、ToolCall 和 Trace。</p>
<div class="card-links">
<a class="link-chip" href="./day-4.html">打开日视图</a>
<a class="link-chip" href="../agent%20week%20plan/day_4_orchestrator_runtime.md">周计划</a>
<a class="link-chip" href="../agent%20week%20plan/day_4_orchestrator_runtime.md">合并文档</a>
</div>
</section>
<section class="card tone-teal">
<h3>Day 5 User Agent MVP</h3>
<p>面向用户的问答和流程辅助层。做查询、解释、规则引用、草稿生成,但严格不碰自动审批、自动付款和自动上线。</p>
<div class="card-links">
<a class="link-chip" href="./day-5.html">打开日视图</a>
<a class="link-chip" href="../agent%20week%20plan/day_5_user_agent_mvp.md">周计划</a>
<a class="link-chip" href="../agent%20week%20plan/day_5_user_agent_mvp.md">合并文档</a>
</div>
</section>
<section class="card tone-olive">
<h3>Day 6 Hermes MVP</h3>
<p>后台数字员工层。做任务触发、风险巡检、日报统计、OCR Mock、知识候选、规则草稿结果都必须可追溯。</p>
<div class="card-links">
<a class="link-chip" href="./day-6.html">打开日视图</a>
<a class="link-chip" href="../agent%20week%20plan/day_6_hermes_mvp.md">周计划</a>
<a class="link-chip" href="../agent%20week%20plan/day_6_hermes_mvp.md">合并文档</a>
</div>
</section>
<section class="card tone-accent">
<h3>Day 7 加固、演示和验收</h3>
<p>不再大扩功能只做回归、权限边界、审计、Trace、测试、演示脚本和交接收口让整周产出可跑、可演示、可继续接手。</p>
<div class="card-links">
<a class="link-chip" href="./day-7.html">打开日视图</a>
<a class="link-chip" href="../agent%20week%20plan/day_7_hardening_demo_acceptance.md">周计划</a>
<a class="link-chip" href="../agent%20week%20plan/day_7_hardening_demo_acceptance.md">合并文档</a>
</div>
</section>
</div>
<div class="section-kicker">Dependency Chain</div>
<h2 class="section-title">跨天依赖链</h2>
<div class="timeline">
<div class="timeline-step"><strong>Day 1</strong>模型、审计、运行日志、最小业务数据源</div>
<div class="timeline-step"><strong>Day 2</strong>把 Day 1 的资产 API 接进规则中心 UI</div>
<div class="timeline-step"><strong>Day 3</strong>在 Day 1/2 基础上产出统一语义结构</div>
<div class="timeline-step"><strong>Day 4</strong>用 Day 3 的语义结果完成路由与权限</div>
<div class="timeline-step"><strong>Day 5</strong>接入 User Agent 问答、解释和草稿</div>
<div class="timeline-step"><strong>Day 6</strong>接入 Hermes 任务、巡检和知识/规则候选</div>
<div class="timeline-step"><strong>Day 7</strong>统一回归、补日志、做演示和交接</div>
</div>
<div class="footer">
打开顺序建议:<a href="./day-1.html">Day 1</a><a href="./day-7.html">Day 7</a>。真正执行时,仍以原始 Markdown 为准,这套 HTML 负责加速定位和浏览。
</div>
</div>
</body>
</html>

View File

@@ -1,426 +0,0 @@
:root {
--bg: #f3ead9;
--bg-deep: #e7d8bc;
--panel: rgba(255, 250, 241, 0.9);
--panel-strong: #fff8ee;
--ink: #1f2a24;
--muted: #64655d;
--line: #dbc8a9;
--accent: #bb5b2c;
--accent-strong: #8d3d1b;
--accent-soft: #f4d9bf;
--teal: #20656d;
--teal-soft: #d8ecee;
--olive: #5f6b3a;
--olive-soft: #e6ecd7;
--shadow: 0 24px 60px rgba(84, 59, 30, 0.12);
--radius-xl: 28px;
--radius-lg: 20px;
--radius-md: 14px;
--max: 1240px;
}
* {
box-sizing: border-box;
}
html {
scroll-behavior: smooth;
}
body {
margin: 0;
font-family: "Trebuchet MS", "Gill Sans", "Lucida Grande", sans-serif;
color: var(--ink);
background:
radial-gradient(circle at top left, rgba(32, 101, 109, 0.14), transparent 26%),
radial-gradient(circle at top right, rgba(187, 91, 44, 0.15), transparent 30%),
linear-gradient(180deg, #f8f0e2 0%, var(--bg) 40%, #efe2cb 100%);
}
a {
color: inherit;
}
.shell {
width: min(100% - 40px, var(--max));
margin: 0 auto;
padding: 28px 0 56px;
}
.topbar {
display: flex;
align-items: center;
justify-content: space-between;
gap: 16px;
flex-wrap: wrap;
margin-bottom: 18px;
}
.brand {
display: inline-flex;
align-items: center;
gap: 12px;
text-decoration: none;
font-weight: 700;
letter-spacing: 0.04em;
text-transform: uppercase;
color: var(--accent-strong);
}
.brand-mark {
display: inline-flex;
align-items: center;
justify-content: center;
width: 42px;
height: 42px;
border-radius: 50%;
background: linear-gradient(135deg, var(--accent), #df9a44);
color: #fff7ef;
box-shadow: 0 14px 30px rgba(187, 91, 44, 0.28);
}
.quick-links,
.day-nav {
display: flex;
flex-wrap: wrap;
gap: 10px;
}
.pill {
display: inline-flex;
align-items: center;
justify-content: center;
min-height: 38px;
padding: 10px 14px;
border-radius: 999px;
border: 1px solid rgba(143, 114, 74, 0.22);
background: rgba(255, 248, 238, 0.75);
text-decoration: none;
color: var(--muted);
font-size: 14px;
transition: transform 180ms ease, border-color 180ms ease, background 180ms ease;
}
.pill:hover,
.pill:focus-visible {
transform: translateY(-1px);
border-color: rgba(187, 91, 44, 0.4);
background: rgba(255, 251, 245, 0.96);
outline: none;
}
.pill.active {
color: #fff6ef;
border-color: transparent;
background: linear-gradient(135deg, var(--accent-strong), var(--accent));
box-shadow: 0 14px 24px rgba(141, 61, 27, 0.24);
}
.hero {
position: relative;
overflow: hidden;
margin-bottom: 22px;
padding: 30px;
border: 1px solid rgba(128, 109, 82, 0.18);
border-radius: var(--radius-xl);
background:
linear-gradient(135deg, rgba(255, 248, 238, 0.95), rgba(247, 236, 216, 0.88)),
var(--panel);
box-shadow: var(--shadow);
}
.hero::after {
content: "";
position: absolute;
right: -50px;
top: -50px;
width: 220px;
height: 220px;
border-radius: 50%;
background: radial-gradient(circle, rgba(32, 101, 109, 0.16), transparent 68%);
}
.hero-badge {
display: inline-flex;
align-items: center;
gap: 8px;
margin-bottom: 12px;
padding: 7px 12px;
border-radius: 999px;
background: var(--accent-soft);
color: var(--accent-strong);
font-size: 13px;
font-weight: 700;
letter-spacing: 0.05em;
text-transform: uppercase;
}
.hero h1 {
margin: 0;
font-family: "Iowan Old Style", "Palatino Linotype", "Book Antiqua", serif;
font-size: clamp(34px, 5vw, 62px);
line-height: 1.03;
}
.hero p {
max-width: 880px;
margin: 14px 0 0;
color: var(--muted);
font-size: 18px;
line-height: 1.65;
}
.hero-meta {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
gap: 14px;
margin-top: 20px;
}
.meta-card {
padding: 14px 16px;
border-radius: var(--radius-md);
background: rgba(255, 255, 255, 0.55);
border: 1px solid rgba(132, 109, 83, 0.16);
}
.meta-label {
margin-bottom: 6px;
color: var(--muted);
font-size: 12px;
font-weight: 700;
letter-spacing: 0.08em;
text-transform: uppercase;
}
.meta-value {
font-size: 16px;
line-height: 1.45;
}
.grid {
display: grid;
gap: 18px;
}
.grid.two {
grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
}
.grid.three {
grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
}
.card {
padding: 22px;
border: 1px solid rgba(132, 109, 83, 0.15);
border-radius: var(--radius-lg);
background: var(--panel);
box-shadow: 0 16px 36px rgba(78, 58, 32, 0.08);
animation: rise 420ms ease both;
}
.card:nth-child(2) { animation-delay: 60ms; }
.card:nth-child(3) { animation-delay: 120ms; }
.card:nth-child(4) { animation-delay: 180ms; }
.card:nth-child(5) { animation-delay: 240ms; }
.card h2,
.card h3 {
margin: 0 0 10px;
font-family: "Iowan Old Style", "Palatino Linotype", "Book Antiqua", serif;
}
.card h2 {
font-size: 28px;
}
.card h3 {
font-size: 22px;
}
.card p {
margin: 0;
color: var(--muted);
line-height: 1.7;
}
.section-title {
margin: 28px 0 14px;
font-family: "Iowan Old Style", "Palatino Linotype", "Book Antiqua", serif;
font-size: 28px;
}
.section-kicker {
margin: 30px 0 8px;
color: var(--accent-strong);
font-size: 13px;
font-weight: 700;
letter-spacing: 0.08em;
text-transform: uppercase;
}
.list,
.compact-list {
margin: 12px 0 0;
padding-left: 18px;
color: var(--ink);
line-height: 1.72;
}
.compact-list {
font-size: 15px;
}
.list li + li,
.compact-list li + li {
margin-top: 8px;
}
.card-links {
display: flex;
flex-wrap: wrap;
gap: 10px;
margin-top: 16px;
}
.link-chip {
display: inline-flex;
align-items: center;
gap: 8px;
padding: 10px 13px;
border-radius: 999px;
background: rgba(255, 255, 255, 0.76);
border: 1px solid rgba(132, 109, 83, 0.18);
text-decoration: none;
font-size: 14px;
}
.tone-warm {
background: linear-gradient(180deg, rgba(244, 217, 191, 0.55), rgba(255, 250, 241, 0.9));
}
.tone-teal {
background: linear-gradient(180deg, rgba(216, 236, 238, 0.76), rgba(255, 250, 241, 0.92));
}
.tone-olive {
background: linear-gradient(180deg, rgba(230, 236, 215, 0.82), rgba(255, 250, 241, 0.92));
}
.tone-accent {
background: linear-gradient(160deg, rgba(141, 61, 27, 0.94), rgba(187, 91, 44, 0.92));
color: #fff8f1;
}
.tone-accent p,
.tone-accent .meta-label,
.tone-accent .meta-value,
.tone-accent li {
color: rgba(255, 248, 241, 0.92);
}
.tone-accent .link-chip,
.tone-accent .pill {
background: rgba(255, 255, 255, 0.14);
border-color: rgba(255, 255, 255, 0.18);
color: #fff8f1;
}
.timeline {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
gap: 12px;
}
.timeline-step {
position: relative;
padding: 16px;
border-radius: var(--radius-md);
border: 1px solid rgba(132, 109, 83, 0.16);
background: rgba(255, 252, 247, 0.84);
}
.timeline-step strong {
display: block;
margin-bottom: 8px;
font-size: 15px;
}
.footer {
margin-top: 26px;
padding: 20px 4px 0;
color: var(--muted);
font-size: 14px;
}
.muted {
color: var(--muted);
}
.table-like {
display: grid;
gap: 12px;
}
.row {
display: grid;
grid-template-columns: minmax(120px, 0.9fr) minmax(0, 2.3fr);
gap: 14px;
padding: 14px 16px;
border-radius: var(--radius-md);
border: 1px solid rgba(132, 109, 83, 0.15);
background: rgba(255, 255, 255, 0.56);
}
.row-label {
font-size: 13px;
font-weight: 700;
letter-spacing: 0.06em;
text-transform: uppercase;
color: var(--accent-strong);
}
.row-value {
line-height: 1.68;
}
code {
padding: 1px 6px;
border-radius: 8px;
background: rgba(32, 101, 109, 0.08);
color: var(--teal);
font-family: "Lucida Console", "Courier New", monospace;
font-size: 0.92em;
}
@keyframes rise {
from {
opacity: 0;
transform: translateY(10px);
}
to {
opacity: 1;
transform: translateY(0);
}
}
@media (max-width: 760px) {
.shell {
width: min(100% - 24px, var(--max));
padding-top: 18px;
}
.hero {
padding: 22px;
}
.hero p {
font-size: 16px;
}
.row {
grid-template-columns: 1fr;
}
}

View File

@@ -1,44 +0,0 @@
# Backend API Swagger 文档
本目录用于沉淀后端接口的 Swagger / OpenAPI 产物,给开发、联调和后续 Agent 接口调用统一对照。
## 目录说明
- `openapi.json`
- 由 FastAPI `app.openapi()` 导出的完整 OpenAPI 规范。
- `interface_inventory.md`
- 基于 OpenAPI 自动整理的接口清单,按 tag 分组查看方法、路径和摘要。
## 在线入口
- Swagger UI`/docs`
- ReDoc`/redoc`
- OpenAPI JSON`/openapi.json`
如果本地默认端口不变,完整地址通常是:
- `http://127.0.0.1:8000/docs`
- `http://127.0.0.1:8000/redoc`
- `http://127.0.0.1:8000/openapi.json`
## 重新生成
`/app/server` 下执行:
```bash
PYTHONPATH=/app/server/src /app/server/.venv/bin/python /app/server/scripts/export_openapi.py
```
## 当前约定
- 全部业务接口前缀:`/api/v1`
- 知识库接口使用请求头模拟登录用户:
- `X-Auth-Username`
- `X-Auth-Name`
- `X-Auth-Role-Codes`
- `X-Auth-Is-Admin`
- Agent 资产写接口支持审计头:
- `X-Actor`
- `X-Request-Id`
- Hermes 运行时模型接口使用:
- `Authorization: Bearer <HERMES_AGENT_SHARED_TOKEN>`

View File

@@ -1,100 +0,0 @@
# Backend API Interface Inventory
- Generated at: `2026-05-11 04:14:05 UTC`
- API title: `X-Financial`
- API version: `0.1.0`
- Total paths: `28`
## Tag Overview
### agent-assets
| Method | Path | Summary |
| --- | --- | --- |
| `GET` | `/api/v1/agent-assets` | 查询 Agent 资产列表 |
| `POST` | `/api/v1/agent-assets` | 创建 Agent 资产 |
| `GET` | `/api/v1/agent-assets/{asset_id}` | 读取 Agent 资产详情 |
| `PATCH` | `/api/v1/agent-assets/{asset_id}` | 更新 Agent 资产 |
| `POST` | `/api/v1/agent-assets/{asset_id}/activate` | 激活资产当前版本 |
| `POST` | `/api/v1/agent-assets/{asset_id}/reviews` | 创建资产审核记录 |
| `GET` | `/api/v1/agent-assets/{asset_id}/versions` | 查询资产版本列表 |
| `POST` | `/api/v1/agent-assets/{asset_id}/versions` | 创建资产版本 |
### agent-runs
| Method | Path | Summary |
| --- | --- | --- |
| `GET` | `/api/v1/agent-runs` | 查询 Agent 运行日志 |
| `GET` | `/api/v1/agent-runs/{run_id}` | 读取单次 Agent 运行详情 |
### audit-logs
| Method | Path | Summary |
| --- | --- | --- |
| `GET` | `/api/v1/audit-logs` | 查询审计日志 |
### auth
| Method | Path | Summary |
| --- | --- | --- |
| `POST` | `/api/v1/auth/login` | 用户登录 |
### bootstrap
| Method | Path | Summary |
| --- | --- | --- |
| `GET` | `/api/v1/bootstrap` | 读取初始化状态 |
| `POST` | `/api/v1/bootstrap` | 写入初始化配置 |
### employees
| Method | Path | Summary |
| --- | --- | --- |
| `GET` | `/api/v1/employees` | 查询员工列表 |
| `POST` | `/api/v1/employees` | 创建员工 |
| `GET` | `/api/v1/employees/meta` | 读取员工目录元数据 |
| `GET` | `/api/v1/employees/{employee_id}` | 读取员工详情 |
| `PATCH` | `/api/v1/employees/{employee_id}` | 更新员工 |
| `POST` | `/api/v1/employees/{employee_id}/disable` | 停用员工 |
### health
| Method | Path | Summary |
| --- | --- | --- |
| `GET` | `/api/v1/health` | 服务健康检查 |
### knowledge
| Method | Path | Summary |
| --- | --- | --- |
| `POST` | `/api/v1/knowledge/documents` | 上传知识库文档 |
| `DELETE` | `/api/v1/knowledge/documents/{document_id}` | 删除知识库文档 |
| `GET` | `/api/v1/knowledge/documents/{document_id}` | 读取知识库文档详情 |
| `GET` | `/api/v1/knowledge/documents/{document_id}/content` | 下载或预览知识库原文 |
| `GET` | `/api/v1/knowledge/documents/{document_id}/onlyoffice-config` | 读取 ONLYOFFICE 预览配置 |
| `POST` | `/api/v1/knowledge/documents/{document_id}/onlyoffice/callback` | 接收 ONLYOFFICE 回调 |
| `GET` | `/api/v1/knowledge/documents/{document_id}/onlyoffice/content` | 读取 ONLYOFFICE 文档源文件 |
| `GET` | `/api/v1/knowledge/library` | 查询知识库目录 |
### reimbursements
| Method | Path | Summary |
| --- | --- | --- |
| `GET` | `/api/v1/reimbursements` | 查询报销申请列表 |
| `POST` | `/api/v1/reimbursements` | 创建报销申请 |
| `GET` | `/api/v1/reimbursements/{request_id}` | 读取报销申请详情 |
### root
| Method | Path | Summary |
| --- | --- | --- |
| `GET` | `/` | 服务根检查 |
### settings
| Method | Path | Summary |
| --- | --- | --- |
| `GET` | `/api/v1/settings` | 读取系统设置 |
| `PUT` | `/api/v1/settings` | 保存系统设置 |
| `POST` | `/api/v1/settings/model-connectivity` | 测试模型连通性 |
| `GET` | `/api/v1/settings/runtime-models/{slot}` | 读取 Hermes 运行时模型配置 |

File diff suppressed because it is too large Load Diff

View File

@@ -1,56 +0,0 @@
# Knowledge Answers TODO
更新时间2026-05-16
目标:
- 让知识库问答的主路径从“LightRAG 检索 + 慢模型二次整理”改为“结构化证据优先 + 模型可选总结”。
- 让问答能力尽量依赖当前文档内容本身,而不是依赖某一份制度、某一个城市或某一种表格写法。
- 参考 Yuxi 的优点,优先补齐 `统一解析思路 + 文档类型友好的结构增强 + 检索后原文证据回退`,不照搬其完整平台基础设施。
Yuxi 调研结论:
- [x] 已完成 Yuxi 调研与方案提炼
备注Yuxi 的通用性主要来自三层:统一文档解析、可切换的 chunk/preset、检索不足时回到解析后 Markdown 继续取证;并不是靠给某个文档写死回答逻辑。
本轮改造原则:
- [x] 先撤掉文档特化硬编码,再补通用结构能力。
- [x] 真实答案只能来自当前命中文档的内容,代码里不固化制度金额、地区档位或条款结论。
- [x] 即使问题不是表格表达,也要能基于章节、条款、列表、键值对、上下文段落给出可读答案。
- [x] 模型只负责“压缩表达”,不负责“凭空补事实”;模型超时时也必须能返回像样的证据型答复。
实施清单:
- [x] 移除当前临时文档特化 fast path
备注:删除当前围绕差旅表格、城市档位、职级档位的临时规则,避免系统继续向单文档 hardcode 演化。
- [x] 入库增强:补通用结构附录
备注:参考 Yuxi 的解析/分块思想,在现有入库文本增强中补充章节、条款、列表、键值对、表格与上下文邻接信息,让非表格关系也能被稳定命中。
- [x] 检索后增强:生成面向回答的证据片段
备注:从命中的 hits 中再次抽取更短、更结构化的 answer evidence优先保留标题路径、条款句、列表项、表格行和与 query 强相关的上下文窗口。
- [x] 回答链路重构:证据驱动直答
备注:新增通用知识问答直答器,先根据 answer evidence 生成可直接展示的短答案;只有在证据不足或问题需要更自然表达时才调用模型。
- [x] 模型总结收口:缩小上下文面,保留原文约束
备注:把传给模型的上下文从“整段命中 chunk”收缩到“高置信 answer evidence”既降延迟也降低答非所问和错列风险。
- [x] 降级回答升级:从“命中摘抄”改成“证据摘要”
备注:即使模型超时或失败,也要返回按证据组织好的结论、依据和缺失信息,而不是大段原文拼贴。
- [x] 测试补齐
备注:覆盖非表格制度文本、表格文本、列表/键值对文本、模型超时降级、去除硬编码路径等关键回归点。
- [x] 真实验证与回填 TODO
备注:已重建当前知识库索引并完成真实验证。当前“回答整理”阶段已降到亚秒级,但 LightRAG 首次/冷启动检索仍受 embedding 与 rerank 耗时影响,后续如要继续压缩总耗时,应进一步优化检索参数与模型链路。
验收标准:
- [x] 常规知识问答不再长时间卡在“正在整理答案”。
- [x] 文档不是表格表达时,仍能基于章节/条款/列表/上下文回答。
- [x] 文档内容变动后,不需要改业务代码里的制度结论或金额常量。
- [x] 模型超时时仍能返回结构清楚、证据明确的答案。
- [x] 相关测试通过,且没有破坏现有知识库问答流程。
验证记录:
- [x] 单测通过:`test_user_agent_service.py``test_knowledge_normalizer.py``test_knowledge_rag_service.py` 共 35 项全部通过。
- [x] 当前知识库文档已按新规则 `force` 重建索引成功。
- [x] 真实问答抽检:`餐补标准是什么?``费用发生后多久内提交报销申请?``前往北京出差的报销标准是什么?`
备注:回答生成阶段约 `0.24s ~ 0.30s`;其中“前往北京出差”问题会明确提示当前证据未直接给出“北京”地区档位映射,不再硬猜。

View File

@@ -1,139 +0,0 @@
# 差旅报销风险管控标准(模拟版)
## 1. 目的
本标准用于约束个人报销中的差旅类单据审核,覆盖以下三类核心风险:
- 行程闭环风险:出发地、目的地、返程地之间是否形成合理链路。
- 票据地点一致性风险:酒店、交通票据与申报目的地是否一致。
- 差标超限风险:员工职级对应的交通舱位、火车席别、住宿金额是否超标。
本标准先以模拟规则落地到系统,用于 AI 验审与直属领导审批前的自动筛查。
## 2. 适用范围
- 报销主类型为 `travel / hotel / transport` 的单据。
- 或者明细附件识别出 `flight_itinerary / train_ticket / hotel_invoice / taxi_receipt / parking_toll_receipt` 的单据。
## 3. 基础定义
### 3.1 目的地
按以下优先级确定本次差旅的“主目的地”:
1. 用户在报销表单中填写的业务地点 `claim.location`
2. 长途交通票据终点城市
3. 酒店票据识别出的酒店所在城市
### 3.2 行程闭环
满足以下任一条件,视为形成合理闭环:
- 单程票据终点与申报目的地一致。
- 多段票据按时间顺序首尾衔接。
- 最后一段票据返回首段出发城市。
### 3.3 合理例外说明
若出现多城市出差、中转、改签、异地返程、展会高峰导致超标等情况,用户必须在报销事由或费用说明中体现原因。示例关键词:
- `中转`
- `转机`
- `经停`
- `改签`
- `多地出差`
- `客户临时变更`
- `展会高峰`
- `协议酒店满房`
- `无直达`
未说明时,系统按高风险处理并退回待补充。
## 4. 风险规则矩阵
### 4.1 行程闭环规则
- 若存在两段及以上长途交通票据,相邻两段的 `上一段终点城市``下一段起点城市` 必须一致。
- 若最终到达城市既不是申报目的地,也不是首段出发城市,则判定为高风险。
- 若识别到多个目的地城市,但事由中未说明多地出差、中转或改签原因,则判定为高风险。
处理方式:
- `高风险`:退回待补充。
- `中风险`:允许流转,但要求直属领导重点复核。
### 4.2 酒店地点一致性规则
- 酒店票据识别出的城市,必须属于以下集合之一:
- 申报目的地
- 长途交通票据中的目的地城市
- 长途交通票据中的返程前停留城市
- 若酒店城市与主目的地、交通链路均不一致,则判定为高风险。
处理方式:
- `高风险`:退回待补充,要求说明异地住宿原因或更换票据。
### 4.3 职级差旅标准
#### 4.3.1 城市分级
- 一线:`北京 / 上海 / 广州 / 深圳`
- 新一线 / 重点城市:`杭州 / 南京 / 苏州 / 武汉 / 成都 / 重庆 / 西安 / 天津 / 宁波 / 厦门 / 青岛 / 长沙`
- 其他城市:除以上外的默认城市
#### 4.3.2 住宿标准(元 / 晚)
| 职级带 | 一线 | 重点城市 | 其他城市 |
| --- | ---: | ---: | ---: |
| P1-P3 | 450 | 380 | 320 |
| P4-P5 | 550 | 480 | 380 |
| P6-P7 | 700 | 620 | 520 |
| M1-M2 | 900 | 820 | 720 |
| M3 及以上 / D 序列 | 1200 | 1000 | 900 |
说明:
- 若票据中能识别出 `X 晚 / X 间夜`,系统按 `总金额 / 间夜数` 计算每晚金额。
- 若无法识别间夜数,默认按 1 晚处理。
#### 4.3.3 交通标准
| 职级带 | 飞机 | 火车 / 高铁 |
| --- | --- | --- |
| P1-P3 | 经济舱 | 二等座 / 硬卧 |
| P4-P5 | 经济舱 | 二等座 / 硬卧 |
| P6-P7 | 超级经济舱及以下 | 一等座 / 软卧及以下 |
| M1-M2 | 商务舱及以下 | 商务座及以下 |
| M3 及以上 / D 序列 | 不做系统硬限制,仍保留人工复核 |
### 4.4 差标超限处理
- 超住宿标准且无说明:`高风险`
- 超住宿标准但有说明:`中风险`
- 飞机舱位或高铁席别超过职级标准且无说明:`高风险`
- 飞机舱位或高铁席别超过职级标准但有说明:`中风险`
## 5. 系统落地口径
### 5.1 票据识别字段
系统优先使用以下字段做判断:
- `route`
- `merchant_name`
- `amount`
- `date`
- OCR 原文中的舱位、席别、间夜数、城市名
### 5.2 AI 验审动作
- 高风险:提交前拦截,状态切回 `待补充`
- 中风险:允许进入直属领导审批,并附带风险标记
- 低风险 / 通过:正常流转
## 6. 当前实现边界
- 城市识别先按常见出差城市做匹配,未覆盖全国全部区县。
- 住宿标准与交通标准为模拟版,可后续迁移到任务规则中心做可配置化。
- 本文档为当前开发阶段的执行依据,后续若规则中心启用动态配置,应以规则中心版本为准。

View File

@@ -1,453 +0,0 @@
# 规则版本中心 UI 方案
## 1. 背景
当前“任务规则中心 > 财务规则 > 公司差旅费报销规则”已经具备:
- 在线 Excel 编辑
- 工作版本 / 线上版本分离
- 最近 5 个版本展示
- 审核、上线、恢复能力
但页面仍然存在一个明显问题:
**版本治理能力已经有了,用户却很难第一眼看见。**
当前版本列表更像“历史记录”,不是一个明确的“版本操作中心”。
用户无法快速判断:
1. 当前真正生效的是哪个版本
2. 当前正在编辑的是哪个版本
3. 从哪里进入版本切换
4. 从哪里发起版本对比
5. 某个版本经历了哪些流转动作
因此,需要把现有“版本列表”升级为一个真正可用的 **版本中心**
---
## 2. 设计目标
### 2.1 用户一眼能看懂
进入规则详情页后,用户无需点击就能立即识别:
- 当前线上版本
- 当前工作版本
- 是否存在未上线工作稿
- 最近版本是否处于待审 / 已通过 / 已驳回状态
### 2.2 关键操作显性化
以下操作不能再隐藏在不明显的位置:
- 切换查看版本
- 与线上版本对比
- 查看完整流转
- 从历史版本恢复
### 2.3 保持 OnlyOffice 是主角
该页面的核心仍然是 Excel 规则表。
版本中心必须增强治理能力,但不能把主表格压缩成附属内容。
---
## 3. 推荐方案
采用:
> **左侧 OnlyOffice 主工作区 + 右侧版本中心 + 顶部显性入口 + 抽屉式详情**
这是比“单独开二级页签”更适合当前页面的方案,因为用户经常需要:
- 一边看表
- 一边知道自己看的是什么版本
- 一边进入版本对比或恢复
---
## 4. 页面整体布局
```text
┌────────────────────────────────────────────────────────────────────┐
│ 标题区:公司差旅费报销规则 │
│ 线上版本 v1.0.5 已上线 工作版本 v1.0.6 待审核 │
│ [下载 Excel] [上传表格] [版本对比] [查看流转] │
├───────────────────────────────────────────────┬────────────────────┤
│ │ 版本中心 │
│ │ │
│ │ ┌──────────────┐ │
│ │ │ 线上版本 │ │
│ │ │ v1.0.5 │ │
│ │ └──────────────┘ │
│ OnlyOffice │ ┌──────────────┐ │
│ 规则表主工作区 │ │ 工作版本 │ │
│ │ │ v1.0.6 │ │
│ │ └──────────────┘ │
│ │ │
│ │ 最近版本 │
│ │ v1.0.6 待审核 │
│ │ v1.0.5 已上线 │
│ │ v1.0.4 历史版本 │
│ │ │
│ │ 最近流转 │
│ │ [查看完整流转] │
└───────────────────────────────────────────────┴────────────────────┘
```
---
## 5. 顶部操作区设计
顶部必须保留并强化四个动作:
| 按钮 | 用途 |
| --- | --- |
| 下载 Excel | 下载当前预览版本 |
| 上传表格 | 导入内容生成新工作稿 |
| 版本对比 | 打开对比抽屉 |
| 查看流转 | 打开流转抽屉 |
### 5.1 版本对比按钮
这是一级入口,不能只藏在版本列表里。
默认行为:
- 基准版本:当前线上版本
- 对比版本:当前工作版本
如果两者相同,则按钮仍可用,但进入后提示:
> 当前工作版本与线上版本一致,可选择其他历史版本进行比较。
### 5.2 查看流转按钮
用于进入当前规则的完整生命周期视图。
不应只展示审计日志,而要展示“版本业务履历”。
---
## 6. 右侧版本中心设计
### 6.1 顶部双版本卡片
```text
线上版本
v1.0.5
已上线
工作版本
v1.0.6
待审核
```
#### 设计目的
用户进入页面后,最先要知道的是:
- **谁在线上**
- **谁正在被编辑**
而不是先看一个无上下文的历史列表。
### 6.2 最近版本列表
每个版本项包含:
- 版本号
- 生命周期状态
- 创建时间
- 变更说明
- 操作入口
建议样式:
```text
v1.0.6 待审核
2026-05-18 09:12
补充出差补助标准
[查看] [与线上比]
v1.0.5 已上线
2026-05-18 08:40
新增补助页签
[查看]
v1.0.4 历史版本
2026-05-17 17:20
修正住宿标准
[查看] [恢复]
```
#### 规则
- `查看`:切换当前预览版本
- `与线上比`:直接以线上版本为基准进入对比
- `恢复`:仅高级管理人员可见
- 当前 `working_version` 不显示“恢复”
### 6.3 最近流转摘要
右侧版本中心底部展示最近 3 条流转:
```text
最近流转
09:12 曹笑竹 保存工作稿
09:25 曹笑竹 提交审核
10:08 顾承宇 审核通过
[查看完整流转]
```
---
## 7. 版本流转时间线设计
## 7.1 入口
两个入口:
1. 顶部 `查看流转`
2. 右侧版本中心底部 `查看完整流转`
## 7.2 容器
使用右侧宽抽屉,不使用小弹窗。
原因:
- 时间线内容会逐步增长
- 审核意见需要足够宽度展示
- 后续可能接入版本说明、操作人、来源版本
## 7.3 时间线内容
时间线按时间倒序或正序展示,推荐默认正序:
```text
● 2026-05-18 09:12
v1.0.6 工作稿创建
曹笑竹 保存工作稿
变更说明:补充出差补助标准
● 2026-05-18 09:25
提交审核
曹笑竹 提交当前工作版本
● 2026-05-18 10:08
审核通过
顾承宇:口径已核对,可上线
○ 待正式上线
```
如果版本来自恢复:
```text
● 基于 v1.0.3 恢复生成 v1.0.7
```
## 7.4 时间线事件类型
| 事件类型 | 说明 |
| --- | --- |
| `created` | 创建版本 |
| `submitted` | 提交审核 |
| `approved` | 审核通过 |
| `rejected` | 驳回 |
| `published` | 正式上线 |
| `restored` | 基于历史版本恢复 |
---
## 8. 版本差异对比设计
## 8.1 入口
版本对比必须有两个入口:
1. 顶部一级按钮:`版本对比`
2. 每个历史版本行内操作:`与线上比`
这样既满足“主动进入”,也满足“看到某个版本就顺手比较”。
## 8.2 容器
使用宽抽屉,推荐宽度:
- 桌面:页面宽度的 70% ~ 80%
- 小屏:全屏
不建议用普通弹窗,因为:
- Excel 差异需要足够展示宽度
- 版本选择器、摘要、表格都要共存
## 8.3 顶部区域
```text
版本对比
基准版本 [v1.0.5 已上线 ▼]
对比版本 [v1.0.6 待审核 ▼]
```
默认值:
- `baseVersion = published_version`
- `targetVersion = working_version`
## 8.4 差异摘要
优先先给决策信息,再给底层明细。
```text
差异摘要
- 修改 2 个工作表
- 新增 1 个工作表
- 修改 12 个单元格
- 删除 2 行
```
如果无差异:
```text
两个版本内容一致,没有发现表格差异。
```
## 8.5 差异详情
第一阶段优先支持 Excel 规则表:
| 工作表 | 位置 | 旧值 | 新值 | 类型 |
| --- | --- | --- | --- | --- |
| 出差补助标准 | B4 | 75 | 90 | 修改 |
| 差旅住宿费标准 | A106 | - | 新增城市 | 新增 |
后续可扩展:
- 仅看新增
- 仅看删除
- 仅看数值变化
- 按工作表筛选
## 8.6 对比结果的业务语气
不要把页面做成“程序员 diff 工具”。
它应该像制度审核页面:
- 先讲影响
- 再讲位置
- 最后给证据
---
## 9. 数据接口设计
## 9.1 时间线接口
建议新增:
```http
GET /agent-assets/{asset_id}/version-timeline
```
返回:
- 版本号
- 事件类型
- 操作人
- 操作时间
- 审核意见
- 来源版本(如有)
## 9.2 对比接口
建议新增:
```http
GET /agent-assets/{asset_id}/versions/compare?base_version=v1.0.5&target_version=v1.0.6
```
返回:
- 基准版本
- 对比版本
- 工作表差异摘要
- 单元格级差异明细
---
## 10. 视觉规范
### 10.1 颜色
沿用当前系统已有色彩,不引入新风格:
| 状态 | 建议色 |
| --- | --- |
| 已上线 | 绿色 |
| 工作稿 | 蓝色 |
| 待审核 | 橙色 |
| 已驳回 | 红色 |
| 历史版本 | 灰色 |
### 10.2 密度
- 右侧版本中心应为紧凑型信息面板
- 不要使用过大的卡片间距
- 不能明显压缩 OnlyOffice 主区域
### 10.3 交互反馈
- 可点击元素必须有 hover
- 当前预览版本必须有 active 高亮
- 抽屉打开后保留明确关闭按钮
- 恢复操作必须二次确认
---
## 11. 推荐实施顺序
### 第一阶段
1. 顶部新增 `版本对比``查看流转`
2. Excel 详情页改成:
- 左侧 OnlyOffice
- 右侧版本中心
3. 右侧展示:
- 线上版本
- 工作版本
- 最近 5 个版本
- 最近 3 条流转
### 第二阶段
1. 实现版本流转抽屉
2. 实现版本对比抽屉
3. 补齐真实后端接口
### 第三阶段
1. 增加更细的工作表筛选
2. 增加更多 diff 维度
3. 增加版本差异导出能力
---
## 12. 本次开发目标
本次开发直接完成以下内容:
1. 规则详情页出现明确的版本中心
2. 页面上出现明确的:
- `版本对比`
- `查看流转`
3. 最近版本列表增加:
- `查看`
- `与线上比`
- `恢复为工作稿`
4. 版本流转抽屉可用
5. 版本对比抽屉可用
6. 对比结果至少支持 Excel 表格的:
- 工作表新增 / 删除
- 单元格新增 / 删除 / 修改

View File

@@ -1,237 +0,0 @@
# 规则版本治理方案
## 1. 背景
当前“任务规则中心”的规则资产只有一个 `current_version` 指针。
它同时承担了三种含义:
1. 财务人员正在编辑的版本
2. 审核中的候选版本
3. 系统运行时真正生效的线上版本
这会直接带来三个问题:
- 财务人员一旦修改 Excel最新内容就会立刻成为 `current_version`,容易被误解为已经正式生效
- 审核、上线、回滚都围绕同一个指针转,权限边界不清晰
- 如果误上线,虽然能切换历史版本,但缺少“线上版本”和“工作版本”分离后的安全缓冲
## 2. 设计目标
这次改造要解决的不是“多存几个历史版本”,而是建立一套可长期使用的规则治理机制:
1. 财务人员可以编辑规则,但编辑结果默认只是草稿
2. 只有高级管理人员审核通过后,规则才能成为正式线上版本
3. 系统运行时只能读取正式线上版本,不能读取草稿
4. 前台要能清楚区分:
- 当前线上版本
- 当前工作版本
- 最近 5 个历史版本
5. 如果误操作上线,可以快速恢复,但恢复动作仍然要留下完整审计链
## 3. 核心模型
### 3.1 双指针版本模型
在规则资产上新增两个版本指针:
| 字段 | 含义 |
| --- | --- |
| `published_version` | 当前正式在线上生效的版本 |
| `working_version` | 当前最新的工作稿 / 待审稿 |
兼容策略:
- 现有 `current_version` 暂时保留,用于兼容历史代码
- 对规则资产来说,后续它只承担“当前工作版本”的兼容语义
- 运行时逻辑不再读取 `current_version`,而是优先读取 `published_version`
### 3.2 版本状态
不额外在版本表中硬存一套容易失真的状态,而是根据“版本指针 + 最新审核记录”动态推导:
| 条件 | 版本状态 |
| --- | --- |
| `version == published_version` | 已上线 |
| `version == working_version` 且无审核记录 | 草稿 |
| `version == working_version` 且最新审核为 `pending` | 待审核 |
| `version == working_version` 且最新审核为 `approved` | 已通过待上线 |
| `version == working_version` 且最新审核为 `rejected` | 已驳回 |
| 其他历史版本 | 历史版本 |
这样可以避免“版本状态”和“审核记录”两套数据互相打架。
## 4. 权限边界
| 角色 | 能力 |
| --- | --- |
| 财务人员 `finance` | 编辑工作稿、上传/导入 Excel、提交审核 |
| 高级管理人员 `manager` / `admin` | 审核通过、驳回、正式发布、恢复历史版本 |
| 其他普通员工 | 只读 |
### 4.1 财务人员
- 可以直接编辑当前 `working_version`
- 每次保存自动生成新版本,并把它设为新的 `working_version`
- 不能把草稿直接变成 `published_version`
### 4.2 高级管理人员
- 可以对 `working_version` 发起:
- 审核通过
- 驳回
- 正式发布
- 只有 `approved` 的工作版本才能发布
## 5. 发布与回滚流程
### 5.1 正常发布
1. 财务人员编辑并保存
2. 系统生成新版本,例如 `v1.0.6`
3. `working_version = v1.0.6`
4. 财务人员提交审核
5. 高级管理人员审核通过
6. 高级管理人员点击“正式上线”
7. `published_version = v1.0.6`
8. 系统运行时切换到新版本
### 5.2 驳回
1. 财务人员提交审核
2. 高级管理人员驳回
3. 当前工作版本保留,但状态显示为“已驳回”
4. 财务人员继续编辑,形成新的工作版本
### 5.3 恢复历史版本
不直接把 `published_version` 指回旧版本,而是采用“复制恢复”的方式:
1. 管理员在最近 5 个版本中选择一个历史版本
2. 系统基于该历史版本内容生成一个新的恢复版本,例如 `v1.0.7`
3. 新版本写入 `working_version`
4. 审核通过后再正式发布
这么做的好处:
- 不会破坏历史链路
- 每一次恢复都有明确的责任人与时间
- 既能快速回滚,又保留审计闭环
## 6. 版本保留策略
### 6.1 前台展示
- 详情页固定展示最近 5 个版本
- 每个版本显示:
- 版本号
- 状态
- 创建人
- 创建时间
- 变更说明
### 6.2 后台保存
后台不能机械地“只保留 5 个版本”,否则可能把关键线上版本挤掉。
建议策略:
1. 始终保留当前 `published_version`
2. 始终保留当前 `working_version`
3. 额外保留最近 5 个历史版本
这样既满足前台简洁,也能避免误删关键版本。
## 7. 前端交互
### 7.1 规则详情页顶部
展示两个醒目的版本标签:
- 当前线上版本
- 当前工作版本
如果两者不同,需要明确提示:
> 当前存在尚未上线的工作稿,系统运行仍以线上版本为准。
### 7.2 编辑区
- 财务人员看到“可编辑工作稿”
- 普通用户只读
- 管理员可编辑,但主要职责仍是审核与发布
### 7.3 版本区
最近 5 个版本中每条都显示状态:
- 已上线
- 草稿
- 待审核
- 已通过待上线
- 已驳回
- 历史版本
可执行操作:
- 查看
- 基于该版本恢复
- 对当前工作版本提交审核 / 审核 / 发布
## 8. 后端改造清单
1. `agent_assets`
- 新增 `published_version`
- 新增 `working_version`
2. 兼容旧数据
- 历史规则资产初始化时:
- `published_version = current_version`
- `working_version = current_version`
3. 版本保存
- 保存新版本后:
- 只更新 `working_version`
- `current_version` 同步为 `working_version` 以兼容旧逻辑
4. 审核
- 审核只针对 `working_version`
5. 发布
- 只允许把已审核通过的 `working_version` 推到 `published_version`
6. 运行时
- 只读取 `published_version`
7. 回滚
- 新增“基于历史版本恢复为新工作稿”的接口
## 9. 前端改造清单
1. 资产详情模型增加:
- `publishedVersion`
- `workingVersion`
- 每个历史版本的派生状态
2. 规则详情页展示:
- 当前线上版本
- 当前工作版本
- 最近 5 个版本
3. 操作权限拆分:
- finance编辑、上传、提交审核
- manager/admin审核、上线、恢复
4. OnlyOffice 编辑逻辑:
- 默认编辑工作版本
- 历史版本只读
5. 正式上线按钮:
- 只有工作版本已审核通过时可用
## 10. 本次实现边界
本轮优先完成以下能力:
1. 规则版本双指针
2. 财务角色可编辑工作稿
3. 正式上线只切换 `published_version`
4. 运行时只读取 `published_version`
5. 最近 5 个版本展示
6. 基于历史版本快速恢复为新工作稿
后续如需要,再继续补:
- 版本差异对比
- 审核意见流转面板
- 发布说明 / 审批单号
- 定时生效

View File

@@ -0,0 +1,3 @@
user1: caoxiaozhu@xf.com / 123456
User2: xiangwanhong@xf.com / 123456
Admin: admin/ admin

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 183 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 266 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 206 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 209 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 172 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 138 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 135 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 149 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 153 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 150 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 296 KiB

View File

@@ -1,18 +0,0 @@
# Work Log - 2026-05-06
## 今日工作
### 下午
- **修复了 Windows Git Bash 启动脚本报错问题**
- 问题:虚拟环境指向不存在的 python3
- 解决:添加检测函数,无效则重建
- **创建了 work-log 技能**
- 自动记录工作日志
---
# 待处理
- [ ] 安装 PostgreSQL
- [ ] 创建 x_financial 数据库

View File

@@ -1,36 +0,0 @@
# Work Log - 2026-05-07
## 今日工作
- **提交 c00db75** (11:50)
- feat: add employee management, backend health check, and UI improvements
- 完成了员工管理模块(后端 + 前端)
- 添加了后端健康检查
- 整理了 UI 资源
- **提交 2d56bc2** (13:48)
- feat: enhance employee CRUD with search, filters, and security module
- 增强了员工搜索和筛选功能
- 添加了安全模块security.py
- 添加了单元测试
- **提交 b8ba0ea** (14:32)
- feat: add auth module with login and access control
- 为系统实现了完整的登录认证功能
- 后端使用 FastAPI 搭建了 auth 服务,支持管理员密钥验证
- 前端对接了登录接口,实现了 Token 存储和自动登录逻辑
- 设计并实现了基于角色的访问控制RBAC区分超级管理员和普通员工
- **提交 e8f3d97** (15:18)
- feat: add settings page with navigation and access control updates
- 搭建了系统设置页面,支持管理员配置系统参数
- 优化了侧边栏导航交互,增加了收起/展开的流畅动画
- 将访问控制规则统一收敛到 accessControl.js避免散落各处
- 统一了 useSystemState 和 useNavigation 两个 composable 的职责
---
# 待处理
- [ ] 安装 PostgreSQL
- [ ] 创建 x_financial 数据库

View File

@@ -1,30 +0,0 @@
# Work Log - 2026-05-08
## 今日工作
- **提交 adda87a** (08:56)
- feat: add system settings with model connectivity and encrypted storage
- 为系统设置页面新增了配置管理功能,支持管理员修改 AI 模型连接参数
- 引入加密存储方案secret_box.py对敏感配置如 API Key使用对称加密保护
- 后端新增 settings 端点、repository 层和 service 层,实现配置的增删改查
- 新增 model_connectivity.py 服务,支持测试 AI 模型连接是否正常
- 前端设置页面大幅重构,增加了模型配置表单和连接测试功能
- 新增数据库表 system_setting 和 system_setting_secret 存储配置和加密值
- 编写了 settings 相关的单元测试,确保配置持久化和服务逻辑正确
- **提交 c5486dd** (10:52)
- feat: 启用后端自动启动与 Setup 引导流程增强
- 启用了后端自动启动功能,用户访问前端时后端自动拉起,无需手动启动 server
- 增强了 Setup 引导流程,新增后端启动进度追踪,分 5 步展示config → deps → server → health → done
- 网络绑定从 127.0.0.1 扩展到 0.0.0.0,支持远程浏览器访问部署的系統
- API URL 动态化,通过 localStorage 持久化配置,支持运行时修改
- 新增后端启动探针probe自动检测后端就绪状态后才允许浏览器继续操作
- Setup 表单智能判断浏览器 host将本地地址自动转换为 0.0.0.0 供远程访问
- **提交 8656866** (11:14)
- feat: 重构模型配置存储与 API Key 加密管理
- 新增 SystemModelSetting 模型slot 为 PK支持 main/backup/vlm/embedding 四个模型槽位配置
- 废弃旧的加密存储方案,改用更规范的数据库表存储加密的 API Key
- 兼容旧版 admin secret 格式,将历史密码记录迁移到标准 scrypt 哈希格式
- 前端 API URL 智能解析,当后端配置为回环地址但浏览器非回环时,自动使用浏览器 host 访问
- 改进 API Key 输入体验,聚焦时自动清除遮罩显示,并提示已从数据库加载密钥

Some files were not shown because too many files have changed in this diff Show More