# 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`:获取连接超时秒数。