diff --git a/.craftkit/designs/engineering-baseline/database-design.md b/.craftkit/designs/engineering-baseline/database-design.md index e73cc7c..28ba011 100644 --- a/.craftkit/designs/engineering-baseline/database-design.md +++ b/.craftkit/designs/engineering-baseline/database-design.md @@ -34,6 +34,7 @@ replacedBy: null erDiagram AUTH_USER ||--o| USER_PROFILE : has AUTH_USER ||--o{ AGENT_RUN : owns + AUTH_USER ||--o{ MODEL_PROVIDER_CONFIG : owns AGENT_RUN ||--o{ AGENT_RUN_EVENT : contains AGENT_RUN ||--o{ TOOL_CALL : contains AGENT_RUN ||--o{ HUMAN_APPROVAL : requests @@ -89,6 +90,21 @@ erDiagram - `lock_version >= 0`。 - token、耗时和费用非负。 +### 4.2.1 `agent_runtime_model_provider_config` + +| 字段 | 类型建议 | 说明 | +| --- | --- | --- | +| `owner_id` | `ForeignKey(PROTECT)` | 用户私有归属 | +| `provider_code` | `CharField` | 对应代码中的服务商稳定编码 | +| `encrypted_api_key` | `TextField` | Fernet 密文,禁止通过页面或 Admin 展示 | +| `key_hint` | `CharField` | 仅保存末四位提示 | +| `status`、`enabled`、`is_default` | 状态字段 | 连接状态和当前默认选择 | +| `default_model_id` | `CharField` | 用户选择或预设推荐模型 | +| `available_models` | `JSONField` | 最近一次验证取得的模型标识快照 | +| `last_verified_at`、`last_error_code` | 审计字段 | 验证时间和稳定错误码 | + +唯一约束为 `(owner_id, provider_code)`。API Key 加密主密钥只从部署环境读取,不进入数据库;主密钥轮换必须先完成密文重加密,不能直接替换后重启。 + 跨字段状态不变量仍由服务层验证,因为 SQLite 与 PostgreSQL 对复杂检查约束和时间语义的行为需要保持一致。 ### 4.3 `agent_runtime_agent_run_event` diff --git a/.craftkit/designs/engineering-baseline/frontend-design.md b/.craftkit/designs/engineering-baseline/frontend-design.md index 63b9f2f..523677b 100644 --- a/.craftkit/designs/engineering-baseline/frontend-design.md +++ b/.craftkit/designs/engineering-baseline/frontend-design.md @@ -49,6 +49,7 @@ replacedBy: null | 个人资料 | `/accounts/profile/` | 普通用户、管理员 | 查看和修改自己的资料 | | 运行列表 | `/runs/` | 普通用户、管理员 | 查看当前用户的运行记录 | | 运行详情 | `/runs//` | 记录所属用户、管理员 | 查看状态、事件和工具调用摘要 | +| API 服务商 | `/runs/providers/` | 普通用户、管理员 | 搜索、筛选并配置自己的模型服务商 | | 管理后台 | `/admin/` | 管理员 | 管理用户和审计记录 | 登录成功默认进入运行列表;退出成功返回登录页。详情页返回列表时保留原分页参数,非法或越权的运行编号统一展示 404 页面。 @@ -114,6 +115,15 @@ replacedBy: null 详情页不展示 API Key、Cookie、密码、完整工具参数或原始模型敏感内容。 +### 4.6 API 服务商页 + +- 使用服务商卡片目录展示官方直连、国内平台、聚合平台和云平台。 +- 卡片明确区分“仅 API Key”和“需要额外配置”,未完成专用适配的平台不开放保存操作。 +- 配置抽屉只接收 API Key、可选模型标识和是否设为默认服务商;Base URL 与协议由服务端预设。 +- 页面只显示密钥末四位提示,保存后不可读取完整密钥。 +- 连接测试通过后才替换已有配置;失败输入不得破坏原有可用密钥。 +- 搜索与分类使用 GET 查询参数,保存和移除使用 POST、CSRF 与重定向。 + ## 5. 模板复用边界 建议模板层级: diff --git a/.craftkit/designs/engineering-baseline/interface-design.md b/.craftkit/designs/engineering-baseline/interface-design.md index 24a6859..3ea380a 100644 --- a/.craftkit/designs/engineering-baseline/interface-design.md +++ b/.craftkit/designs/engineering-baseline/interface-design.md @@ -94,6 +94,24 @@ replacedBy: null - 事件和完成的工具调用设置为只读或限制修改。 - 人工确认处理必须调用领域服务,不能只修改单个状态字段。 +### 3.7 模型服务商配置 + +`GET /runs/providers/` + +- 返回内置服务商目录、当前用户连接状态、搜索和分类结果。 +- 不返回密文 API Key,已配置密钥只显示末四位提示。 + +`POST /runs/providers//configure/` + +- 输入:API Key、可选默认模型、是否设为默认服务商。 +- 服务端按固定预设端点请求模型目录;验证成功后才加密保存。 +- 验证失败返回安全错误说明,不透传上游正文,不覆盖旧密钥。 + +`POST /runs/providers//disconnect/` + +- 只删除当前用户对应配置;删除默认配置后自动选择一个剩余可用配置。 +- GET 请求不得删除或修改配置。 + ## 4. 表单契约 ### 4.1 登录表单 diff --git a/README.md b/README.md index aebe1bc..5379f90 100644 --- a/README.md +++ b/README.md @@ -29,12 +29,12 @@ JobRadar 是一套面向个人使用、以 Agent 为核心的智能岗位发现 | 异步任务 | Celery + Redis | 规划中 | | 定时调度 | Celery Beat | 规划中 | | Agent 运行时 | OpenAI Agents SDK(Python) | 规划中 | -| 模型接口 | OpenAI Responses API | 规划中 | +| 模型接口 | 多服务商预设 + OpenAI/Anthropic/Gemini 协议 | 配置基础已完成,真实调用规划中 | | Agent 输出 | Pydantic 结构化模型 | 规划中 | | 可观测性 | Agents SDK Tracing + 业务运行记录 | 规划中 | | Agent 评测 | 官方 Agent Evals 思路 + 本地评测集 | 规划中 | | 用户系统 | Django 内置认证 + 简化用户资料 | 规划中 | -| WebUI | Django Admin + 自定义 Django 页面 | 规划中 | +| WebUI | Django Admin + 自定义 Django 页面 | 认证、运行记录与 API 服务商配置已完成 | | 部署 | Docker Compose + Nginx/Caddy + HTTPS | 规划中 | 第一阶段优先采用 Django Admin 管理站点、规则、企业和任务数据,再为岗位浏览与决策流程开发自定义页面。出现明确的前后端分离需求后,再评估是否增加 Django REST Framework 和 Vue。 @@ -158,6 +158,18 @@ python -m playwright install chromium - 采集器必须设置并发、频率、超时和指数退避,不能绕过验证码、登录保护或访问控制。 - 企业性质及 AI 判断必须保存来源、判断时间和置信度;信息不足时应标记为待人工复核。 +### 模型服务商配置 + +登录后可访问 `/runs/providers/` 配置模型服务商。OpenAI、Claude、DeepSeek、Gemini、阿里云百炼、智谱 AI、硅基流动及部分 OpenAI 兼容平台已提供固定端点预设;Azure OpenAI、AWS Bedrock 等需要部署或 IAM 参数的平台目前仅展示目录状态。 + +页面保存 API Key 前必须配置独立主密钥: + +```powershell +$env:MODEL_API_KEY_ENCRYPTION_KEY="请使用至少32个字符的高强度随机值" +``` + +该主密钥不得提交到仓库。遗失或直接替换主密钥会导致已有 API Key 无法解密;正式轮换前必须实现密文重加密流程。 + ## 用户系统 系统面向公网部署,因此第一阶段即接入用户认证,但不设计复杂的角色权限体系: diff --git a/docs/agent-contract.md b/docs/agent-contract.md index 9d55ba3..4d09a1f 100644 --- a/docs/agent-contract.md +++ b/docs/agent-contract.md @@ -39,6 +39,8 @@ 运行上下文至少包含 `user_id`、`agent_run_id`、`search_task_id`、个人画像版本、规则版本、评分配置版本和当前运行预算。上下文不包含网站明文密码、Cookie、模型 API Key 等敏感值;工具在服务端根据授权范围读取凭据。 +模型运行配置在 Gateway 调用前根据当前用户的默认服务商解析。Agent 上下文和持久化运行请求只记录服务商编码与模型标识,不携带可解密密文或明文 API Key。服务商配置缺失、密钥不可解密或默认模型为空时,应在真实调用前以配置错误终止,不影响登录、配置页和历史运行查询。 + ## 人工确认边界 以下情况必须暂停或转人工处理: diff --git a/docs/architecture.md b/docs/architecture.md index afc8cf4..8293b75 100644 --- a/docs/architecture.md +++ b/docs/architecture.md @@ -41,6 +41,15 @@ Agent 不是对岗位描述进行一次总结的接口,而是任务执行主 - 保存 run、turn、tool call、tool result、trace、耗时、token 用量、异常和人工确认状态。 - 第一版不使用 SandboxAgent;业务只需受控网络和数据库工具,不需要开放 Shell 或任意文件执行能力。 +## 模型服务商配置边界 + +- 普通用户通过 Django 服务端页面维护自己的模型服务商配置,配置之间按用户归属隔离。 +- 服务商公开协议、基础地址和推荐模型由代码预设;页面不能提交或覆盖预设地址,避免形成任意网络请求入口。 +- OpenAI、Claude、DeepSeek、Gemini、阿里云百炼、智谱、硅基流动及常见聚合平台按各自协议验证模型目录;验证请求不发送对话内容,不产生模型推理调用。 +- API Key 使用独立部署主密钥进行可逆加密,数据库、页面、日志、Agent 上下文和运行摘要均不得出现明文。 +- Azure OpenAI、AWS Bedrock 及需要地域、部署、IAM 或业务空间参数的平台只展示接入状态,不得误标为只填 API Key 即可使用。 +- 真实 Gateway 在执行边界按当前用户解析默认服务商、模型和密钥;密钥不会进入 `AgentExecutionRequest`。 + ## 用户与权限边界 - 使用 Django 内置认证、Session 和密码管理能力。 diff --git a/docs/roadmap.md b/docs/roadmap.md index f36420c..d924bbb 100644 --- a/docs/roadmap.md +++ b/docs/roadmap.md @@ -20,10 +20,11 @@ replacedBy: null - [x] 为用户私有业务数据建立统一归属边界。 - [ ] 开发与测试默认使用SQLite,并建立可切换PostgreSQL的迁移基线。 - [ ] 接入OpenAI Agents SDK。 +- [x] 建立用户级模型服务商目录、API Key 加密存储、连接验证和运行时配置解析。 - [x] 建立Agent Run、运行事件、工具调用和人工确认模型。 - [ ] 增加统一日志、测试和代码质量工具。 -当前状态:用户资料、数据归属、Agent 运行持久化、最小页面及 SDK 测试替身编排闭环已经落地;真实 Agents SDK 接入仍属于第二阶段。第一阶段剩余 PostgreSQL 集成验证、Ruff/pytest 环境同步、生产配置检查及人工页面验收。 +当前状态:用户资料、数据归属、Agent 运行持久化、模型服务商配置页及 SDK 测试替身编排闭环已经落地;真实 Agents SDK 接入仍属于第二阶段。第一阶段剩余 PostgreSQL 集成验证、生产配置检查及人工页面验收。 验收条件:开发与生产配置隔离,用户可以安全登录,SQLite下迁移和测试通过,PostgreSQL空库迁移及核心模型测试通过,最小Agent运行数据可持久化。