Skip to content

GUM Node SDK

本页说明如何在 Node.js Backend 中使用 @steamory-agent-kit/gum 接入 GUM Memory:创建 Session、写入对话消息、召回 Memory,并记录用户 Action。

GUM API Key 只能放在服务端。不要把 API Key 暴露给浏览器、移动端应用或公开仓库。

Before you start

你需要:

  • Node.js 18 或更高版本。
  • 一个可用的 GUM API Key。
  • 一个服务端运行环境,例如 Node.js API route、worker 后端、Express 服务或队列任务。

如果只是本地验证,可以先设置环境变量:

bash
export GUM_API_KEY="<your-gum-api-key>"

Install

bash
npm install @steamory-agent-kit/gum

SDK 同时提供 ESM、CommonJS 和 TypeScript 类型声明。Node.js 18+ 环境可以直接使用内置 fetch

Quickstart

下面的示例完成最短接入路径:初始化客户端、创建 Session、写入几条对话消息,然后召回相关 Memory。

ts
import { GumClient } from "@steamory-agent-kit/gum";

const gum = new GumClient({
  apiKey: process.env.GUM_API_KEY!,
});

const session = await gum.sessions.create({
  user_id: "user_123",
  title: "Team scheduling session",
});

await session.addMessages([
  {
    role: "user",
    content:
      "For team scheduling, use Berlin when I mention Europe and Toronto when I mention the Americas.",
  },
  {
    role: "assistant",
    content:
      "Got it. I will use Berlin for Europe scheduling and Toronto for Americas scheduling.",
  },
]);

const memory = await session.getMemory({
  query: "which city should be used for Europe team scheduling",
});

console.log(memory.data);

Checkpoint

这段代码运行后,你应该能拿到一个 Session 对象,并从 memory.data 中读取 GUM 返回的 Memory 结果。session.id 是后续继续写入消息和召回 Memory 的稳定标识。

Use GUM in an assistant turn

在真实 Agent 或助手系统中,推荐的顺序是:

  1. 用户输入到达 Node.js Backend。
  2. 使用当前 session.id 召回相关 Memory。
  3. 将 Memory 放入模型上下文。
  4. 得到模型回复后,把用户消息和助手回复写回 GUM。
ts
import { GumClient } from "@steamory-agent-kit/gum";

const gum = new GumClient({
  apiKey: process.env.GUM_API_KEY!,
});

type ModelInput = {
  userContent: string;
  recalledMemory: unknown;
};

async function generateAssistantReply(input: ModelInput): Promise<string> {
  // Replace this function with your OpenAI, Anthropic, Gemini, or local model call.
  return `I will use the recalled memory for: ${input.userContent}`;
}

export async function assistantTurn(params: {
  sessionId: string;
  userContent: string;
}) {
  const session = gum.sessions.fromId(params.sessionId);

  const memory = await session.getMemory({
    query: params.userContent,
    details: true,
  });

  const assistantReply = await generateAssistantReply({
    userContent: params.userContent,
    recalledMemory: memory.data,
  });

  await session.addMessages([
    { role: "user", content: params.userContent },
    { role: "assistant", content: assistantReply },
  ]);

  return {
    reply: assistantReply,
    memory: memory.data,
  };
}

Checkpoint

生产环境中通常在创建新对话时保存 session.id。后续请求只需要用 gum.sessions.fromId(sessionId) 恢复本地 Session handle;这个操作不会发起网络请求。

Client configuration

默认情况下只需要传入 apiKey。如果你使用 GUM 默认服务,不需要配置 host

ts
import { GumClient } from "@steamory-agent-kit/gum";

const gum = new GumClient({
  apiKey: process.env.GUM_API_KEY!,
});

需要连接自定义部署或调整超时时,再传入其他选项:

ts
const gum = new GumClient({
  apiKey: process.env.GUM_API_KEY!,
  host: "gum.asix.inc",
  timeoutMs: 30_000,
});
OptionTypeDefaultDescription
apiKeystring必填GUM API Key。SDK 会发送 Authorization: Api-Key <apiKey>。如果传入值已经带 Api-Key 前缀,SDK 不会重复添加。
hoststringgum.asix.incGUM 服务 host。普通 host 会补全为 HTTPS,显式 http:// 或 https:// 会保留,末尾 / 会被移除。
timeoutMsnumber30000默认请求超时时间,单位毫秒。设置为 0 可以关闭 SDK timeout。
fetchFetchLikeglobalThis.fetchFetch-compatible 实现,可用于测试、代理、自定义运行时或观测封装。

Health check

gum.health(options?) 检查 GUM 服务健康状态,适合在启动检查、部署验证或监控探针中使用。

ts
const health = await gum.health();

console.log(health);

参数:

NameTypeRequiredDescription
optionsRequestOptions单次请求选项。可以覆盖 timeout、abort signal 和 headers。

Sessions

Session 是 GUM 中承载一段用户对话和 Memory 召回上下文的对象。优先使用 Session handle 上的方法;只有在你更适合传递原始 Session ID 时,再使用 lower-level resource 方法。

Create a Session

gum.sessions.create(input, options?) 创建 Session,并返回 Session 对象。user_id 是当前 GUM API 的必填字段。

ts
const session = await gum.sessions.create({
  user_id: "user_123",
  title: "Support chat",
  metadata: {
    source: "web-chat",
    locale: "en-US",
  },
});

console.log(session.id);
console.log(session.rawResponse);

参数:

NameTypeRequiredDescription
inputSessionCreateRequest创建 Session 的请求体。
input.user_idstring业务系统中的用户 ID。GUM 使用它把 Session 和用户 Memory 关联起来。
input.titlestring | nullSession 标题,适合保存会话主题或来源说明。
input.metadataRecord<string, unknown> | null自定义元数据,例如渠道、语言、产品模块或业务 trace 信息。
optionsRequestOptions单次请求选项。

session.rawResponse 保留创建 Session 时 GUM 返回的原始 response envelope。如果 GUM 成功响应但没有返回 data.session_id,SDK 会抛出普通 Error,消息为 Gum API did not return data.session_id

Restore a Session handle

gum.sessions.fromId(sessionId) 从已有 Session ID 创建本地 Session handle,不会发起网络请求。

ts
const session = gum.sessions.fromId("session_123");

await session.addMessage({
  role: "user",
  content: "Continue with the city preference from earlier.",
});

参数:

NameTypeRequiredDescription
sessionIdstring已经由 GUM 创建并保存在业务系统中的 Session ID。

Add messages

session.addMessage(message, options?) 写入单条消息。

ts
await session.addMessage({
  role: "user",
  content: "For Europe planning, keep Berlin as the default city.",
  metadata: {
    channel: "chat",
  },
});

参数:

NameTypeRequiredDescription
messageMessage要写入当前 Session 的单条消息。
message.rolestring消息角色,例如 user、assistant、system 或你的业务自定义角色。
message.contentstring消息正文。GUM 会基于它沉淀和召回 Memory。
message.idstring | null业务侧消息 ID。用于和你的消息表、日志或 trace 关联。
message.metadataRecord<string, unknown>消息级元数据,例如渠道、模型名、语言或业务标签。
message.timestampstring | Date | null消息发生时间。传入 Date 时 SDK 会序列化为 ISO string。
message.created_atstring | Date | null消息创建时间。适合和服务端写入时间区分。
message.statuspending | chunked | processed | failed消息处理状态。
optionsRequestOptions单次请求选项。

session.addMessages(input, options?) 写入多条消息。input 可以是消息数组,也可以是包含 messages 字段的对象。

ts
await session.addMessages([
  {
    role: "user",
    content: "Use Toronto for Americas planning.",
  },
  {
    role: "assistant",
    content: "Understood. I will use Toronto for Americas planning.",
  },
]);

await session.addMessages({
  messages: [
    {
      role: "user",
      content: "Keep those defaults for future scheduling tasks.",
      timestamp: new Date(),
    },
  ],
});

参数:

NameTypeRequiredDescription
inputMessage[] | AddMessagesRequest要写入的消息集合。数组形式会被 SDK 包装为 { messages }。
input.user_idstring | null可选用户 ID。通常创建 Session 时已经绑定 user_id,不需要重复传。
input.messagesMessage[]要写入当前 Session 的消息列表。使用数组简写时,这个字段由 SDK 自动生成。
optionsRequestOptions单次请求选项。

消息中的 Date 会被序列化为 ISO string。请求体中的 undefined 字段会被移除。

Lower-level Session methods

如果你只想传递 Session ID,可以直接使用 resource 方法。

ts
await gum.sessions.addMessages("session_123", [
  {
    role: "user",
    content: "Draft the next Europe team agenda.",
  },
]);

const memory = await gum.sessions.getMemory("session_123", {
  query: "which city should be used for Europe planning",
});

gum.sessions.addMessages(sessionId, input, options?) 参数:

NameTypeRequiredDescription
sessionIdstring要写入消息的 Session ID。SDK 会在 URL 中安全编码这个值。
inputMessage[] | AddMessagesRequest要写入的消息集合。
optionsRequestOptions单次请求选项。

gum.sessions.getMemory(sessionId, params?, options?) 参数:

NameTypeRequiredDescription
sessionIdstring要召回 Memory 的 Session ID。SDK 会在 URL 中安全编码这个值。
paramsGetSessionMemoryParams召回参数。省略时会请求当前 Session 的默认 Memory。
optionsRequestOptions单次请求选项。

Memory recall and recall_config

session.getMemory(params?, options?) 从当前 Session 召回 Memory。query 用于聚焦召回内容,details 用于请求更详细的返回数据。

ts
const memory = await session.getMemory({
  query: "which city should be used for Europe or Americas planning",
  details: true,
});

参数:

NameTypeRequiredDescription
paramsGetSessionMemoryParams召回参数。省略时按 GUM 默认策略召回当前 Session Memory。
params.querystring召回查询文本。建议传入当前用户意图,而不是完整 prompt。
params.detailsboolean是否请求更详细的 Memory 返回数据。具体返回字段以 GUM API 为准。
params.recall_configRecallConfig | null召回配置。传入时 SDK 使用 POST context 请求;传入 null 表示显式发送空配置。
optionsRequestOptions单次请求选项。

默认情况下,SDK 使用 GET context 请求。当传入 recall_config 时,SDK 会改用 POST context 请求,并把召回配置放在 JSON body 中。

ts
const memory = await session.getMemory({
  query: "which city should be used for the user's scheduling request",
  details: true,
  recall_config: {
    message_recent_limit: 20,
    message_semantic_top_k: 8,
    query_router: "single_hop_parallel",
    enable_long_term_recall: false,
  },
});

常用 recall_config 字段:

FieldTypePurpose
message_recent_limitnumber控制最近消息召回数量。
message_semantic_top_knumber控制消息语义召回数量。
message_semantic_min_scorenumber控制消息语义召回的最低分数。
query_router"single_hop_direct" | "single_hop_parallel" | "multi_hop_chain"选择 query routing 策略。
enable_long_term_recallboolean控制是否启用长期 Memory 召回。
enable_long_term_rerankboolean控制是否启用长期 Memory rerank。

User Actions

User Action 用于记录用户在产品中的关键行为,例如页面访问、按钮点击、工具调用或任务状态变化。它适合沉淀 Action Memory,帮助 Agent 理解用户行为上下文。

ts
await gum.userActions.create({
  user_id: "user_123",
  timestamp: new Date(),
  content: "User opened the Europe team scheduling page",
  session_id: "session_123",
  event_type: "page_view",
  page: "team_scheduling",
  anchors: {
    region: "Europe",
    city: "Berlin",
  },
  metadata: {
    source: "assistant-api",
  },
});

gum.userActions.create(input, options?) 参数:

NameTypeRequiredDescription
inputActionLogInput用户 Action 事件请求体。
input.user_idstring触发该 Action 的业务用户 ID。
input.timestampstring | DateAction 发生时间。传入 Date 时 SDK 会序列化为 ISO string。
input.contentstringAction 的自然语言描述,建议写清用户做了什么。
input.session_idstring | null关联的 Session ID。用于把行为和对话上下文连接起来。
input.device_idstring | null设备 ID。适合多端行为分析。
input.appstring | null应用或产品模块名称。
input.platformstring | null平台,例如 web、ios、android 或 server。
input.event_typestring | null事件类型,例如 page_view、click、tool_call。
input.pagestring | null页面、路由或功能入口。
input.anchorsRecord<string, string> | null可检索锚点,例如 region、city、document_id。
input.metadataRecord<string, unknown> | null自定义元数据。
input.entitiesstring[] | null和 Action 相关的实体名称或 ID。
optionsRequestOptions单次请求选项。

timestamp 可以是 ISO string 或 Date。如果传入 Date,SDK 会自动序列化。

Runtime behavior

Request options

每个 SDK 方法都可以在最后一个参数传入请求选项,用于覆盖单次请求的 timeout、abort signal 或 header。

ts
const controller = new AbortController();

const memory = await session.getMemory(
  {
    query: "which scheduling city should be used",
  },
  {
    timeoutMs: 5_000,
    signal: controller.signal,
    headers: {
      "X-Request-Id": "request_123",
    },
  },
);
OptionTypeDescription
timeoutMsnumber覆盖单次请求超时。
signalAbortSignal外部 abort signal。
headersHeadersInit追加请求头。

Response envelope

gum.sessions.create() 返回 Session 对象外,resource 方法返回 GUM response envelope。

ts
type GumEnvelope<T = unknown> = {
  data?: T;
  success?: boolean;
  message?: string;
  error?: unknown;
  [key: string]: unknown;
};

例如:

  • session.getMemory() 返回 Promise<GumEnvelope<SessionMemory>>
  • session.addMessages() 返回 GUM response envelope。
  • gum.userActions.create() 返回 Promise<GumEnvelope<CreateActionResponse>>

Serialization

SDK 在发送 JSON body 前会做轻量序列化:

  • Date 会转换为 ISO string。
  • 对象和数组中的 undefined 字段会被移除。
  • null 会保留,适合显式传递空值。

Error handling

SDK 暴露三个主要错误类型:

ts
import {
  GumApiError,
  GumConnectionError,
  GumTimeoutError,
} from "@steamory-agent-kit/gum";

try {
  await session.getMemory({
    query: "which scheduling city should be used",
  });
} catch (error) {
  if (error instanceof GumApiError) {
    console.error(error.status, error.detail, error.body);
  } else if (error instanceof GumTimeoutError) {
    console.error(`Request timed out after ${error.timeoutMs}ms`);
  } else if (error instanceof GumConnectionError) {
    console.error("Network or fetch failure", error.cause);
  } else {
    throw error;
  }
}
ErrorWhen it is thrown
GumApiErrorGUM 返回非 2xx 响应。包含 status、statusText、headers、body 和 detail。
GumConnectionError底层 fetch 在收到响应前失败。
GumTimeoutError请求因 SDK timeout 或外部 AbortSignal 被中断。它继承自 GumConnectionError。

TypeScript reference

常用类型可以从包根路径导入:

ts
import type {
  ActionLogInput,
  AddMessagesRequest,
  CreateActionResponse,
  GumClientOptions,
  GumEnvelope,
  Message,
  RecallConfig,
  RequestOptions,
  SessionMemory,
  SessionCreateRequest,
} from "@steamory-agent-kit/gum";

import { GumClient, Session } from "@steamory-agent-kit/gum";

核心类型速查:

ts
type QueryRouter =
  | "single_hop_direct"
  | "single_hop_parallel"
  | "multi_hop_chain";

interface SessionCreateRequest {
  user_id: string;
  title?: string | null;
  metadata?: Record<string, unknown> | null;
}

interface Message {
  role: string;
  content: string;
  id?: string | null;
  metadata?: Record<string, unknown>;
  timestamp?: string | Date | null;
  created_at?: string | Date | null;
  status?: "pending" | "chunked" | "processed" | "failed";
}

Troubleshooting

apiKey must not be empty

apiKey 为空字符串或只包含空白字符。确认服务端已经设置 GUM_API_KEY,并且没有在构建阶段意外执行了需要运行时环境变量的代码。

ts
const gum = new GumClient({
  apiKey: process.env.GUM_API_KEY!,
});

401 或 403

检查 API Key 是否正确、是否带有访问当前 GUM 服务的权限,以及请求是否发往预期 host。SDK 会自动添加 Api-Key 前缀,不需要手动拼接。

请求超时

默认 timeout 是 30 秒。你可以在客户端级别或单次请求级别调整。

ts
const gum = new GumClient({
  apiKey: process.env.GUM_API_KEY!,
  timeoutMs: 60_000,
});

返回 Memory 为空

先确认你已经向同一个 Session 写入消息,再使用能描述用户意图的 query 召回。对于需要更细控制的场景,再加入 recall_config

面向 Agent 的身份、记忆与网页行动基础设施。