Documentation
¶
Overview ¶
agent.go 装配声明式 sub-agent:与主循环**同构**的隔离子循环—— 同一套 harness(L1 纪律 + Ring 0 闸门 + 评审循环 + 压缩),只是 persona/工具面/画像不同。对应 Claude Code 的 .claude/agents/*.md。
三条在装配时固定的边界:
- 接口边界:大脑只看到 description + params,内部循环被隐藏;
- 上下文边界:每次调用从零起一轮(fresh;fork 以调用方对话快照 起步),内部消息不回流宿主上下文;
- 权限边界:工具面被锁定为声明的子集,不继承宿主能力。
fetch.go:外部 skillpack 的拉取与本地化(vendoring)。
ref 三种形态(见 docs/skillpack-design.md §3):
github.com/<owner>/<repo>[/<subdir>]@<tag|sha> 经 codeload zip 拉取 https://<host>/<path>.zip 直链归档(需 integrity 或 allow_unpinned) file:<path> 本地目录(开发/私有分发,每次重物化)
产物落 <root>/.skills 形态的目录树 + skills.lock(供给链事实): 启动期命中且树哈希与 lock 相符 → 零网络;缺失按策略补拉;哈希不符 fail fast,永不静默重下。只用 stdlib,仅装配期可达(运行期零网络)。
pack.go:skillpack——外部 SKILL.md 技能包在框架内的执行形态(模型自主、 指令驱动;与确定性编排同为 kind=skill,消费方无差别选品,溯源看 Tags)。
渐进披露映射(docs/skillpack-design.md §2):
frontmatter name/description → capability.Meta(L1,常驻目录供选品) Markdown 正文 → 内部 react 循环的 persona 层(L2,选中才加载) 打包文件 → pack_read 只读工具(L3,按需;路径囚笼) allowed-tools → 工具面白名单(∩ 条目收紧 ∩ 目录)
执行是隔离子循环:正文不进宿主上下文,宿主只见 L1 与最终结果;Ring 0 闸门与内部 skill 同源(applyGates);条目声明 context: fork 时以调用方 对话快照起步(复用编排步骤的同名字段语义)。
Package skill 实现两类可声明执行体(概念收敛后的最终形态,见 docs/concept-convergence-plan.md):
- skill(Declaration/Build):Agent Skills 标准语义的过程卡—— 「任务书模板 + 参数 schema」,调用返回执行指引,宿主主循环 亲自照指引执行,工具由装配层直挂宿主。全量共享主上下文, 因为执行者就是主大脑本人。
- sub-agent(AgentDecl/BuildAgent,见 agent.go):同构的隔离 子循环——与主循环同一套 harness,只是 persona/工具面/画像 不同。必然隔离(fresh 缺省,fork 快照可选),事实靠调用方 显式传参。
上下文分界线就是"有没有第二个大脑":skill 没有(主上下文全量 可见),sub-agent 有(必然隔离)。中间态不存在。
Index ¶
- Constants
- func Build(ctx context.Context, decl *Declaration, deps Deps) (capability.Capability, error)
- func BuildAgent(ctx context.Context, decl *AgentDecl, deps Deps) (capability.Capability, error)
- func BuildPack(ctx context.Context, m *PackManifest, ov PackOverrides, deps Deps, ...) (capability.Capability, error)
- func NewDelegate(m einomodel.ToolCallingChatModel, host []capability.Capability, ...) capability.Capability
- type AgentDecl
- type Declaration
- type DelegateConfig
- type Deps
- type ModelDecl
- type PackDir
- type PackManifest
- type PackOptions
- type PackOverrides
- type PackSpec
- type Selector
Constants ¶
const TagProcedureCard = capability.TagProcedureCard
TagProcedureCard 别名 core 常量(digest 豁免与计划面都认它)。
Variables ¶
This section is empty.
Functions ¶
func Build ¶
func Build(ctx context.Context, decl *Declaration, deps Deps) (capability.Capability, error)
Build 把 skill 声明装配为过程卡能力:调用不跑子循环,而是渲染任务书 并作为执行指引返回,宿主主循环亲自照做——Agent Skills 的标准语义 (指令注入 + 工具常驻)。声明的 tools 由装配层直挂宿主工具面,这里 只产卡片本体。
取舍(见 docs/single-agent-mode-plan.md §5):主循环亲自执行消除 "证据经子循环终答转述"的损耗;需要机械保真交付(deliver:)或隔离 上下文的实体,声明成 sub-agent(BuildAgent)。
func BuildAgent ¶
func BuildAgent(ctx context.Context, decl *AgentDecl, deps Deps) (capability.Capability, error)
BuildAgent 把 sub-agent 声明装配为能力:解析引用并锁版本 → 检查依赖 → 构建标准循环 Runner → 套上 manifest。产物身份 cap://agent/<ns>/<name> (与 A2A 远程 agent 同 kind,身份语义统一)。
func BuildPack ¶
func BuildPack(ctx context.Context, m *PackManifest, ov PackOverrides, deps Deps, extra ...capability.Capability) (capability.Capability, error)
func NewDelegate ¶
func NewDelegate(m einomodel.ToolCallingChatModel, host []capability.Capability, cfg DelegateConfig, deps Deps) capability.Capability
NewDelegate 构造 delegate 内置能力。host 是宿主的原始工具面(未套宿主 级门闸——子循环用 applyGates 自套,与 component 同一纪律)。
Types ¶
type AgentDecl ¶
type AgentDecl struct {
// Name 形如 "research/analyst",namespace/name。
Name string `yaml:"name"`
Version string `yaml:"version"`
Description string `yaml:"description"`
Params map[string]capability.ParamDecl `yaml:"params"`
// Prompt 是 persona + 任务书模板,params 以 {name} 占位渲染。
Prompt prompt.Value `yaml:"prompt"`
// Capabilities 是内部工具面(最小权限子集),CapRef 模式;命名空间
// 装配层用 tools: 短形态预解析注入(Deps.Capabilities),此字段供
// 程序化装配按目录选品。
Capabilities struct {
Include []string `yaml:"include"`
Exclude []string `yaml:"exclude"`
} `yaml:"capabilities"`
// Model 是专属模型,nil 跟随宿主(装配层按画像链解析后注入)。
Model *ModelDecl `yaml:"model"`
// MaxSteps 是内部循环轮数上限(yaml 键 max_rounds,0 用默认)。
MaxSteps int `yaml:"max_rounds"`
MaxStepsLegacy *int `yaml:"max_steps"` // 已废弃:改 max_rounds
// Deliver 是产出的交付语义:attach(存底,终答引用 #dN 即原文随行)
// | always(恒随行)| direct(独占轮次时原文即终答);缺省 = 证据。
Deliver string `yaml:"deliver"`
// Compaction 启用内部循环的上下文压缩(长任务建议开启)。
Compaction loop.CompactionConfig `yaml:"compaction"`
// Context 是起始上下文:fresh(缺省,零上下文起步)| fork(以调用方
// 对话快照+任务书起步;背景无损继承,内部过程仍不回流)。心法:
// 先把事实显式写进输入,写不进或写不全才 fork。
Context string `yaml:"context"`
// Todo 给内部循环挂调用级临时清单:键 = 本次执行域,生命周期 =
// 一次调用,结束即弃——宿主计划不受影响,sub-agent 保持无状态
// 可重入。默认关;长到需要计划通常是"该拆成结构"的信号。
Todo bool `yaml:"todo"`
// ——已移除键,误写装配期报错指路——
EngineLegacy *string `yaml:"engine"`
EngineConfigLegacy map[string]any `yaml:"engine_config"`
ModeLegacy *string `yaml:"mode"`
}
AgentDecl 是一个声明式 sub-agent 的完整声明(subagents: 条目)。 没有 engine 键:sub-agent 永远运行标准循环(同构),这是概念收敛 的硬边界——需要不同"执行形态"的诉求用 skill(主循环照指引执行) 或宿主代码编排(eino compose + AsLambda)表达。
type Declaration ¶
type Declaration struct {
// Kind 是产物的 cap kind:空=skill。
Kind string `yaml:"-"`
// Name 形如 "research/competitor_report",namespace/name。
Name string `yaml:"name"`
Version string `yaml:"version"`
Description string `yaml:"description"`
Params map[string]capability.ParamDecl `yaml:"params"`
// Prompt 是任务书模板(业务知识所在),params 以 {name} 占位渲染。
Prompt prompt.Value `yaml:"prompt"`
// ——以下键已随概念收敛移除(skill 永远在主循环执行,没有内部
// 循环;隔离执行体声明成 sub-agent)。误写装配期报错指路。——
ModeLegacy *string `yaml:"mode"`
EngineLegacy *string `yaml:"engine"`
EngineConfigLegacy map[string]any `yaml:"engine_config"`
DeliverLegacy *string `yaml:"deliver"`
TodoLegacy *bool `yaml:"todo"`
CompactionLegacy map[string]any `yaml:"compaction"`
MaxStepsLegacy *int `yaml:"max_steps"`
}
Declaration 是一个 skill(过程卡)的完整声明:任务书 + 参数 schema。 这与 Agent Skills 标准的 SKILL.md 同构(name/description/正文指引)。 需要隔离执行的实体不是 skill——声明成 sub-agent(subagents:,见 AgentDecl)。
type DelegateConfig ¶
type DelegateConfig struct {
Enabled bool `yaml:"enabled"`
MaxRounds int `yaml:"max_rounds"` // 子循环轮数缺省 8;调用参数只可收紧
MaxParallel int `yaml:"max_parallel"` // 并发上限缺省 4,超出排队
}
DelegateConfig 是动态委派的治理面(agents.delegate)。
type Deps ¶
type Deps struct {
Catalog Selector
Prompts prompt.Source
DefaultModel einomodel.ToolCallingChatModel
// LoopPrompt 是 L1 框架规约,sub-agent 内部循环复用,保持运行纪律一致。
LoopPrompt string
// Capabilities 是预解析的工具面。非空时跳过 Catalog 选品,由调用方
// (命名空间装配层)负责引用解析与边界校验。
Capabilities []capability.Capability
// ToolTimeout 是内部工具面的单次调用超时(0 默认,<0 关闭)。
ToolTimeout time.Duration
// Retry 是专属模型的瞬时错误重试策略(DefaultModel 由上层包装)。
Retry loop.RetryConfig
// DigestOver 启用内部工具面的大结果消化:超过该 rune 数的工具
// 结果先落 run 级暂存,由模型带任务提取要点后入上下文(0 关闭)。
DigestOver int
// Truncate 是工具结果硬截断上限(rune;0 用内置默认)。与宿主 agent
// 同一画像键(digest.truncate),装配层透传,保证子循环同一纪律。
Truncate int
// DegradeKeep 是暂存降级时的应急保留量(rune;0 用内置默认 24000),
// 画像键 digest.degrade_keep。
DegradeKeep int
// Todo 是 sub-agent 调用级清单的持有对象(仅 decl.Todo 时用),由装配层
// 注入后端。清单是调用级临时草稿(结束即弃),用进程内后端即可。
Todo *todo.Todo
// AgentHub 按名解析已装配 agent(skillpack frontmatter `agent:` 字段,
// eino AgentHub 的本地等价物)。装配层注入;查找延迟到调用期(agent
// 可能晚于技能装配),名字合法性由装配层在装配期校验。
AgentHub func(name string) (capability.Capability, bool)
// ModelHub 按名解析具名模型(skillpack frontmatter `model:` 字段)。
// 装配层注入,装配期解析,查不到 fail fast。
ModelHub func(ctx context.Context, name string) (einomodel.ToolCallingChatModel, error)
}
Deps 是装配 skill / sub-agent 所需的环境。Catalog/Prompts 均为接口: 只依赖"能选品""能解析引用"两个行为,不依赖装配层的具体目录/解析器。
type ModelDecl ¶
type ModelDecl struct {
Provider string `yaml:"provider" json:"provider"`
Config map[string]any `yaml:"config" json:"config"`
}
ModelDecl 是专属模型声明(sub-agent 与 skillpack 用),nil 则跟随宿主。
type PackDir ¶
type PackDir struct {
Dir string // 本地目录(.skills/<ns>/<name>@<version>)
Ref string
NS string
Name string
Version string
SHA string // 内容树哈希(sha256)
}
PackDir 是一个已物化并通过校验的包。
func EnsurePack ¶
EnsurePack 保证 spec 引用的包物化在 root 下并通过校验。
lock 命中且目录树哈希相符 → 直接返回(零网络); 缺失:RequireLocal → 错;否则拉取,与 lock(若有)比对后落盘; 哈希不符 → 错(篡改/漂移,永不静默重下)。
file: 引用是本地开发形态,每次重物化并刷新 lock(漂移是预期)。
type PackManifest ¶
type PackManifest struct {
NS, Name string
Version string
Description string
Body string // SKILL.md 正文(L2)
AllowedTools []string // frontmatter allowed-tools(CapRef 模式)
Dir string // 本地物化目录
Ref string // 来源 ref(观测/回溯)
SHA string // 内容树哈希
HasFiles bool // 除 SKILL.md 外还有文件(决定挂不挂 pack_read)
// Runtimes 是包内脚本类型(按扩展名检测:.py→python .js/.mjs→node
// .sh→bash),非空说明是脚本型技能包:装配层据此绑定 exec 工具
// (工作目录=包目录),包风险经 exec 工具传播为 Dangerous。
Runtimes []string
// 以下来自 frontmatter,与 eino ADK Skill middleware 协议对齐:
// Context 已归一为全库统一词表:""/fresh(隔离,默认)| fork(带
// 调用方对话快照)。第三方包的旧值在解析处兼容映射(fork→fresh、
// fork_with_context→fork)并记 warn。Agent/Model 按名指定执行
// agent 或模型,经 Deps.AgentHub/ModelHub 解析。
Context string
Agent string
Model string
}
PackManifest 是解析后的技能包。
func LoadManifest ¶
func LoadManifest(pd PackDir) (*PackManifest, error)
LoadManifest 从已物化的包目录解析 manifest(pd 来自 EnsurePack)。
type PackOptions ¶
type PackOptions struct {
RequireLocal bool // true:缺失即错(为打包期物化预留的收紧档)
AllowUnpinned bool // true:放行未 pin 的 ref(lock 仍会锁死首次解析结果)
}
PackOptions 是获取策略(app 级 skillpacks 块)。
type PackOverrides ¶
type PackOverrides struct {
Model *ModelDecl // 专属模型,nil 跟随宿主默认
MaxSteps int
Tools []string // 白名单收紧(与 allowed-tools 求交集)
Context string // "" | fresh | fork(与编排步骤同义)
}
PackOverrides 是 use: 条目的本地覆盖(名字覆盖走 PackSpec.Name, 物化目录与 lock 以最终名记账)。
type PackSpec ¶
type PackSpec struct {
Use string // ref 字符串
Integrity string // "sha256:<hex>",可选:强校验归档字节
Name string // 本地覆盖 "ns/name",可空(取 frontmatter)
}
PackSpec 是一条外部引用(config 的 use: 条目解析后)。
type Selector ¶
type Selector interface {
Select(include, exclude []string) ([]capability.Capability, error)
}
Selector 是能力选品的最小契约(消费方定义):按 CapRef include/exclude 选出工具子集。*source.Catalog 天然实现。