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 服务或队列任务。
如果只是本地验证,可以先设置环境变量:
export GUM_API_KEY="<your-gum-api-key>"Install
npm install @steamory-agent-kit/gumSDK 同时提供 ESM、CommonJS 和 TypeScript 类型声明。Node.js 18+ 环境可以直接使用内置 fetch。
Quickstart
下面的示例完成最短接入路径:初始化客户端、创建 Session、写入几条对话消息,然后召回相关 Memory。
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 或助手系统中,推荐的顺序是:
- 用户输入到达 Node.js Backend。
- 使用当前
session.id召回相关 Memory。 - 将 Memory 放入模型上下文。
- 得到模型回复后,把用户消息和助手回复写回 GUM。
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。
import { GumClient } from "@steamory-agent-kit/gum";
const gum = new GumClient({
apiKey: process.env.GUM_API_KEY!,
});需要连接自定义部署或调整超时时,再传入其他选项:
const gum = new GumClient({
apiKey: process.env.GUM_API_KEY!,
host: "gum.asix.inc",
timeoutMs: 30_000,
});| Option | Type | Default | Description |
|---|---|---|---|
| apiKey | string | 必填 | GUM API Key。SDK 会发送 Authorization: Api-Key <apiKey>。如果传入值已经带 Api-Key 前缀,SDK 不会重复添加。 |
| host | string | gum.asix.inc | GUM 服务 host。普通 host 会补全为 HTTPS,显式 http:// 或 https:// 会保留,末尾 / 会被移除。 |
| timeoutMs | number | 30000 | 默认请求超时时间,单位毫秒。设置为 0 可以关闭 SDK timeout。 |
| fetch | FetchLike | globalThis.fetch | Fetch-compatible 实现,可用于测试、代理、自定义运行时或观测封装。 |
Health check
gum.health(options?) 检查 GUM 服务健康状态,适合在启动检查、部署验证或监控探针中使用。
const health = await gum.health();
console.log(health);参数:
| Name | Type | Required | Description |
|---|---|---|---|
| options | RequestOptions | 否 | 单次请求选项。可以覆盖 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 的必填字段。
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);参数:
| Name | Type | Required | Description |
|---|---|---|---|
| input | SessionCreateRequest | 是 | 创建 Session 的请求体。 |
| input.user_id | string | 是 | 业务系统中的用户 ID。GUM 使用它把 Session 和用户 Memory 关联起来。 |
| input.title | string | null | 否 | Session 标题,适合保存会话主题或来源说明。 |
| input.metadata | Record<string, unknown> | null | 否 | 自定义元数据,例如渠道、语言、产品模块或业务 trace 信息。 |
| options | RequestOptions | 否 | 单次请求选项。 |
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,不会发起网络请求。
const session = gum.sessions.fromId("session_123");
await session.addMessage({
role: "user",
content: "Continue with the city preference from earlier.",
});参数:
| Name | Type | Required | Description |
|---|---|---|---|
| sessionId | string | 是 | 已经由 GUM 创建并保存在业务系统中的 Session ID。 |
Add messages
session.addMessage(message, options?) 写入单条消息。
await session.addMessage({
role: "user",
content: "For Europe planning, keep Berlin as the default city.",
metadata: {
channel: "chat",
},
});参数:
| Name | Type | Required | Description |
|---|---|---|---|
| message | Message | 是 | 要写入当前 Session 的单条消息。 |
| message.role | string | 是 | 消息角色,例如 user、assistant、system 或你的业务自定义角色。 |
| message.content | string | 是 | 消息正文。GUM 会基于它沉淀和召回 Memory。 |
| message.id | string | null | 否 | 业务侧消息 ID。用于和你的消息表、日志或 trace 关联。 |
| message.metadata | Record<string, unknown> | 否 | 消息级元数据,例如渠道、模型名、语言或业务标签。 |
| message.timestamp | string | Date | null | 否 | 消息发生时间。传入 Date 时 SDK 会序列化为 ISO string。 |
| message.created_at | string | Date | null | 否 | 消息创建时间。适合和服务端写入时间区分。 |
| message.status | pending | chunked | processed | failed | 否 | 消息处理状态。 |
| options | RequestOptions | 否 | 单次请求选项。 |
session.addMessages(input, options?) 写入多条消息。input 可以是消息数组,也可以是包含 messages 字段的对象。
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(),
},
],
});参数:
| Name | Type | Required | Description |
|---|---|---|---|
| input | Message[] | AddMessagesRequest | 是 | 要写入的消息集合。数组形式会被 SDK 包装为 { messages }。 |
| input.user_id | string | null | 否 | 可选用户 ID。通常创建 Session 时已经绑定 user_id,不需要重复传。 |
| input.messages | Message[] | 是 | 要写入当前 Session 的消息列表。使用数组简写时,这个字段由 SDK 自动生成。 |
| options | RequestOptions | 否 | 单次请求选项。 |
消息中的 Date 会被序列化为 ISO string。请求体中的 undefined 字段会被移除。
Lower-level Session methods
如果你只想传递 Session ID,可以直接使用 resource 方法。
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?) 参数:
| Name | Type | Required | Description |
|---|---|---|---|
| sessionId | string | 是 | 要写入消息的 Session ID。SDK 会在 URL 中安全编码这个值。 |
| input | Message[] | AddMessagesRequest | 是 | 要写入的消息集合。 |
| options | RequestOptions | 否 | 单次请求选项。 |
gum.sessions.getMemory(sessionId, params?, options?) 参数:
| Name | Type | Required | Description |
|---|---|---|---|
| sessionId | string | 是 | 要召回 Memory 的 Session ID。SDK 会在 URL 中安全编码这个值。 |
| params | GetSessionMemoryParams | 否 | 召回参数。省略时会请求当前 Session 的默认 Memory。 |
| options | RequestOptions | 否 | 单次请求选项。 |
Memory recall and recall_config
session.getMemory(params?, options?) 从当前 Session 召回 Memory。query 用于聚焦召回内容,details 用于请求更详细的返回数据。
const memory = await session.getMemory({
query: "which city should be used for Europe or Americas planning",
details: true,
});参数:
| Name | Type | Required | Description |
|---|---|---|---|
| params | GetSessionMemoryParams | 否 | 召回参数。省略时按 GUM 默认策略召回当前 Session Memory。 |
| params.query | string | 否 | 召回查询文本。建议传入当前用户意图,而不是完整 prompt。 |
| params.details | boolean | 否 | 是否请求更详细的 Memory 返回数据。具体返回字段以 GUM API 为准。 |
| params.recall_config | RecallConfig | null | 否 | 召回配置。传入时 SDK 使用 POST context 请求;传入 null 表示显式发送空配置。 |
| options | RequestOptions | 否 | 单次请求选项。 |
默认情况下,SDK 使用 GET context 请求。当传入 recall_config 时,SDK 会改用 POST context 请求,并把召回配置放在 JSON body 中。
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 字段:
| Field | Type | Purpose |
|---|---|---|
| message_recent_limit | number | 控制最近消息召回数量。 |
| message_semantic_top_k | number | 控制消息语义召回数量。 |
| message_semantic_min_score | number | 控制消息语义召回的最低分数。 |
| query_router | "single_hop_direct" | "single_hop_parallel" | "multi_hop_chain" | 选择 query routing 策略。 |
| enable_long_term_recall | boolean | 控制是否启用长期 Memory 召回。 |
| enable_long_term_rerank | boolean | 控制是否启用长期 Memory rerank。 |
User Actions
User Action 用于记录用户在产品中的关键行为,例如页面访问、按钮点击、工具调用或任务状态变化。它适合沉淀 Action Memory,帮助 Agent 理解用户行为上下文。
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?) 参数:
| Name | Type | Required | Description |
|---|---|---|---|
| input | ActionLogInput | 是 | 用户 Action 事件请求体。 |
| input.user_id | string | 是 | 触发该 Action 的业务用户 ID。 |
| input.timestamp | string | Date | 是 | Action 发生时间。传入 Date 时 SDK 会序列化为 ISO string。 |
| input.content | string | 是 | Action 的自然语言描述,建议写清用户做了什么。 |
| input.session_id | string | null | 否 | 关联的 Session ID。用于把行为和对话上下文连接起来。 |
| input.device_id | string | null | 否 | 设备 ID。适合多端行为分析。 |
| input.app | string | null | 否 | 应用或产品模块名称。 |
| input.platform | string | null | 否 | 平台,例如 web、ios、android 或 server。 |
| input.event_type | string | null | 否 | 事件类型,例如 page_view、click、tool_call。 |
| input.page | string | null | 否 | 页面、路由或功能入口。 |
| input.anchors | Record<string, string> | null | 否 | 可检索锚点,例如 region、city、document_id。 |
| input.metadata | Record<string, unknown> | null | 否 | 自定义元数据。 |
| input.entities | string[] | null | 否 | 和 Action 相关的实体名称或 ID。 |
| options | RequestOptions | 否 | 单次请求选项。 |
timestamp 可以是 ISO string 或 Date。如果传入 Date,SDK 会自动序列化。
Runtime behavior
Request options
每个 SDK 方法都可以在最后一个参数传入请求选项,用于覆盖单次请求的 timeout、abort signal 或 header。
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",
},
},
);| Option | Type | Description |
|---|---|---|
| timeoutMs | number | 覆盖单次请求超时。 |
| signal | AbortSignal | 外部 abort signal。 |
| headers | HeadersInit | 追加请求头。 |
Response envelope
除 gum.sessions.create() 返回 Session 对象外,resource 方法返回 GUM response envelope。
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 暴露三个主要错误类型:
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;
}
}| Error | When it is thrown |
|---|---|
| GumApiError | GUM 返回非 2xx 响应。包含 status、statusText、headers、body 和 detail。 |
| GumConnectionError | 底层 fetch 在收到响应前失败。 |
| GumTimeoutError | 请求因 SDK timeout 或外部 AbortSignal 被中断。它继承自 GumConnectionError。 |
TypeScript reference
常用类型可以从包根路径导入:
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";核心类型速查:
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,并且没有在构建阶段意外执行了需要运行时环境变量的代码。
const gum = new GumClient({
apiKey: process.env.GUM_API_KEY!,
});401 或 403
检查 API Key 是否正确、是否带有访问当前 GUM 服务的权限,以及请求是否发往预期 host。SDK 会自动添加 Api-Key 前缀,不需要手动拼接。
请求超时
默认 timeout 是 30 秒。你可以在客户端级别或单次请求级别调整。
const gum = new GumClient({
apiKey: process.env.GUM_API_KEY!,
timeoutMs: 60_000,
});返回 Memory 为空
先确认你已经向同一个 Session 写入消息,再使用能描述用户意图的 query 召回。对于需要更细控制的场景,再加入 recall_config。