| name | stello-agent-creation |
| description | StelloAgent 创建配置教程。完整说明 createStelloAgent 的每个配置项,包含 sessionDefaults、storage、tools、skills、forkProfiles、session 层接入、orchestration 等。 |
StelloAgent 创建配置教程
最小可用示例
import {
createStelloAgent,
ToolRegistryImpl,
SkillRouterImpl,
type EngineLifecycleAdapter,
type ConfirmProtocol,
type SessionTree,
} from '@stello-ai/core'
import type { SessionStorage } from '@stello-ai/session'
const agent = createStelloAgent({
sessions,
storage: sessionStorage,
capabilities: {
lifecycle,
tools: new ToolRegistryImpl(),
skills: new SkillRouterImpl(),
confirm: { ... },
},
session: {
sessionLoader: async (id) => ({ session: loadedSession, config: null }),
},
})
配置结构总览
interface StelloAgentConfig {
sessions: SessionTree
storage?: SessionStorage
sharedMemory?: SharedMemoryStore
sessionDefaults?: SessionConfig
capabilities: {
lifecycle: EngineLifecycleAdapter
tools: EngineToolRuntime
skills: SkillRouter
confirm: ConfirmProtocol
profiles?: ForkProfileRegistry
}
session?: StelloAgentSessionConfig
runtime?: StelloAgentRuntimeConfig
orchestration?: StelloAgentOrchestrationConfig
}
所有 Session 共用 sessionDefaults。Root 没有专属配置,与子 session 走同一套 fork 合成链(详见 fork-design)。
"全 memory → 反思 → 定向 insight" 的循环由应用层基于 orchestrator-facing SDK 自行实现(不在配置注入点里)。
1. storage —— Orchestrator-facing 数据 SDK
storage: SessionStorage 注入后,StelloAgent 暴露以下 data-IO 方法(详见 stello-agent-usage):
listSessionDigests(filter?) —— 批量收集所有 Session 的 { id, label, status, memory, insight }
getSessionMetadata(id) —— 单个 Session 的 { memory, insight }
listMessages(id, options?) —— 读取指定 Session 的 L3 消息
putMemory(id, content) / putInsight(id, content) / clearInsight(id)
重要:应用层需保证 sessions(拓扑)与 storage(内容)指向同一份后端——SessionTree.listAll() 返回的 id 必须能在 SessionStorage 上 getMemory。
未注入 storage 时,上述方法会抛错;其余编排能力(turn / stream / fork / archive)不受影响。
2. sessionDefaults —— Agent 级默认配置
所有 Session 的配置基线,fork 合成链的最低优先级层。
createStelloAgent({
sessionDefaults: {
llm: defaultLlm,
consolidateFn: defaultConsolidateFn,
compressFn: defaultCompressFn,
systemPrompt: '你是一个助手。',
skills: undefined,
},
})
SessionConfig 完整字段:
interface SessionConfig {
systemPrompt?: string
llm?: LLMAdapter
tools?: LLMCompleteOptions['tools']
skills?: string[]
consolidateFn?: SessionCompatibleConsolidateFn
compressFn?: SessionCompatibleCompressFn
}
Root session 的固化配置由你创建 root 时通过 agent.createSession({ label }) + 后续 sessions.putConfig(rootId, ...) 设置——或在 sessionDefaults 给出全局默认即可。Root 没有特殊待遇。
3. capabilities — 能力注入
3.1 tools — 用户自定义工具
import { ToolRegistryImpl } from '@stello-ai/core'
const toolRegistry = new ToolRegistryImpl()
toolRegistry.register({
name: 'save_note',
description: '保存笔记到当前会话',
parameters: {
type: 'object',
properties: {
note: { type: 'string', description: '笔记内容' },
},
required: ['note'],
},
execute: async (args, _ctx) => {
await db.saveNote(String(args.note))
return { success: true, data: { saved: true } }
},
})
要点:
parameters 是 JSON Schema 格式,LLM 据此生成参数
execute(args, ctx) 返回 { success: true, data: ... } 或 { success: false, error: '...' }
- tool 执行失败时 Engine 自动将 error 作为 tool result 返回给 LLM,不中断对话
- 内置 tool(
stello_create_session / activate_skill)需要在 ToolRegistryImpl([...]) 构造时显式 opt-in(参考 createSessionTool() / activateSkillTool(skills) factory)
3.2 skills — Skill 注册表
Skill 是两级渐进式加载的 prompt 片段:LLM 始终看到 name + description,主动调用 activate_skill 后注入完整 content。
import { SkillRouterImpl, loadSkillsFromDirectory } from '@stello-ai/core'
const skillRouter = new SkillRouterImpl()
skillRouter.register({
name: 'code-review',
description: '代码审查专家,激活后按标准流程审查代码质量',
content: `你现在是代码审查专家。...`,
})
const fileSkills = await loadSkillsFromDirectory('./skills')
for (const skill of fileSkills) {
skillRouter.register(skill)
}
activate_skill 是否对 LLM 可见取决于 skills.getAll().length > 0,以及该 session 的 SessionConfig.skills 白名单(详见 fork-design 的 skills 三态语义)。
3.3 profiles — Fork Profile 注册表(可选)
ForkProfile 是预定义的 fork 配置模板,extends SessionConfig。LLM 调用 stello_create_session 时可通过 profile 参数引用。
import { ForkProfileRegistryImpl } from '@stello-ai/core'
const forkProfiles = new ForkProfileRegistryImpl()
forkProfiles.register('poet', {
systemPrompt: '你是一位诗人。所有回复必须用诗歌形式。',
systemPromptMode: 'preset',
})
forkProfiles.register('region-expert', {
systemPromptFn: (vars) => `你是${vars.region}地区的留学专家。`,
systemPromptMode: 'preset',
llm: cheaperLlmAdapter,
skills: ['search', 'summarize'],
consolidateFn: researchConsolidateFn,
})
forkProfiles.register('researcher', {
systemPrompt: '你是研究助手,善于深入分析。',
systemPromptMode: 'prepend',
context: 'inherit',
})
完整字段、合成规则、systemPromptMode 三种模式见 skill fork-design。
3.4 lifecycle — 生命周期适配器
const lifecycle: EngineLifecycleAdapter = {
bootstrap: async (sessionId) => ({
context: await memory.assembleContext(sessionId),
session: await sessions.get(sessionId),
}),
afterTurn: async (sessionId, userMsg, assistantMsg) => {
await memory.appendRecord(sessionId, userMsg)
await memory.appendRecord(sessionId, assistantMsg)
return { coreUpdated: false, memoryUpdated: false, recordAppended: true }
},
}
3.5 confirm — 确认协议
const confirm: ConfirmProtocol = {
async confirmSplit(proposal) {
return agent.forkSession(proposal.parentId, {
label: proposal.suggestedLabel,
})
},
async dismissSplit() {},
async confirmUpdate() {},
async dismissUpdate() {},
}
4. session — Session 层接入
StelloAgentSessionConfig 是纯 I/O 数据加载,按 ID 加载 Session 实例与其固化配置。
session: {
sessionLoader: async (sessionId) => {
const session = await loadSession(sessionId, {
storage: sessionStorage,
llm: currentLlm,
})
if (!session) throw new Error(`Session not found: ${sessionId}`)
return {
session,
config: null,
}
},
serializeSendResult: (result) => JSON.stringify(result),
toolCallParser: customParser,
}
所有 Session(含 root)由同一个 sessionLoader 按 id 加载。Root 与子 session 的差异只在拓扑 (TopologyNode.parentId === null),loader 无需区分。
两种 session 接入方式:
| 方式 | 配置 | 适用场景 |
|---|
| Session 适配 | session.sessionLoader | 使用 @stello-ai/session 包(推荐) |
| 直接提供 runtime | runtime.resolver | 自定义 session 实现 |
5. orchestration — 编排策略(可选)
consolidateEveryNTurns
orchestration: {
consolidateEveryNTurns: 5,
}
每 5 轮自动 consolidate(fire-and-forget)。
splitGuard
import { SplitGuard } from '@stello-ai/core'
orchestration: {
splitGuard: new SplitGuard(sessions, {
minTurns: 3,
cooldownTurns: 5,
}),
}
hooks
orchestration: {
hooks: {
onRoundStart({ sessionId, input }) {},
onRoundEnd({ sessionId, turn }) {},
onSessionFork({ parentId, child }) {},
onToolCall({ sessionId, toolCall }) {},
onError({ source, error }) {},
},
}
所有 hooks fire-and-forget:抛错时 emit error 事件,不中断对话。
6. 完整配置示例
import {
createStelloAgent,
ToolRegistryImpl,
SkillRouterImpl,
ForkProfileRegistryImpl,
SplitGuard,
SessionTreeImpl,
NodeFileSystemAdapter,
InMemorySharedMemoryStore,
createSessionTool,
activateSkillTool,
memoryRecallTool,
memoryRememberTool,
memoryForgetTool,
} from '@stello-ai/core'
import {
loadSession,
InMemoryStorageAdapter,
createOpenAICompatibleAdapter,
} from '@stello-ai/session'
const fs = new NodeFileSystemAdapter('./data')
const sessions = new SessionTreeImpl(fs)
const sessionStorage = new InMemoryStorageAdapter()
const sharedMemory = new InMemorySharedMemoryStore()
const llm = createOpenAICompatibleAdapter({
apiKey: process.env.OPENAI_API_KEY!,
model: 'gpt-4o',
})
const skills = new SkillRouterImpl()
skills.register({
name: 'data-analysis',
description: '数据分析模式:激活后按结构化流程分析数据',
content: '你是数据分析专家...',
})
const toolRegistry = new ToolRegistryImpl([
createSessionTool(),
activateSkillTool(skills),
memoryRecallTool(),
memoryRememberTool(),
memoryForgetTool(),
])
toolRegistry.register({
name: 'search_knowledge',
description: '搜索知识库',
parameters: {
type: 'object',
properties: { query: { type: 'string' } },
required: ['query'],
},
execute: async (args, _ctx) => ({
success: true,
data: await knowledgeBase.search(String(args.query)),
}),
})
const profiles = new ForkProfileRegistryImpl()
profiles.register('researcher', {
systemPrompt: '你是研究助手,善于深入分析。',
systemPromptMode: 'prepend',
context: 'inherit',
skills: ['search', 'data-analysis'],
})
let agent: ReturnType<typeof createStelloAgent>
agent = createStelloAgent({
sessions,
storage: sessionStorage,
sharedMemory,
sessionDefaults: {
llm,
systemPrompt: '你是一个助手。',
},
session: {
sessionLoader: async (sessionId) => {
const session = await loadSession(sessionId, { storage: sessionStorage, llm })
if (!session) throw new Error(`Session not found: ${sessionId}`)
return { session, config: null }
},
},
capabilities: {
lifecycle: {
bootstrap: async (sessionId) => ({
context: { core: {}, memories: [], currentMemory: null, scope: null },
session: await sessions.get(sessionId),
}),
afterTurn: async () => ({ coreUpdated: false, memoryUpdated: false, recordAppended: true }),
},
tools: toolRegistry,
skills,
profiles,
confirm: {
confirmSplit: async (p) => agent.forkSession(p.parentId, { label: p.suggestedLabel }),
dismissSplit: async () => {},
confirmUpdate: async () => {},
dismissUpdate: async () => {},
},
},
orchestration: {
consolidateEveryNTurns: 5,
splitGuard: new SplitGuard(sessions, { minTurns: 3, cooldownTurns: 5 }),
hooks: {
onSessionFork({ parentId, child }) {
console.log(`Fork: ${parentId} → ${child.id} (${child.label})`)
},
},
},
})
const root = await agent.createSession({ label: 'Main' })
await agent.enterSession(root.id)
const result = await agent.turn(root.id, '帮我分析一下市场趋势')
console.log(result.turn.finalContent)
7. 自行实现 reflection 循环
"全 memory → 反思 → 定向 insight" 的循环由应用层实现:
async function reflect(agent: StelloAgent, llm: LLMAdapter): Promise<void> {
const digests = await agent.listSessionDigests({ status: 'active' })
const reflection = await llm.complete([
{ role: 'system', content: '你是 orchestrator,请综合各 session 的 memory,对需要纠偏/补充信息的 session 写出 insight。' },
{ role: 'user', content: JSON.stringify(digests) },
])
const { insights } = JSON.parse(reflection.content ?? '{}') as { insights: Record<string, string> }
await Promise.all(
Object.entries(insights).map(([sessionId, content]) =>
agent.putInsight(sessionId, content),
),
)
}
8. 运行时使用
Agent 创建后的运行时操作(createSession / turn / stream / fork / attach / detach / 数据 SDK 等)见 skill stello-agent-usage。