跳到主要内容

鉴权 (Authentication)

SDK 的每个请求都带一个 Bearer 凭据;你传哪种凭据,决定了能以谁的身份、调用哪些接口。 一共三种,先按「代码跑在哪里、代表谁」选对,再往下看细节。

三种凭据

凭据形如代表从哪来放在哪
个人 API Keymysta_…你这个账号app.openhex.tech → 设置 → API Key只放后端 / 本地脚本
工作区 API Keysk_…你的一个工作区用个人 API Key 调接口签发,见工作区 API 概览只放后端
会话令牌JWT(eyJ…工作区里的某一个成员你的后端用工作区 API Key 签发,见会话令牌可以交给浏览器、小程序、App

我该用哪个?

场景凭据
写脚本、后端任务,调用自己的 Agent个人 API Key
以所有者身份训练 Agent个人 API Key
你的后端管理工作区(开通成员、发积分、签发令牌)工作区 API Key
你的用户在网页 / 小程序 / App 里和 Agent 对话会话令牌

各凭据能调用的接口:

能力个人 API Key工作区 API Key会话令牌
对话附件✅(以账号本人身份)✅(以成员身份)
训练模式✅(仅自己的 Agent)
工作区 API仅签发 / 管理工作区 API Key

Agent ID

除了凭据,对话还需要知道和哪个 Agent 对话,也就是 Agent ID:一个形如 56941e40-47ad-49b0-bf88-cb8845b06c0e 的 UUID。建议和 API Key 一样放进环境变量,本文档统一叫它 OPENHEX_AGENT_ID

在网页上找到它

  1. 打开 app.openhex.tech,在首页的 Agent 列表里点开要调用的 Agent。
  2. 看浏览器地址栏:https://app.openhex.tech/console/<Agent ID>/…/console/ 后面那一段就是 Agent ID。

用接口列出

用个人 API Key 列出你名下的全部 Agent,从返回里取 id

curl https://api.openhex.tech/api/v2/agents \
-H "Authorization: Bearer mysta_..."
# → [ { "id": "56941e40-…", "name": "大顺", "is_public": true, … }, … ]

服务商后端持有工作区 API Key 时,用 client.workspace(slug).listAgents() 列出工作区里的 Agent,见读取 Agent

在代码里使用

SDK 不会自动读取 OPENHEX_AGENT_ID(只有 OPENHEX_API_KEY 有环境变量兜底),需要显式传入:

export OPENHEX_API_KEY=mysta_...
export OPENHEX_AGENT_ID=56941e40-...
const client = new OpenhexClient({ agentId: process.env.OPENHEX_AGENT_ID });

Agent ID 不是密钥,可以出现在前端代码里;但浏览器里读不到服务器的环境变量。Next.js 需要加 NEXT_PUBLIC_ 前缀(例如 NEXT_PUBLIC_OPENHEX_AGENT_ID)才会打包进前端。API Key 不要这样做。

在代码里传入

import { OpenhexClient } from '@openhex-ai/agent-sdk';

const client = new OpenhexClient({ apiKey: 'mysta_...' });

在 Node.js 里可以省略 apiKey,SDK 会读取环境变量 OPENHEX_API_KEY

export OPENHEX_API_KEY=mysta_...
const client = new OpenhexClient(); // 从 OPENHEX_API_KEY 读取

两处都没有时,构造函数立即抛出 AuthenticationError,不会发出任何请求。浏览器里没有环境变量,必须显式传入。

浏览器里的正确做法

⚠️ 个人 API Key 和工作区 API Key 都绝不能进入浏览器、小程序包或 App 安装包。它们等同于账号 / 工作区的全部权限,打包进前端就等于公开。

客户端只拿会话令牌。标准做法是你的后端提供一个接口,按你自己的登录态为用户换发令牌:

// 后端
const ws = new OpenhexClient({ apiKey: process.env.OPENHEX_WORKSPACE_KEY! })
.workspace(process.env.OPENHEX_WORKSPACE_SLUG!);

app.post('/openhex/token', async (req, res) => {
const { token, expires_at } = await ws.startVisitorSession({
sp_user_ref: req.user.id,
ttl_seconds: 1800,
});
res.json({ token, expires_at });
});
// 前端
<ChatWidget agentId="" getToken={() => fetch('/openhex/token', { method: 'POST' }).then(r => r.json()).then(d => d.token)} />

如果你更希望浏览器完全不接触任何 OpenHex 凭据,也可以在你的后端做一层反向代理,由代理替换 Authorization 头。这时浏览器端传一个明显是占位符的值即可:

new OpenhexClient({ baseUrl: '/openhex-proxy', apiKey: 'injected-by-proxy' });

占位符不要用 mysta_ / sk_ 开头——万一代理忘了替换,上游返回的 401 一眼就能看出原因。

连接配置

配置默认值说明
apiKeyOPENHEX_API_KEY上述三种凭据之一
baseUrlhttps://api.openhex.tech平台 API 地址,走代理时改成代理地址
timeoutMs30000非流式请求的超时(毫秒)
fetch全局 fetch自定义 fetch 实现(测试、特殊运行时)

SDK 只会把凭据发往 baseUrl 所在的域名。把一个其他域名的完整 URL 传给底层请求方法,SDK 会直接拒绝并抛出 OpenhexSdkError,避免凭据被带到别处。

凭据相关的错误

状态码常见原因
401凭据缺失、无效或已过期;或者用错了类型(例如用个人 Key 调只接受工作区 Key 的方法)
403凭据有效但无权访问(例如工作区 Key 和 slug 不属于同一个工作区、Key 已吊销、成员已停用)
404对当前凭据而言资源不存在(例如会话令牌访问别人 Agent 的训练接口)

完整的错误处理见错误处理

下一步