Agent 队列服务 · API 接口文档

外部上传一个 tar.gz 信函包,即时拿到 Job ID;后台 worker 异步跑 Agent,把 Full JSON 结果存入数据库,不落任何文件。

模块 c-agent(FastAPI · c_agent.service:app) · 文档日期 2026-07-01

§基本信息

Base URL(本地)http://localhost:8084(端口可由 --port / PORT 改)
协议HTTP/JSON;上传为 multipart/form-data
鉴权/jobs* 需带 Authorization: Bearer <api_key>;缺失/失效 → 401。key 在 /admin 管理页创建(见 §鉴权)。
自动文档Swagger UI GET /docs · ReDoc GET /redoc · OpenAPI GET /openapi.json

§鉴权 · API Key

/jobs* 三个接口均需在请求头带 API key:

http
Authorization: Bearer <api_key>
bash
# 带 key 调用
curl --noproxy '*' -H "Authorization: Bearer <api_key>" localhost:8084/jobs/<job_id>

§数据准备(前置)

本服务分析的是 VA Rating Decision Letters。调用 POST /jobs 前,先把待分析的信件准备成一个 tar.gz:

  1. Box Client 下载该 case 的 Rating Decision Letters。
  2. 打包成一个 tar.gz(如 letters.tar.gz)。
  3. 上传到 POST /jobs(见下),后台异步分析。
flow
Box Client(Rating Decision Letters)
      │  下载 + 打包
      ▼
  letters.tar.gz  ──POST /jobs──▶  Agent 队列  ──异步分析──▶  Full JSON(入库)

§接口一览

方法路径说明
POST/jobs上传 tar.gz,入队,返回 Job ID
GET/jobs/{job_id}查 job 状态(queued/running/done/failed + 重试信息)
GET/jobs/{job_id}/result取已完成 job 的 Full JSON

以上 3 个接口均需 Authorization: Bearer <api_key>(见 §鉴权);key 的创建/吊销在 /admin 管理页(密码门禁)。

1提交任务(入队)

POST/jobs

multipart/form-data 上传一个 tar.gz 信函包并入队。

请求头
http
Authorization: Bearer <api_key>
表单字段
字段类型必填说明
filefile (.tar.gz)VA Rating Decision Letters 压缩包;服务端解压到本 job 目录(tar-slip 防护:跳过 ../绝对路径/symlink/__MACOSX/dotfile)
veteranstring退伍军人姓名("Last, First"
case_idstring业务案号
modelstringClaude model id;留空则用服务端默认 RDE_MODEL。解析后的具体 model 会写入 rde_agent_jobs.model,并在 200 响应里回显。
200 响应
json
{ "job_id": "beea4837bf85404aa98d8cf8997b68bb", "status": "queued", "files": "1" }
  • job_id:后续查询/取结果用的句柄。
  • files:解压出的有效文件数。

model 未传时取服务端默认 RDE_MODEL,解析后写入 rde_agent_jobs.model不在响应中返回。)

错误

401 缺失/失效 API key({"detail":"missing API key ..."} / "invalid or revoked API key")。
400 不是合法 tar.gz({"detail":"not a valid tar.gz: ..."}),或包内无可用文件({"detail":"archive contained no usable files"})。

示例
bash
curl --noproxy '*' -X POST localhost:8084/jobs \
  -H "Authorization: Bearer <api_key>" \
  -F 'file=@letters.tar.gz'

2查询任务状态

GET/jobs/{job_id}
200 响应
json
{
  "job_id": "beea4837...",
  "status": "running",
  "attempt_count": 1,
  "max_attempts": 5,
  "next_at": 0,
  "last_error": null,
  "has_result": false
}
字段说明
statusqueued / running / done / failed
attempt_count已尝试次数(领取即 +1)
max_attempts上限(默认 5)
next_at下次可领取的 unix 秒;失败重试时 = 上次失败时刻 + 60s
last_error最近一次失败原因(成功为 null
has_result是否已可取结果(status==done
错误

401 缺失/失效 API key。 404 {"detail":"job not found"}

示例
bash
curl --noproxy '*' -H "Authorization: Bearer <api_key>" localhost:8084/jobs/<job_id>

3取结果

GET/jobs/{job_id}/result

取已完成 job 的 Full JSON(RdeSidecar 全量超集:canonical 10 字段 + docx_rows / veteran_profile / smc_note 等渲染内容)。

200 响应
json
{ "job_id": "beea4837...", "full_json": { "veteran": { "...": "..." }, "current_ratings": [], "smc_pillars": {}, "...": "..." } }
错误

401 缺失/失效 API key。
404 {"detail":"job not found"} — 没有这个 job。
404 {"detail":"result not ready"} — job 还没跑完。

示例
bash
curl --noproxy '*' -H "Authorization: Bearer <api_key>" localhost:8084/jobs/<job_id>/result

§Job 状态机与重试

flow
queued  ──(worker 领取, attempt+1)──▶  running
running ──成功──▶  done    (结果写入 rde_agent_results.full_json)
running ──失败 & attempt<max──▶  queued  (next_at = now+60s,1 分钟后重试)
running ──失败 & attempt>=max──▶ failed  (last_error 记录原因)

§前置条件:建表(迁移)

服务 不自动建表。首次部署先手动应用迁移:

bash
psql "$KNOWLEDGE_WELL_DSN" -f c-agent/migrations/20260623000001_rde_agent_queue.up.sql
psql "$KNOWLEDGE_WELL_DSN" -f c-agent/migrations/20260701000002_api_keys_admin.up.sql

两个迁移分别建 job 队列表与 API key / admin 限流表;否则入队或鉴权会因表缺失报错。(dev_restart.sh 会自动按序应用 migrations/ 下全部 *.up.sql。)

§端到端示例

bash
# 0. 到 /admin(密码 RDE_ADMIN_PASSWORD)创建 API key,得到 <api_key>(仅显示一次)
KEY='<api_key>'

# 1. 入队
curl --noproxy '*' -X POST localhost:8084/jobs -H "Authorization: Bearer $KEY" -F 'file=@letters.tar.gz'
# → {"job_id":"abc...","status":"queued","files":"4"}

# 2. 轮询到 done
curl --noproxy '*' -H "Authorization: Bearer $KEY" localhost:8084/jobs/abc...

# 3. 取结果
curl --noproxy '*' -H "Authorization: Bearer $KEY" localhost:8084/jobs/abc.../result