feat: 初始化零工后端代码

This commit is contained in:
Daniel
2026-04-01 14:19:25 +08:00
parent c6fabe262c
commit 84f8be7c0e
41 changed files with 2813 additions and 147 deletions

View File

@@ -1,8 +1,98 @@
# API 文档
# 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",
@@ -12,38 +102,242 @@
}
```
## 抽取接口
### `POST /poc/extract/job`
请求:
字段说明:
- `service`API 进程状态。
- `database`:数据库连通状态(`ok/error`)。
- `rag`:检索增强组件状态(`ok/error`)。
- `timestamp`:服务端当前时间。
### `GET /poc/ops/ai/metrics`
用途:查看 AI 调用观测指标限流、熔断、降级、fallback 命中率)。
返回示例:
```json
{ "text": "明天下午南山会展中心需要2个签到协助5小时150/人,女生优先" }
{
"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": "我做过商场促销和活动签到,也能做登记和引导,周末都能接,福田南山都方便。" }
{
"text": "我做过商场促销和活动签到,也能做登记和引导,周末都能接,福田南山都方便。"
}
```
返回结构:同 `ExtractResponse`,其中 `data``WorkerCard`
说明:
- 适合把聊天文本/简历摘要快速转成可入库结构。
- 若模型无法识别关键字段,会在 `missing_fields` 中给出提示。
## 入库接口
### `POST /poc/ingest/job`
用途:写入或更新岗位卡片(同时更新检索索引)。
请求体:
```json
{ "job": { "...": "JobCard" } }
{
"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": { "...": "WorkerCard" } }
{
"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`
说明:导入样本数据、词表、Qdrant 检索索引数据。
用途:导入内置样本数据(岗位、工人、技能、类目、区域)并构建检索数据。
请求体:无。
返回示例:
```json
{
"jobs": 100,
"workers": 300,
"skills": 120,
"categories": 20,
"regions": 50
}
```
说明:
- 适合开发环境初始化。
- 重复执行会触发 upsert 逻辑(覆盖同 ID 数据)。
## 匹配接口
### `POST /poc/match/workers`
支持 `job_id` 或内联 `job`
用途:以岗位为源,匹配合适工人。
请求体(二选一):
1.`job_id`(按已入库岗位匹配):
```json
{
"job_id": "job_001",
@@ -51,8 +345,51 @@
}
```
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`
支持 `worker_id` 或内联 `worker`
用途:以工人为源,匹配合适岗位。
请求体(二选一):
1.`worker_id`
```json
{
"worker_id": "worker_001",
@@ -60,16 +397,212 @@
}
```
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`
### `GET /poc/workers`
### `GET /poc/jobs/{job_id}`
### `GET /poc/workers/{worker_id}`
## 交接说明
- 抽取接口返回 `success/data/errors/missing_fields`,方便后续切换更强 LLM 时做错误回退
- 匹配接口输出 `breakdown` 五维打分,可直接给后续运营、策略或模型团队继续调权。
- `packages/shared-types/src/index.ts` 保留了前端可复用类型定义。
### `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`:获取连接超时秒数。

View File

@@ -0,0 +1,19 @@
# 容量基线(自动生成)
- 生成时间: 2026-03-31 14:36:58 +0800
- API_BASE: http://127.0.0.1:8000
- TOTAL_REQUESTS: 80
- CONCURRENCY: 20
| 场景 | 成功率 | RPS | 平均延迟(ms) | P95(ms) | P99(ms) |
| --- | --- | --- | --- | --- | --- |
| health | 1.0 | 19.34 | 978.98 | 1434.66 | 1544.06 |
| jobs | 1.0 | 95.39 | 197.95 | 409.12 | 424.99 |
| match_workers | 1.0 | 20.81 | 913.73 | 1975.6 | 2118.65 |
| match_jobs | 1.0 | 19.88 | 975.29 | 2001.08 | 2147.74 |
| match_workers_cached | 1.0 | 23.52 | 819.62 | 1220.26 | 1331.26 |
| match_jobs_cached | 1.0 | 25.21 | 759.14 | 1077.45 | 1200.4 |
| match_workers_async | 1.0 | 211.09 | 89.04 | 151.04 | 158.89 |
| match_jobs_async | 1.0 | 221.04 | 83.96 | 143.35 | 162.95 |
> 建议:该基线仅代表当前单机/当前数据量下表现,发布前请在目标环境按 2x/5x 峰值复测。

View File

@@ -5,6 +5,12 @@
cd gig-poc
sh infrastructure/scripts/dev-up.sh
```
默认会自动完成:
- 启动容器并健康检查
- bootstrap 样本数据
- 闭环验收(抽取 -> 入库 -> 匹配 -> 解释)
- 导出 `docs/openapi.json`
- 可选压测并生成 `docs/CAPACITY_BASELINE.md``RUN_BASELINE_ON_UP=true`
## 演示步骤
1. 打开 `http://127.0.0.1:5173`
@@ -21,6 +27,42 @@ cd gig-poc
sh infrastructure/scripts/prod-up.sh
```
## 生产环境停止
```bash
cd gig-poc
sh infrastructure/scripts/prod-down.sh
```
## OpenAPI 交接文件导出
```bash
cd gig-poc
sh infrastructure/scripts/export-openapi.sh
```
## OpenAPI 固化入库(离线)
```bash
cd gig-poc
sh infrastructure/scripts/freeze-openapi.sh
```
## 一键闭环验收(可单独执行)
```bash
cd gig-poc
sh infrastructure/scripts/acceptance-e2e.sh
```
## 容量基线压测(可单独执行)
```bash
cd gig-poc
sh infrastructure/scripts/load-baseline.sh
```
## 高并发演示建议
1. 同步匹配:调用 `POST /poc/match/workers` 观察实时结果。
2. 异步匹配削峰:调用 `POST /poc/match/workers/async` 获取 `task_id`
3. 轮询结果:调用 `GET /poc/match/queue/{task_id}` 直到 `status=done`
4. 打开 `GET /poc/ops/system/metrics` 观察缓存命中率、队列积压和限流熔断状态。
## 演示建议
- 先演示系统状态页,确认健康与 bootstrap 正常
- 再演示岗位找人、人找岗位两个闭环

View File

@@ -39,10 +39,45 @@
- `LLM_BASE_URL`OpenAI 兼容接口地址
- `LLM_API_KEY`:模型服务密钥
- `LLM_MODEL`:模型名称
- `LLM_FALLBACK_BASE_URLS`LLM 备用端点列表JSON 数组)
- `AI_RATE_LIMIT_PER_MINUTE`AI 请求每分钟限流阈值
- `AI_CIRCUIT_BREAKER_FAIL_THRESHOLD`:熔断触发失败次数
- `AI_CIRCUIT_BREAKER_COOLDOWN_SECONDS`:熔断冷却秒数
- `EMBEDDING_ENABLED`:是否启用正式 embedding
- `EMBEDDING_BACKEND``hash``openai_compatible`
- `EMBEDDING_BASE_URL` / `EMBEDDING_API_KEY` / `EMBEDDING_MODEL`embedding 配置
- `INGEST_ASYNC_ENABLED`:是否启用异步入库队列
- `INGEST_QUEUE_MAX_SIZE`:异步队列最大长度
- `MATCH_CACHE_ENABLED`:是否启用匹配缓存
- `MATCH_CACHE_TTL_SECONDS`:匹配缓存 TTL
- `QUERY_CACHE_ENABLED`:是否启用查询缓存(列表与详情)
- `QUERY_CACHE_TTL_SECONDS`:查询缓存 TTL
- `CACHE_BACKEND`:缓存后端,`memory``redis`
- `REDIS_URL`Redis 连接串
- `APP_RATE_LIMIT_PER_MINUTE`:全局请求限流阈值
- `APP_CIRCUIT_BREAKER_*`:全局熔断参数(错误率、窗口、冷却)
- `ALERT_WEBHOOK_URL`:告警 webhook可选
- `DATABASE_POOL_SIZE` / `DATABASE_MAX_OVERFLOW` / `DATABASE_POOL_TIMEOUT`:数据库连接池参数
- `MATCH_ASYNC_ENABLED`:是否启用异步匹配队列
- `MATCH_QUEUE_MAX_SIZE`:异步匹配队列最大长度
## 启动方式
1. `cd gig-poc`
2. `sh infrastructure/scripts/dev-up.sh`
3. 默认会自动执行:
- 健康检查 + bootstrap
- 一键闭环验收脚本(抽取 -> 入库 -> 匹配 -> 解释)
- 导出 `docs/openapi.json`
4. 可选开启容量基线压测:
- `RUN_BASELINE_ON_UP=true sh infrastructure/scripts/dev-up.sh`
## 生产环境启动/停止
- 启动:`sh infrastructure/scripts/prod-up.sh`
- 停止:`sh infrastructure/scripts/prod-down.sh`
- 可选环境变量:
- `WEB_PORT`(默认 `80`
- `API_PORT`(默认 `8000`
- `BOOTSTRAP_ON_UP`(默认 `true`,可设置为 `false` 跳过样本初始化)
## 样本导入方式
`dev-up.sh` 会在健康检查通过后自动触发 `/poc/ingest/bootstrap`,导入 100 岗位、300 工人和词表。
@@ -50,6 +85,11 @@
## API 地址
- `http://127.0.0.1:8000`
- OpenAPI`http://127.0.0.1:8000/docs`
- OpenAPI JSON 导出:`sh infrastructure/scripts/export-openapi.sh`
- OpenAPI 固化(离线生成并入库):`sh infrastructure/scripts/freeze-openapi.sh`
- AI 观测接口:`GET /poc/ops/ai/metrics`
- 系统观测接口:`GET /poc/ops/system/metrics`
- 异步匹配接口:`POST /poc/match/workers/async``POST /poc/match/jobs/async``GET /poc/match/queue/{task_id}`
## 前端访问地址
- `http://127.0.0.1:5173`
@@ -61,6 +101,53 @@
4. 点击入库并匹配岗位
5. 在系统状态页执行健康检查和样本导入
## 一键闭环验收
```bash
cd gig-poc
sh infrastructure/scripts/acceptance-e2e.sh
```
该脚本会自动验证两条链路:
- 岗位文本抽取 -> 岗位入库 -> 岗位匹配工人 -> 匹配解释
- 工人文本抽取 -> 工人入库 -> 工人匹配岗位 -> 匹配解释
## 容量基线压测
```bash
cd gig-poc
sh infrastructure/scripts/load-baseline.sh
```
输出文件:
- `docs/CAPACITY_BASELINE.md`
可选参数:
- `TOTAL_REQUESTS`(默认 `400`
- `CONCURRENCY`(默认 `40`
## 规模化建议(上线前)
- 应用层:开启多实例部署(建议至少 2 个 API 实例)并接入负载均衡。
- 数据层PostgreSQL、Qdrant 使用托管或主从/集群形态,避免单点。
- 链路层:优先走异步入库接口(`/poc/ingest/*/async`)吸收突发写流量。
- 匹配层:高峰请求优先走异步匹配接口(`/poc/match/*/async`)做削峰。
- 观测层:接入 `/poc/ops/system/metrics``/poc/ops/ai/metrics` 到监控告警系统。
- 发布层:每次发布前更新 `docs/openapi.json``docs/CAPACITY_BASELINE.md`
## K8s 扩容部署(基础模板)
目录:`infrastructure/k8s`
```bash
cd gig-poc
kubectl apply -k infrastructure/k8s
```
包含资源:
- API Deployment + Service + HPA默认 3~20 副本)
- Web Deployment + Service + HPA默认 2~10 副本)
- Redis Deployment + Service
- Ingress 示例路由
详细策略说明见:`docs/SCALING.md`
## 已实现范围
- 岗位抽取
- 工人抽取

19
gig-poc/docs/SCALING.md Normal file
View File

@@ -0,0 +1,19 @@
# 扩容与高 DAU 策略
## 当前能力
- API/Web 提供 K8s 多副本与 HPA 模板:`infrastructure/k8s`
- Redis 缓存后端支持:热点匹配与查询链路缓存
- 异步队列:入库与匹配都支持异步削峰
- 观测接口:`/poc/ops/system/metrics``/poc/ops/ai/metrics`
## 推荐上线形态
1. API 多副本(>=3+ HPA3~20
2. Web 多副本(>=2+ HPA2~10
3. Redis 独立高可用(哨兵或托管)
4. PostgreSQL、Qdrant 使用托管或主从/集群
5. 异步接口承接高峰写流量与匹配重算
## 发布前门槛
- 运行 `sh infrastructure/scripts/load-baseline.sh`
- 更新并提交 `docs/CAPACITY_BASELINE.md`
- 验证 P95/P99、成功率和队列积压指标

File diff suppressed because one or more lines are too long