# 申勤物业知识图谱 Agent 问答系统 将 DMS 业务数据按模板导出、评估并构建为 Neo4j 知识图谱,通过 LangGraph + DeepSeek 提供可溯源问答,提供网页操作和命令行测试。 当前生产流程由 `METADATA_TEMPLATE_DIR` 目录内的 `*.xlsx` 模板和 `RELATION_DIR/relation.xlsx` 驱动(默认位置为 `data/templates/metadata/`、`data/templates/`);现有元数据模板为**人员信息、项目信息**。历史 15 类固定模板属于旧流程,不代表当前已接入的数据范围。 ## 快速开始 ### 1. 准备环境和配置 开发与默认部署统一使用 Python 3.14.5(由 `.python-version` 固定;依赖声明下限为 3.11)、uv、可连接的 Neo4j 和原生 Redis,以及 DMS、DeepSeek 的访问配置。以下命令均在项目根目录执行。 ```powershell uv sync --frozen # 仅首次创建配置,已有 .env 时保留原配置 if (!(Test-Path .env)) { Copy-Item .env.example .env } ``` `.env.example` 按用户要求与当前 `.env` 原样同步,包含真实配置和凭据;仅限受控环境使用,不应提交到公开仓库或对外共享。按实际环境编辑 `.env`,配置项以 [.env.example](.env.example) 和 [config.py](src/step2_graph_building/config.py) 为准: | 配置 | 用途 | |---|---| | `EMBEDDING_MODEL_DIR` | 下载和运行共用的模型目录,支持项目外绝对路径 | | `EMBEDDING_MODEL_REPO`、`EMBEDDING_MODEL_SOURCE` | 默认 `Qwen/Qwen3-Embedding-0.6B`、`modelscope`;来源也可设为 `huggingface` | | `METADATA_TEMPLATE_DIR` | metadata 模板目录,当前为 `data/templates/metadata`,支持项目外绝对路径 | | `RELATION_DIR` | 关系文件所在目录,当前为 `data/templates`;文件名固定为 `relation.xlsx` | | `SERVICE_HOST`、`SERVICE_PORT` | 服务监听 IP/地址和端口,当前局域网试用配置为 `0.0.0.0`、`8000` | | `NEO4J_URI`、`NEO4J_USER`、`NEO4J_PASSWORD`、`NEO4J_DATABASE` | 图数据库连接与目标数据库 | | `DEEPSEEK_API_KEY`、`DEEPSEEK_BASE_URL`、`DEEPSEEK_MODEL` | 数据评估、元图谱语义说明与问答模型 | | `REDIS_URL`、`REDIS_CONTEXT_TTL_SECONDS` | 会话持久化;示例保留时间为 1296000 秒(15 天) | | `DMS_BASE_URL`、`DMS_USERNAME`、`DMS_PASSWORD` | 模板取数;运行时自动获取和刷新 token | | `STEP1_ANALYSIS_MAX_WORKERS` | 数据评估并发数,示例为 3 | | `STEP2_RELATION_SIMILARITY_THRESHOLD` | 评分关系阈值,示例为 0.8,须严格大于才连边 | 评分关系使用本地 Qwen3 模型,目录由 `EMBEDDING_MODEL_DIR` 配置(默认 `models/Qwen3-Embedding-0.6B`);Linux 部署入口会自动下载并验证,服务启动本身不下载或预加载模型。Redis 不需要 RedisJSON / RediSearch 模块。 ### 模板和关系文件路径 在 `.env` 中配置两个独立目录;当前配置保持原目录: ```dotenv METADATA_TEMPLATE_DIR=data/templates/metadata RELATION_DIR=data/templates ``` 服务器上的文件可以放在项目之外,例如 Windows: ```dotenv METADATA_TEMPLATE_DIR="D:/knowledge-data/metadata" RELATION_DIR="D:/knowledge-data/relations" ``` Linux 示例: ```dotenv METADATA_TEMPLATE_DIR=/srv/knowledge-data/metadata RELATION_DIR=/srv/knowledge-data/relations ``` `METADATA_TEMPLATE_DIR` 直接存放各 metadata `.xlsx` 文件;`RELATION_DIR` 是目录,程序自动读取其中的 **`relation.xlsx`**,不要把文件名写进此变量。目录必须存在且服务运行账号有读取权限;程序不会自动迁移或创建模板文件。路径含空格时用引号包裹;Windows 示例使用 `/`。 绝对路径按原位置读取,相对路径统一相对于项目根目录解析,不随启动工作目录变化。进程环境变量优先于 `.env`;独立取数/评估的 `--templates`、独立构图的 `--template-dir` 和 `--relations` 可覆盖配置(`--relations` 仍传完整文件路径)。 统一更新的模板指纹检查、取数、数据评估、主键推断和关系构图均读取这两个配置。迁移文件并修改 `.env` 后,重新运行 `uv run python scripts/update_data.py --mode templates`;不会自动移动已有文件。日常服务启动读取已发布版本,不会因为目录改变自动取数或构图。 ### Linux 完整部署(含 uv、Python 和模型) 参考 `proposa-ai` 的部署步骤,新增 [deploy.sh](deploy.sh)。在服务器准备项目代码、`uv.lock`、`.env` 和模板文件后执行: ```bash sh deploy.sh setup # 仅准备 uv、Python、项目依赖和模型 sh deploy.sh templates # 完整准备 → 模板更新 → 自动启动服务(首次部署推荐) sh deploy.sh dms # 完整准备 → 数据更新 → 自动启动服务 sh deploy.sh start # 完整准备 → 启动已有版本 sh deploy.sh restart # 准备完成 → 停止旧服务 → 加载新代码启动 sh deploy.sh model # 准备环境并检查/补下载模型,不更新业务数据 ``` 不传参数时等同 `templates`。脚本自动检测/安装 uv,安装 Python(默认读取 `.python-version` 中的 3.14.5,可用 `DEPLOY_PYTHON` 覆盖),执行 `uv sync --frozen`,再下载并验证本地模型;任一步失败会停止后续步骤。完整模型跳过下载,仍进行本地加载和编码验证。 现有 `.env` 不覆盖;若缺失则从 `.env.example` 创建,完整部署会停止并提示填写真实配置,重新执行后继续。`setup`/`model` 可先完成环境和模型准备。Neo4j、Redis、DMS 和 DeepSeek 仍须提前配置可用,脚本不安装这些外部服务。 此入口完成准备和更新后,通过 `nohup` 在后台启动服务,退出终端后服务继续运行。日志追加到 `.runtime/service.log`,使用 `tail -f .runtime/service.log` 查看启动结果;替换代码后可运行 `sh deploy.sh restart`。脚本不提供崩溃自动拉起或开机自启。日常更新和启动也统一使用此脚本。 详见 [服务器部署说明](docs/deployment.md),包含安装开关、模型源、镜像源、Windows 使用方式及失败恢复。 Linux 的模板/数据更新成功后都会自动启动服务;更新失败不会启动,修复后重新执行对应命令。更新已经成功、仅启动失败时,执行 `sh deploy.sh start` 即可。 ### Windows 本地测试(PowerShell,无需 Git Bash) 在项目根目录打开 PowerShell。已安装 uv 且 `.env` 已配置时,首次或依赖变化后执行: ```powershell uv sync --frozen if ($LASTEXITCODE -ne 0) { throw "环境安装失败" } uv run --frozen python scripts/download_model.py if ($LASTEXITCODE -ne 0) { throw "模型准备失败" } ``` 现有完整模型会跳过下载并验证本地加载。日常操作直接调用 Python 脚本: | 操作 | PowerShell 命令 | |---|---| | 模板、关系或评分阈值更新 | `uv run --frozen python scripts/update_data.py --mode templates` | | 仅业务数据更新 | `uv run --frozen python scripts/update_data.py --mode dms` | | 启动已有版本 | `uv run --frozen python scripts/start_service.py` | | 替换代码后重启 | `uv run --frozen python scripts/start_service.py --restart` | 首次初始化必须选择 `templates`,会取数、评估、构图并发布;`dms` 要求已有匹配的模板版本。上表中的两条更新命令只更新数据。希望更新成功后自动启动时,直接复制执行下面对应代码块,无需等待完成后再手动输入启动命令: **模板更新并启动:** ```powershell uv run --frozen python scripts/update_data.py --mode templates if ($LASTEXITCODE -eq 0) { uv run --frozen python scripts/start_service.py } else { throw "模板更新失败,未启动服务" } ``` **数据更新并启动:** ```powershell uv run --frozen python scripts/update_data.py --mode dms if ($LASTEXITCODE -eq 0) { uv run --frozen python scripts/start_service.py } else { throw "数据更新失败,未启动服务" } ``` 以上写法兼容 Windows PowerShell 5.1 和 PowerShell 7。更新前先在旧服务终端按 `Ctrl+C` 停止服务;仅修改代码时可直接使用 `--restart`。旧版没有管理记录的服务,首次仍需手动停止一次。服务在当前终端前台运行,关闭终端会影响服务。 所有命令沿用 `.env` 中的路径、监听 IP 和端口,不需要每次传参。环境和模型准备失败时先修复再更新;数据更新成功但启动失败时,修复后只执行启动命令即可。 ### 浏览器访问 当前 `.env` 已配置为允许同一局域网的同事访问(从 `.env.example` 新建配置时,请按需调整): ```dotenv SERVICE_HOST=0.0.0.0 SERVICE_PORT=8000 ``` 启动时读取配置,修改后需重启服务。端口必须是 `1–65535` 的整数;缺少配置或配置无效时会报错。通常无需传入监听参数;优先级为命令行参数 > 进程环境变量 > 项目 `.env`。 `0.0.0.0` 表示监听本机所有 IPv4 网络接口,不能作为浏览器访问地址。启动脚本会打印本机和当前可识别的局域网访问地址;本机固定使用: | 页面 | 本机访问地址 | |---|---| | 问答与元图谱 | [打开本机页面](http://127.0.0.1:8000/) | 局域网 IP 可能随网络或 DHCP 分配变化,不在文档中写死。以启动时打印的“局域网访问”地址为准;若未打印,可在服务器电脑运行 `ipconfig` 查看当前网卡的 IPv4 地址,并将 `http://<该地址>:8000/` 发给同事。修改端口后,访问地址也需使用新端口。 日常只需运行此启动命令。启动时检查发布文件并连接 Neo4j、Redis,不重新取数或构图;终端按 `Ctrl+C` 停止。修改 `.env` 后需停止并重新启动服务。 若本机可访问、同事无法访问,检查 Windows 防火墙是否允许当前网络配置文件下的 TCP 8000 入站连接,以及网络是否开启客户端隔离。可让同事在 PowerShell 运行 `Test-NetConnection <启动时打印的局域网IP> -Port 8000` 排查端口连通性。当前服务未接入鉴权与完整权限控制,试用人员可访问现有数据。 ## 数据更新 按变化类型选择模式: | 场景 | 命令 | 元图谱处理 | |---|---|---| | 仅 DMS 业务数据变化 | `uv run python scripts/update_data.py --mode dms` | 保留已有元图谱及其主键定义 | | 模板、字段、关系规则或评分阈值变化 | `uv run python scripts/update_data.py --mode templates` | 重新评估主键并生成元图谱 | | 自动判断(默认模式) | `uv run python scripts/update_data.py --mode auto` | 无版本基线或模板指纹变化时完整更新,否则按 dms 更新 | 三种模式都会重新取数、刷新评估并重建业务图谱。`dms` 模式要求已有且匹配的模板版本基线,否则会拒绝执行。模板保持约定格式时,增删节点类别和关系后重跑更新即可;缺少主键值的记录会逐行警告并跳过,其余有效记录继续更新;原始 Excel 保留。若评估未提供有效唯一键、表头不符或关系配置错误,仍需修复后重跑。 发布清单为 `output/current_release.json`,对应版本的数据、评估和更新报告保存在 `.runtime/releases//`。排错时查看该目录的 `update_report.json`:`warnings` 保存跳过记录的文件、工作表、行号及缺失字段,`skipped_rows` 为跳过总数,`nodes` 中分别记录各模板跳过数和合并数。被跳过记录不参与图谱查询,补齐源数据后重新更新。页面检查元图谱版本变化后刷新展示;仅更新 DMS 时元图谱统计仍是上次模板更新时的快照,实时业务数量以查询结果为准。 ### 更新版本的时间与保留数量 新目录使用北京时间 `YYYYMMDD_HHMMSS_微秒_唯一标识`,例如 `20260904_170319_584831_<唯一标识>`;发布清单记录 `created_at`,更新报告另记录 `finished_at`,均含 `+08:00` 时区。 每次模板或数据更新结束后,在更新锁内清理 `.runtime/releases/`,最多保留 **10份**(包含成功与失败更新)。第10份保留,新增第11份后从最早的可清理版本开始删除;积压超过一份时一次清理到10份。当前发布版本及其引用、刚完成的更新目录受到保护。仅数据更新将元图谱文件原样复制到新目录,元图谱版本和内容不变,避免依赖被删除的旧目录。 已有UUID目录不重命名,以目录最后修改时间参与排序。清理只处理系统命名的版本目录,跳过未知目录、符号链接及目录联接;删除前验证路径边界。被占用或权限不足的目录会保留并提示,可能暂时超过10份,后续更新重试;清理结果写入 `update_report.json` 的 `retention`。更新过程中会短暂出现第11份,结束后清理;本策略控制份数,不是磁盘容量配额。 ### 前端数据质量提醒 服务启动后,图谱页与独立聊天页顶部会显示红色感叹号和缺主键记录总数;没有此类问题时隐藏。点击后按文件分组显示数量,可切换文件查看工作表、Excel行号、缺失字段及每条问题记录的全部字段,缺失主键标红,空值显示“(空)”。嵌入聊天窗口不重复显示提醒。 提醒读取当前发布版本的 `update_report.json`,点击时从同版本 production 工作簿读取问题行,不重新拉取DMS或调用模型。每30秒及窗口重新获得焦点时检查;更新后自动切换当前版本,补齐并成功发布后提醒消失。报告不可用会提示并允许重试,不会误显示为零问题。 ## relation.xlsx 关系规则与判断方式 在 `RELATION_DIR/relation.xlsx`(默认 [data/templates/relation.xlsx](data/templates/relation.xlsx))中,每行定义一条规则,命中后生成 `起点节点 -[边名]-> 终点节点`。表头必须且只能包含以下五列(列顺序可调整);实际列名为 **`判断方法`**,填写时不要改成“判断方式”。 | 列名 | 定义与填写要求 | |---|---| | `起点` | 起点 metadata 模板名,不带 `.xlsx`,例如 `人员信息`。 | | `终点` | 终点 metadata 模板名,不带 `.xlsx`,例如 `项目信息`。 | | `连接字段` | 写成 `起点字段-终点字段`;两端字段须存在于对应模板,且能唯一解析。 | | `判断方法` | 仅支持 `相等`、`包含`、`评分`,每行选择一种。 | | `边名` | 命中后生成的有向关系名称,例如 `服务于`、`父项目为`。 | 设起点字段值为 A、终点字段值为 B,三种方法定义如下: | 判断方法 | 判断条件 | 适用场景与示例 | |---|---|---| | `相等` | 读取后的值类型相同,且值完全相等;不自动去除首尾空格或忽略大小写。 | 工号、项目编号等精确关联。文本 `P001` 与 `P001` 命中,与 ` P001 ` 不命中;数值 `123` 与文本 `"123"` 不命中。 | | `包含` | A、B 都必须是文本;A 是 B 的子串,或 B 是 A 的子串,即双向包含,完全相同也命中。 | 简称与全称、一个字段列出多个项目等场景。`北园 / 南园` 与 `北园` 命中;短文本 `园` 也会与 `北园` 命中,应留意过宽匹配。 | | `评分` | A、B 都必须是文本;使用本地 `Qwen3-Embedding-0.6B` 编码,计算向量余弦相似度,分数**严格大于**阈值才命中。 | 名称表述不同、需要语义相似匹配的场景。假设阈值为 `0.8`,得分 `0.81` 命中,`0.80` 不命中;具体文本得分以模型实际计算为准。 | 评分阈值由 `.env` 的 `STEP2_RELATION_SIMILARITY_THRESHOLD` 统一配置,必须是 `[-1, 1]` 内的有限数(示例配置为 `0.8`),不在 relation 中增加阈值列。评分会连接所有超过阈值的节点对,不只选最高分的一个目标;`相等`、`包含` 不使用评分阈值。 当前文件中的填写示例: | 起点 | 终点 | 连接字段 | 判断方法 | 边名 | |---|---|---|---|---| | 项目信息 | 项目信息 | 上级项目编号-项目编号 | 相等 | 父项目为 | | 人员信息 | 项目信息 | 当前服务项目名称-项目名称 | 包含 | 服务于 | | 人员信息 | 人员证书 | 工号-工号 | 相等 | 拥有证书 | 第一行表示“子项目 → 父项目”。判断条件的对称性不会改变边方向,也不会自动生成反向边。 共同规则: - 空单元格、空字符串和纯空白文本不参与匹配,数值 `0` 不视为空值;非空文本保留原有空格及大小写。 - 同一主键的记录合并后,字段可能保留多个非空值。两端任意一对值命中即可连边;同一规则、同一节点对只保留一条边,评分取命中的最高分。不会把多个值拼成字符串再比较。 - 非空规则行的五列都必须填写。未知模板、不存在或有歧义的连接字段、未知判断方法、重复规则会报错;`包含`、`评分` 遇到非文本的非空连接值也会报错。完全空白的行和工作表可保留。 修改规则或评分阈值后,运行 `uv run python scripts/update_data.py --mode templates` 重新构图并发布。实现依据见 [production.py](src/step2_graph_building/graph/production.py) 中的 `load_rules`、`match_rule` 和 `prepare_graph`。 ## 问答方式 ### 网页 启动服务后,在浏览器打开首页提问。网页默认关闭自动确认,可按测试需要手动开启;确认查询计划后查看回答及来源。不同会话分别保留历史上下文。 ### 命令行 ```powershell # 单次问答;不加 --auto 时逐次等待人工确认 uv run python scripts/ask.py "目前有多少个项目?" --auto # 交互多轮问答 uv run python scripts/ask.py ``` 输入 `清空` 或 `新话题` 重置上下文,输入 `退出` 或 `quit` 结束。`--debug` 显示诊断信息,`--user` 指定用户标识(默认 `admin01`,不代表权限检查已生效)。CLI 上下文仅在当前进程内保留;网页会话使用 Redis 持久化。 ## 当前实现与入口 生产问答在元图谱 `meta.schema_version == 2` 时走以下分支: ```text 问题理解与本轮元图谱快照 → 选择相关数据评估 → 简单查询直接构造 / 完整模型规划 → 计划确认 → Schema 校验与只读查询编译 → Neo4j 查询 → 可溯源回答 ``` 查询支持字段筛选、多值匹配、关系连接和聚合;明细最多返回 200 行,不支持的计划明确说明原因。数据评估只辅助规划,不能替代事实查询。执行前后会检查数据版本,版本变化时要求重新提问。旧元图谱保留接地、能力拓展、双层审查和历史复用流程。 | 位置 | 职责 | |---|---| | `deploy.sh`、`scripts/download_model.py` | Linux 环境引导、模型下载与本地加载验证 | | `src/step0_pre_prepare/` | DMS 自动认证与连接检查 | | `src/step1_data_aggregation/` | 模板驱动取数、字段画像、质量评估 | | `src/step2_graph_building/` | 生产构图、元图谱、配置和发布版本读取 | | `src/step3_qa_agent/agent/production.py` | 生产查询规划、确认、执行与回答 | | `src/step3_qa_agent/retrieval/production_query.py` | 根据元图谱校验 JSON 并编译受控查询 | | `src/step4_web/data_update.py` | 统一数据更新与版本发布 | | `src/step4_web/api.py`、`html/` | 后端服务、会话管理与前端页面 | | `METADATA_TEMPLATE_DIR`、`RELATION_DIR` | metadata 模板与 relation 规则目录,默认位于 `data/templates/` | | `.runtime/releases/`、`output/current_release.json` | 统一更新产物与当前版本指针 | | `api_log/` | 请求、执行结果和错误日志 | | `reference/`、`data/test_data/` | 原始参考资料与测试数据 | ### 问答速度优化 生产分支对可完整表达为单数据集的计数、属性查询和简单列表,在问题理解后直接构造计划, 减少一次规划模型调用;复杂条件、跨关系或用户修改计划时回退完整规划。人工确认与实际查询保留。 理解和规划仅输出必要的紧凑 JSON,省略空字段、默认值和重复字段,保留全部业务条件。 `QA_FAST_PLAN_ENABLED` 与 `QA_COMPACT_INTERMEDIATE_ENABLED` 默认均为 true, 可分别在环境配置中设为 false 关闭;改代码/配置后重启服务即可,无需更新图谱。 请求日志新增阶段耗时、模型流调用记录和快速路径命中原因。说明与验证入口见 [Step3 速度优化](docs/step3-qa-agent.md)。 ### 确认答案后缓存 答案下的“答案正确,加入缓存”用于人工确认;保存后可“撤销缓存”。 查询计划的确认和自动确认不会保存答案缓存。重复提问精确命中后显示“已复用你确认的历史答案”, 直接复用答案和来源。永久保存(不设置TTL),数据版本发布成功后删除全部旧数据版本缓存,按会话、上下文、数据/Schema版本和模型/策略隔离; 新建会话或改变上下文可能不命中,相似问题仍走正常流程。 错误、截断、待澄清、修改过条件及明确依赖历史指代/相对时间的回答不提供缓存按钮。 关闭“历史复用”可绕过读取。`QA_ANSWER_CACHE_ENABLED`默认true; `QA_ANSWER_CACHE_TTL_SECONDS`已停用,即使旧环境仍配置该值也不设置过期时间; 问答缓存清理只操作独立索引,不影响Redis会话上下文的过期策略。服务启动时将尚存的当前版本旧TTL缓存转为永久;已过期消失的记录无法恢复。发布完成后立即清理旧数据版本;Redis故障记录在更新报告的`answer_cache_cleanup`,服务启动及运行期间每60秒重试。原子版本校验阻止旧回答在版本切换后重新入库;用户仍可主动撤销缓存。 修改提示词/权限策略时递增`QA_ANSWER_CACHE_POLICY_VERSION`(默认1),重启后生效。 详细边界与接口见[Step3文档](docs/step3-qa-agent.md)、[API说明](docs/api-reference.md)。 ### 独立构图与历史工具 日常维护使用上面的统一更新入口。`scripts/build_graph.py --check-only` 是独立 Step2 预检:读取 `data/production/`、metadata 模板和 relation;历史默认主键文件 `data/graph_keys.json` 已移除,使用该入口须通过 `--keys <配置路径>` 提供主键配置,**不会跟随统一发布清单选择生产目录**。完整独立构图也不负责切换统一发布清单,不应与统一更新流程混用。 独立 Step2 使用显式主键配置;统一 `templates` 更新则从数据评估取得唯一键。两者都按唯一键合并记录、保留不同非空属性值,并按 relation 规则构建关系。 历史固定模板生成、测试数据生成、显式 JSON 构图及 `build_meta.py` 不属于日常生产操作。详细说明见 [Step2 构图文档](docs/step2-graph-building.md)。 ## 文件保留与清理 `dist/` 是 `uv build` 生成的分发包目录,当前部署直接从源码执行 `uv sync --frozen`,不依赖它。本次已删除旧 wheel;以后需要分发包时可通过 `uv build` 重新生成。 | 文件或目录 | 检查结论 | |---|---| | `dist/` | 已删除旧构建产物;可重建,部署不需要 | | 根目录 `meta_graph_v7.png`、`meta_graph_project_self_loops.png` | 已删除旧生成图片;没有页面或文档引用,生成代码仍保留,重新生成的图片已加入 Git 忽略 | | 根目录、`src/`、`scripts/` 下的 `__pycache__/` | 已清理,可由 Python 自动重建 | | `.uv-cache/` | 下载缓存,可在没有安装/更新任务时清理,但下次安装可能重新下载;本次保留 | | `.venv/`、`models/` | 当前环境和模型资产,正常部署需保留;删后必须重新安装/下载 | | `output/current_release.json`、`.runtime/releases/` | 发布清单及生产数据/元图谱/评估快照,不能当普通缓存删除;每次更新结束后自动保留最多10份运行目录,保护当前发布引用,按时间从旧到新清理 | | `output/` 中字段映射与历史元图谱 | 映射资料仍供辅助脚本读取,历史元图谱仍作兼容回退,保留;两张 production-preview 图片及旧 step2_build_report.json、step2_schema_candidate.json 已清理 | | 旧模板生成、构图、元图谱和检索脚本/模块 | 仍有兼容入口、运行时导入或文档引用,本次保留;移除前需先退役对应功能并做回归 | | `api_log/`、`server.log`、`.runtime/qa/` | 日志和验证证据,本次保留,可按运维留存周期归档 | 部署必须保留 `pyproject.toml`、`uv.lock`、`.python-version`、`.env`、`src/`、`scripts/`、`html/`、`deploy.sh`,以及 `.env` 指向的模板、关系和模型文件。已有服务还依赖当前发布清单及其引用的完整版本文件。源码部署不需要携带旧 wheel 或 Python 缓存;Windows `.venv` 不应复制到 Linux。 ## 排错与验证边界 | 现象 | 检查项 | |---|---| | 服务提示发布文件缺失 | 首次运行先执行 templates 更新;已有版本检查清单指向的文件是否完整 | | Neo4j 连接失败 | 检查数据库是否启动,以及 URI、端口、数据库名和凭据 | | Redis 连接失败 | 检查 Redis 服务和 `REDIS_URL`,服务启动依赖连接成功 | | 更新被拒绝或失败 | 检查模板指纹、唯一键与该版本 `update_report.json`;同一时间只运行一个更新任务 | | 问答提示数据已更新 | 重新提问,建立当前版本的查询上下文 | | 结果为空或问题不支持 | 核对当前模板字段、关系与数据范围;通过页面提示和 `api_log/` 查看执行信息 | 统一更新及生产查询已有实现,真实数据更新、服务启动和页面问答的完整端到端验收仍待完成;历史独立 Step2 的成功记录不能替代这一验收。当前功能状态和实际验证记录见 `feature_list.json`、`development-progress.md`。 更多设计与分步骤说明见 [文档索引](docs/README.md) 和 [技术方案](docs/技术方案.md)。部分分步文档保留阶段性或历史实现说明,使用入口以本 README 对照的当前代码为准。 重启细节与失败恢复见 [服务器部署说明](docs/deployment.md)。内部接口参考已移至 [开发文档](docs/api-reference.md)。 ### 开发环境检查 Windows PowerShell 在项目根目录运行 `./init.ps1`;Linux / macOS 运行 `bash init.sh`。两个入口均检查锁定依赖、Harness 与 Python 编译。Windows 无需安装或配置 Bash;若本机脚本执行策略阻止运行,可使用 `powershell -NoProfile -ExecutionPolicy Bypass -File ./init.ps1`,仅对该进程生效。Codex 的 `setup refresh had errors` 是执行器沙箱初始化故障,与项目脚本无关。 ### 查询条件没有匹配时 生产问答会在明细为空或计数为零时,查询相近的实际属性值。例如“中级电工”可能提示“证书名称:电工 → 水电工”,并保留“级别=中级”。可勾选一个或多个候选后点继续,也可输入多个序号或完整值并用逗号分隔;同一字段选择多个值时按任一值命中重新查询。选择“都不是”会清除其他选项并保留原条件结束。开启自动确认也不会自动替你选择。候选按字符相似度生成且有数量上限,并非完整词表或同义词认定;无需重新构图,重启服务后生效。