一键导入
stello-agent-usage
StelloAgent 运行时使用教程。覆盖 Session 生命周期、createSession、turn/stream 对话、fork 配置合成链、orchestrator-facing 数据 SDK、runtime 管理、热更新等运行时 API。
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
菜单
StelloAgent 运行时使用教程。覆盖 Session 生命周期、createSession、turn/stream 对话、fork 配置合成链、orchestrator-facing 数据 SDK、runtime 管理、热更新等运行时 API。
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
基于 SOC 职业分类
StelloAgent 创建配置教程。完整说明 createStelloAgent 的每个配置项,包含 sessionDefaults、storage、tools、skills、forkProfiles、session 层接入、orchestration 等。
Engine 职责定义:per-session-round 生命周期管理器。驱动 tool call 循环,管理单个 Session 的多轮对话。不感知树结构,不感知调度。
Fork 机制完整说明。覆盖 ForkProfile 与 EngineForkOptions 的字段对齐、四层 fallback 合成链(sessionDefaults → parent → profile → forkOptions)、systemPrompt 合成三种模式、skills 三态语义、持久化边界(SerializableSessionConfig 只固化 systemPrompt/skills)。任何涉及 fork / profile / stello_create_session / 配置合成 的工作都应读这个。
Stello 框架内所有 LLM 调用位置的消息结构速查。覆盖 Session 对话、compress、consolidate;应用层 reflection 调用由 orchestrator 自行决定。
Consolidation 触发机制:自动触发通过 Factory 配置内联,手动触发通过 StelloAgent API;全局 reflection 由应用层在 SDK 之上自行实现。
Server 层设计:传输层架构决策、StelloAgent 映射原则、连接态管理模式。存储层见 server-storage,Engine 细节见 engine-design。
| name | stello-agent-usage |
| description | StelloAgent 运行时使用教程。覆盖 Session 生命周期、createSession、turn/stream 对话、fork 配置合成链、orchestrator-facing 数据 SDK、runtime 管理、热更新等运行时 API。 |
前置知识:
createStelloAgent(config)的配置方式见 skillstello-agent-creation。 本文档聚焦于 Agent 构建完成后的运行时操作。
对话起点是一个普通 Session(parentId === null),由 agent.createSession() 创建——不传 parentId 即为新 root。
const root = await agent.createSession({ label: 'Main' })
await agent.enterSession(root.id)
agent.createSession({ parentId?, label? }) 做了什么:
sessions.createSession({ parentId, label }) 创建拓扑节点(parentId 缺省即 parentId === null)TopologyNode(含 id / parentId / children / refs / depth / label 等)Root 没有特殊待遇——它就是一个普通 Session。多个 root 合法(森林)。全局默认 systemPrompt / skills 等配置在 sessionDefaults 即可。
createSession → enterSession → turn / stream (× N) → leaveSession → archiveSession
const bootstrap = await agent.enterSession(sessionId)
// bootstrap.context — 组装好的上下文(MemoryEngine 视角)
// bootstrap.session — SessionMeta(id, label, status, turnCount 等)
行为:触发 lifecycle.bootstrap(),初始化 Engine runtime。如果该 session 已有活跃 Engine,复用而非重建。
const result = await agent.turn(sessionId, '帮我分析市场趋势')
// result.turn.finalContent — 最终文本回复(tool loop 结束后)
// result.turn.toolRoundCount — 经历了几轮 tool call 循环
// result.turn.toolCallsExecuted — 实际执行了多少个 tool
// result.turn.rawResponse — 原始最终 LLM 响应
const streamResult = await agent.stream(sessionId, '帮我分析市场趋势')
for await (const chunk of streamResult) {
process.stdout.write(chunk)
}
const result = await streamResult.result
console.log(result.turn.finalContent)
await agent.turn(sessionId, input, {
maxToolRounds: 5, // 限制 tool call 循环轮数(默认无限)
signal: abortController.signal, // 支持取消(中断当前轮 LLM/tool 调用)
onToolCall: (toolCall) => { /* ... */ },
onToolResult: (result) => { /* ... */ },
})
await agent.leaveSession(sessionId) // 触发 consolidation 调度(fire-and-forget)
await agent.archiveSession(sessionId) // 标记归档,之后不应再 turn()
| 方式 | 触发者 | 入口 |
|---|---|---|
| LLM 发起 | LLM 调用 stello_create_session 内置 tool | 需在 capabilities.tools opt-in 注册 |
| 代码发起 | 应用层调用 agent.forkSession() | 手动编排 |
forkSession 参数const child = await agent.forkSession(sessionId, {
// ── 必填 ──
label: '市场分析-深度研究',
// ── SessionConfig 字段(可选,参与合成链)──
systemPrompt: '你是市场分析专家...',
llm: specializedLlm,
tools: customTools,
skills: ['search', 'summarize'],
consolidateFn: customConsolidateFn,
compressFn: customCompressFn,
// ── Fork 专属字段(可选)──
prompt: '请深入分析半导体行业', // fork 后立即发送的首条消息
context: 'inherit', // 'none'(默认)| 'inherit' | ForkContextFn
topologyParentId: otherNodeId, // 显式指定拓扑父节点(不传 = 当前 sessionId)
profile: 'researcher', // 引用预注册的 ForkProfile 名称
profileVars: { region: '北美' }, // ForkProfile.systemPromptFn 的模板变量
})
// child: TopologyNode
// child.id — 新 session 的 ID
// child.parentId — 拓扑父节点 ID
// child.sourceSessionId — fork 时的上下文来源 session ID
// child.depth — 拓扑深度(root = 0)
// child.label — 显示名称
Fork 后需要单独 enterSession(child.id) 才能在子 session 上 turn()。
context)await agent.forkSession(sessionId, { label: '子任务', context: 'none' }) // 空白开始(默认)
await agent.forkSession(sessionId, { label: '深度研究', context: 'inherit' }) // 完整继承 L3
await agent.forkSession(sessionId, {
label: '摘要子任务',
context: async (parentMessages) => parentMessages.slice(-10), // 自定义裁剪
})
fork 时按 sessionDefaults → 父 session 固化 config → ForkProfile → EngineForkOptions 顺序合成,后者覆盖前者。root 也是普通 session,从 root fork 会正常继承 root 的固化 config。
详见 skill fork-design。
需要在创建 agent 时注入 storage: SessionStorage(顶层)。这套 API 让外部 orchestrator(应用层 / Claude Code / Codex / Kitkit 等)能够在对话之外直接读取和回写每个 Session 的数据。
const roots = await agent.listRoots() // TopologyNode[]
const forest = await agent.getTopology() // SessionTreeNode[](嵌套森林)
const node = await agent.getTopologyNode(sessionId) // 单个 TopologyNode
const sessions = await agent.listSessions({ status: 'active' }) // SessionMeta[]
const view = await agent.getSessionMetadata(sessionId)
// view.memory — string | null(持久;不进 send 上下文)
// view.insight — string | null(一次性 inbox;下次 send 注入并 clear)
const digests = await agent.listSessionDigests({ status: 'active' })
// digests[i] = { id, label, status, memory, insight }
应用层把这份数据喂给反思层 LLM,由它产出 per-session insight,再调用 agent.putInsight 定向回写。完整模式见 skill session-usage。
const messages = await agent.listMessages(sessionId, { limit: 100 })
await agent.putMemory(sessionId, '当前进展摘要...') // 持久 memory(替换语义)
await agent.putInsight(sessionId, '需要重新评估方向...') // 一次性 insight(send 消费后 clear)
await agent.clearInsight(sessionId) // 主动清除
未在 agent 创建时注入 storage 时,这些方法会抛错。
适用于 WebSocket 等多客户端连接场景,通过引用计数管理 Engine 生命周期。
await agent.attachSession(sessionId, connectionId) // WS 连接建立
await agent.detachSession(sessionId, connectionId) // WS 连接断开
agent.hasActiveEngine(sessionId) // 是否有活跃 Engine
agent.getEngineRefCount(sessionId) // 当前引用计数
回收策略:
createStelloAgent({
runtime: {
resolver: myResolver,
recyclePolicy: { idleTtlMs: 30_000 },
},
})
// 运行时更新
agent.updateConfig({ runtime: { idleTtlMs: 60_000 } })
const root = await agent.createSession({ label: 'Main' })
await agent.enterSession(root.id)
await agent.turn(root.id, '你好')
await agent.turn(root.id, '继续上个话题')
await agent.leaveSession(root.id)
const root = await agent.createSession({ label: 'Main' })
await agent.enterSession(root.id)
await agent.turn(root.id, '我需要研究三个市场')
const children = await Promise.all([
agent.forkSession(root.id, { label: '美国市场', systemPrompt: '你是美国市场专家' }),
agent.forkSession(root.id, { label: '欧洲市场', systemPrompt: '你是欧洲市场专家' }),
agent.forkSession(root.id, { label: '亚洲市场', systemPrompt: '你是亚洲市场专家' }),
])
await Promise.all(
children.map(async (child) => {
await agent.enterSession(child.id)
await agent.turn(child.id, '分析半导体供应链')
await agent.leaveSession(child.id) // 触发 consolidation
}),
)
// 独立的研究/写作两条线,互不影响
const research = await agent.createSession({ label: 'Research' })
const writing = await agent.createSession({ label: 'Writing' })
await agent.enterSession(research.id)
await agent.turn(research.id, '调研材料 ...')
await agent.enterSession(writing.id)
await agent.turn(writing.id, '基于已有材料写一份 ...')
const all = await agent.listRoots() // 两个 root 都会出现
async function reflect(agent: StelloAgent, llm: LLMAdapter): Promise<void> {
const digests = await agent.listSessionDigests({ status: 'active' })
// ... 应用层 prompt 把 digests 喂给 llm,解析出 per-target insight ...
for (const [id, content] of Object.entries(insightsByTarget)) {
await agent.putInsight(id, content)
}
}
详见 stello-agent-creation §7。
ws.on('connection', async (socket) => {
const holderId = socket.id
socket.on('enter', async ({ sessionId }) => {
await agent.attachSession(sessionId, holderId)
await agent.enterSession(sessionId)
})
socket.on('message', async ({ sessionId, input }) => {
const stream = await agent.stream(sessionId, input)
for await (const chunk of stream) {
socket.send(JSON.stringify({ type: 'chunk', data: chunk }))
}
const result = await stream.result
socket.send(JSON.stringify({ type: 'done', data: result }))
})
socket.on('close', async () => {
for (const sessionId of socket.sessions) {
await agent.detachSession(sessionId, holderId)
}
})
})
| 方法 | 返回值 | 说明 |
|---|---|---|
createSession({ parentId?, label? }) | Promise<TopologyNode> | 创建拓扑节点(不传 parentId 即新 root;多 root 合法) |
enterSession(id) | Promise<BootstrapResult> | 进入 session,触发 bootstrap |
turn(id, input, opts?) | Promise<EngineTurnResult> | 同步对话轮次(含 tool call 循环) |
stream(id, input, opts?) | Promise<EngineStreamResult> | 流式对话轮次 |
leaveSession(id) | Promise<{ sessionId }> | 离开 session,触发 consolidation 调度 |
forkSession(id, opts) | Promise<TopologyNode> | 创建子 session,执行配置合成链 |
archiveSession(id) | Promise<{ sessionId }> | 归档 session |
consolidateSession(id) | Promise<void> | 手动触发该 session 的 consolidation |
attachSession(id, holderId) | Promise<OrchestratorEngine> | 附着 runtime 持有者 |
detachSession(id, holderId) | Promise<void> | 释放 runtime 持有者 |
hasActiveEngine(id) | boolean | 是否有活跃 Engine |
getEngineRefCount(id) | number | 当前引用计数 |
updateConfig(patch) | void | 热更新运行时配置 |
storage)| 方法 | 返回值 | 说明 |
|---|---|---|
listSessions(filter?) | Promise<SessionMeta[]> | 列出所有 session |
listRoots() | Promise<TopologyNode[]> | 列出所有 root |
getTopology() | Promise<SessionTreeNode[]> | 完整森林(嵌套树) |
getTopologyNode(id) | Promise<TopologyNode | null> | 单个节点 |
getSessionMetadata(id) | Promise<{ memory, insight }> | 单 session 的 memory + insight |
listSessionDigests(filter?) | Promise<SessionDigest[]> | 批量收集所有 Session 的 digest |
listMessages(id, options?) | Promise<Message[]> | 读取 L3 消息 |
putMemory(id, content) | Promise<void> | 写入 memory |
putInsight(id, content) | Promise<void> | 写入 insight(一次性) |
clearInsight(id) | Promise<void> | 清除 insight |
| 属性 | 类型 | 说明 |
|---|---|---|
config | StelloAgentConfig | 归一化后的完整配置 |
sessions | SessionTree | 拓扑树 |
memory | MemoryEngine | 记忆引擎 |
storage | SessionStorage | undefined | 数据存储(未注入时 data-IO 方法不可用) |
profiles | ForkProfileRegistry | undefined | Fork 模板注册表 |