智能体

接入前端工具

让智能体调用网页函数,并用返回值继续回答。

让智能体按需读取当前页面,或执行页面上的动作。你在智能体里声明工具,在 Kit 页面实现同名回调;Kit 把结果送回会话,智能体继续回答。

准备接入

准备一个能回复的 Kit 页面、服务智能体的公开 ID(agent_…),以及宿主后端的 API Key。下面以读取课程选择为例,不需要视频、数据库或额外依赖。宿主网站须已有验证登录态的 POST /api/praxis-token 路由,返回 { token },详见嵌入令牌与用户。它是你的路由,不是 Praxis API。

前端工具适合按需读取。每条消息都需要的小事实,使用页面上下文。

在智能体声明工具

将以下文件保存为 register-tool.ts,替换 agent_example,在已注入 PRAXIS_API_KEY 的服务端运行 bun register-tool.ts。它先读取智能体,再通过公开 API 更新 tools,保留其他工具,并用当前 version 防止覆盖并发修改。

// register-tool.ts — run on the server with: bun register-tool.ts
const key = process.env.PRAXIS_API_KEY;
if (!key) throw new Error("Set PRAXIS_API_KEY on the server");
const url = "https://api-develop.deepraxis.com/agent/v1/agents/agent_example";
const headers = { Authorization: `Bearer ${key}`, "Content-Type": "application/json" };
const currentResponse = await fetch(url, { headers });
if (!currentResponse.ok) throw new Error(`Read failed: ${currentResponse.status}`);
const current = await currentResponse.json();
const tool = {
  type: "custom",
  name: "read_selected_lesson",
  description: "Read the selected lesson when the user asks which lesson is open.",
  input_schema: { type: "object", properties: {}, additionalProperties: false },
};
const tools = [...(current.tools ?? []).filter(
  (item: { type: string; name?: string }) =>
    !(item.type === "custom" && item.name === tool.name),
), tool];
const response = await fetch(url, {
  method: "POST", headers,
  body: JSON.stringify({ version: current.version, tools }),
});
if (!response.ok) throw new Error(`Update failed: ${response.status}`);
const saved = await response.json();
console.log({ id: saved.id, version: saved.version });

预期结果: 终端输出智能体 ID 和新版本。让宿主签发新版本的令牌,再开始新会话;已固定旧版本的令牌或已有会话不会自动换到新定义。若嵌入策略固定版本,在控制台更新接入版本,或签发时明确指定新 version。

工具名须匹配 ^[a-zA-Z0-9_-]{1,64}$,不能与其他自定义工具或内置工具重名。input_schema.type 必须是 object;描述要说明何时调用。仅在页面实现函数,不会把工具自动加入智能体。

实现页面回调

将下面的 HTML 放到宿主网站。它使用 Develop 的 Kit 和 API;页面来源需要在嵌入策略中获准。

<!doctype html>
<html lang="zh-CN">
<meta charset="utf-8" />
<title>课程助手</title>
<label>当前课程
  <select id="lesson">
    <option value="第三课:配送规则">第三课:配送规则</option>
    <option value="第四课:退货流程">第四课:退货流程</option>
  </select>
</label>
<output id="tool-status" aria-live="polite"></output>
<praxis-agent style="display:block;height:600px"></praxis-agent>
<script type="module">
  import "https://kit-develop.praxisusercontent.com/v1/praxis-kit.js";
  await customElements.whenDefined("praxis-agent");
  const chat = document.querySelector("praxis-agent");
  const lesson = document.querySelector("#lesson");
  chat.onClientTool = async ({ name }) => {
    if (name !== "read_selected_lesson") throw new Error(`Unknown tool: ${name}`);
    return { title: lesson.value };
  };
  chat.addEventListener("praxis.tool.change", event => {
    const { name, status, isError } = event.detail;
    document.querySelector("#tool-status").textContent =
      `${name}: ${status}${isError ? " (error)" : ""}`;
  });
  chat.addEventListener("praxis.log", event => console.warn(event.detail));
  chat.setOptions({
    api: {
      url: "https://api-develop.deepraxis.com",
      getToken: async () => {
        const response = await fetch("/api/praxis-token", {
          method: "POST", credentials: "same-origin",
        });
        if (!response.ok) throw new Error(`Token request failed: ${response.status}`);
        const { token } = await response.json();
        if (typeof token !== "string" || !token) throw new Error("Missing token");
        return token;
      },
    },
    agent: { name: "课程助手" },
  });
</script>
</html>

onClientTool 是元素的 JavaScript 属性,不能放进 HTML 属性或 setOptions。回调收到 { id, name, input },分别是调用编号、工具名和输入;参数应由你的函数校验。对未知工具名抛错,不要返回成功。

字符串返回值原样发送,其他可序列化值转成 JSON 文本,undefined 转成空字符串。抛错、Promise 拒绝或序列化失败会作为错误结果返回。不要在结果里放其他用户的数据或凭据。

验证调用与恢复

询问「请调用工具告诉我正在看哪一课」。预期结果: 页面状态依次显示 start、end,智能体根据工具返回的课程回答。换课后再次提问,返回当前选择。end 表示服务端已接收结果,不代表整轮回复结束。

现象检查与处理
没有调用确认新会话使用含工具定义的版本,描述明确说明触发情境
返回 not available on this page在调用前给元素赋上 onClientTool
回调失败修正输入校验或页面逻辑;错误结果会交给智能体
praxis.log 报结果提交失败回调不会自动重跑;核对网络及会话状态,勿盲目重做有副作用的动作

服务端最多等待 120 秒;超时记入错误结果后继续。Kit 会认领调用编号,并检查历史结果以避免重复执行,但这不是跨标签页事务保证。会改变业务数据的工具必须由后端鉴权并做幂等处理。

授权与下一步

前端 custom 工具不经过平台的工具确认卡。需要用户确认的页面动作,由你的界面处理;真正的数据权限必须在后端检查,不能依赖浏览器或模型参数。

配置工具授权 · 组件参考 · 更新智能体 API。

导出

本页内容