Skip to main content

状态、工具与用户知识

为智能体附加状态,定义 LLM 可调用的自定义工具,并在首次对话前为用户预加载知识。

自定义状态

在聊天时注入 LLM 上下文的灵活键值存储。用它将环境状态、任务进度、资源或任何应用数据直接传入每次 AI 响应。

作用域模型

全局状态
每实例——在一个实例的所有用户间共享。适用于环境状态、配置、智能体状态、全局事件。
每用户状态
每实例 + 每用户——限定于实例中的某一用户。适用于已分配任务、工作流进度、用户偏好、活跃工具。

实例

所有状态都限定于某个 instanceId——你的智能体的一个部署上下文(例如工作区或环境)。省略 instanceId 则使用默认实例。参见实例了解如何管理多个上下文。

创建状态

import { Sonzai } from "@sonzai-labs/agents";

const client = new Sonzai({ apiKey: "sk-..." });

// 全局状态(所有用户共享)
await client.agents.customStates.create("agent-id", {
key:         "current_status",
value:       "Processing requests",
scope:       "global",
contentType: "text",
instanceId:  "workspace-1",    // 省略则使用默认实例
});

// 每用户状态
await client.agents.customStates.create("agent-id", {
key:         "assigned_tasks",
value:       { reports: 1, reviews: 3 },
scope:       "user",
contentType: "json",
userId:      "user-123",
instanceId:  "workspace-1",
});

插入或更新(Upsert)

upsert 在键不存在时创建状态,或在键已存在时更新值。幂等——可安全地在每次更新周期调用。

await client.agents.customStates.upsert("agent-id", {
key:   "workflow_stage",
value: "review_started",
scope: "user",
userId: "user-123",
});

按键获取

通过复合键检索特定状态。

const state = await client.agents.customStates.getByKey("agent-id", {
key:    "assigned_tasks",
scope:  "user",
userId: "user-123",
});

console.log(state.value);     // { reports: 1, reviews: 3 }
console.log(state.updatedAt); // ISO 时间戳

列出状态

// 某实例的所有全局状态
const globals = await client.agents.customStates.list("agent-id", {
scope:      "global",
instanceId: "workspace-1",
});

// 特定用户的所有每用户状态
const userStates = await client.agents.customStates.list("agent-id", {
scope:  "user",
userId: "user-123",
});

按键删除

await client.agents.customStates.deleteByKey("agent-id", {
key:    "assigned_tasks",
scope:  "user",
userId: "user-123",
});

工具

工具让 LLM 在推理过程中调用函数。Sonzai 处理带 sonzai_ 前缀的内置工具。自定义工具由你定义并由你的后端执行——Sonzai 将调用作为副作用暴露出来。

使用自己的 LLM?

如果你使用独立记忆模式(自带 LLM),Sonzai 暴露你可以接入自己的智能体框架(LangChain、Vercel AI SDK、Gemini 函数调用等)的工具模式。详见工具集成指南

内置工具(能力)

按智能体切换平台管理的能力。这些在智能体创建时启用或通过能力 API 更新。

sonzai_memory_recall(始终开启)

在推理时搜索存储的记忆。自动注入上下文。

sonzai_remember_name(可切换)

为未来的对话持久化用户姓名。默认开启。

sonzai_web_search(可切换)

通过 Google 进行实时网络搜索。默认开启。

sonzai_inventory(可切换)

读取用户资源项目并与知识库数据关联。

// 在智能体创建时设置能力
const agent = await client.agents.create({
agentId: "your-stable-uuid",  // 推荐——使创建操作幂等
name: "Luna",
big5: { openness: 0.75, conscientiousness: 0.6, extraversion: 0.8,
        agreeableness: 0.7, neuroticism: 0.3 },
toolCapabilities: {
  webSearch:       true,
  rememberName:    true,
  imageGeneration: false,
  inventory:       true,
},
});

// 或更新现有智能体的能力
await client.agents.update("agent-id", {
toolCapabilities: {
  webSearch: false,
  inventory: true,
},
});

保留前缀

sonzai_ 前缀为系统保留。你的自定义工具不得使用——API 会拒绝它们。

自定义工具(智能体级别)

与智能体一起存储的持久工具,在每次聊天中可用,与会话或实例无关。

// 创建自定义工具
await client.agents.createCustomTool("agent-id", {
name: "check_inventory",
description: "Check the user's current tasks and their statuses",
parameters: {
  type: "object",
  properties: {
    item_type: {
      type: "string",
      description: "Filter by category: active, pending, completed",
    },
  },
},
});

// 列出所有自定义工具
const tools = await client.agents.listCustomTools("agent-id");

// 更新工具的描述或参数
await client.agents.updateCustomTool("agent-id", "check_inventory", {
description: "Check and summarize the user's tasks by category",
});

// 删除工具
await client.agents.deleteCustomTool("agent-id", "check_inventory");

会话级工具(临时)

为特定会话动态注入工具。会话工具与智能体级工具合并——同名的会话工具优先。会话结束时丢弃。

选项 1——为现有会话设置

await client.agents.sessions.setTools("agent-id", "session-id", [
{
  name: "execute_action",
  description: "Execute an action from the agent's capabilities",
  parameters: {
    type: "object",
    properties: {
      action_name: { type: "string" },
      target:      { type: "string" },
    },
    required: ["action_name"],
  },
},
]);

选项 2——随聊天调用内联传入

for await (const event of client.agents.chatStream({
agent:    "agent-id",
messages: [{ role: "user", content: "Check my tools" }],
userId:   "user-123",
toolDefinitions: [
  {
    name:        "check_inventory",
    description: "List the agent's active tools",
    parameters:  { type: "object", properties: {} },
  },
],
})) {
// 处理事件...
}

处理工具调用

当 LLM 决定调用自定义工具时,它会作为 SSE 流中的副作用出现。你的后端执行工具并在下一条消息中返回结果。

1. 接收工具调用

const toolCalls: { name: string; arguments: Record<string, unknown> }[] = [];

for await (const event of client.agents.chatStream({
agent:    "agent-id",
messages: [{ role: "user", content: "What tasks do I have?" }],
userId:   "user-123",
})) {
// 将内容流式传输给用户
const content = event.choices?.[0]?.delta?.content;
if (content) process.stdout.write(content);

// 从副作用中收集工具调用
const calls = event.sideEffects?.externalToolCalls ?? [];
toolCalls.push(...calls);
}

2. 执行并返回结果

// 在你的后端执行工具调用
const toolResults: string[] = [];
for (const call of toolCalls) {
const result = await myBackend.executeTool(call.name, call.arguments);
toolResults.push(result);
}

// 在下一条聊天消息中返回结果
for await (const event of client.agents.chatStream({
agent:    "agent-id",
userId:   "user-123",
messages: [
  { role: "user",  content: "What tasks do I have?" },
  { role: "tool",  content: toolResults.join("\n") },
],
})) {
process.stdout.write(event.choices?.[0]?.delta?.content ?? "");
}

工具作用域总结

类型作用域持久性管理方式
内置(sonzai_所有实例平台管理SDK 能力、仪表盘
智能体级自定义所有实例持久SDK、仪表盘
会话级每会话临时SDK(内联或 setTools)

用户范围知识(预填)

在用户第一次对话之前预填智能体对用户的了解。适用于 CRM 数据、用户档案、历史购买记录,或任何从第一天起就应该可用的用户特定知识。

预填用户

primeUser 异步地为用户预填事实。返回一个任务 ID,你可以轮询它来检查提取何时完成。

const job = await client.agents.priming.primeUser(
"agent-id",
"user-123",
{
  display_name: "Jane Smith",
  metadata: {
    company: "Acme Corp",
    title:   "Product Manager",
    email:   "[email protected]",
    custom:  { tier: "premium", region: "us-west" },
  },
  content: [
    {
      type:    "text",
      content: "Jane joined in 2024 and prefers concise answers. She focuses on mobile growth.",
    },
  ],
  source: "crm_import",
},
);

// 检查预填何时完成
const status = await client.agents.priming.getPrimeStatus(
"agent-id", "user-123", job.jobId
);
console.log(status.status); // "pending" | "processing" | "completed" | "failed"

获取和更新用户元数据

// 获取用户的存储元数据
const meta = await client.agents.priming.getMetadata("agent-id", "user-123");
console.log(meta.displayName, meta.company, meta.customFields);

// 更新元数据(局部更新——未指定字段保留原值)
await client.agents.priming.updateMetadata("agent-id", "user-123", {
custom: { tier: "enterprise", lastContact: "2026-03-28" },
});

批量导入(多个用户)

一次导入多个用户。返回任务 ID 以追踪进度。

const job = await client.agents.priming.batchImport("agent-id", {
users: [
  {
    userId:      "user-1",
    displayName: "Alice",
    metadata:    { company: "Acme", custom: { tier: "pro" } },
    content:     [{ type: "text", content: "Alice is a power user." }],
  },
  {
    userId:      "user-2",
    displayName: "Bob",
    metadata:    { company: "Globex" },
  },
],
source: "bulk_crm_sync",
});

// 轮询导入状态
const status = await client.agents.priming.getImportStatus(
"agent-id", job.jobId
);
console.log(status.processed, status.total, status.failed);

// 列出最近的导入任务
const jobs = await client.agents.priming.listImportJobs("agent-id", 10);

实际应用

自定义状态和工具是每种使用场景的两大扩展点——但你存储什么以及暴露哪些工具差异显著。

状态是场景和世界层数据。 存储在聊天之间持久化并驱动世界的事物: 任务进度、可解锁内容标志、场景状态、角色携带的世界内物品库存。

工具是表达性行为。 角色可以在你的应用中做的事—— 表达情绪、更换服装、移动到不同场景、赠送礼物。 描述要生动,这样 LLM 才能自然地调用它们。

await client.agents.sessions.setTools("agent-id", {
  userId: "user-123",
  tools: [
    {
      name: "change_scene",
      description: "Move to a new location in the story. Use when the scene has run its course or a new chapter begins.",
      parameters: { type: "object", properties: { location: { type: "string" } }, required: ["location"] },
    },
  ],
});

不要包含移交工具。 伴侣永远不应该推给人工—— 关系本身就是产品。

相关内容

On this page