Files
qinglong/docs/operations/ql3-local-ai-feature.md

7.0 KiB
Raw Permalink Blame History

QingLong 3.0 本机 AI Feature 操作手册

本手册只适用于 edgestandalone。Cluster 不得使用本机 Owner command 代替 TLS identity、平台 Policy、quota 和职责分离。

部署与启动边界

基础 edge/standalone application 制品不安装 @qinglong/ai。需要本机 AI 时,部署 显式的 edge-application-aistandalone-application-ai 制品。ADR-0178 已提供 ql3-local-application headless executable 和统一 product composition,但通用 CLI 当前只直接支持 deployment=excludedinstalled AI 必须由受信 host 注入 provider authority。不要把 token 写入启动配置来绕过这道门。受审 composition 为:

@qinglong/local-application/ai-feature

不要改为调用基础 @qinglong/local-application 后自行加载 provider。受审入口只在 9007 head 为 active 且完整 AI schema/history/checksum 通过时动态加载 AI deployment excluded、schema absent 和 inactive 都不会加载 provider。

基础进程配置、SIGTERM drain 和低敏日志见 本机 Headless Application 手册

管理命令不会向常驻进程注入代码,也不包含 watcher:

  • inspect 成功返回 runtimeAction: "none"
  • activatedeactivate 及其 exact replay 成功返回 runtimeAction: "restart_required"

activate 后必须重启应用,重启成功且 AI 状态为 active 才表示 provider 已装配。 deactivate 提交后数据库 admission fence 已立即生效;当前进程下一次 AI 操作会拒绝 请求并进入 drain。完成有界 drain 后重启应用,确认 AI 状态为 inactive 且 provider loader 为零,才完成可验证卸载。

安全前置

  1. 使用 QingLong 部署用户执行,不使用远程 HTTP、聊天输入或公共目录传递命令。
  2. command 目录权限设为 0700command file 设为 0600
  3. 准备当前 local-console credential presentation 和 Owner pepper keyring。
  4. 对已有数据库先完成 SQLite 文件及 -wal/-shm 一致性备份,并记录备份制品的 SHA-256;新库可使用 fresh_database
  5. 不手工修改 QingLong3AiSchemaMigrations、feature transition/head 或 AI 业务表。

以下路径必须替换成当前部署的规范化绝对路径。UUID 必须为新的 v4 UUID。

1. Inspect

{
  "schemaVersion": 1,
  "operation": "ai-feature.inspect",
  "options": {
    "deploymentRoot": "/opt/qinglong",
    "databasePath": "/opt/qinglong/data/qinglong3.sqlite",
    "profile": "edge",
    "ownerPepperKeyringDirectory": "/opt/qinglong/config/owner-keys",
    "credentialFilePath": "/opt/qinglong/private/owner-credential.json"
  },
  "request": {
    "requestId": "ai-feature-inspect-20260727",
    "failureAuditEventId": "00000000-0000-4000-8000-000000000001"
  }
}
ql3-ai-feature run --command-file /opt/qinglong/private/ai-feature-inspect.json

保存输出中的 migrationPlanDigestschemaState

  • absent:没有 AI feature schema
  • partial_or_drifted:可能是中断的 reviewed migration,也可能是漂移;不要手工修表;
  • ready90019007 history/checksum 和全部本机 AI 表已通过只读核对。

2. 首次启用

新库使用:

{
  "schemaVersion": 1,
  "operation": "ai-feature.activate",
  "options": {
    "deploymentRoot": "/opt/qinglong",
    "databasePath": "/opt/qinglong/data/qinglong3.sqlite",
    "profile": "edge",
    "ownerPepperKeyringDirectory": "/opt/qinglong/config/owner-keys",
    "credentialFilePath": "/opt/qinglong/private/owner-credential.json"
  },
  "request": {
    "requestId": "ai-feature-activate-20260727",
    "failureAuditEventId": "00000000-0000-4000-8000-000000000002",
    "mutationId": "ai-feature-activate-20260727",
    "expectedGeneration": 0,
    "expectedState": null,
    "expectedMigrationDigest": "REPLACE_WITH_INSPECTED_PLAN_DIGEST",
    "safety": {
      "mode": "fresh_database",
      "backupEvidenceDigest": null
    }
  }
}

已有库把 safety 改为:

{
  "mode": "backup_verified",
  "backupEvidenceDigest": "REPLACE_WITH_64_HEX_BACKUP_EVIDENCE_DIGEST"
}

命令中断时,保留同一私有 command file 原样重试。不得生成新 mutation 来“绕过” partial schema。只有返回 schemaState=readyactivation.state=active 后,价格管理和 新 ModelInvocation admission 才可用。确认响应中的 runtimeAction="restart_required",随后重启 AI application 制品;不要等待后台 watcher,因为系统不会创建 watcher。

3. 非破坏性停用

先停止产生新 AI 请求并等待现有 invocation 终结。使用 inspect 返回的 generation

{
  "schemaVersion": 1,
  "operation": "ai-feature.deactivate",
  "options": {
    "deploymentRoot": "/opt/qinglong",
    "databasePath": "/opt/qinglong/data/qinglong3.sqlite",
    "profile": "edge",
    "ownerPepperKeyringDirectory": "/opt/qinglong/config/owner-keys",
    "credentialFilePath": "/opt/qinglong/private/owner-credential.json"
  },
  "request": {
    "requestId": "ai-feature-deactivate-20260727",
    "failureAuditEventId": "00000000-0000-4000-8000-000000000003",
    "mutationId": "ai-feature-deactivate-20260727",
    "expectedGeneration": 1,
    "expectedState": "active",
    "expectedMigrationDigest": "REPLACE_WITH_INSPECTED_PLAN_DIGEST",
    "safety": {
      "mode": "preserve_existing",
      "backupEvidenceDigest": null
    }
  }
}

出现 LOCAL_AI_FEATURE_IN_FLIGHT_INVOCATION 时不要删行;等待 completion/recovery 收敛后原样重试。成功停用不会删除 schema、价格、usage、quota、invocation 或审计 事实。确认 runtimeAction="restart_required",等待当前进程有界 drain,再重启并 inspect;重启后的 AI 状态必须为 inactive

4. 重新启用

重新 inspect,使用当前 inactive generation、expectedState: "inactive" 和新的 mutation/request/audit ID。已有 durable data 必须使用 backup_verified,不能再声明 fresh_database

5. 失败处理

  • ...COMMAND_CONFIGURATION_INVALID:命令 shape、路径、权限或字段不合法;
  • ...TRANSITION_CONFLICTplan digest、CAS、mutation replay 或身份发生漂移;
  • ...DATA_SAFETY_REJECTED:空库/备份声明不满足当前 durable data
  • ...FEATURE_NOT_READYschema/history/checksum 未通过;
  • ...FENCE_REJECTED / ...OWNER_REJECTEDcredential/pepper/User/Owner 已漂移;
  • ...IN_FLIGHT_INVOCATION:仍有未完成调用;
  • ...MIGRATION...UNAVAILABLE:保留原命令和数据库,先检查磁盘、锁、完整性与审计, 不手工补 history。

每次操作后再次 inspect,并执行 SQLite integrity_check、备份可恢复性和应用启动门。 若 active head 存在但应用启动返回 LOCAL_AI_FEATURE_APPLICATION_UNAVAILABLE,不得绕过 AI 入口启动成“部分 ready”: 检查部署是否确实包含 @qinglong/ai、90019007 history/checksum、provider credential 和 recovery 状态;修复后重新执行同一产品启动门。