决策模型与智能判定工作台
配置与权限
决策模型使用现有 kind: Model,在模型管理中新增、编辑或删除。
用户模型沿用个人和团队权限,管理员通过公共模型管理发布公共模型。
用户表单选择“决策模型”,协议选择 SystemOne 或 OpenAI Decisions;
公共模型 JSON 使用同样的字段。
apiVersion: agent.wecode.io/v1
kind: Model
metadata:
name: decision-systemone
namespace: default
displayName: SystemOne 判定
spec:
modelType: decision
protocol: systemone
isWeworkAvailable: true
modelConfig:
env:
model: systemone
model_id: jev-latest
base_url: https://api.typesafe.ai/v1
api_key: <provider-api-key>
status:
state: Available
OpenAI 配置使用 protocol: openai、env.model: openai,并填写该服务的
模型 ID 和 HTTPS API 地址。决策模型不设置对话用途的 apiFormat。
base_url 接受服务根地址、以 /v1 结尾的 API 基址或对应完整端点。
SystemOne 的端点为 /v1/systemone,OpenAI 的端点为 /v1/decisions;
与协议不匹配的端点、带凭证、查询参数或片段的地址会被拒绝。
api_key 使用现有 Model 凭证及占位符机制,仅在后端执行时解密和解析。
不要把真实凭证写入源代码或 Smart App 环境变量。
部署侧凭证扩展
app.services.model_credential_service 提供共享扩展入口:
register_model_api_key_resolver(resolver):在部署启动时注册异步解析器。- 解析器签名为
async def resolver(template: str, current_user: User) -> str | None。 template是配置中的原始占位符,不会被同名全局环境变量遮蔽。current_user是实际请求用户,不是公共或共享 Model 的所有者。- 返回
None表示不处理该模板,保留普通 Model 配置的既有解析结果。 - 对已处理的模板必须返回有效 key;空值、异常或超时均阻止请求,不回退到全局 key。
LLM 代理和决策执行共用此入口。模型连接测试仅接受直接提供的密钥, 不解析服务器占位符,也不调用部署凭证解析器。决策执行要求非空 key, 其 30 秒总预算包含凭证解析和上游请求,兼容 Python 3.10。 凭证解析默认最多 30 秒,不缓存用户 key,也不修改已保存的 Model。 目录查询不调用凭证解析器。部署专属的接口、鉴权配置及用户 key 获取逻辑 应保留在部署扩展中;开源代码不实现特定企业的占位符语义。
默认混合网关通过 backend-rs/config/routes.toml 将 GET、POST /api/models/decisions交给 Rust。Rust 复用统一模型聚合的可见性和授权检查, 每次执行重新读取目录及 Model 配置。部署侧通过现有AppState.llm_proxy_credentials注册LlmProxyCredentials`,与 Rust LLM 代理
共用凭证解析器;输入保留原始模板和当前请求用户。解析失败或返回无效 key
会阻止执行。Rust 同样不缓存凭证、不跟随重定向、不重试上游请求,且对请求
和响应分别限制 1 MiB。Python 实现及其测试保留为兼容性参照。
公共模型继续遵守 isVisible、allowedUsersEnabled 和 allowedUsers。
只有启用 isWeworkAvailable 的决策模型进入工作台目录。
决策模型不会进入 Shell 的对话模型列表。
请求链路
Smart App(decisionModel capability)
-> Executor loopback route + opaque route token
-> Wegent 后端(当前用户登录态)
-> Model CRD 指定的决策服务
Executor 不再读取 WEWORK_DECISION_PROXY_UPSTREAM_URL 或
WEWORK_DECISION_PROXY_DEFAULT_MODEL,也不再持有专用的模型 key 兑换缓存。
后端是模型地址、协议和凭证的唯一配置来源,必须能够访问配置的决策服务。
现有本地路由仍使用协议版本 1:
GET {WEWORK_DECISION_ROUTER_BASE_URL}/status:获取实时模型目录。POST {WEWORK_DECISION_ROUTER_BASE_URL}/v1/decisions:执行判定。- 两个请求都使用本地标记
Authorization: Bearer wework-local-router。 - 直接调用后端时,两个操作分别为
GET、POST /api/models/decisions, 使用 Wegent 登录凭证而非本地标记。
目录示例:
{
"protocolVersion": 1,
"defaultModel": "<catalog-model-id>",
"models": [
{
"id": "<catalog-model-id>",
"displayName": "SystemOne 判定",
"modelId": "jev-latest",
"protocol": "systemone",
"type": "public",
"namespace": "default"
}
]
}
模型选择器使用 displayName 展示选项,保存并发送 id,不要发送
modelId,也不要自行拼接模型标识。目录 ID 根据资源来源、命名空间、
所有者和名称生成,区分同名个人与公共模型;它不是访问凭证。
更新模型配置后 ID 保持稳定,执行时重新读取配置和权限。
目录为空时 models: []、defaultModel: "",应保留选择器和刷新入口并阻止发送。
目录和判定响应都设置 Cache-Control: no-store。
统一判定格式
Smart App 保持 SystemOne 风格的 state 和具名 questions,不因提供商切换
请求格式。以下请求可发送给目录中的任何决策模型:
{
"model": "<selected-catalog-model-id>",
"state": { "comment": "支付连续失败" },
"questions": {
"urgent": { "type": "noul", "instructions": "是否需要紧急处理?" },
"department": {
"type": "choice",
"instructions": "应该由哪个部门处理?",
"criteria": { "billing": "支付问题", "technical": "系统故障" }
},
"severity": {
"type": "score",
"instructions": "问题的严重程度?",
"criteria": ["轻微", "可绕过", "完全阻塞"]
}
}
}
后端对 SystemOne 保留结构化状态、指令和 criteria。对于 OpenAI,结构化
状态和指令序列化为 JSON 文本,noul 转换为 predicate,具名问题转换
为含 name 的数组,choice/score criteria 转换为 choices/levels。
返回的 answers 统一为具名对象,predicate probability 转回 noul,
概率数组转回概率映射,score legend 从原始 criteria 重建。
OpenAI refusal 保留为 {"type": "refusal"},调用者必须处理拒绝状态。
此统一接口的状态是文本或结构化 JSON,不提供原生 OpenAI 图像输入接口。
请求与响应大小限制为 1 MiB,每次最多 20 个问题。choice 支持 1–255 个 选项,score 支持 2–10 个等级。非法问题、缺失或重复答案、非法数值会 明确失败;不会换协议、回退到对话模型或执行其他模型。
模型被删除、停用、隐藏或收回权限后,旧 ID 返回 model_not_found。
调用者刷新目录并重新选择模型,不应自动改用另一模型。上游错误只返回固定
错误信息和请求 ID,不返回提供商响应正文、调试数据或凭证。
从环境配置迁移
- 在现有模型管理中创建决策 Model,填写实际协议、地址、模型 ID 和凭证。
- 开启
isWeworkAvailable,检查公共模型可见性及白名单。 - 部署后端和 Executor,刷新工作台的模型目录。
- 删除旧的两个决策环境变量。不要再通过安装包品牌配置写入它们。
协议参考:TypeSafe API、 OpenAI Decisions。