Files
Airtep/gig-poc/docs/API.md
2026-04-01 14:19:25 +08:00

609 lines
16 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# API 文档(中文完整版)
## 机器可读文档(推荐作为联调基准)
- Swagger UI`http://127.0.0.1:8000/docs`
- OpenAPI JSON`http://127.0.0.1:8000/openapi.json`
- 一键导出:
```bash
cd gig-poc
sh infrastructure/scripts/export-openapi.sh
```
- 导出到自定义路径:
```bash
sh infrastructure/scripts/export-openapi.sh ./docs/openapi.prod.json
```
## 通用约定
- 基础路径:默认通过网关暴露为 `/api`,下文写的是服务内部路径(如 `/poc/...`)。
- 数据格式:`Content-Type: application/json`
- 时间字段ISO-8601 格式(示例:`2026-03-30T12:00:00+08:00`)。
- 分数字段:大部分评分为 `0~1` 浮点数。
- 常见错误码:
- `400/422`:请求参数不合法(字段缺失、类型不匹配、取值超范围)。
- `404`:查询对象不存在(如岗位 ID、工人 ID、匹配记录 ID 不存在)。
- `500`:服务内部异常(数据库、向量检索、模型调用失败等)。
## 数据结构说明
### Salary薪资结构
| 字段 | 类型 | 说明 |
| --- | --- | --- |
| `type` | `daily/hourly/monthly/task` | 薪资类型:日薪/时薪/月薪/按单 |
| `amount` | `number` | 薪资金额 |
| `currency` | `string` | 货币,默认 `CNY` |
### SkillScore技能分
| 字段 | 类型 | 说明 |
| --- | --- | --- |
| `name` | `string` | 技能名称 |
| `score` | `number` | 技能熟练度,范围 `0~1` |
### JobCard岗位卡片
| 字段 | 类型 | 说明 |
| --- | --- | --- |
| `job_id` | `string` | 岗位唯一 ID |
| `title` | `string` | 岗位标题 |
| `category` | `string` | 岗位类别 |
| `description` | `string` | 岗位描述 |
| `skills` | `string[]` | 需要的技能列表 |
| `city` | `string` | 城市 |
| `region` | `string` | 区域 |
| `location_detail` | `string` | 详细地址或地标 |
| `start_time` | `datetime` | 开始时间 |
| `duration_hours` | `number` | 工时(小时,>0 |
| `headcount` | `number` | 需求人数(>0 |
| `salary` | `Salary` | 薪资信息 |
| `work_mode` | `string` | 工作模式(如兼职/全职/活动) |
| `tags` | `string[]` | 业务标签 |
| `confidence` | `number` | 抽取或录入置信度,范围 `0~1` |
### WorkerCard工人卡片
| 字段 | 类型 | 说明 |
| --- | --- | --- |
| `worker_id` | `string` | 工人唯一 ID |
| `name` | `string` | 姓名/昵称 |
| `description` | `string` | 自我描述 |
| `skills` | `SkillScore[]` | 技能及熟练度 |
| `cities` | `string[]` | 可接单城市 |
| `regions` | `string[]` | 可接单区域 |
| `availability` | `string[]` | 可上岗时段(自由文本) |
| `experience_tags` | `string[]` | 经验标签 |
| `reliability_score` | `number` | 履约可靠性分,范围 `0~1` |
| `profile_completion` | `number` | 档案完善度,范围 `0~1` |
| `confidence` | `number` | 抽取或录入置信度,范围 `0~1` |
### MatchResult匹配结果
| 字段 | 类型 | 说明 |
| --- | --- | --- |
| `match_id` | `string` | 匹配记录 ID |
| `source_type` | `job_to_worker/worker_to_job` | 匹配方向 |
| `source_id` | `string` | 发起匹配的实体 ID |
| `target_id` | `string` | 被匹配到的实体 ID |
| `match_score` | `number` | 综合匹配分(`0~1` |
| `breakdown.skill_score` | `number` | 技能匹配分 |
| `breakdown.region_score` | `number` | 地域匹配分 |
| `breakdown.time_score` | `number` | 时间匹配分 |
| `breakdown.experience_score` | `number` | 经验匹配分 |
| `breakdown.reliability_score` | `number` | 可靠性匹配分 |
| `reasons` | `string[]` | 至少 3 条可解释理由 |
## 系统接口
### `GET /health`
用途检查服务、数据库、RAG 组件是否可用。
返回示例:
```json
{
"service": "ok",
"database": "ok",
"rag": "ok",
"timestamp": "2026-03-30T12:00:00+08:00"
}
```
字段说明:
- `service`API 进程状态。
- `database`:数据库连通状态(`ok/error`)。
- `rag`:检索增强组件状态(`ok/error`)。
- `timestamp`:服务端当前时间。
### `GET /poc/ops/ai/metrics`
用途:查看 AI 调用观测指标限流、熔断、降级、fallback 命中率)。
返回示例:
```json
{
"metrics": {
"requests_total": 12,
"success_total": 10,
"fail_total": 2,
"fallback_total": 1,
"rate_limited_total": 0,
"circuit_open_total": 0,
"endpoint_failover_total": 1,
"fallback_hit_rate": 0.0833,
"success_rate": 0.8333,
"failure_rate": 0.1667
}
}
```
### `GET /poc/ops/system/metrics`
用途:查看全局系统护栏指标(流量限流、熔断状态、缓存命中率、异步队列状态)。
返回示例:
```json
{
"traffic": {
"requests_total": 1000,
"rate_limited_total": 0,
"circuit_blocked_total": 0,
"window_requests": 120,
"window_errors": 3,
"window_error_rate": 0.025,
"avg_latency_ms": 35.4,
"circuit_open": 0
},
"cache": {
"backend": "redis",
"match_hit_rate": 0.62,
"query_hit_rate": 0.73,
"match_size": 320,
"query_size": 800
},
"ingest_queue": {
"queued": 0,
"processed": 1200,
"failed": 2
},
"match_queue": {
"queued": 2,
"processed": 3400,
"failed": 7
}
}
```
## 抽取接口
### `POST /poc/extract/job`
用途:将岗位自然语言文本抽取为结构化 `JobCard`
请求体:
```json
{
"text": "明天下午南山会展中心需要2个签到协助5小时150/人,女生优先"
}
```
请求字段说明:
- `text`:待抽取文本,最小长度 5。
返回结构:`ExtractResponse`
```json
{
"success": true,
"data": {
"job_id": "job_demo_001",
"title": "活动签到协助",
"category": "会展活动",
"description": "南山会展中心活动签到协助",
"skills": ["签到", "引导"],
"city": "深圳",
"region": "南山",
"location_detail": "南山会展中心",
"start_time": "2026-04-01T14:00:00+08:00",
"duration_hours": 5,
"headcount": 2,
"salary": { "type": "daily", "amount": 150, "currency": "CNY" },
"work_mode": "兼职",
"tags": ["女生优先"],
"confidence": 0.88
},
"errors": [],
"missing_fields": []
}
```
字段说明:
- `success`:是否抽取成功。
- `data`:抽取出的结构化岗位对象;失败时可能为 `null`
- `errors`:错误信息列表。
- `missing_fields`:缺失字段列表,便于前端二次补录。
### `POST /poc/extract/worker`
用途:将工人自然语言文本抽取为结构化 `WorkerCard`
请求体:
```json
{
"text": "我做过商场促销和活动签到,也能做登记和引导,周末都能接,福田南山都方便。"
}
```
返回结构:同 `ExtractResponse`,其中 `data``WorkerCard`
说明:
- 适合把聊天文本/简历摘要快速转成可入库结构。
- 若模型无法识别关键字段,会在 `missing_fields` 中给出提示。
## 入库接口
### `POST /poc/ingest/job`
用途:写入或更新岗位卡片(同时更新检索索引)。
请求体:
```json
{
"job": {
"job_id": "job_001",
"title": "活动签到",
"category": "会展活动",
"description": "负责活动签到与引导",
"skills": ["签到", "沟通"],
"city": "深圳",
"region": "福田",
"location_detail": "会展中心",
"start_time": "2026-04-02T09:00:00+08:00",
"duration_hours": 8,
"headcount": 3,
"salary": { "type": "daily", "amount": 180, "currency": "CNY" },
"work_mode": "兼职",
"tags": ["展会"],
"confidence": 0.95
}
}
```
返回:返回入库后的 `JobCard`(通常与请求体一致)。
### `POST /poc/ingest/worker`
用途:写入或更新工人卡片(同时更新检索索引)。
请求体:
```json
{
"worker": {
"worker_id": "worker_001",
"name": "张三",
"description": "有活动执行经验",
"skills": [
{ "name": "签到", "score": 0.9 },
{ "name": "引导", "score": 0.8 }
],
"cities": ["深圳"],
"regions": ["福田", "南山"],
"availability": ["周末全天"],
"experience_tags": ["会展", "地推"],
"reliability_score": 0.92,
"profile_completion": 0.86,
"confidence": 0.93
}
}
```
返回:返回入库后的 `WorkerCard`(通常与请求体一致)。
### `POST /poc/ingest/job/async`
用途:异步岗位入库,快速返回任务 ID不阻塞主请求。
返回示例:
```json
{
"task_id": "queue_xxx",
"status": "queued"
}
```
### `POST /poc/ingest/worker/async`
用途:异步工人入库,快速返回任务 ID不阻塞主请求。
返回结构同 `POST /poc/ingest/job/async`
### `GET /poc/ingest/queue/{task_id}`
用途:查询异步入库任务状态。
可能状态:
- `queued`
- `processing`
- `done`
- `failed`
- `not_found`
### `POST /poc/ingest/bootstrap`
用途:导入内置样本数据(岗位、工人、技能、类目、区域)并构建检索数据。
请求体:无。
返回示例:
```json
{
"jobs": 100,
"workers": 300,
"skills": 120,
"categories": 20,
"regions": 50
}
```
说明:
- 适合开发环境初始化。
- 重复执行会触发 upsert 逻辑(覆盖同 ID 数据)。
## 匹配接口
### `POST /poc/match/workers`
用途:以岗位为源,匹配合适工人。
请求体(二选一):
1.`job_id`(按已入库岗位匹配):
```json
{
"job_id": "job_001",
"top_n": 10
}
```
2. 传内联 `job`(不依赖入库):
```json
{
"job": { "...": "JobCard" },
"top_n": 10
}
```
字段说明:
- `job_id`:岗位 ID。
- `job`:完整岗位对象。
- `top_n`:返回条数,范围 `1~50`,默认 `10`
- `job_id``job` 至少提供一个。
返回:
```json
{
"items": [
{
"match_id": "match_001",
"source_type": "job_to_worker",
"source_id": "job_001",
"target_id": "worker_007",
"match_score": 0.87,
"breakdown": {
"skill_score": 0.9,
"region_score": 1.0,
"time_score": 0.8,
"experience_score": 0.85,
"reliability_score": 0.8
},
"reasons": ["技能高度匹配", "同区域可到岗", "有同类活动经验"]
}
]
}
```
错误说明:
-`job_id` 不存在且未传 `job` 时,返回 `404`,提示“岗位不存在”。
### `POST /poc/match/jobs`
用途:以工人为源,匹配合适岗位。
请求体(二选一):
1.`worker_id`
```json
{
"worker_id": "worker_001",
"top_n": 10
}
```
2. 传内联 `worker`
```json
{
"worker": { "...": "WorkerCard" },
"top_n": 10
}
```
字段约束:
- `worker_id``worker` 至少提供一个。
- `top_n` 范围 `1~50`,默认 `10`
返回:`MatchResponse`,结构同上,`source_type``worker_to_job`
错误说明:
-`worker_id` 不存在且未传 `worker` 时,返回 `404`,提示“工人不存在”。
### `POST /poc/match/workers/async`
用途:岗位异步匹配工人(削峰入口),快速返回任务 ID。
请求体:
```json
{
"job_id": "job_001",
"top_n": 10
}
```
返回示例:
```json
{
"task_id": "mq_xxx",
"status": "queued"
}
```
### `POST /poc/match/jobs/async`
用途:工人异步匹配岗位(削峰入口),快速返回任务 ID。
请求体:
```json
{
"worker_id": "worker_001",
"top_n": 10
}
```
返回结构同 `POST /poc/match/workers/async`
### `GET /poc/match/queue/{task_id}`
用途:查询异步匹配任务状态,完成后返回 `items` 结果集。
可能状态:
- `queued`
- `processing`
- `done`
- `failed`
- `not_found`
### `GET /poc/match/explain/{match_id}`
用途:查询单条匹配记录详情与解释理由。
路径参数:
- `match_id`:匹配记录 ID。
返回:
```json
{
"match": {
"match_id": "match_001",
"source_type": "job_to_worker",
"source_id": "job_001",
"target_id": "worker_007",
"match_score": 0.87,
"breakdown": {
"skill_score": 0.9,
"region_score": 1.0,
"time_score": 0.8,
"experience_score": 0.85,
"reliability_score": 0.8
},
"reasons": ["技能高度匹配", "同区域可到岗", "有同类活动经验"]
}
}
```
错误说明:
- 找不到匹配记录时返回 `404`,提示“匹配记录不存在”。
### `POST /poc/match/feedback`
用途:提交匹配反馈(接受/拒绝),用于在线更新排序权重。
请求体:
```json
{
"match_id": "match_001",
"accepted": true
}
```
返回:
```json
{
"weights": {
"skill": 0.36,
"region": 0.21,
"time": 0.14,
"experience": 0.14,
"reliability": 0.15
},
"learning_enabled": true
}
```
错误说明:
- `match_id` 不存在时返回 `404`,提示“匹配记录不存在”。
### `GET /poc/match/weights`
用途:查看当前生效排序权重(默认权重或学习后的权重)。
返回结构同 `POST /poc/match/feedback`
## 查询接口
### `GET /poc/jobs`
用途:分页前的基础列表查询(当前返回全量)。
返回:
```json
{
"items": [{ "...": "JobCard(JSON)" }],
"total": 100
}
```
### `GET /poc/workers`
用途:查询工人列表(当前返回全量)。
返回:
```json
{
"items": [{ "...": "WorkerCard(JSON)" }],
"total": 300
}
```
### `GET /poc/jobs/{job_id}`
用途:根据 ID 查询单个岗位。
路径参数:
- `job_id`:岗位 ID。
返回:`JobCard`
错误说明:
- ID 不存在返回 `404`,提示“岗位不存在”。
### `GET /poc/workers/{worker_id}`
用途:根据 ID 查询单个工人。
路径参数:
- `worker_id`:工人 ID。
返回:`WorkerCard`
错误说明:
- ID 不存在返回 `404`,提示“工人不存在”。
## 交接建议
-`docs/openapi.json` 作为机器契约,`docs/API.md` 作为业务语义解释。
- 前端与测试联调时,优先校验:
- 抽取失败时 `errors/missing_fields` 是否按预期返回。
- 匹配结果 `breakdown` 五维分是否完整。
- `top_n` 边界值(`1``50``>50`)的校验行为。
## 升级配置说明
- 抽取增强schema-aware 重试):
- `EXTRACTION_LLM_MAX_RETRIES`LLM 校验失败后的修复重试次数,默认 `2`
- 检索 embedding 可配置:
- `EMBEDDING_ENABLED`:是否启用正式 embedding默认 `false`
- `EMBEDDING_BACKEND``hash``openai_compatible`
- `EMBEDDING_BASE_URL` / `EMBEDDING_API_KEY` / `EMBEDDING_MODEL`embedding 服务配置。
- `EMBEDDING_VECTOR_SIZE`embedding 维度(需与 Qdrant 集合维度一致)。
- 排序在线学习:
- `RANKING_LEARNING_ENABLED`:是否启用反馈学习,默认 `true`
- `RANKING_LEARNING_RATE`:在线更新学习率,默认 `0.08`
- 权重持久化文件:`data/match_weights.json`
- 全局稳定性护栏:
- `APP_RATE_LIMIT_PER_MINUTE`:全局每分钟请求上限。
- `APP_CIRCUIT_BREAKER_ERROR_RATE`:窗口 5xx 错误率触发阈值。
- `APP_CIRCUIT_BREAKER_MIN_REQUESTS`:熔断判定最小请求数。
- `APP_CIRCUIT_BREAKER_WINDOW_SECONDS`:错误率统计窗口。
- `APP_CIRCUIT_BREAKER_COOLDOWN_SECONDS`:熔断冷却时长。
- `ALERT_WEBHOOK_URL`:告警 webhook 地址(可选)。
- 异步队列与缓存:
- `INGEST_ASYNC_ENABLED`:是否启用异步入库队列。
- `INGEST_QUEUE_MAX_SIZE`:队列最大长度。
- `MATCH_ASYNC_ENABLED`:是否启用异步匹配队列。
- `MATCH_QUEUE_MAX_SIZE`:异步匹配队列最大长度。
- `MATCH_CACHE_ENABLED`:是否启用匹配缓存。
- `MATCH_CACHE_TTL_SECONDS`:匹配缓存有效期。
- `QUERY_CACHE_ENABLED`:是否启用查询缓存。
- `QUERY_CACHE_TTL_SECONDS`:查询缓存有效期。
- `CACHE_BACKEND`:缓存后端 `memory/redis`
- `REDIS_URL`Redis 连接地址。
- 数据库连接池:
- `DATABASE_POOL_SIZE`:连接池大小。
- `DATABASE_MAX_OVERFLOW`:溢出连接数。
- `DATABASE_POOL_TIMEOUT`:获取连接超时秒数。