外部上传一个 tar.gz 信函包,即时拿到 Job ID;后台 worker 异步跑 Agent,把 Full JSON 结果存入数据库,不落任何文件。
| 项 | 值 |
|---|---|
| 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 |
/jobs* 三个接口均需在请求头带 API key:
Authorization: Bearer <api_key>{"detail":"invalid or revoked API key"}。GET /admin 创建 / 查看 / 吊销;明文 key 仅创建时返回一次,请立即保存。/admin 需管理密码(服务端环境变量 RDE_ADMIN_PASSWORD,登录状态存于浏览器直至「退出」);密码每天最多试 50 次(RDE_ADMIN_MAX_LOGIN_PER_DAY),超出当天锁定(429)。GET /healthz、GET /docs、首页 GET / 与 GET /admin 页面本身无需 key。# 带 key 调用
curl --noproxy '*' -H "Authorization: Bearer <api_key>" localhost:8084/jobs/<job_id>本服务分析的是 VA Rating Decision Letters。调用 POST /jobs 前,先把待分析的信件准备成一个 tar.gz:
tar.gz(如 letters.tar.gz)。POST /jobs(见下),后台异步分析。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 管理页(密码门禁)。
multipart/form-data 上传一个 tar.gz 信函包并入队。
Authorization: Bearer <api_key>| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
file | file (.tar.gz) | 是 | VA Rating Decision Letters 压缩包;服务端解压到本 job 目录(tar-slip 防护:跳过 ../绝对路径/symlink/__MACOSX/dotfile) |
veteran | string | 是 | 退伍军人姓名("Last, First") |
case_id | string | 是 | 业务案号 |
model | string | 否 | Claude model id;留空则用服务端默认 RDE_MODEL。解析后的具体 model 会写入 rde_agent_jobs.model,并在 200 响应里回显。 |
{ "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"})。
curl --noproxy '*' -X POST localhost:8084/jobs \
-H "Authorization: Bearer <api_key>" \
-F 'file=@letters.tar.gz'{
"job_id": "beea4837...",
"status": "running",
"attempt_count": 1,
"max_attempts": 5,
"next_at": 0,
"last_error": null,
"has_result": false
}| 字段 | 说明 |
|---|---|
status | queued / 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"}
curl --noproxy '*' -H "Authorization: Bearer <api_key>" localhost:8084/jobs/<job_id>取已完成 job 的 Full JSON(RdeSidecar 全量超集:canonical 10 字段 + docx_rows / veteran_profile / smc_note 等渲染内容)。
{ "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 还没跑完。
curl --noproxy '*' -H "Authorization: Bearer <api_key>" localhost:8084/jobs/<job_id>/resultqueued ──(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 记录原因)RDE_WORKER_CONCURRENCY(默认 2),用 FOR UPDATE SKIP LOCKED 并发安全领取。RDE_RETRY_DELAY_SEC(默认 60s),上限 RDE_MAX_ATTEMPTS(默认 5)。RDE_JOB_TIMEOUT_SEC(默认 3600s = 1h):超时取消该次运行并按失败处理(重试/耗尽后 failed)。服务 不自动建表。首次部署先手动应用迁移:
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。)
# 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