# PlantAI + RAG + QA 客户端部署包 本目录可以交给客户:不含供应商私钥和明文 `K_master`,只能采集指纹、配置 TPM、验证供应商签名、解封密钥和解密已授权资产。 ## 客户专属配置 — `install.env` 变量详解 以下表格覆盖 `install.env.example` 中所有变量。每客户交付时据此填写 `install.env`。 | 变量 | 默认值 | 作用 | 影响路径 | 每客户必改 | 取值依据 | |------|--------|------|----------|:----------:|----------| | `PLANTAI_ROOT` | `/opt/PlantAI` 或 `$HOME/PlantAI` | 安装根目录,其下自动创建所有子目录 | → `bin/` `config/` `assets/` `data/` `releases/` `runtime/` | 通常不改 | 客户目录规范(如 `/data/PlantAI`) | | `RELEASE_SRC` | `./release` | 供应商发行包解压目录,安装时从此取 VERSION / app/ / assets/ / config/ | → `$PLANTAI_ROOT/releases//` 的源 | 不改 | 保留默认值 | | `DEVICE_ID` | `$(hostname)` | 设备业务标识,写入许可证和日志,用于绑定设备身份 | → 出现在 `license.json` / 监控系统 | **必改** | `<客户缩写>-<机器角色>-<序号>`,如 `huanuo-web01` | | `PLANTAI_WEB_PORT` | `7880` | PlantAI Web 服务监听端口 | → 服务绑定端口 | 偶尔改 | 客户现有服务已占用时 | | `RAG_PORT` | `7900` | RAG 服务监听端口 | → 服务绑定端口 | 偶尔改 | 客户现有服务已占用时 | | `PLANTAI_PYTHON` | `python3` | PlantAI 后端使用的 Python 解释器路径 | → 执行 `plantai_client.py` / 后端进程 | **必改** | 问客户 conda 环境路径,如 `/opt/miniconda3/envs/plantai/bin/python` | | `RAG_PYTHON` | 同 `PLANTAI_PYTHON` | RAG 服务使用的 Python 解释器路径 | → 执行 `start_qa_v1_0_0_7908.sh` 等 | **必改** | 同上,通常与 `PLANTAI_PYTHON` 相同 | | `NEO4J_URI` | `bolt://127.0.0.1:7687` | Neo4j 图数据库连接地址 | → 应用通过此 URI 连接图数据库 | 通常改 IP | 客户 Neo4j 实际主机 IP | | `NEO4J_USER` | `neo4j` | Neo4j 用户名 | → 数据库连接认证 | 通常不改 | 除非客户改了用户名 | | `NEO4J_PASSWORD` | 无 | Neo4j 密码 | → 数据库连接认证 | **必改** | 客户管理员提供,**禁用默认/空密码** | | `QDRANT_URL` | `http://127.0.0.1:6333` | Qdrant 向量数据库 HTTP 地址 | → 应用通过此 URL 读写向量 | 通常改 IP | 客户 Qdrant 实际主机 IP | | `V15_QDRANT_COLLECTION` | 无 | Qdrant 集合名,反映客户 + 数据版本 | → 读写此集合中的向量数据 | **必改** | `v15_<客户缩写>_<日期>`,如 `v15_huanuo_20260701` | | `V15_BGE_MODEL` | `bge-m3:567m` | Ollama 中的 embedding 模型名 | → 文本向量化使用的模型 | 不改 | 仅更换 embedding 策略时动 | | `V15_OLLAMA_EMBED_URL` | `http://127.0.0.1:11434` | Ollama 服务 URL | → embedding API 调用地址 | 偶尔改 | Ollama 不在本机时改 IP | | `INSTALL_USER_SERVICE` | `0` | 是否注册 systemd --user 自启服务 | → `$HOME/.config/systemd/user/plantai.service` | 可选 | 客户要求开机自启时设 `=1` | **安全要求:** - `install.env` 创建后执行 `chmod 600` - **只写入真实密码**到 `install.env`,`install.env.example` 永远只含占位符 - `install.env` 包含客户凭证,禁止提交到代码仓库或分享 ## 交付结构 ```text client/ bin/plantai_client.py # 客户端工具(采集指纹、TPM、解密) bin/PlantAI-launcher # 启动器(解密代码运行资产到 tmpfs,启动三项目) install_plantai.sh # 安装脚本(fingerprint / install / tpm2-setup) install.env.example # ⬅ 客户据此创建 install.env(每客户不同) phase_d_tpm.sh # 阶段 D:TPM 初始化 + 指纹采集(硬件) phase_d_swtpm_test.sh # 软件 TPM 测试版本 README.md # 本文件 release/ ⬅ 解压供应商发行包到这里 VERSION app/PlantAI_compiled/ app/RAG/ app/QA/ app/start_all.sh DELIVERY_MANIFEST.json assets/runtime-assets.enc assets/runtime-assets.manifest.json config/supplier_public_key.pem ``` 另随包交付 `plantai-rag-runtime-data-.tar` 及对应 `.sha256`,其中包含 Qdrant、Neo4j 数据卷、BGE reranker 和本地 Ollama 模型 `bge-m3:567m`、`qwen2.5:14b-instruct`。数据库卷不放入 `/dev/shm`,避免约 70GB 持久数据占满内存文件系统。 > `install.env`(含真实密码)由客户在部署时根据 `install.env.example` 创建,不包含在初始交付包中。 ## 每客户修改指南(交付前必做) `install.env.example` → `install.env` 按上方表格填写即可,此处只列 README 中需要客户化的文本: | 位置 | 当前内容 | 改为 | |------|----------|------| | 准备配置 | `tar -C release -xzf plantai-rag-release-1.0.0.tar.gz` | 版本号改为本次实际版本 | | 导入授权 | `PROVISION_BUNDLE=/path/to/plantai-provision-DEVICE.tar.gz` | `DEVICE` 替换为 `install.env` 中 `DEVICE_ID` | | 正式启动 | `PLANTAI_ROOT=/opt/PlantAI` | 改为 `install.env` 中 `PLANTAI_ROOT` 值 | | 外部服务 | `ollama pull qwen3:0.6b` | 模型版本按本次实际版本改 | 另在 README 末尾追加客户档案: ```markdown ## 本次交付记录 - **客户名称**: - **DEVICE_ID**: - **发行包版本**: - **交付日期**: - **供应商负责人**: ``` ### 交付前 checklist - [ ] `client/` 中删除了 `install.env`(只留 `.example`) - [ ] `client/` 中删除了 `package_client.sh` - [ ] `install.env.example` 中无真实密码 - [ ] 发行包 `plantai-rag-release-.tar.gz` 已单独发给客户 ## 1. 准备配置与发行包 ```bash cp install.env.example install.env chmod 600 install.env mkdir -p release tar -C release -xzf plantai-rag-release-1.0.0.tar.gz sha256sum -c release/SHA256SUMS ``` 在 `install.env` 设置安装路径、Python 解释器以及 Neo4j/Qdrant/Ollama 变量。真实密码不要写入 `install.env.example`。 ## 2. TPM 2.0 初始化(每台目标机只做一次) 推荐直接执行阶段 D 一键脚本: ```bash ./phase_d_tpm.sh ``` 它会依次检查 TPM、复用或创建 TPM 密钥、采集指纹,并拒绝缺少 TPM 公钥/attestation 的弱指纹。 下面是等价的手工命令,仅用于排错: ```bash ls -l /dev/tpmrm0 /dev/tpm0 tpm2_getrandom 8 ./install_plantai.sh tpm2-setup ``` 不要删除 `$PLANTAI_ROOT/config/tpm/`,也不要反复运行初始化。更换 TPM/主板或删除持久化 TPM key 后,旧授权将无法解封。 ## 3. 采集指纹并交给供应商 ### 无真实 TPM 时的软件测试入口 ```bash ./phase_d_swtpm_test.sh ``` 该入口会使用端口 2321/2322 的 swtpm,自动运行阶段 D,并在指纹中写入 `test_only_swtpm=true`。它只能验证流程,不能提供硬件级保护。阶段 E 测试签发必须显式设置 `ALLOW_SOFTWARE_TPM_TEST=1`。 ```bash ./install_plantai.sh fingerprint ``` 将 `$PLANTAI_ROOT/config/device_fingerprint.json` 发给供应商。生产授权必须包含 `tpm_public_key` 和 `attestation`;只有普通 DMI/磁盘信息的指纹不能提供 TPM 硬件绑定。 ## 4. 导入授权并安装 ```bash PROVISION_BUNDLE=/path/to/plantai-provision-DEVICE.tar.gz ./install_plantai.sh install ``` 校验并展开随包交付的持久化运行数据: ```bash sha256sum -c plantai-rag-runtime-data-1.0.0.tar.sha256 mkdir -p "${PLANTAI_ROOT:-/opt/PlantAI}/data" tar -C "${PLANTAI_ROOT:-/opt/PlantAI}/data" \ -xf plantai-rag-runtime-data-1.0.0.tar ``` 安装结束会执行 `PlantAI-launcher --check-only`:验证许可证签名、硬件匹配、TPM 解封、资产清单和 AES-GCM 解密。任何一步失败都不应启动服务。 正式启动: ```bash PLANTAI_ROOT=/opt/PlantAI /opt/PlantAI/bin/PlantAI-launcher ``` 启动器默认把加密的 PlantAI/RAG `models/prompts` 解密到 `/dev/shm`;QA 的 Qdrant、Neo4j 与大模型保留在 `$PLANTAI_ROOT/data/runtime-assets`。客户启动 脚本会依次检查/启动 Qdrant、Neo4j、独立端口的本地 Ollama、QA、RAG、 PlantAI。不要设置 `PLANTAI_PERSIST_RUNTIME=1`,除非明确接受代码运行资产明文落盘风险。 ## 5. 依赖与端口 客户机需预装 Docker 与 Ollama。启动脚本会使用交付数据自动拉起依赖,无需 联网拉取模型。默认端口如下: ```bash curl -fsS http://127.0.0.1:16333/collections # Qdrant curl -fsS http://127.0.0.1:17474 # Neo4j HTTP curl -fsS http://127.0.0.1:11435/api/tags # 交付专用 Ollama curl -fsS http://127.0.0.1:7925/api/v1/qa-v1-1-73/health curl -fsS http://127.0.0.1:7900/health curl -fsS http://127.0.0.1:7880/ ``` ## 安全边界 - `.so` 是逆向加固,不是密码学加密。 - TPM 保护的是解封 `K_master` 的能力;私钥从不离开 TPM。 - 许可证和 `asset.key.enc` 通过 SHA-256 绑定,不能跨设备混用。 - 客户端没有生成供应商密钥、自签许可证或重新加密资产的命令。 - 供应商的 `plantai_server_package`、私钥、口令文件、`master_keys/` 永不进入 client。