执行控制

控制工具执行的行为——结果处理、超时与重试、结果压缩、取消支持。

工具执行结果

工具的执行结果会被自动序列化为字符串返回给模型。tool() 函数内部会自动处理结果的包装:

  • 成功时:返回 { success: true, data: <结果> }
  • 失败时:返回 { success: false, error: "<错误信息>" }

你的 execute 函数可以返回任何类型——字符串、对象、数字——deepseek-kit 会自动处理序列化:

const tool1 = tool({
  name: 'getString',
  description: '返回字符串结果',
  schema: z.object({ query: z.string() }),
  execute: async () => '这是一段文本结果',
})

const tool2 = tool({
  name: 'getObject',
  description: '返回结构化结果',
  schema: z.object({ id: z.string() }),
  execute: async () => ({ name: '张三', age: 25, email: 'zhangsan@example.com' }),
})

超时与重试

超时

为可能耗时较长的工具设置超时时间,避免无限等待。默认超时为 60 秒:

const slowApiTool = tool({
  name: 'slowApi',
  description: '调用慢速 API',
  schema: z.object({ query: z.string() }),
  execute: async (input) => {
    return await callSlowApi(input.query)
  },
  timeout: 30000,
})

重试

为不可靠的工具配置自动重试次数。当执行失败时,deepseek-kit 会自动重新调用,直到成功或达到最大重试次数:

const unreliableApiTool = tool({
  name: 'unreliableApi',
  description: '调用不可靠的 API',
  schema: z.object({ query: z.string() }),
  execute: async (input) => {
    return await callUnreliableApi(input.query)
  },
  retries: 3,
})

超时和重试可以组合使用——每次重试都会受到超时限制:

const robustTool = tool({
  name: 'robustApi',
  description: '调用需要重试和超时保护的 API',
  schema: z.object({ query: z.string() }),
  execute: async (input) => {
    return await callApi(input.query)
  },
  timeout: 10000,
  retries: 2,
})

结果压缩

当工具返回大量输出(如文件内容、API 响应)时,原始结果会占用模型上下文窗口的很大一部分。compact 选项使用 LLM 压缩冗长的工具结果,同时保留智能体继续推理所需的所有信息。

基本用法

使用默认设置启用压缩(阈值:1500 字符,模型:deepseek-v4-flash):

const readFileTool = tool({
  name: 'readFile',
  description: '读取文件内容',
  schema: z.object({ path: z.string().describe('文件路径') }),
  compact: true,
  execute: async (input) => {
    return await fs.readFile(input.path, 'utf-8')
  },
})

自定义配置

你可以传入对象代替 true 来自定义压缩行为:

const readFileTool = tool({
  name: 'readFile',
  description: '读取文件内容',
  schema: z.object({ path: z.string().describe('文件路径') }),
  compact: {
    threshold: 3000,
    model: 'deepseek-v4',
  },
  execute: async (input) => {
    return await fs.readFile(input.path, 'utf-8')
  },
})
  • threshold(number,默认 1500)— 触发压缩的工具结果最小字符长度。短于此长度的结果将原样返回。
  • model(Model,默认 'deepseek-v4-flash')— 用于压缩内容的 LLM。

AbortSignal 取消支持

deepseek-kit 在整个工具执行管道中支持 AbortSignal,允许你取消正在进行的工具调用。这在用户取消请求或需要在应用层面强制时间限制时非常有用。

在智能体中使用

signal 传递给 generateTextagent.generate 以启用取消功能:

const controller = new AbortController()

const result = await agent.generate({
  prompt: '读取一个大文件的内容',
  signal: controller.signal,
})

// 5 秒后取消
setTimeout(() => controller.abort(), 5000)

当信号被中止时:

  • 正在执行的工具调用会立即被取消
  • 待执行的重试会被跳过
  • 智能体循环停止并抛出 AbortError

与超时配合使用

AbortSignaltimeout 选项协同工作。timeout 作为每次尝试的时间限制,而 AbortSignal 提供外部取消能力:

const controller = new AbortController()

const slowTool = tool({
  name: 'slowApi',
  description: '调用慢速 API',
  schema: z.object({ query: z.string() }),
  timeout: 30000,
  execute: async (input) => {
    return await callSlowApi(input.query)
  },
})

// timeout 和 signal 都可以取消执行
const result = await agent.generate({
  tools: [slowTool],
  prompt: '搜索一些内容',
  signal: controller.signal,
})