## 为什么做这一步 权威文档 74 份此前**只在本机**,评审者 clone 分支后看不到任何设计文档;而仓库里那两份同名目录 是 **2026-09-16 之前的过期副本,连文件名都是旧的**(无体系编号)。本次按「**权威覆盖过期**」入库。 ## 入库内容 | 目录 | 文件数 | 体积 | 说明 | |---|---|---|---| | `客服agent/` | 24 | 0.77 MB | `D2.1`~`D2.6` 对外交付四件套 + 演示脚本/答辩报告 + `_build` 构建工具 | | `开发文档/` | 50 | 2.16 MB | `D1.x` 索引与决策、`D3.x` 方案、`D4.x` 清除与重构留痕、`D5.x` 业务流程、`D6.x` 业务事实基座、`D7.x` 交付物、`D8.x` 规范 | **旧的过期副本整体移除**(`客服Agent执行Todolist.md` → `D2.1-客服Agent执行Todolist.md` 之类 的改名 + 新增 `D2.5`/`D2.6`),入库后目录内容与权威副本**逐文件一致(零差异,已复核)**。 ## 入库前的安全扫描(必须留痕) - 扫描规则:`sk-` 类密钥 / `Bearer` 长串 / `password=`、`api_key=` 赋值 / 会话中出现过的两把明文 key 片段。 - 结论:**真实密钥只出现在 `.env`**(已被 `.gitignore` 命中,未入库);`.env.example` 与 `config/risk.env.example` 只有**空占位**。 - 文档内唯一命中是 `D3.1` 里一处**截断的示例 JWT**(`Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...`), 末尾带省略号,是接口文档的示意值,**不是可用凭据**。
433 lines
41 KiB
HTML
433 lines
41 KiB
HTML
<!-- ==================== 0 ==================== -->
|
||
<h1 id="0.-文档定位与前提">0. 文档定位与前提</h1>
|
||
|
||
<h2 id="0.1-目的与范围">0.1 目的与范围</h2>
|
||
|
||
<p>本文档回答「<strong>分几步做、按什么顺序、谁做什么、做到什么算完成</strong>」。它是四份交付文档中的<strong>「计划」分册</strong>:上游接《客服 Agent 需求文档》(做什么),下游发《客服 Agent 执行 Todolist》(逐项任务与验收动作)。</p>
|
||
|
||
<table>
|
||
<thead><tr><th>覆盖</th><th>不覆盖(归属)</th></tr></thead>
|
||
<tbody>
|
||
<tr><td>前置条件与准入、测试环境要求、纪律基线</td><td>需求条目与验收标准 → 《需求文档》§1.4/§1.5/§2.2</td></tr>
|
||
<tr><td>工程落位(原位改造 / 最小新增 / 最小挂载)</td><td>逐项任务的 DoD 与验证命令 → 《执行 Todolist》</td></tr>
|
||
<tr><td>批次划分、里程碑、关键路径、串行约束、并行通道</td><td>集合划分、分块、检索参数 → 《知识库设计方案》</td></tr>
|
||
<tr><td>底座接触面与两组会签、质量门禁、完工判据、交付物</td><td>溯源取证与理由 → <code>D4.1-客服Agent重构报告-2026-09-16.md</code></td></tr>
|
||
</tbody>
|
||
</table>
|
||
|
||
<h2 id="0.2-与其他三份文档的关系">0.2 与其他三份文档的关系</h2>
|
||
|
||
<table>
|
||
<thead><tr><th>文档</th><th>在这套体系中的角色</th><th>与本文档的接口</th></tr></thead>
|
||
<tbody>
|
||
<tr><td><strong>《需求文档》</strong></td><td>要做什么、边界在哪、验收标准</td><td>本文档的每个批次都指向它的一组 FR / NFR / 红线</td></tr>
|
||
<tr><td><strong>本文档</strong></td><td><strong>分几步、什么顺序、谁做、何时算完</strong></td><td>—</td></tr>
|
||
<tr><td><strong>《执行 Todolist》</strong></td><td>逐项任务与验收动作(开工只看那一份)</td><td>本文档定批次与顺序,Todolist 定每项的 DoD</td></tr>
|
||
<tr><td><strong>《知识库设计方案》</strong></td><td>知识库专项设计</td><td>D 批次(检索护栏)与 B 批次(语料)的规格来源</td></tr>
|
||
</tbody>
|
||
</table>
|
||
|
||
<blockquote class="callout-info"><p><strong>📌 四份交付文档的配套关系</strong><br>① <strong><code>D2.2-客服Agent需求文档.html</code></strong>——需求与验收标准:<strong>功能需求 48 条(FR-CS-001~048)+ 非功能需求 21 条(NFR-CS-001~021)</strong>,含 <strong>三条业务红线</strong>(风险等级唯一来源=问卷测评 / 先风险揭示后客户确认 / 不生成交易指令)与范围边界;<br>② <strong><code>D2.3-客服Agent开发计划.html</code></strong>(本文档)——<strong>51 项 / 7 个批次 / 12 步关键路径</strong>;<br>③ <strong><code>D2.1-客服Agent执行Todolist.md</code></strong>——逐项 DoD 与验证动作(<strong>开工只看那一份</strong>);<br>④ <strong><code>D2.4-客服Agent知识库设计方案.html</code></strong>——知识库专项。</p></blockquote>
|
||
|
||
<h2 id="0.3-当前状态与两处重大变化">0.3 当前状态与两处重大变化</h2>
|
||
|
||
<table>
|
||
<thead><tr><th>项</th><th>状态</th></tr></thead>
|
||
<tbody>
|
||
<tr><td>客服 Agent 模块</td><td><strong>已按形态 A 整体清除</strong>(2026-09-16,删 34 文件 + 摘 17 个共享文件引用,回退副本 <code>_cs_purge_backup/</code>)——下一步是<strong>重建</strong></td></tr>
|
||
<tr><td><strong>投顾模块</strong></td><td><strong>已于 2026-09-17 整体清除</strong>(后端 21 文件 + 前端 <code>employee-advisor/</code> 9 文件 + <code>/api/v1/advisor</code> 全部端点 + 5 个脚本 + 14 个测试 + 相关权限码)。<strong>验证:0 语法错误、0 悬空 import</strong>;备份 <code>_advisor_purge_backup/</code></td></tr>
|
||
<tr><td><strong>身份与鉴权方向</strong></td><td>已拍板:<strong>「方案乙(收敛)现在做 → 方案甲(拆轴)MVP 后」</strong></td></tr>
|
||
<tr><td>工程纪律</td><td>19 项决策已全部定案;底座接触面已逐文件取证</td></tr>
|
||
</tbody>
|
||
</table>
|
||
|
||
<blockquote class="callout-warn"><p><strong>⚠️ 投顾清除带来一个必须正视的后果</strong>:投顾原是<strong>第二条回归业务线</strong>,用于验证 6 个底座公共件的改动。清除后,底座改动的回归验证<strong>只剩客服一条线</strong>。因此本计划把「<strong>测试环境就位(G-00)</strong>」列为<strong>最优先的前置</strong>——没有可运行的门禁时改底座,等于盲改。</p></blockquote>
|
||
|
||
<hr>
|
||
|
||
<!-- ==================== 1 ==================== -->
|
||
<h1 id="1.-前置条件与准入">1. 前置条件与准入</h1>
|
||
|
||
<h2 id="1.1-开工前必须闭环的五项">1.1 开工前必须闭环的五项</h2>
|
||
|
||
<table>
|
||
<thead><tr><th>#</th><th>事项</th><th>不闭环的后果</th><th>谁确认</th></tr></thead>
|
||
<tbody>
|
||
<tr><td><strong>T-01</strong></td><td>Embedding 模型与维度(底座实况)</td><td><strong>维度不一致 → 检索结果无意义(静默错误)</strong>;建集合的动作需重做</td><td>后端架构师</td></tr>
|
||
<tr><td><strong>T-02</strong></td><td>三集合是否已存在及其 Schema</td><td>决定「首次建集合」还是「改造既有」——影响 D 批次全部落点</td><td>后端架构师</td></tr>
|
||
<tr><td><strong>T-03</strong></td><td>RAG 基础设施的落位与签名</td><td><strong>影响面最大</strong>:决定检索是「改造既有签名」还是「新建入口」;新建入口=产生第二条可能漏过滤的路径</td><td>后端架构师</td></tr>
|
||
<tr><td><strong>T-04</strong></td><td>一期安全路由是否被二期完整覆盖(含关键词 diff)</td><td><strong>唯一带安全性的删除</strong>:若覆盖不全,删一期路由会造成安全回归</td><td>安全/合规负责人</td></tr>
|
||
<tr><td><strong>T-05</strong></td><td><strong>底座接触面授权</strong>(组 2 的 4 个文件)</td><td>不做则<strong>访客权限无法实时收紧</strong>、受理与执行身份可能不一致(RK-20)</td><td>项目负责人 + 底座 owner</td></tr>
|
||
</tbody>
|
||
</table>
|
||
|
||
<h2 id="1.2-测试环境就位">1.2 测试环境就位(G-00 · 最优先)</h2>
|
||
|
||
<blockquote class="callout-warn"><p><strong>⚠️ G-00 不是形式要求</strong>:当前本机<strong>依赖零安装、无 venv</strong>,只能做语法层验证(<code>py_compile</code> + AST 悬空 import 扫描)。而 G-01 要改<strong>鉴权入口</strong>与 <strong>Worker 执行路径</strong>、D 批次要改<strong>检索层</strong>——<strong>没有可运行的测试套件时,这些改动等于盲改</strong>。</p></blockquote>
|
||
|
||
<table>
|
||
<thead><tr><th>动作</th><th>DoD</th></tr></thead>
|
||
<tbody>
|
||
<tr><td>依赖与 venv 就位</td><td><code>pip install -e .</code> 成功;<code>python -c "import fastapi, sqlalchemy, asyncmy, pydantic"</code> 通过(<strong>须实测能 import 依赖,不能只看 <code>--version</code></strong>)</td></tr>
|
||
<tr><td>门禁基线</td><td>按 <code>docs/14</code> 命令集跑通并记录原始数字:<code>ruff check app tests tools alembic</code> / <code>mypy app</code> / <code>pytest tests/unit tests/contract</code> / <code>pytest tests/integration</code> / <code>python tools/audit_schema.py</code>(<strong>预期 90 张表 = 89 业务表 + alembic_version</strong>)</td></tr>
|
||
<tr><td>跑前纪律</td><td><strong>跑验收脚本前先停常驻 Worker</strong>(否则抢队列);集成测试前先 <code>seed_test_rbac.py</code> + <code>set_user_password.py</code></td></tr>
|
||
</tbody>
|
||
</table>
|
||
|
||
<h2 id="1.3-纪律基线">1.3 纪律基线</h2>
|
||
|
||
<table>
|
||
<thead><tr><th>#</th><th>纪律</th><th>说明</th></tr></thead>
|
||
<tbody>
|
||
<tr><td>1</td><td><strong>零 DDL</strong></td><td>本期不改表结构、不加字段;`tools/audit_schema.py` 前后一致是硬证据</td></tr>
|
||
<tr><td>2</td><td><strong>分层判据</strong></td><td>「被多个 Agent 使用 / 在 <code>ToolRegistry</code> 注册为公共只读工具 / 承载鉴权·记忆·意图·模型·工具·合规·审计·持久化 8 项中任一项」→ <strong>底座层,须会签</strong>;否则业务层,自主重构</td></tr>
|
||
<tr><td>3</td><td><strong>会签门(先提案后动手)</strong></td><td>未获受理的项按降级方案执行,<strong>不得静默绕过</strong>;也不得为「绕过会签」而在业务层重造同一能力</td></tr>
|
||
<tr><td>4</td><td><strong>禁止新建检索入口</strong></td><td>两个入口=两条可能漏过滤的路径;只能改造既有签名</td></tr>
|
||
<tr><td>5</td><td><strong>证据留痕</strong></td><td>每项任务须给出「改了哪些文件 / 为什么 / 验证方式 / 未验部分」</td></tr>
|
||
</tbody>
|
||
</table>
|
||
|
||
<hr>
|
||
|
||
<!-- ==================== 2 ==================== -->
|
||
<h1 id="2.-工程落位">2. 工程落位</h1>
|
||
|
||
<h2 id="2.1-三类落位的纪律">2.1 三类落位的纪律</h2>
|
||
|
||
<p>本次为<strong>重构既有实现</strong>,且底座<strong>原则上不可修改</strong>,因此遵循「<strong>原位改造 + 最小新增 + 最小挂载</strong>」。</p>
|
||
|
||
<table>
|
||
<thead><tr><th>类型</th><th>内容</th><th>纪律</th></tr></thead>
|
||
<tbody>
|
||
<tr><td><strong>原位改造</strong></td><td>客服 Agent 主体、会话记忆、转人工三件套</td><td>不改文件名、不改对外签名、不迁移目录;改造前先确认既有行为的验证方式</td></tr>
|
||
<tr><td><strong>最小新增</strong></td><td>档位过滤、档位标注器、主体判定、访客令牌、访客限流、合规词库、<code>actor.py</code>、<code>knowledge_tier.py</code></td><td>不新增架构层;文件名与既有命名风格一致</td></tr>
|
||
<tr><td><strong>最小挂载</strong></td><td>路由注册、Agent 工厂分支、配置项追加</td><td>只追加不改既有逻辑;每处追加在评审中单独说明理由</td></tr>
|
||
<tr><td><strong>不触碰</strong></td><td>投顾已清除(无对象);其余公共基座<strong>只调用不改写</strong></td><td>例外见 §4.2(组 2 的本轮扩张)</td></tr>
|
||
</tbody>
|
||
</table>
|
||
|
||
<h2 id="2.2-目录落位">2.2 目录落位(按既有真实结构)</h2>
|
||
|
||
<div class="code-block">
|
||
<div class="code-header"><span class="code-lang">text · 客服 Agent 重建的文件落位(既有 / 新增)</span></div>
|
||
<pre><code>app/
|
||
├── api/
|
||
│ ├── controllers/
|
||
│ │ ├── agent_runs.py # 既有 · 扩展:承载客服对话路由
|
||
│ │ ├── conversations.py # 既有 · 复用:会话消息与反馈
|
||
│ │ └── knowledge.py # 既有 · 复用:知识库 upload/list/search/delete
|
||
│ └── dependencies/
|
||
│ ├── auth.py # ★组2 · 改:跳过身份解析的条件语义化(G-01b)
|
||
│ └── rate_limit.py # 既有 · 复用:登录与访客令牌的 IP 闸门
|
||
├── service/
|
||
│ ├── agent/
|
||
│ │ ├── base.py # ★组2 · 改:访客不召回的「谓词」替换(G-01b)
|
||
│ │ ├── authorizer.py # 既有 · 复用(方案甲落地时才改)
|
||
│ │ ├── bootstrap.py # 既有 · 扩展:注册重发后的客服 Agent 与工具
|
||
│ │ └── implementations/
|
||
│ │ └── customer_service.py # ★ 重建主体(原 748 行已随形态A清除)
|
||
│ ├── agent_run_application_service.py # 既有 · 扩展:补身份装配
|
||
│ ├── customer_service_session_memory_service.py # 既有 · 复用 + 扩展访客会话
|
||
│ ├── customer_service_handover_{context,admin,action}_service.py # 既有 · 复用(486 行)
|
||
│ ├── knowledge_search_service.py # 既有 · 改造:检索签名 fail-closed(D-01)
|
||
│ ├── knowledge_tool.py # 既有 · 改造:删 `del context`(D-04)
|
||
│ ├── tool_executor.py # 既有 · 复用(方案甲落地时才改)
|
||
│ └── visibility_tagger.py # 新增:档位标注器(含 internal 剔除)
|
||
├── core/
|
||
│ ├── config.py # 既有 · 追加配置项
|
||
│ ├── compliance_context.py # 既有 · 改造:补短否定式(C-04)
|
||
│ ├── customer_service_rules.py # 既有 · 复用:唯一安全路由 route_message()
|
||
│ ├── knowledge_schema.py # 既有 · 复用:运行时字段探测(禁字面量)
|
||
│ ├── memory_scope.py # 既有 · 复用:记忆范围唯一口径
|
||
│ ├── actor.py # ★新增(G-01):访客判定与三元组唯一来源
|
||
│ ├── knowledge_tier.py # ★新增(G-03):档位推导,调 actor
|
||
│ └── security.py # ★组2 · 改:访客分支改调 actor(G-01)
|
||
├── worker/
|
||
│ └── runtime.py # ★组2 · 改:三元组第二份副本改调 actor(G-01)
|
||
└── static/portal/common/customer-service-widget/ # 既有 · 复用:客服挂件</code></pre>
|
||
</div>
|
||
|
||
<blockquote class="callout-warn"><p><strong>⚠️ 标 ★组2 的 4 个文件是本轮唯一主动扩张的底座接触面</strong>(<code>core/security.py</code>、<code>worker/runtime.py</code>、<code>api/dependencies/auth.py</code>、<code>service/agent/base.py</code>)。其中 3 个原本写在「底座零改动清单」里。<strong>必须单独会签、单独 PR</strong>,不得与组 1 混提交。</p></blockquote>
|
||
|
||
<hr>
|
||
|
||
<!-- ==================== 3 ==================== -->
|
||
<h1 id="3.-执行计划">3. 执行计划</h1>
|
||
|
||
<h2 id="3.1-批次总览">3.1 批次总览(7 个批次 · 51 项)</h2>
|
||
|
||
<table>
|
||
<thead><tr><th>批次</th><th>主题</th><th>项数</th><th>目标</th><th>是否碰底座</th></tr></thead>
|
||
<tbody>
|
||
<tr><td><strong>A</strong></td><td>冻结与准备</td><td>10</td><td>把「当前是什么样」钉死,后续任何「红了」都能区分是<strong>我改坏的</strong>还是<strong>本来就有的</strong></td><td>否(产出会签材料)</td></tr>
|
||
<tr><td><strong>B</strong></td><td>语料与话术</td><td>5</td><td>把客户可见的跨层不一致一次清干净;<strong>串行,只重跑一次灌库</strong></td><td>1 处(<code>governance.py</code>)</td></tr>
|
||
<tr><td><strong>C</strong></td><td>规则重构与安全</td><td>9</td><td>补齐安全缺口与访客侧推介边界;<strong>一次定稿关键词表、一次双向验证</strong></td><td>2 处(<code>compliance_context</code> / <code>governance</code>)</td></tr>
|
||
<tr><td><strong>D</strong></td><td>架构护栏</td><td>7</td><td>为「加档位 / 加身份」备前置;<strong>D-02 是静默降级,静态扫描抓不到</strong></td><td>2 处(<code>knowledge_search_service</code> / <code>knowledge_tool</code>)</td></tr>
|
||
<tr><td><strong>E</strong></td><td>业务闭环与出口</td><td>8</td><td>建单白名单、priority、reason_code 枚举化(含 1 项挂起)</td><td>1 处(<code>agent_persistence_service</code>)</td></tr>
|
||
<tr><td><strong>F</strong></td><td>演示与收口</td><td>7</td><td>文档回写、演示准备、dry-run</td><td>否</td></tr>
|
||
<tr><td><strong>G</strong></td><td><strong>访客与鉴权</strong>(新增)</td><td>5</td><td>把「访客与角色分离」落为可执行任务</td><td><strong>4 处(主动扩张)</strong></td></tr>
|
||
</tbody>
|
||
</table>
|
||
|
||
<h2 id="3.2-批次A-冻结与准备">3.2 批次 A · 冻结与准备(10 项,立即开动)</h2>
|
||
|
||
<table>
|
||
<thead><tr><th>ID</th><th>任务</th><th>关键 DoD</th><th>风险</th></tr></thead>
|
||
<tbody>
|
||
<tr><td>A-01</td><td>安全用例集基线复现</td><td>逐条记录通过/失败;<strong>改为「只登记预期、不跑实测」</strong>——被测对象已不存在,实测后移至 C-06 之后</td><td>LOW</td></tr>
|
||
<tr><td>A-02</td><td>门禁数字基线</td><td>5 项命令 + 日期 + 解释器路径 + SQLAlchemy 补丁版;<strong>跑前先停 Worker</strong></td><td>LOW</td></tr>
|
||
<tr><td>A-03</td><td>配置与环境快照</td><td>active 版本 id + 条数 + <strong><code>agent_tools</code> 白名单全文</strong>(须同时含「客户侧」与「游客侧」知识工具);三集合字段名 + 行数;embedding 模型名 + 维度</td><td>LOW</td></tr>
|
||
<tr><td>A-04</td><td>业务一致性三查基线</td><td>品牌名 / 占位符 / 界面名差集 + <strong>旧热线号码全部位置</strong>(清单里只要求 4 份清单)</td><td>LOW</td></tr>
|
||
<tr><td>A-05</td><td>演示前检查清单固化</td><td>五项:Docker Desktop → Milvus → Worker → 行情未过期 → <code>MILVUS_LOCAL_URI</code> 为空</td><td>LOW</td></tr>
|
||
<tr><td>A-06</td><td>分支与 PR 策略</td><td>每批次一个 PR;<strong>底座会签项单独一个 PR</strong>(便于 owner 只审那一份 diff)</td><td>LOW</td></tr>
|
||
<tr><td>A-07</td><td><strong>访客链路可用性实测</strong></td><td>实跑一次访客请求;确认「游客侧知识工具」在白名单内;<strong>记录访客 <code>context.user_id</code> 形态</strong>(须为数字串)</td><td><strong>中</strong></td></tr>
|
||
<tr><td>A-08</td><td>前端约束与配合点复核</td><td>产出「需前端配合项清单」;结论可以是 0 项,但必须是核对后的 0 项</td><td>LOW</td></tr>
|
||
<tr><td>A-09</td><td><strong>《可改文件白名单》落文</strong></td><td>四类:纯新增 / 允许修改 / 提案后由底座方修改 / <strong>禁止修改</strong>;附「零 DDL」声明与基线截图</td><td>LOW</td></tr>
|
||
<tr><td>A-10</td><td><strong>底座会签申请单落文</strong></td><td>对<strong>组 1 六处 + 组 2 四处</strong>逐项写清六件事:改什么 / 为什么是公共缺陷 / 最小化边界 / 规范依据 / 影响面 / 降级方案</td><td>LOW</td></tr>
|
||
</tbody>
|
||
</table>
|
||
|
||
<h2 id="3.3-批次B至F摘要">3.3 批次 B ~ F 摘要</h2>
|
||
|
||
<table>
|
||
<thead><tr><th>批次</th><th>关键任务</th><th>必须记住的一条</th></tr></thead>
|
||
<tbody>
|
||
<tr><td><strong>B</strong>(5)</td><td>B-01 语料入库门禁四查 → B-02 语料一次性修正 → B-03 界面指代修正 → <strong>B-04 重跑灌库(唯一一次)</strong> → B-05 热线与服务时间单点化(五组落点)</td><td><strong>顺序不可调</strong>:门禁 → 改语料 → 定值 → 重跑 + 三查。B-05 含 1 处底座改动须会签;验收口径为 <code>app/ tests/ tools/ knowledge/</code> 范围内 grep 旧值 = 0(<code>docs/**</code> 历史记载<strong>不改</strong>)</td></tr>
|
||
<tr><td><strong>C</strong>(9)</td><td>C-01 零容忍集语义纠错 → C-03 安全词表取回 → C-04 补短否定式 → C-06 四向验证 → C-07 删除一期路由</td><td><strong>C-03 必须从留痕文档逐条抄,不许凭记忆重写</strong>(词条缩水不报错);<strong>C-06 → C-07</strong>,直接删一期路由=提示词注入拦截消失</td></tr>
|
||
<tr><td><strong>D</strong>(7)</td><td>D-01 检索签名 fail-closed → D-02 按集合逐个拼过滤表达式 → D-03 over-fetch → <strong>D-04 删 <code>del context</code>、按身份推导档位</strong> → D-06 访客主体口径</td><td><strong>D-02 的落点有三处</strong>(主检索 + 产品名召回 + 父块召回),<strong>必须同批改</strong>;漏改后两处 → 概括型问句继续静默转人工</td></tr>
|
||
<tr><td><strong>E</strong>(8)</td><td>E-01 建单白名单 + priority + <code>reason_code</code> 枚举化 → E-02 日志按 reason 区分 → E-03 出口 → E-04 审计(含 1 项挂起)</td><td><strong>建单白名单必须限定 <code>run.agent_type == "customer_service"</code></strong>——否则改动其它 Agent 的既有建单行为</td></tr>
|
||
<tr><td><strong>F</strong>(7)</td><td>F-01 重建含主体过滤的历史读取 → F-05 文档回写 → F-06 dry-run</td><td><strong>F-01 禁止从备份恢复旧实现</strong>——那份正是「只按 <code>session_id</code> 取历史、跨主体可读」的缺陷本体;须在新链路重写并调用 <code>memory_scope</code></td></tr>
|
||
</tbody>
|
||
</table>
|
||
|
||
<h2 id="3.4-批次G-访客与鉴权">3.4 批次 G · 访客与鉴权(5 项 · 独立会签组)</h2>
|
||
|
||
<table>
|
||
<thead><tr><th>ID</th><th>任务</th><th>DoD 要点</th><th>依赖</th><th>风险</th></tr></thead>
|
||
<tbody>
|
||
<tr><td><strong>G-00</strong></td><td>测试环境就位</td><td>门禁可运行并记录基线(见 §1.2)</td><td>—</td><td>LOW</td></tr>
|
||
<tr><td><strong>G-01</strong></td><td><strong>访客权威单点化</strong>(方案乙)</td><td>① 三元组<strong>只有一个构造来源</strong>;② <code>security.py</code> 与 <code>runtime.py</code> 均调用它;③ <strong>对外行为零变化</strong>(问答、限流、令牌 TTL 全部不变);④ 新增<strong>接缝单测</strong>:同一输入下两侧产出必须相等(这正是当前缺失的测试)</td><td>G-00</td><td><strong>中</strong></td></tr>
|
||
<tr><td><strong>G-01b</strong></td><td>判定口径单点化</td><td>6 处访客判断全部改走统一谓词;⚠️ <strong>Agent 基类那处的「位置与层级」不得变</strong>(仍留在基类、仍不依赖 Agent 声明位)</td><td>G-01</td><td><strong>中</strong></td></tr>
|
||
<tr><td><strong>G-02</strong>(挂起)</td><td>身份轴(方案甲)</td><td><code>roles</code> 回归纯 RBAC;20 余处 <code>allowed_roles</code> 中的 <code>"visitor"</code> 迁至身份轴声明</td><td>G-01b、MVP 演示跑通</td><td><strong>高</strong></td></tr>
|
||
<tr><td><strong>G-03</strong></td><td>档位推导单点化</td><td>档位由统一谓词推导,<strong>不由工具层自行判身份字段</strong>;⇒ 将来 G-02 落地时只需改 1 个文件</td><td>G-01b、D-01</td><td>LOW</td></tr>
|
||
</tbody>
|
||
</table>
|
||
|
||
<h2 id="3.5-里程碑">3.5 里程碑</h2>
|
||
|
||
<div class="mermaid">
|
||
flowchart LR
|
||
M1["M1 冻结完成<br/>批次 A + G-00 完成"] --> M2["M2 语料与话术一致<br/>批次 B 完成"]
|
||
M2 --> M3["M3 安全与规则就绪<br/>批次 C 完成"]
|
||
M3 --> M4["M4 身份与护栏就位<br/>批次 G-01/G-01b/G-03 + D 批次完成"]
|
||
M4 --> M5["M5 业务闭环<br/>批次 E 完成"]
|
||
M5 --> M6["M6 演示跑通<br/>批次 F 完成(最终验收)"]
|
||
|
||
style M1 fill:#e3f2fd,stroke:#1976d2
|
||
style M4 fill:#fff3e0,stroke:#f57c00
|
||
style M6 fill:#c8e6c9,stroke:#388e3c
|
||
</div>
|
||
|
||
<hr>
|
||
|
||
<!-- ==================== 4 ==================== -->
|
||
<h1 id="4.-底座接触面与两组会签">4. 底座接触面与两组会签</h1>
|
||
|
||
<h2 id="4.1-组-1-六文件八处">4.1 组 1 · 六文件八处(原计划内,须会签)</h2>
|
||
|
||
<table>
|
||
<thead><tr><th>#</th><th>文件</th><th>触碰项</th><th>改什么</th></tr></thead>
|
||
<tbody>
|
||
<tr><td>1</td><td><code>service/knowledge_search_service.py</code></td><td><strong>D-01</strong></td><td><code>include_internal: bool</code> → <strong><code>tiers: frozenset[str]</code>(必填、无默认值)</strong>;<code>_visibility_filter</code> 同步按 <code>tiers</code> 拼表达式;非法值收敛为 <code>{"public"}</code></td></tr>
|
||
<tr><td>2</td><td>同上</td><td><strong>D-02</strong></td><td>表达式<strong>按集合逐个拼</strong>(<code>filter=expression if schema.has("visibility") else None</code>);缺字段时<strong>不再回落 public</strong>;增加「因缺字段跳过过滤」的独立计数</td></tr>
|
||
<tr><td>3</td><td><code>service/knowledge_tool.py</code></td><td><strong>D-04</strong></td><td>删 <code>del context</code>;按身份推导档位后传入检索</td></tr>
|
||
<tr><td>4</td><td><code>core/compliance_context.py</code></td><td><strong>C-04</strong></td><td><code>NEGATION_CUES</code> 补短否定式:<code>不保本</code> / <code>不保收益</code> / <code>非保本</code> / <code>并非保本</code> / <code>不确保</code> / <code>不担保</code></td></tr>
|
||
<tr><td>5</td><td><code>service/agent/governance.py</code></td><td><strong>B-05</strong></td><td>删旧热线常量与只对旧号生效的脱敏白名单分支 → 内联为固定脱敏返回(<strong>该分支已成为不可达死代码</strong>)</td></tr>
|
||
<tr><td>6</td><td><code>service/agent_run_application_service.py</code></td><td><strong>D-06 + F-01</strong></td><td>① 访客消息的 <code>customer_id</code> 按身份取值(访客为空);② 重写历史读取并<strong>调用记忆范围模块</strong>做主体过滤</td></tr>
|
||
<tr><td>7</td><td><code>service/agent_persistence_service.py</code></td><td><strong>E-01</strong></td><td>建单白名单(<strong>限定客服 Agent</strong>)+ 赋 <code>priority</code> + <code>reason_code</code> 枚举化</td></tr>
|
||
</tbody>
|
||
</table>
|
||
|
||
<h2 id="4.2-组-2-访客与鉴权四文件">4.2 组 2 · 访客与鉴权四文件(<strong>本轮主动扩张</strong>)</h2>
|
||
|
||
<blockquote class="callout-warn"><p><strong>⚠️ 为什么必须单列</strong>:这 4 个文件<strong>不在组 1 名单内</strong>,其中 3 个还写在「底座零改动清单」里。单列的目的是让「<strong>本次主动扩张了底座接触面</strong>」这件事<strong>可见、可审、可单独回滚</strong>,而不是藏在某处顺手改掉。</p></blockquote>
|
||
|
||
<table>
|
||
<thead><tr><th>#</th><th>文件</th><th>触碰项</th><th>改什么</th><th>最小化边界</th></tr></thead>
|
||
<tbody>
|
||
<tr><td>2-1</td><td><code>core/security.py</code></td><td><strong>G-01</strong></td><td>访客分支改为调用新增的 <code>actor.anonymous_context()</code>(<strong>行为逐字不变</strong>,只改「值从哪来」)</td><td>不动 <code>jwt.decode</code> 参数、不动 <code>sub</code> 校验、不动 <code>visitor</code> claim 语义</td></tr>
|
||
<tr><td>2-2</td><td><code>worker/runtime.py</code></td><td><strong>G-01</strong></td><td>同上——<strong>第二份副本</strong>改为调用同一构造点</td><td>不动 <code>restore_context()</code> 签名、不动身份解析分支</td></tr>
|
||
<tr><td>2-3</td><td><code>api/dependencies/auth.py</code></td><td><strong>G-01b</strong></td><td>「跳过身份解析」的条件改为语义化谓词</td><td>不动鉴权入口结构、不动 401 口径、<strong>不新增任何路由</strong></td></tr>
|
||
<tr><td>2-4</td><td><code>service/agent/base.py</code></td><td><strong>G-01b</strong></td><td>访客不召回的<strong>谓词</strong>替换</td><td>⚠️ <strong>仍留在基类、仍不依赖 Agent 声明位</strong>——这是底线,不是可选项(不变量②)</td></tr>
|
||
</tbody>
|
||
</table>
|
||
|
||
<p><strong>与「零改动清单」的关系</strong>:原清单把 <code>app/api/**</code>、<code>app/worker/**</code>、<code>service/agent/base.py</code> 列为「本次明确不碰」。<strong>本轮明确修订该声明</strong>——上述 4 项由批次 G 触碰,依据是《需求文档》FR-CS-043 / FR-CS-044。<strong>除这 4 个文件外,零改动清单的其余条目继续有效。</strong></p>
|
||
|
||
<blockquote class="callout-info"><p><strong>📌 额外复核项</strong>:<code>docs/33</code>/<code>docs/34</code> 对 <code>security.py</code> 做过<strong>逐行实证</strong>(涉及 <code>sub</code> 生成、<code>decode</code> 参数、<code>sub</code> 校验、访客分支位置等若干行)。本组改动会<strong>使这些行号漂移</strong>,因此 G-01 完成后<strong>必须复核那些逐行结论是否仍成立</strong>,并在会签单里说明。</p></blockquote>
|
||
|
||
<h2 id="4.3-会签流程">4.3 会签流程</h2>
|
||
|
||
<table>
|
||
<thead><tr><th>步</th><th>动作</th><th>产物</th></tr></thead>
|
||
<tbody>
|
||
<tr><td>1</td><td>A-09 落文《可改文件白名单》(四类)</td><td>纪律凭据 + 零 DDL 声明</td></tr>
|
||
<tr><td>2</td><td>A-10 落文会签申请单(<strong>组 1 与组 2 各一份</strong>)</td><td>可抄送底座 owner 的正式申请</td></tr>
|
||
<tr><td>3</td><td>提交 → 等待受理(<strong>唯一的外部队列</strong>)</td><td>受理记录</td></tr>
|
||
<tr><td>4</td><td>受理后由底座方修改(或授权后自改)</td><td><strong>单独 PR</strong>,只含该组 diff</td></tr>
|
||
<tr><td>5</td><td>未获受理 → 走降级方案并文档标注</td><td>降级登记</td></tr>
|
||
</tbody>
|
||
</table>
|
||
|
||
<hr>
|
||
|
||
<!-- ==================== 5 ==================== -->
|
||
<h1 id="5.-关键路径与约束">5. 关键路径与约束</h1>
|
||
|
||
<h2 id="5.1-关键路径">5.1 关键路径(12 步 + 1 个会签等待窗口)</h2>
|
||
|
||
<div class="code-block">
|
||
<div class="code-header"><span class="code-lang">text · 最长链</span></div>
|
||
<pre><code>[会签窗口:A-10 提交 → 底座方受理 组1 六处 + 组2 四处] ──┐
|
||
↓
|
||
A-02 → A-07 → G-01 → G-01b → D-01 → D-02 → G-03 → D-04
|
||
→ D-06 → E-01 → E-03 → F-03 ──→ 演示跑通
|
||
↑
|
||
B-01 → B-02 → B-05 → B-04 ───┤
|
||
│
|
||
C-01 → C-03 → C-09 → C-06 ───┘</code></pre>
|
||
</div>
|
||
|
||
<p><strong>最长链 = 12 步</strong>(含 G 链)。<strong>会签往返不影响步数,但是唯一的外部队列——越早提交越早有回音,故 A-10 排在 A 批次内优先执行。</strong></p>
|
||
|
||
<h2 id="5.2-十二条硬串行约束">5.2 十二条硬串行约束(违反即返工)</h2>
|
||
|
||
<table>
|
||
<thead><tr><th>#</th><th>约束</th><th>违反后果</th></tr></thead>
|
||
<tbody>
|
||
<tr><td>S-1</td><td><strong>B-01 门禁 → B-02 改语料 → B-04 重跑</strong></td><td>顺序颠倒会把问题再灌一遍</td></tr>
|
||
<tr><td>S-2</td><td><strong>B-05 热线定值 → B-02 填值</strong></td><td>语料里会填进旧的/占位的号码</td></tr>
|
||
<tr><td>S-3</td><td><strong>C-06 验证 → C-07 删除</strong></td><td>直接删一期路由 <strong>→ 提示词注入拦截消失</strong>(唯一带安全性的删除)</td></tr>
|
||
<tr><td>S-4</td><td><strong>D-02 修过滤表达式 → 任何集合加 <code>visibility</code> / 改字段名</strong></td><td>缺字段的集合被同一表达式打挂 → 被吞成 failure → <code>degraded=True</code> → <strong>客服全员「引导人工」且不报错</strong></td></tr>
|
||
<tr><td>S-5</td><td><strong>D-01 fail-closed → D-04 传身份</strong></td><td>身份传进没有 fail-closed 语义的签名 = 把「记得过滤」交回调用方</td></tr>
|
||
<tr><td>S-6</td><td><strong>D-03 over-fetch 与 D-01/D-02 同批</strong></td><td>只有过滤没有 over-fetch → 过滤后 TopK 不足 → 上层误判「无答案」</td></tr>
|
||
<tr><td>S-7</td><td><strong>集合 schema 变更后必须重启 API + Worker</strong></td><td>检索服务是进程级单例,schema 缓存永不失效</td></tr>
|
||
<tr><td>S-8</td><td><strong>禁止在知识出口启用未完成的来源引用链路</strong></td><td>治理层只认 memory/tool 来源 → 返回 knowledge 引用会让<strong>整个 run 失败</strong></td></tr>
|
||
<tr><td>S-9</td><td><strong>底座两组未获会签前不得动手</strong></td><td>绕过 = 形成第二套实现,其中一套必然漏掉隔离</td></tr>
|
||
<tr><td>S-10</td><td><strong>访客侧开关未做严禁开始出口与演示第 1 步</strong></td><td>服务访客的 Agent 声明缺失 → 游客线<strong>永久失效</strong>,且失败表现为「请登录」,<strong>与设计如此无法区分</strong></td></tr>
|
||
<tr><td><strong>S-11</strong></td><td><strong>G-00 → G-01 → G-01b → G-03 → D-04</strong></td><td>① 无测试环境改鉴权链路=盲改;② G-01 不做就改 D-04,档位会依赖两份可能不一致的身份定义;③ D-04 若自行判身份字段,则 G-02 落地时必须改两处,<strong>分离收益归零</strong></td></tr>
|
||
<tr><td><strong>S-12</strong></td><td><strong>三处交叉点顺序固定:G-01b → D-06 → F-01</strong>(同一文件不同段)</td><td>倒序会互相覆盖;且访客主体口径依赖身份判定已单点化</td></tr>
|
||
</tbody>
|
||
</table>
|
||
|
||
<h2 id="5.3-并行通道">5.3 若多人并行:按「文件不相交」切四路</h2>
|
||
|
||
<table>
|
||
<thead><tr><th>通道</th><th>负责批次</th><th>独占文件</th></tr></thead>
|
||
<tbody>
|
||
<tr><td>通道 1 · 语料</td><td>批次 B 全部 + F-06</td><td><code>knowledge/*</code>、语料构建脚本</td></tr>
|
||
<tr><td>通道 2 · 规则与数据层</td><td>批次 C 全部 + E-01(业务侧)</td><td><code>core/customer_service_rules.py</code>、禁用词种子</td></tr>
|
||
<tr><td>通道 3 · 检索护栏</td><td>批次 D 全部 + F-01</td><td><code>knowledge_search_service.py</code>、<code>knowledge_tool.py</code>、<code>core/knowledge_tier.py</code></td></tr>
|
||
<tr><td>通道 4 · 出口与文档</td><td>批次 A + E-02/E-04 + F 文档类</td><td><code>implementations/customer_service.py</code>、<code>docs/*</code></td></tr>
|
||
<tr><td><strong>通道 0 · 底座会签</strong></td><td>组 1 六处 + <strong>组 2 四处</strong></td><td>各自<strong>单独一个 PR</strong>,由底座 owner 审</td></tr>
|
||
</tbody>
|
||
</table>
|
||
|
||
<p><strong>三处交叉点需串行</strong>:① <code>agent_run_application_service.py</code> 由通道 3(D-06)与通道 4(F-01)先后改,且现在又加入 G-01b——<strong>顺序固定 G-01b → D-06 → F-01</strong>;② <code>agent_persistence_service.py</code> 只由通道 2(E-01)改;③ <code>tool_executor.py</code> 仅由条件触发项碰,且排在其后。</p>
|
||
|
||
<hr>
|
||
|
||
<!-- ==================== 6 ==================== -->
|
||
<h1 id="6.-质量门禁与完工判据">6. 质量门禁与完工判据</h1>
|
||
|
||
<h2 id="6.1-质量门禁">6.1 质量门禁</h2>
|
||
|
||
<table>
|
||
<thead><tr><th>门禁</th><th>命令 / 判据</th></tr></thead>
|
||
<tbody>
|
||
<tr><td>代码检查</td><td><code>ruff check app tests tools alembic</code> → 0 错</td></tr>
|
||
<tr><td>类型检查</td><td><code>mypy app</code> → 0 错。<strong>注意 SQLAlchemy 补丁版差异会造成量级差异</strong>(曾出现「一边上百个错、另一边 0 错」)</td></tr>
|
||
<tr><td>单测 + 契约测</td><td><code>pytest tests/unit tests/contract</code> → <strong>0 failed</strong>(绝对用例数会随开发增减,判据是 0 failed)</td></tr>
|
||
<tr><td>集成测</td><td><code>pytest tests/integration</code> → 0 failed。前置:先跑 RBAC 种子与口令脚本</td></tr>
|
||
<tr><td>零 DDL</td><td><code>python tools/audit_schema.py</code> → <strong>90 张表(89 业务表 + alembic_version)</strong>,前后一致</td></tr>
|
||
<tr><td>文档守卫</td><td><code>python tools/check_authoritative_docs.py</code> 通过</td></tr>
|
||
<tr><td>离线兜底</td><td>无依赖环境下的替代验证:全量 <code>py_compile</code> 0 错 + AST 悬空 import 0 条</td></tr>
|
||
</tbody>
|
||
</table>
|
||
|
||
<h2 id="6.2-整体完工判据">6.2 整体完工判据(12 条)</h2>
|
||
|
||
<table>
|
||
<thead><tr><th>#</th><th>判据</th><th>怎么验</th></tr></thead>
|
||
<tbody>
|
||
<tr><td>1</td><td>业务一致性三查全绿</td><td>语料 0 占位符、0 旧品牌;热线/服务时间代码与语料一致;界面名全在站内链接表内</td></tr>
|
||
<tr><td>2</td><td><strong>安全只增不减</strong></td><td>红队用例与 A-01 基线逐条对比,<strong>无一条变松</strong></td></tr>
|
||
<tr><td>3</td><td>规则三个方向都对</td><td>概念题可答 + 诱导性问法仍拒答 + 访客推荐类请求不产生推介</td></tr>
|
||
<tr><td>4</td><td><strong>护栏生效</strong></td><td>访客检索 <code>registered</code> 返回空、客户同期正常;公开问题召回量与基线一致;「缺字段的集合」有独立计数、不再污染降级标记</td></tr>
|
||
<tr><td>5</td><td>访客主体一致</td><td>访客消息 <code>customer_id</code> 为空;工单侧同为 NULL;历史读取走记忆范围模块</td></tr>
|
||
<tr><td>6</td><td>工单分类正确</td><td>「答不上来」不建单;反诈工单 <code>P0</code>;投诉 <code>P1</code>;主动要人工 <code>P2</code>;<strong>其它 Agent 建单行为未变</strong></td></tr>
|
||
<tr><td>7</td><td>门禁干净</td><td>§6.1 全部通过</td></tr>
|
||
<tr><td>8</td><td><strong>演示跑通</strong></td><td>MVP 演示步骤全部可见,含「无投资建议类内容」</td></tr>
|
||
<tr><td>9</td><td>红线可举证</td><td>适当性不匹配场景可在消息表与审计表中还原「揭示 → 确认」顺序</td></tr>
|
||
<tr><td>10</td><td><strong>底座纪律达标</strong></td><td>实际改动文件 ⊆ A-09 白名单;两组每一处都有会签记录(或走降级并文档标注);零 DDL 证据;未绕过统一鉴权/工具/合规/审计流程</td></tr>
|
||
<tr><td>11</td><td><strong>访客与角色已分离</strong></td><td>访客三元组只有一个构造来源;访客链路端到端行为与动手前逐项一致;身份判定已全部走单点模块;档位由档位模块推导;三条不变量逐条可举证</td></tr>
|
||
<tr><td>12</td><td><strong>文档一致</strong></td><td>四份文档交叉引用无冲突;<code>docs/**</code> 历史记载已按 F-05 回写标记</td></tr>
|
||
</tbody>
|
||
</table>
|
||
|
||
<hr>
|
||
|
||
<!-- ==================== 7 ==================== -->
|
||
<h1 id="7.-风险与分工">7. 风险与分工</h1>
|
||
|
||
<h2 id="7.1-头号风险">7.1 头号风险:投顾清除后失去第二条回归业务线</h2>
|
||
|
||
<blockquote class="callout-warn"><p><strong>⚠️ 本条必须置顶</strong>:投顾原本是 <strong>6 个底座公共件改动时的对照组</strong>——它是唯一完好的业务线,能在改底座时暴露跨模块回归。它在 2026-09-17 被整体清除后:<strong>底座改动的回归验证只剩客服一条线</strong>。<br><strong>应对三条</strong>:① <strong>G-00(测试环境就位)优先级上调为最前置</strong>;② 底座两组改动<strong>必须全量跑 §6.1 门禁</strong>,不得只跑单测;③ 组 2 单独 PR,便于<strong>独立回滚</strong>。</p></blockquote>
|
||
|
||
<h2 id="7.2-风险重排">7.2 风险重排(前 8 项)</h2>
|
||
|
||
<table>
|
||
<thead><tr><th>排名</th><th>风险</th><th>最高风险点</th><th>对策</th></tr></thead>
|
||
<tbody>
|
||
<tr><td>1</td><td><strong>失去对照组</strong>(投顾已清除)</td><td>底座改动无第二条线兜底</td><td>G-00 前置 + 全量门禁 + 组 2 单独 PR</td></tr>
|
||
<tr><td>2</td><td><strong>D-02</strong> 过滤器按集合逐个拼</td><td>改错会让客服<strong>全员转人工且不报错</strong></td><td>先补两类替身测试(部分集合有/部分没有、字段名不同)再改实现;上线后立刻验召回量不变;保留独立计数</td></tr>
|
||
<tr><td>3</td><td><strong>G-01/G-01b</strong> 身份单点化</td><td>改鉴权入口与 Worker 执行路径,<strong>无测试环境时是盲改</strong></td><td>G-00 必须先完成;新增<strong>接缝单测</strong>(两侧产出必须相等);对外行为零变化的验收方式</td></tr>
|
||
<tr><td>4</td><td><strong>C-06</strong> 四向验证 / <strong>C-03</strong> 词表取回</td><td>词表缩水不报错;补偿式修改会放过真实承诺</td><td>从留痕文档<strong>逐条抄</strong>;四个方向用例都必须有;反例守卫</td></tr>
|
||
<tr><td>5</td><td><strong>C-09</strong> 访客推介边界</td><td>按主体分化输出规则时可能误伤客户侧(或反之)</td><td>客户侧必须做<strong>回归验证</strong>;<strong>按身份分支而非合并词表</strong></td></tr>
|
||
<tr><td>6</td><td><strong>E-01</strong> 建单白名单</td><td>若不限定 <code>agent_type</code>,会改动其它 Agent 的建单行为</td><td>DoD 明确「仅对客服 Agent 生效」;把其它 Agent 的既有建单用例纳入回归</td></tr>
|
||
<tr><td>7</td><td><strong>A-07</strong> 访客链路实测</td><td>若游客侧工具未在白名单,<strong>全线失败表现为「请登录」</strong></td><td>实测 + 日志按 reason 区分;A-03 快照留白名单全文</td></tr>
|
||
<tr><td>8</td><td><strong>B-04 / F-06</strong> 两次连外部服务</td><td>环境问题伪装成功能缺陷</td><td>先跑 A-03/A-05 快照与自检;B-04 前停 Worker;F-06 先 dry-run</td></tr>
|
||
</tbody>
|
||
</table>
|
||
|
||
<h2 id="7.3-分工与交付物">7.3 分工与交付物</h2>
|
||
|
||
<table>
|
||
<thead><tr><th>角色</th><th>职责</th><th>对应批次</th></tr></thead>
|
||
<tbody>
|
||
<tr><td>后端架构师</td><td>骨架、鉴权与身份、DB、统一响应、知识库接口、会话记忆、合规子模块、转人工、工单</td><td>A / G / E / 部分 B·C</td></tr>
|
||
<tr><td>AI 工程师</td><td>文档解析、向量化、集合与检索、意图分类、主流程、事件</td><td>D / 部分 B·C</td></tr>
|
||
<tr><td>业务开发(咨询)</td><td>合规词库、适当性规则、客群分层口径</td><td>评审 C / E</td></tr>
|
||
<tr><td>全员</td><td>演示准备与最终验收</td><td>F</td></tr>
|
||
</tbody>
|
||
</table>
|
||
|
||
<table>
|
||
<thead><tr><th>#</th><th>交付物</th><th>形态</th><th>验收人</th></tr></thead>
|
||
<tbody>
|
||
<tr><td>1</td><td>四份文档(需求 / 开发计划 / 执行 Todolist / 知识库设计方案)</td><td>HTML ×3 + Markdown ×1</td><td>团队 + 讲师</td></tr>
|
||
<tr><td>2</td><td>客服 Agent 源码</td><td><code>.py</code></td><td>代码评审人</td></tr>
|
||
<tr><td>3</td><td>接口文档(自动生成 + 补充说明)</td><td>在线 + Markdown</td><td>全栈/集成</td></tr>
|
||
<tr><td>4</td><td>知识库入库清单与来源映射表</td><td>Markdown</td><td>AI 工程师</td></tr>
|
||
<tr><td>5</td><td>测试报告(按 §6.1 门禁实际执行结果)</td><td>Markdown</td><td>全员</td></tr>
|
||
<tr><td>6</td><td>演示脚本</td><td>Markdown</td><td>主讲人</td></tr>
|
||
<tr><td>7</td><td>开发过程会议纪要(≥ 5 份)</td><td>Markdown</td><td>团队</td></tr>
|
||
<tr><td>8</td><td><strong>会签材料</strong>(可改文件白名单 + 会签申请单 ×2)</td><td>Markdown</td><td>底座 owner</td></tr>
|
||
<tr><td>9</td><td><strong>清除留痕</strong>(客服形态A + 投顾清除的执行报告与回退备份说明)</td><td>Markdown</td><td>项目负责人</td></tr>
|
||
</tbody>
|
||
</table>
|
||
|
||
<hr>
|
||
|
||
<blockquote class="callout-info"><p><strong>文档结束</strong> —— 本文档为《南方基金·智能服务系统》智能客服 Agent 的<strong>开发计划 v1.0</strong>,是四份交付文档的「计划」分册。开工时以《客服 Agent 执行 Todolist》为唯一入口;本文档定顺序与约束,Todolist 定每项的 DoD 与验证动作。</p></blockquote>
|