AGC 本地配套后端未启动 BgFilter worker,导致角色图抠图回退 Aliyun Matting #257

Closed
opened 2026-09-02 21:05:14 +08:00 by lhk229 · 0 comments
Owner

Issue:AGC 本地配套后端未启动 BgFilter worker,导致角色图抠图回退 Aliyun Matting

Issue 标题

AGC npm run agc 的配套后端未启动或校验 BgFilter worker,角色图生成时本机 8083 连接失败并回退到 Aliyun Matting

问题摘要

本地使用 AGC 客户端生成角色图时,原图生成正常,但后处理没有优先走本机 BgFilter worker,而是在访问 http://127.0.0.1:8083/internal/bgfilter/v1/remove-background 时连续连接失败,最终触发既有的 Aliyun Matting 兜底。

这不是远程 BgFilter provider 调用失败,也不是生产图片处理逻辑错误。当前问题集中在 AGC 开发启动链路:npm run agc 使用的 backend 启动模式只拉起 SpacetimeDB 和 api-server,没有把 BgFilter worker 纳入同一启动单元;AGC 的后端 ready 检查也没有检查 worker 的 /readyz

影响

  • AGC 本地角色图、图标素材、UI 素材提取等需要 background_mode=flat 的流程,可能稳定回退到 Aliyun Matting。
  • 本地联调无法验证“AGC → api-server → loopback BgFilter worker → 远程 BgFilter provider”的正常路径。
  • 客户端启动阶段不会暴露 worker 缺失,只有真正生成图片时才出现连接重试和延迟。
  • 生成结果仍可成功落库,但最终素材的处理 provider 会记录为 Aliyun Matting,容易误判为生成 provider 选错。

目前未发现生产部署路径存在同一个启动遗漏。生产使用独立的 genarrative-bgfilter-worker.service,本 Issue 仅针对 AGC 本地开发启动路径。

复现条件

  1. 在仓库根目录执行 npm run agc
  2. AGC 客户端连接本地 API,或使用 AGC 配套后端默认的本地 API。
  3. 登录后生成一张需要角色图自动抠图的图片。
  4. 查看 api-server 日志和生成结果的素材 provider。

本次实际证据

启动状态

本次 .app/dev-stack.json 的运行命令为 backend,状态中:

api-server: running
spacetime: running
bgfilter-worker: idle

API 日志

logs/api-server/api-server-20260902-123319.log 记录:

12:41:37 ~ 12:42:07 连接本机 127.0.0.1:8083 失败,共 7 次重试
12:42:14              worker_code="deadline_exceeded"
12:42:14              editor_bgfilter_worker_fallback_to_aliyun_matting

失败请求目标为:

http://127.0.0.1:8083/internal/bgfilter/v1/remove-background

同一时间段没有对应的 logs/bgfilter-worker/ 运行日志,也没有 worker 侧远程 provider 调用记录,因此请求没有进入本机 BgFilter worker,更没有发起远程 BgFilter provider 调用。

兜底结果

随后日志显示:

12:42:16  开始调用阿里云通用抠图 SegmentCommonImage
12:42:17  阿里云通用抠图调用成功
12:42:22  最终 image.png 上传成功

本地数据库中同一任务同时存在:

  • VectorEngine / gpt-image-2 的 provider 原图;
  • Aliyun Matting / segment-common-image 的最终处理图。

这说明原图生成成功,只有本地 BgFilter 后处理阶段未运行。

根因定位

1. AGC 使用了 backend 启动模式

脚本链路为:

npm run agc
→ agc:serve
→ apps/ai-game-creator-shell/scripts/start-dev-stack.mjs
→ npm run agc:backend
→ node scripts/dev.mjs backend

2. backend 分支没有启动 Rust 双进程

文件:scripts/dev.mjs

当前 startCommand('backend') 只执行:

await this.startSpacetimeForFullStack();
await this.services.get('api-server').start();
await this.waitForApiServer();

bgfilter-worker 的启动和 readiness 等待只在 startRustServicePair() 中执行。该双进程编排目前被 allapi-server 路径使用,backend 路径没有复用。

3. AGC 的后端 ready 检查漏掉 worker

文件:apps/ai-game-creator-shell/scripts/start-dev-stack.mjs

当前 isBackendReady() 只检查:

api-server /healthz
SpacetimeDB /v1/ping

没有检查:

bgfilter-worker /readyz

因此 API 和 SpacetimeDB 正常时,AGC 会认为配套后端已 ready,即使 8083 没有监听。

4. 形成“启动成功、业务时才失败”的延迟暴露

父 API 的 BgFilter 客户端仍按配置指向本机 127.0.0.1:8083。由于 worker 没有启动,只有在图片生成进入抠图阶段时才发生连接重试,达到预算后才回退 Aliyun。

建议修复方向

推荐采用组合修复:

A. 让 backend 复用 startRustServicePair()

启动顺序统一为:

SpacetimeDB
→ 启动 bgfilter-worker
→ 等待 bgfilter-worker /readyz
→ 启动 api-server
→ 等待 api-server /healthz

同时把 backend 的 watcher 纳入:

spacetime
api-server
bgfilter-worker

这样 AGC 仍只持有一个 agc:backend 子进程,API 和 worker 的启动、重启、日志及退出清理都沿用现有双进程机制。

B. AGC 后端复用门禁增加 worker readiness

isBackendReady() 应同时要求:

api-server 状态 active 且 /healthz 返回 2xx
SpacetimeDB 状态 active 且 /v1/ping 返回 2xx
bgfilter-worker 状态 active 且 /readyz 返回 2xx

避免 AGC 复用“API 和数据库正常、worker 缺失”的不完整本地后端。

C. 保留现有 fallback 语义

不要因为本地启动问题而删除或绕过:

BgFilter → Aliyun Matting → 本地键色

修复后仍应允许真实的远程 BgFilter provider 故障按既有设计回退到 Aliyun。只有在 worker 未启动时,才应在 AGC 启动阶段直接暴露问题。

不建议的做法

  • 不建议让 api-server 绕过本机 worker 直接调用远程 BgFilter。
  • 不建议关闭 Aliyun fallback 来掩盖 worker 启动问题。
  • 不建议在 start-dev-stack.mjs 内再复制一套 worker 启动、端口、日志和退出清理逻辑。
  • 不建议只增加 /readyz 检查而不启动 worker;那只能把业务时失败改成启动时失败。

验收标准

启动与复用

  • npm run agc 启动后,.app/dev-stack.jsonbgfilter-worker 为 active/running。
  • http://127.0.0.1:8083/readyz 返回 200,端口漂移时以实际状态文件地址为准。
  • AGC 不会在 worker 缺失时误判配套后端 ready。
  • 停止 AGC 后,API 和 BgFilter worker 均能被同一启动器收束,不留下孤儿进程。

业务链路

  • 本机 worker 正常且远程 provider 正常时,角色图最终素材记录的处理 provider 为 BgFilter
  • 本机 worker 正常但远程 provider 失败时,仍按设计回退到 Aliyun Matting
  • 本机 worker 缺失时,AGC 启动阶段应失败并明确提示,而不是等生成图片时重试数十秒后才降级。

测试

  • scripts/dev.test.ts 增加 backend 路径会启动并等待 Rust 双进程的测试。
  • apps/ai-game-creator-shell/tests/start-dev-stack.test.ts 增加 worker readiness 纳入 isBackendReady() 的测试。
  • 增加“API + SpacetimeDB 正常但 worker 缺失时不可复用”的回归场景。
  • 保留并验证 BgFilter provider 失败时 Aliyun fallback 的既有测试。

范围与非目标

本 Issue 只处理:

  • AGC 本地开发启动器;
  • backend 模式的 Rust 服务编排;
  • AGC 后端 ready/reuse 门禁;
  • 对应启动和回退测试。

本 Issue 不处理:

  • 225/226 的请求标记和 tracking 数据模型;
  • 生产 systemd 服务编排;
  • BgFilter provider 协议、模型参数和远程服务实现;
  • Aliyun Matting 或本地键色算法本身。

当前结论

这是一个 AGC 本地开发启动缺陷:npm run agcbackend 模式漏启动 BgFilter worker,且 ready 检查漏检 worker。生产处理逻辑和 fallback 逻辑在本次证据范围内是正确的。

# Issue:AGC 本地配套后端未启动 BgFilter worker,导致角色图抠图回退 Aliyun Matting ## Issue 标题 AGC `npm run agc` 的配套后端未启动或校验 BgFilter worker,角色图生成时本机 `8083` 连接失败并回退到 Aliyun Matting ## 问题摘要 本地使用 AGC 客户端生成角色图时,原图生成正常,但后处理没有优先走本机 BgFilter worker,而是在访问 `http://127.0.0.1:8083/internal/bgfilter/v1/remove-background` 时连续连接失败,最终触发既有的 Aliyun Matting 兜底。 这不是远程 BgFilter provider 调用失败,也不是生产图片处理逻辑错误。当前问题集中在 AGC 开发启动链路:`npm run agc` 使用的 `backend` 启动模式只拉起 SpacetimeDB 和 `api-server`,没有把 BgFilter worker 纳入同一启动单元;AGC 的后端 ready 检查也没有检查 worker 的 `/readyz`。 ## 影响 - AGC 本地角色图、图标素材、UI 素材提取等需要 `background_mode=flat` 的流程,可能稳定回退到 Aliyun Matting。 - 本地联调无法验证“AGC → api-server → loopback BgFilter worker → 远程 BgFilter provider”的正常路径。 - 客户端启动阶段不会暴露 worker 缺失,只有真正生成图片时才出现连接重试和延迟。 - 生成结果仍可成功落库,但最终素材的处理 provider 会记录为 `Aliyun Matting`,容易误判为生成 provider 选错。 目前未发现生产部署路径存在同一个启动遗漏。生产使用独立的 `genarrative-bgfilter-worker.service`,本 Issue 仅针对 AGC 本地开发启动路径。 ## 复现条件 1. 在仓库根目录执行 `npm run agc`。 2. AGC 客户端连接本地 API,或使用 AGC 配套后端默认的本地 API。 3. 登录后生成一张需要角色图自动抠图的图片。 4. 查看 `api-server` 日志和生成结果的素材 provider。 ## 本次实际证据 ### 启动状态 本次 `.app/dev-stack.json` 的运行命令为 `backend`,状态中: ```text api-server: running spacetime: running bgfilter-worker: idle ``` ### API 日志 `logs/api-server/api-server-20260902-123319.log` 记录: ```text 12:41:37 ~ 12:42:07 连接本机 127.0.0.1:8083 失败,共 7 次重试 12:42:14 worker_code="deadline_exceeded" 12:42:14 editor_bgfilter_worker_fallback_to_aliyun_matting ``` 失败请求目标为: ```text http://127.0.0.1:8083/internal/bgfilter/v1/remove-background ``` 同一时间段没有对应的 `logs/bgfilter-worker/` 运行日志,也没有 worker 侧远程 provider 调用记录,因此请求没有进入本机 BgFilter worker,更没有发起远程 BgFilter provider 调用。 ### 兜底结果 随后日志显示: ```text 12:42:16 开始调用阿里云通用抠图 SegmentCommonImage 12:42:17 阿里云通用抠图调用成功 12:42:22 最终 image.png 上传成功 ``` 本地数据库中同一任务同时存在: - `VectorEngine / gpt-image-2` 的 provider 原图; - `Aliyun Matting / segment-common-image` 的最终处理图。 这说明原图生成成功,只有本地 BgFilter 后处理阶段未运行。 ## 根因定位 ### 1. AGC 使用了 `backend` 启动模式 脚本链路为: ```text npm run agc → agc:serve → apps/ai-game-creator-shell/scripts/start-dev-stack.mjs → npm run agc:backend → node scripts/dev.mjs backend ``` ### 2. `backend` 分支没有启动 Rust 双进程 文件:`scripts/dev.mjs` 当前 `startCommand('backend')` 只执行: ```js await this.startSpacetimeForFullStack(); await this.services.get('api-server').start(); await this.waitForApiServer(); ``` 而 `bgfilter-worker` 的启动和 readiness 等待只在 `startRustServicePair()` 中执行。该双进程编排目前被 `all` 和 `api-server` 路径使用,`backend` 路径没有复用。 ### 3. AGC 的后端 ready 检查漏掉 worker 文件:`apps/ai-game-creator-shell/scripts/start-dev-stack.mjs` 当前 `isBackendReady()` 只检查: ```text api-server /healthz SpacetimeDB /v1/ping ``` 没有检查: ```text bgfilter-worker /readyz ``` 因此 API 和 SpacetimeDB 正常时,AGC 会认为配套后端已 ready,即使 `8083` 没有监听。 ### 4. 形成“启动成功、业务时才失败”的延迟暴露 父 API 的 BgFilter 客户端仍按配置指向本机 `127.0.0.1:8083`。由于 worker 没有启动,只有在图片生成进入抠图阶段时才发生连接重试,达到预算后才回退 Aliyun。 ## 建议修复方向 推荐采用组合修复: ### A. 让 `backend` 复用 `startRustServicePair()` 启动顺序统一为: ```text SpacetimeDB → 启动 bgfilter-worker → 等待 bgfilter-worker /readyz → 启动 api-server → 等待 api-server /healthz ``` 同时把 `backend` 的 watcher 纳入: ```text spacetime api-server bgfilter-worker ``` 这样 AGC 仍只持有一个 `agc:backend` 子进程,API 和 worker 的启动、重启、日志及退出清理都沿用现有双进程机制。 ### B. AGC 后端复用门禁增加 worker readiness `isBackendReady()` 应同时要求: ```text api-server 状态 active 且 /healthz 返回 2xx SpacetimeDB 状态 active 且 /v1/ping 返回 2xx bgfilter-worker 状态 active 且 /readyz 返回 2xx ``` 避免 AGC 复用“API 和数据库正常、worker 缺失”的不完整本地后端。 ### C. 保留现有 fallback 语义 不要因为本地启动问题而删除或绕过: ```text BgFilter → Aliyun Matting → 本地键色 ``` 修复后仍应允许真实的远程 BgFilter provider 故障按既有设计回退到 Aliyun。只有在 worker 未启动时,才应在 AGC 启动阶段直接暴露问题。 ## 不建议的做法 - 不建议让 `api-server` 绕过本机 worker 直接调用远程 BgFilter。 - 不建议关闭 Aliyun fallback 来掩盖 worker 启动问题。 - 不建议在 `start-dev-stack.mjs` 内再复制一套 worker 启动、端口、日志和退出清理逻辑。 - 不建议只增加 `/readyz` 检查而不启动 worker;那只能把业务时失败改成启动时失败。 ## 验收标准 ### 启动与复用 - `npm run agc` 启动后,`.app/dev-stack.json` 中 `bgfilter-worker` 为 active/running。 - `http://127.0.0.1:8083/readyz` 返回 `200`,端口漂移时以实际状态文件地址为准。 - AGC 不会在 worker 缺失时误判配套后端 ready。 - 停止 AGC 后,API 和 BgFilter worker 均能被同一启动器收束,不留下孤儿进程。 ### 业务链路 - 本机 worker 正常且远程 provider 正常时,角色图最终素材记录的处理 provider 为 `BgFilter`。 - 本机 worker 正常但远程 provider 失败时,仍按设计回退到 `Aliyun Matting`。 - 本机 worker 缺失时,AGC 启动阶段应失败并明确提示,而不是等生成图片时重试数十秒后才降级。 ### 测试 - `scripts/dev.test.ts` 增加 `backend` 路径会启动并等待 Rust 双进程的测试。 - `apps/ai-game-creator-shell/tests/start-dev-stack.test.ts` 增加 worker readiness 纳入 `isBackendReady()` 的测试。 - 增加“API + SpacetimeDB 正常但 worker 缺失时不可复用”的回归场景。 - 保留并验证 BgFilter provider 失败时 Aliyun fallback 的既有测试。 ## 范围与非目标 本 Issue 只处理: - AGC 本地开发启动器; - `backend` 模式的 Rust 服务编排; - AGC 后端 ready/reuse 门禁; - 对应启动和回退测试。 本 Issue 不处理: - 225/226 的请求标记和 tracking 数据模型; - 生产 systemd 服务编排; - BgFilter provider 协议、模型参数和远程服务实现; - Aliyun Matting 或本地键色算法本身。 ## 当前结论 这是一个 AGC 本地开发启动缺陷:`npm run agc` 的 `backend` 模式漏启动 BgFilter worker,且 ready 检查漏检 worker。生产处理逻辑和 fallback 逻辑在本次证据范围内是正确的。
lhk229 self-assigned this 2026-09-02 21:05:20 +08:00
lhk229 added a new dependency 2026-09-02 21:37:06 +08:00
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Depends on
Reference: GenarrativeAI/Genarrative#257