CellSpec 完整参考
CellSpec 是创建和配置 Cell 的声明式规格。本文档详细描述每个字段的语义、默认值和约束。
概述
CellSpec 使用 struct embedding 分层组织:
type CellSpec struct {
ID string // 不可变,Cell 唯一标识
CellCoreSpec // 核心配置
CellAdapterSpec // 外设配置
CellSchedulingSpec // 调度与配额
CellPortableSpec // 可移植性
}
Go 嵌入保持向后兼容——spec.Timezone 等价于 spec.CellCoreSpec.Timezone。
字段可变性
每个字段带 wesgine:"immutable|mutable|restricted" tag:
| 标记 | 含义 |
|---|---|
immutable | 创建后不可修改 |
mutable | 可通过 UpdateSpec 修改 |
restricted | 需要特殊条件才能修改 |
核心字段(CellCoreSpec)
ID(不可变)
Cell 的唯一标识符。创建后不可更改。
spec := wesgine.CellSpec{
ID: "dept-legal", // 推荐使用有意义的标识
}
命名规范:
- 只包含小写字母、数字和连字符
- 不以连字符开头或结尾
- 最大长度 63 字符
Timezone(不可变)
Cell 的时区设置,影响 Cron 调度和日志时间戳。
Timezone: "Asia/Shanghai" // IANA 时区名
Locale(可变)
影响系统提示词的语言偏好。
Locale: "zh-CN"
Compliance(可变)
合规类别,自动映射到治理预设:
| ComplianceClass | GovernMode | NetworkPolicy | 适用场景 |
|---|---|---|---|
standard | open | allow | 编程/通用 |
pii-strict | locked | internal_only | PII 保护 |
financial | locked | internal_only | 金融合规 |
healthcare | locked | internal_only | 医疗合规 |
治理字段
Governance
控制 Cell 的效果边界:
Governance: wesgine.CellGovernance{
GovernMode: "open", // "open" 或 "locked"
DenyPaths: []string{"/etc/shadow", "/root"},
NetworkPolicy: "allow", // "allow" / "internal_only" / "deny"
}
EnginePaths
引擎自身路径声明,用于路径边界判定:
EnginePaths: []string{"/var/lib/wesgine/cells/my-cell"},
RedactorRules
脱敏规则,用于敏感数据清洗:
RedactorRules: []wesgine.RedactorRule{
{Pattern: `\b\d{18}\b`, Replacement: "[身份证号已脱敏]"},
},
Provider 字段
ProviderStrategy(可变)
决定 Cell 如何选择 LLM Provider:
| 策略 | 行为 |
|---|---|
own_only | 只用 Cell 私有 Provider |
shared_only | 只用 Hypervisor 共享 Provider |
own_first | 私有优先,fallback 到共享 |
shared_first | 共享优先,fallback 到私有 |
自动推导规则:
- 只有私有 Provider → 自动推导为
own_only - 只有共享 Provider → 自动推导为
shared_only - 两侧都有 → 必须显式声明,否则
ErrProviderStrategyUnset
PrivateProviders
Cell 独有的 Provider 列表:
PrivateProviders: []config.ProviderConfig{
{
Name: "my-openai",
Type: "openai",
BaseURL: "https://api.openai.com/v1",
APIKeyRef: config.SecretRef{
Source: "inline",
Value: "sk-...",
},
Models: []config.ModelConfig{
{
Name: "gpt-4o",
ContextWindow: 128000,
SupportsVision: true,
},
},
},
}
AllowedModels
限制 Cell 可使用的模型白名单:
AllowedModels: []string{"gpt-4o", "claude-3-5-sonnet"},
DisallowActorProvider
禁止 Actor 级 BYOK(自带密钥):
DisallowActorProvider: true,
外设字段(CellAdapterSpec)
Channels
IM 渠道声明:
Channels: []channel.ChannelConfig{
{
Platform: "wecom",
CorpID: "wxLegal...",
AgentID: 1000001,
SecretRef: config.SecretRef{Source: "env", Name: "WECOM_SECRET"},
},
},
邮箱账号声明:
Email: []email.Config{
{
Address: "ai@example.com",
SMTPHost: "smtp.example.com",
SMTPPort: 465,
Password: config.SecretRef{Source: "env", Name: "EMAIL_PASSWORD"},
},
},
MCPs
MCP Server 声明:
MCPs: []mcp.ServerConfig{
{
Name: "legal-mcp",
Transport: "stdio",
Command: []string{"/opt/mcp/legal/bin/server"},
},
},
Cron
定时任务声明(出生声明,INV-SEED-01):
Cron: []cron.JobSpec{
{
Name: "weekly-report",
Schedule: "0 9 * * 1",
AgentID: "reporter",
Prompt: "生成本周工作报告",
},
},
重要:
Cron和
HeadlessBrowser / Playwright / Desktop
浏览器和桌面自动化(可选):
HeadlessBrowser: &wesgine.HeadlessBrowserConfig{}, // 服务端 chromedp
Playwright: &wesgine.PlaywrightConfig{}, // 用户浏览器自动化
Desktop: &wesgine.DesktopConfig{ // 桌面自动化
Command: "/usr/local/bin/device-agent",
Transport: "stdio",
},
STT
语音转写(可选):
STT: &wesgine.STTConfig{
Model: "whisper-1",
},
Plugins
JSON-RPC 子进程 Plugin(可选):
Plugins: []string{"/opt/plugins/my-plugin"},
调度与配额(CellSchedulingSpec)
Quotas
Cell 资源配额:
Quotas: wesgine.CellQuotas{
MaxConcurrentRuns: 5,
TokensPerMinute: 100000,
TokensPerDay: 5000000,
MaxIMChannels: 10,
MaxMCPServers: 20,
MaxCronJobs: 50,
MaxEmailAccounts: 5,
MaxSkillsInstalled: 100,
MaxPlugins: 10,
},
CycleDetect
循环检测配置:
CycleDetect: &wesgine.CycleDetectConfig{
ActionTermThreshold: 50,
ExplorationTermThreshold: 100,
IdenticalCallTermThreshold: 7,
},
Roles
Cell 内角色列表(用于 Token 签发)。
SDK Hooks(json:"-")
以下字段标记为 json:"-",不参与序列化,必须在 GetOrCreate 之前通过代码绑定:
HostEnvironment
宿主环境注入(编辑器 buffer overlay、终端路由等):
spec.HostEnvironment = &deviceagent.Host{...}
OnStarted
Cell 启动完成回调:
spec.OnStarted = func(cell *wesgine.Cell) {
log.Printf("Cell %s 已启动", cell.ID())
}
ProviderLiveKeyFn(关键)
动态密钥获取函数,wes: / org: 类型 Provider 必填:
liveTokens := &providerid.LiveTokenSource{}
spec.ProviderLiveKeyFn = liveTokens.Key
// auth 初始化后绑定实际的 JWT accessor
liveTokens.Bind(auth.IdentityAccessToken, auth.ValidAccessToken)
INV-CELL-08:落盘了
wes:/org:Provider(SourceLive)却不绑ProviderLiveKeyFn→EnsureActivefail-loud。
QualityGate
质量门控回调(编辑验证):
spec.QualityGate = func(ctx context.Context, result QualityResult) error {
// 自定义验证逻辑
return nil
}
PostRunFn
Run 结束后回调:
spec.PostRunFn = func(ctx context.Context, summary RunSummary) {
// 记录统计、发送通知等
}
最佳实践
- ID 命名:使用有业务含义的名称(
dept-legal、ws-a1b2c3d4),避免随机字符串 - Provider 绑定:在
GetOrCreate之前完成所有json:"-"hook 的绑定 - 配额设置:生产环境务必设置合理的
Quotas,防止资源滥用 - 治理预设:优先使用
Compliance一键装配,避免手工拼装 Governance - 出生声明:
Cron和Email只在首次 boot 播种,运行时修改走 Handle API
注意事项
ID和Timezone创建后不可变- 存储路径由引擎从
(DataDir, ID)推出,没有CellSpec.Storage字段 - 未声明
Governance时默认ModeOpen,不是 fail-loud Compliance热切换只 swapRedactorRules,不增删DenyPaths