docs: 品牌全量口径统一为「南方基金」+ 作废文档清理
1) 客服 Agent 四份交付文档 + 构建脚手架:品牌由包装占位 XX科技 / 旧名 南方财富 统一为南方基金(热线 400-889-8899 / 官网 nffund.com),系统名改为「智能服务系统」; 同步追加 §0.4 修订记录行,工程记录行保留原占位字面以支撑硬编码扫描验收。 2) 开发文档:清理 28 份已作废/残留文档(14 份移出归档 + 14 份仓库副本), 新增《文档规整方案与开发前待决事项-2026-09-17》。 3) 客服agent 四份交付文档首次纳入本分支。
This commit is contained in:
@@ -0,0 +1,141 @@
|
||||
# 本机开发环境搭建记录(2026-09-10)
|
||||
|
||||
> 背景:接手客服 Agent 项目时,`group_fqcd_jr` 工作区在这台机器上**从未初始化过**。
|
||||
> 本文记录实际做了什么、当前状态、以及两个仍然存在的环境限制,供后续接手人(人或 AI)复用,避免重复踩坑。
|
||||
>
|
||||
> 本文是环境记录,**不是**数据库设计文档,不改变 `docs/00-新数据库基线设计.md` 的基线地位。
|
||||
|
||||
## 1. 做了什么
|
||||
|
||||
### 1.1 Python 解释器与依赖
|
||||
|
||||
- 项目 `pyproject.toml` 要求 `requires-python = ">=3.13,<3.14"`;`docs/09`/`docs/14` 要求
|
||||
`conda activate jr_py313`。**该 conda 环境在本机不存在**,机器上其它 conda 环境(`jinrong`/`conda_3.13`/`agent`)
|
||||
依赖均不完整。本机默认 `python` 是 3.10.4,**低于项目要求,不可用**。
|
||||
- 实际做法:用 anaconda 的 Python 3.13.5 在项目内创建 `.venv`(`.venv/` 已在 `.gitignore` 中):
|
||||
```powershell
|
||||
& "C:\Users\Windows\anaconda3\python.exe" -m venv .venv
|
||||
```
|
||||
- 本机 `ensurepip` 会因临时目录权限失败,因此把 `.venv/pyvenv.cfg` 的
|
||||
`include-system-site-packages` 改为 `true`,复用 anaconda 已装的一批包(含 pip)。
|
||||
- 随后补齐缺失依赖:
|
||||
```powershell
|
||||
.\.venv\Scripts\python.exe -m pip install "asyncmy>=0.2,<1" "redis>=5.2,<6" "neo4j>=5.28,<6" `
|
||||
"pytest-asyncio>=0.25,<1" "ruff>=0.9,<1" "mypy>=1.14,<2" aiosqlite
|
||||
```
|
||||
|
||||
**发现一处依赖清单缺项**:测试套件在 5 个文件中使用 `sqlite+aiosqlite` DSN
|
||||
(`tests/unit/worker/test_offsite_mail_worker.py`、`tests/unit/service/test_offsite_mail_adapter.py`、
|
||||
`tests/unit/service/test_offsite_document_recognition_adapter.py`、`tests/unit/service/test_offsite_smtp_adapter.py`),
|
||||
但 `pyproject.toml` 的 `dev` 附加依赖和 `requirements.txt` **都没有声明 `aiosqlite`**,
|
||||
导致这 4 个 worker 测试在干净环境下必然报 `ModuleNotFoundError: No module named 'aiosqlite'`。
|
||||
本文记录该问题但**未擅自修改依赖清单**——是否把 `aiosqlite` 正式加进 `dev` 依赖,需要项目负责人确认。
|
||||
|
||||
### 1.2 `.env`
|
||||
|
||||
`.env` 不提交 git(已在 `.gitignore`)。按 `docs/09` §1 从 `.env.example` 复制后填写本机值。
|
||||
本机实际使用的关键值:
|
||||
|
||||
| 键 | 本机值 | 说明 |
|
||||
|---|---|---|
|
||||
| `MYSQL_DSN` | `mysql+asyncmy://jr_app:change-me@127.0.0.1:3306/jr_agent` | 与 `.env.example` 约定一致 |
|
||||
| `REDIS_URL` | `redis://127.0.0.1:6379/0` | 本机 6379 可用 |
|
||||
| `MILVUS_URI` | `http://127.0.0.1:19530` | **当前不可用**,见第 3 节 |
|
||||
| `NEO4J_URI` | `bolt://127.0.0.1:7687` | **当前不可用**,见第 3 节 |
|
||||
| `DASHSCOPE_API_KEY` | 空 | 子项目 A 的 embedding 端点密钥,**待用户提供** |
|
||||
|
||||
### 1.3 JWT 密钥
|
||||
|
||||
`config/jwt/` 原本整个不存在(该目录已在 `.gitignore`)。用 `cryptography` 生成 RS256 2048 位密钥对:
|
||||
|
||||
- `config/jwt/jwt-private.pem`:PKCS8,**只用于签发测试 Token**(服务端不读它);
|
||||
- `config/jwt/jwt-public.pem`:SubjectPublicKeyInfo,`JwtAuthenticator` 只读公钥验签。
|
||||
|
||||
生成后已做**签发→验签往返验证**(`sub=9001`,含 `iss`/`aud`/`exp`/`nbf`/`jti` 全部必填声明),通过。
|
||||
|
||||
### 1.4 数据库
|
||||
|
||||
本机 MySQL 是**原生安装的 MySQL 8.0.27**(不是 Docker),凭据 `root`/`123456`(实测确认),
|
||||
原有 18 个业务库(`dify`、`wolin_stu_sys` 等)**未做任何改动**。
|
||||
|
||||
为项目新建(幂等):
|
||||
|
||||
- 数据库 `jr_agent`(`utf8mb4` / `utf8mb4_0900_ai_ci`);
|
||||
- 用户 `jr_app`@`localhost` 与 `jr_app`@`127.0.0.1`,密码 `change-me`,仅授权 `jr_agent.*`。
|
||||
|
||||
**初始化顺序(重要,项目文档未写明这一点)**:基线表**不由 Alembic 创建**。
|
||||
`alembic/versions/20260909_agent_platform_v31.py` 的 `down_revision = None`,只创建 9 张平台增量表;
|
||||
而它之后的 `20260909_session` 迁移会对 `sys_user` 建外键,因此**如果直接跑 `alembic upgrade head` 会报
|
||||
`(1824, "Failed to open the referenced table 'sys_user'")`**。正确顺序是:
|
||||
|
||||
```powershell
|
||||
# 1) 先应用基线建表脚本(39 条 CREATE TABLE,脚本自带 SET FOREIGN_KEY_CHECKS=0/1 包裹)
|
||||
# 该文件由 tools/generate_baseline_sql.py 从 docs/00 生成,代码库中没有任何地方自动应用它。
|
||||
# 2) 再跑迁移
|
||||
.\.venv\Scripts\python.exe -m alembic upgrade head
|
||||
# 3) 校验
|
||||
.\.venv\Scripts\python.exe tools\audit_schema.py
|
||||
```
|
||||
|
||||
结果:`schema audit passed: 59 business tables`,与 `TODO.md` 记录的 59 张一致。
|
||||
|
||||
**顺带取得一项 spec 需要的事实**:现库 `fin_knowledge_meta.milvus_collection` 实测为
|
||||
`varchar(64) NOT NULL`(默认值空),从现库层面印证了子项目 A 设计文档 §3.1 的修正结论
|
||||
——该字段是基线自带、无需新增迁移,且因 `NOT NULL` 必须逐行显式赋值。
|
||||
|
||||
## 2. 验收状态(2026-09-10 实测)
|
||||
|
||||
| 检查项 | 命令 | 结果 |
|
||||
|---|---|---|
|
||||
| 全量测试 | `pytest -q` | **183 passed** |
|
||||
| 静态检查 | `ruff check app tests` | All checks passed |
|
||||
| 类型检查 | `mypy app` | Success: no issues found in 104 source files |
|
||||
| 数据库结构 | `tools/audit_schema.py` | passed: 59 business tables |
|
||||
| JWT 往返 | 签发→验签 | 通过 |
|
||||
| 服务连通 | MySQL / Redis | 可用;Milvus / Neo4j **不可用** |
|
||||
|
||||
183 passed 与 `to_do_list.md` 第 14 项记录的"全量 183 passed"完全一致,说明环境搭建正确、代码未被改动破坏。
|
||||
|
||||
## 3. 两个仍然存在的环境限制
|
||||
|
||||
### 3.1 pytest 临时目录 ACL 异常(本机环境问题,非项目缺陷)
|
||||
|
||||
本机 pytest 每次新建的 basetemp(`pytest-of-Windows` 及 `--basetemp` 指定的目录)会被套上
|
||||
**连属主都 `Access is denied` 的 ACL**,导致:
|
||||
|
||||
- 直接跑 `pytest` 时,8 个使用 `tmp_path` 夹具的测试在 setup 阶段报 `PermissionError`,
|
||||
会话结束时还会在 `cleanup_dead_symlinks` 崩一次(此时**测试本身其实已经跑过**);
|
||||
- 该 ACL 无法用 `Remove-Item -Force` 或 `takeown` + `icacls` 修复。
|
||||
|
||||
已确认这与 DSH 沙箱无关(在无沙箱模式下同样复现),是"anaconda Python 3.13 + Windows + `tempfile` 0o700 模式"
|
||||
组合下的环境问题。**它不影响项目代码正确性**:把 `tmp_path` 指向普通目录后,
|
||||
同一批测试全部通过,全量结果即为上表的 183 passed。
|
||||
|
||||
排查过程中的有效手段(供后续复用):用 `-p` 加载一个工作区内的临时插件覆盖 `tmp_path` 夹具,
|
||||
即可把这 8 个测试的 setup 错误还原为真实结果。**注意 pytest 只自动加载名为 `conftest.py` 的文件**,
|
||||
放在 `tests/` 之外、名字不是 `conftest.py` 的模块必须通过 `-p` 显式加载。
|
||||
|
||||
### 3.2 Milvus / Neo4j 不可用
|
||||
|
||||
Docker Desktop 当前未运行,`19530`(Milvus)与 `7687`/`7474`(Neo4j)端口均关闭。
|
||||
影响:
|
||||
|
||||
- 无法核实 Milvus 中**是否已被胜宇建过**同名的 `fin_faq_collection`/`fin_product_collection`/`fin_policy_collection`
|
||||
集合及其字段结构(子项目 A §9 第 2 项,仍待确认);
|
||||
- 无法执行 Milvus 建集合脚本与向量写入/检索的真实联调;
|
||||
- `tests/environment/check_services.py` 无法完整通过。
|
||||
|
||||
Milvus 可用后需要执行:先查现有集合名与 schema,确认无冲突后再跑
|
||||
`tools/setup_milvus_knowledge_collections.py`。
|
||||
|
||||
## 4. 待用户确认的外部事实(当前仍未解决)
|
||||
|
||||
1. **DashScope API Key 与额度**:子项目 A 的 `text-embedding-v3` 端点需要一条真实密钥
|
||||
(`.env` 中变量名已预留为 `DASHSCOPE_API_KEY`,`secret_ref` 用 `env:DASHSCOPE_API_KEY`),
|
||||
以及该账号额度/计费能否覆盖本项目调用量。
|
||||
2. **`context_window` 取值**:创建 `ModelEndpointConfig` 记录时该字段必填,
|
||||
需按阿里云官方文档确认 `text-embedding-v3` 的单次输入 Token 上限。
|
||||
3. **`agent_faq_synonym.created_by` 用哪个 `sys_user.id`**:该列非空且带外键 `fk_synonym_created_by → sys_user(id)`,
|
||||
导入脚本必须填一个真实存在的用户 ID(详见子项目 A 设计文档 §4.1)。
|
||||
4. **Milvus 集合归属**:见 3.2。
|
||||
5. **`aiosqlite` 是否正式加入 `dev` 依赖**:见 1.1。
|
||||
Reference in New Issue
Block a user