# AtlasSplit **Repository Path**: rainyjensen/AtlasSplit ## Basic Information - **Project Name**: AtlasSplit - **Description**: 输入 Excel/CSV + 需求描述,自动完成统计、分摊、校验并写回结果。 - **Primary Language**: Unknown - **License**: AGPL-3.0 - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2025-09-26 - **Last Updated**: 2026-09-01 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # 天衡 · AtlasSplit — 可审计表格分摊 Agent [English](README.en.md) | 简体中文 > 自然语言需求 → Pydantic 结构化计划 → 人工预览审批 → 无模型凭据的确定性执行 → 哈希与审批日志审计。 AtlasSplit 面向财务和业务表格分摊场景。LangChain 只负责把自然语言转换为受约束的分摊计划;真正的 Excel/CSV 处理由确定性执行器完成,默认先预览、不直接写文件。 ## 核心亮点 - **计划与执行分离**:LLM 不生成需要直接执行的业务代码,只生成经过 Pydantic 校验的等额或权重分摊计划。 - **显式审批**:`plan` 保存不可变计划文件,`approve-plan` 只执行用户已经查看过的同一份计划。 - **防止计划漂移**:审批时重新校验计划 SHA-256 和源文件 SHA-256,源数据被替换后拒绝执行。 - **隔离执行**:确定性执行器运行在无模型凭据的限时子进程中。 - **结果可恢复**:结果原子写入;目标文件已存在时先保存时间戳备份。 - **全链路审计**:预览、审批、完成或失败事件追加写入 `runs/approvals.jsonl`。 - **自动化质量门禁**:当前测试套件包含 50 项测试,并由 Gitee Go 执行 pytest 与 Ruff。 ## 架构 ```text 自然语言任务 + Excel/CSV │ ▼ LangChain 结构化规划器 │ AllocationPlan ▼ Pydantic 字段与操作白名单校验 │ ▼ 影响预览 + 不可变计划文件 │ 用户显式审批 ▼ 无模型凭据的限时子进程 │ ▼ 确定性 pandas/openpyxl 执行与合计校验 │ ├── outputs/result.xlsx ├── outputs/backups/ └── runs/approvals.jsonl ``` ## 快速开始 ### 1. 创建环境并安装 ```powershell python -m venv .venv .\.venv\Scripts\Activate.ps1 python -m pip install --upgrade pip python -m pip install -r requirements.txt ``` 需要安装 `atlassplit` 命令时,可以改用 `python -m pip install -e .`。需要完全复现当前依赖版本时,使用 `requirements-lock.txt`。 ### 2. 配置 OpenAI-compatible 模型 ```powershell $env:OPENAI_BASE_URL="https://api.deepseek.com" $env:OPENAI_API_KEY="" $env:LLM_MODEL="deepseek-v4-flash" ``` 密钥只通过环境变量传入,不要提交 `.atlasplit_cli.json`、`.env` 或真实密钥。 ### 3. 生成并预览计划 准备一份不包含敏感信息的 Excel 或 CSV,并把 `` 替换为实际路径: ```powershell python cli.py plan --excel "" --task "按人员等额分摊100元" ``` 命令会展示经过校验的 `AllocationPlan` 和影响预览,并把不可变计划保存到 `runs/plans/`。这一步不会修改输出文件。 ### 4. 审批并执行同一计划 将上一条命令打印的路径替换到 ``: ```powershell python cli.py approve-plan --plan-file "" --execution-timeout 60 ``` 成功后检查: - `outputs/result.xlsx`:分摊结果。 - `outputs/backups/`:旧结果的时间戳备份。 - `runs/approvals.jsonl`:计划哈希、源文件哈希和执行状态。 ## 计划与结果示例 以下是字段示意,实际值由输入表格和任务决定: ```json { "source_sheet": "Sheet1", "entity_column": "人员", "method": "equal", "total": 100.0, "decimals": 2, "output_sheet": "Result" } ``` 执行结果包含行数、期望总额、实际分配总额、差值和 `valid` 状态。只有校验通过的结果才视为成功。 ## 支持范围 结构化确定性执行器当前支持: - Excel 和 CSV 输入。 - 等额分摊与权重分摊。 - 指定总额,或从表格列聚合总额。 - 指定工作表、接收方字段、权重字段和输出工作表。 - 0~6 位小数,以及合计差值校验。 旧 `run` 命令仍用于尚未进入确定性白名单的长尾任务。它会在限时子进程中执行受审计的生成代码,但不是容器级安全边界;不可信或财务关键任务应优先使用 `plan` / `approve-plan`。 ## 一步一步运行测试 ### 第一步:安装开发依赖 ```powershell .\.venv\Scripts\Activate.ps1 python -m pip install -r requirements-dev.txt ``` 推荐使用与 CI 一致的 Python 3.10,Python 3.12 也可以。如果现有环境提示 `No module named 'pydantic_core._pydantic_core'`,不要直接删除它;先退出环境并保留备份,再重建: ```powershell deactivate Rename-Item .venv .venv-broken py -3.10 -m venv .venv .\.venv\Scripts\Activate.ps1 python -m pip install --upgrade pip python -m pip install -r requirements-dev.txt ``` ### 第二步:运行全部测试 ```powershell python -m pytest -q ``` 当前基线应显示 `50 passed`。如果失败,先重新运行失败用例并显示完整堆栈: ```powershell python -m pytest tests\test_plan_engine.py -vv ``` ### 第三步:运行静态检查 ```powershell python -m ruff check . ``` 命令退出码为 0 且显示 `All checks passed!` 才表示通过。 ### 第四步:手工验证审批保护 1. 执行 `plan`,确认只创建计划、没有写入结果。 2. 复制输入文件后修改原文件,再执行 `approve-plan`,应因源文件哈希变化而拒绝。 3. 恢复输入并重新生成计划,审批一次应成功。 4. 再次审批同一计划,应被重复审批保护拒绝。 不要在唯一一份业务文件上做手工破坏测试,请始终使用副本。 ## 已验证结果与待补实验 | 项目 | 当前状态 | |---|---| | 自动化测试 | 50 passed | | Ruff | Gitee Go 与本地检查 | | 计划/源文件哈希保护 | 自动化测试覆盖 | | 原子写入、备份和重复审批保护 | 自动化测试覆盖 | | 1 万/5 万/10 万行 P50、P95 | 待提交基准脚本后发布 | | 金额守恒率与峰值内存 | 待提交基准数据后发布 | README 不发布无法由测试集、硬件信息和脚本复现的性能数字。 ## 目录说明 - `plan_models.py`:Pydantic 计划、预览、审批和执行结果契约。 - `plan_engine.py`:规划、预览、确定性执行、验证与审计。 - `plan_worker.py`:无模型凭据的限时执行入口。 - `cli.py`:`plan`、`approve-plan` 及兼容命令。 - `agent.py`:旧生成代码执行链路。 - `tests/`:pytest 回归测试。 ## 安全说明 - 不要在仓库、日志、截图或示例命令中提交真实 API Key。 - 历史中出现过的密钥必须保持撤销状态,不得复用。 - 子进程可以限制崩溃和无限运行的影响,但不能替代容器、虚拟机或操作系统沙箱。 - 审批日志不记录模型凭据或原始表格内容。 ## License 见 [LICENSE](LICENSE)。