INVALID_TOOL_RESULTS
您传递给模型的 ToolMessages 数量过多、过少或不匹配。
当使用模型调用工具时,模型响应的 AIMessage 将包含一个 tool_calls 数组。 要继续流程,您传递回模型的下一个消息必须是对于该数组中的每个项目都恰好有一个 ToolMessage,其中包含该工具调用的结果。 每个 ToolMessage 必须具有一个 tool_call_id 字段,该字段与 AIMessage 上的 tool_calls 之一匹配。
例如,给定来自模型的以下响应
import { z } from "zod";
import { tool } from "@langchain/core/tools";
import { ChatOpenAI } from "@langchain/openai";
import { BaseMessageLike } from "@langchain/core/messages";
const model = new ChatOpenAI({
  model: "gpt-4o-mini",
});
const dummyTool = tool(
  async () => {
    return "action complete!";
  },
  {
    name: "foo",
    schema: z.object({}),
  }
);
const modelWithTools = model.bindTools([dummyTool]);
const chatHistory: BaseMessageLike[] = [
  {
    role: "user",
    content: `Call tool "foo" twice with no arguments`,
  },
];
const responseMessage = await modelWithTools.invoke(chatHistory);
console.log(responseMessage);
AIMessage {
  "id": "chatcmpl-AIgT1xUd6lkWAutThiiBsqjq7Ykj1",
  "content": "",
  "additional_kwargs": {
    "tool_calls": [
      {
        "id": "call_BknYpnY7xiARM17TPYqL7luj",
        "type": "function",
        "function": "[Object]"
      },
      {
        "id": "call_EHf8MIcTdsLCZcFVlcH4hxJw",
        "type": "function",
        "function": "[Object]"
      }
    ]
  },
  "response_metadata": {
    "tokenUsage": {
      "promptTokens": 42,
      "completionTokens": 37,
      "totalTokens": 79
    },
    "finish_reason": "tool_calls",
    "usage": {
      "prompt_tokens": 42,
      "completion_tokens": 37,
      "total_tokens": 79,
      "prompt_tokens_details": {
        "cached_tokens": 0
      },
      "completion_tokens_details": {
        "reasoning_tokens": 0
      }
    },
    "system_fingerprint": "fp_e2bde53e6e"
  },
  "tool_calls": [
    {
      "name": "foo",
      "args": {},
      "type": "tool_call",
      "id": "call_BknYpnY7xiARM17TPYqL7luj"
    },
    {
      "name": "foo",
      "args": {},
      "type": "tool_call",
      "id": "call_EHf8MIcTdsLCZcFVlcH4hxJw"
    }
  ],
  "invalid_tool_calls": [],
  "usage_metadata": {
    "output_tokens": 37,
    "input_tokens": 42,
    "total_tokens": 79,
    "input_token_details": {
      "cache_read": 0
    },
    "output_token_details": {
      "reasoning": 0
    }
  }
}
仅使用一个工具响应调用模型将导致错误
const toolResponse1 = await dummyTool.invoke(responseMessage.tool_calls![0]);
chatHistory.push(responseMessage);
chatHistory.push(toolResponse1);
await modelWithTools.invoke(chatHistory);
BadRequestError: 400 An assistant message with 'tool_calls' must be followed by tool messages responding to each 'tool_call_id'. The following tool_call_ids did not have response messages: call_EHf8MIcTdsLCZcFVlcH4hxJw
    at APIError.generate (/Users/jacoblee/langchain/langchainjs/libs/langchain-openai/node_modules/openai/error.js:45:20)
    at OpenAI.makeStatusError (/Users/jacoblee/langchain/langchainjs/libs/langchain-openai/node_modules/openai/core.js:291:33)
    at OpenAI.makeRequest (/Users/jacoblee/langchain/langchainjs/libs/langchain-openai/node_modules/openai/core.js:335:30)
    at process.processTicksAndRejections (node:internal/process/task_queues:95:5)
    at async /Users/jacoblee/langchain/langchainjs/libs/langchain-openai/dist/chat_models.cjs:1441:29
    at async RetryOperation._fn (/Users/jacoblee/langchain/langchainjs/node_modules/p-retry/index.js:50:12) {
  status: 400,
  headers: {
    'access-control-expose-headers': 'X-Request-ID',
    'alt-svc': 'h3=":443"; ma=86400',
    'cf-cache-status': 'DYNAMIC',
    'cf-ray': '8d31d4d95e2a0c96-EWR',
    connection: 'keep-alive',
    'content-length': '315',
    'content-type': 'application/json',
    date: 'Tue, 15 Oct 2024 18:21:53 GMT',
    'openai-organization': 'langchain',
    'openai-processing-ms': '16',
    'openai-version': '2020-10-01',
    server: 'cloudflare',
    'set-cookie': '__cf_bm=e5.GX1bHiMVgr76YSvAKuECCGG7X_RXF0jDGSMXFGfU-1729016513-1.0.1.1-ZBYeVqX.M6jSNJB.wS696fEhX7V.es._M0WcWtQ9Qx8doEA5qMVKNE5iX6i7UKyPCg2GvDfM.MoDwRCXKMSkEA; path=/; expires=Tue, 15-Oct-24 18:51:53 GMT; domain=.api.openai.com; HttpOnly; Secure; SameSite=None, _cfuvid=J8gS08GodUA9hRTYuElen0YOCzMO3d4LW0ZT0k_kyj4-1729016513560-0.0.1.1-604800000; path=/; domain=.api.openai.com; HttpOnly; Secure; SameSite=None',
    'strict-transport-security': 'max-age=31536000; includeSubDomains; preload',
    'x-content-type-options': 'nosniff',
    'x-ratelimit-limit-requests': '30000',
    'x-ratelimit-limit-tokens': '150000000',
    'x-ratelimit-remaining-requests': '29999',
    'x-ratelimit-remaining-tokens': '149999967',
    'x-ratelimit-reset-requests': '2ms',
    'x-ratelimit-reset-tokens': '0s',
    'x-request-id': 'req_f810058e7f047fafcb713575c4419161'
  },
  request_id: 'req_f810058e7f047fafcb713575c4419161',
  error: {
    message: "An assistant message with 'tool_calls' must be followed by tool messages responding to each 'tool_call_id'. The following tool_call_ids did not have response messages: call_EHf8MIcTdsLCZcFVlcH4hxJw",
    type: 'invalid_request_error',
    param: 'messages',
    code: null
  },
  code: null,
  param: 'messages',
  type: 'invalid_request_error',
  attemptNumber: 1,
  retriesLeft: 6
}
如果我们添加第二个响应,则调用将按预期成功,因为我们现在每个工具调用都有一个工具响应
const toolResponse2 = await dummyTool.invoke(responseMessage.tool_calls![1]);
chatHistory.push(toolResponse2);
await modelWithTools.invoke(chatHistory);
AIMessage {
  "id": "chatcmpl-AIgTPDBm1epnnLHx0tPFTgpsf8Ay6",
  "content": "The tool \"foo\" was called twice, and both times returned the result: \"action complete!\".",
  "additional_kwargs": {},
  "response_metadata": {
    "tokenUsage": {
      "promptTokens": 98,
      "completionTokens": 21,
      "totalTokens": 119
    },
    "finish_reason": "stop",
    "usage": {
      "prompt_tokens": 98,
      "completion_tokens": 21,
      "total_tokens": 119,
      "prompt_tokens_details": {
        "cached_tokens": 0
      },
      "completion_tokens_details": {
        "reasoning_tokens": 0
      }
    },
    "system_fingerprint": "fp_e2bde53e6e"
  },
  "tool_calls": [],
  "invalid_tool_calls": [],
  "usage_metadata": {
    "output_tokens": 21,
    "input_tokens": 98,
    "total_tokens": 119,
    "input_token_details": {
      "cache_read": 0
    },
    "output_token_details": {
      "reasoning": 0
    }
  }
}
但是,如果我们添加重复的、额外的工具响应,则调用将再次失败
const duplicateToolResponse2 = await dummyTool.invoke(
  responseMessage.tool_calls![1]
);
chatHistory.push(duplicateToolResponse2);
await modelWithTools.invoke(chatHistory);
BadRequestError: 400 Invalid parameter: messages with role 'tool' must be a response to a preceeding message with 'tool_calls'.
    at APIError.generate (/Users/jacoblee/langchain/langchainjs/libs/langchain-openai/node_modules/openai/error.js:45:20)
    at OpenAI.makeStatusError (/Users/jacoblee/langchain/langchainjs/libs/langchain-openai/node_modules/openai/core.js:291:33)
    at OpenAI.makeRequest (/Users/jacoblee/langchain/langchainjs/libs/langchain-openai/node_modules/openai/core.js:335:30)
    at process.processTicksAndRejections (node:internal/process/task_queues:95:5)
    at async /Users/jacoblee/langchain/langchainjs/libs/langchain-openai/dist/chat_models.cjs:1441:29
    at async RetryOperation._fn (/Users/jacoblee/langchain/langchainjs/node_modules/p-retry/index.js:50:12) {
  status: 400,
  headers: {
    'access-control-expose-headers': 'X-Request-ID',
    'alt-svc': 'h3=":443"; ma=86400',
    'cf-cache-status': 'DYNAMIC',
    'cf-ray': '8d31d57dff5e0f3b-EWR',
    connection: 'keep-alive',
    'content-length': '233',
    'content-type': 'application/json',
    date: 'Tue, 15 Oct 2024 18:22:19 GMT',
    'openai-organization': 'langchain',
    'openai-processing-ms': '36',
    'openai-version': '2020-10-01',
    server: 'cloudflare',
    'set-cookie': '__cf_bm=QUsNlSGxVeIbscI0rm2YR3U9aUFLNxxqh1i_3aYBGN4-1729016539-1.0.1.1-sKRUvxHkQXvlb5LaqASkGtIwPMWUF5x9kF0ut8NLP6e0FVKEhdIEkEe6lYA1toW45JGTwp98xahaX7wt9CO4AA; path=/; expires=Tue, 15-Oct-24 18:52:19 GMT; domain=.api.openai.com; HttpOnly; Secure; SameSite=None, _cfuvid=J6fN8u8HUieCeyLDI59mi_0r_W0DgiO207wEtvrmT9Y-1729016539919-0.0.1.1-604800000; path=/; domain=.api.openai.com; HttpOnly; Secure; SameSite=None',
    'strict-transport-security': 'max-age=31536000; includeSubDomains; preload',
    'x-content-type-options': 'nosniff',
    'x-ratelimit-limit-requests': '30000',
    'x-ratelimit-limit-tokens': '150000000',
    'x-ratelimit-remaining-requests': '29999',
    'x-ratelimit-remaining-tokens': '149999956',
    'x-ratelimit-reset-requests': '2ms',
    'x-ratelimit-reset-tokens': '0s',
    'x-request-id': 'req_aebfebbb9af2feaf2e9683948e431676'
  },
  request_id: 'req_aebfebbb9af2feaf2e9683948e431676',
  error: {
    message: "Invalid parameter: messages with role 'tool' must be a response to a preceeding message with 'tool_calls'.",
    type: 'invalid_request_error',
    param: 'messages.[4].role',
    code: null
  },
  code: null,
  param: 'messages.[4].role',
  type: 'invalid_request_error',
  attemptNumber: 1,
  retriesLeft: 6
}
此外,如果 ToolMessages 前面没有带有工具调用的 AIMessage,则不应将 ToolMessages 传递回模型。 例如,这将失败
await modelWithTools.invoke([
  {
    role: "tool",
    content: "action completed!",
    tool_call_id: "dummy",
  },
]);
BadRequestError: 400 Invalid parameter: messages with role 'tool' must be a response to a preceeding message with 'tool_calls'.
    at APIError.generate (/Users/jacoblee/langchain/langchainjs/libs/langchain-openai/node_modules/openai/error.js:45:20)
    at OpenAI.makeStatusError (/Users/jacoblee/langchain/langchainjs/libs/langchain-openai/node_modules/openai/core.js:291:33)
    at OpenAI.makeRequest (/Users/jacoblee/langchain/langchainjs/libs/langchain-openai/node_modules/openai/core.js:335:30)
    at process.processTicksAndRejections (node:internal/process/task_queues:95:5)
    at async /Users/jacoblee/langchain/langchainjs/libs/langchain-openai/dist/chat_models.cjs:1441:29
    at async RetryOperation._fn (/Users/jacoblee/langchain/langchainjs/node_modules/p-retry/index.js:50:12) {
  status: 400,
  headers: {
    'access-control-expose-headers': 'X-Request-ID',
    'alt-svc': 'h3=":443"; ma=86400',
    'cf-cache-status': 'DYNAMIC',
    'cf-ray': '8d31d5da7fba19aa-EWR',
    connection: 'keep-alive',
    'content-length': '233',
    'content-type': 'application/json',
    date: 'Tue, 15 Oct 2024 18:22:34 GMT',
    'openai-organization': 'langchain',
    'openai-processing-ms': '25',
    'openai-version': '2020-10-01',
    server: 'cloudflare',
    'set-cookie': '__cf_bm=qK6.PWACr7IYuMafLpxumD4CrFnwHQiJn4TiGkrNTBk-1729016554-1.0.1.1-ECIk0cvh1wOfsK41a1Ce7npngsUDRRG93_yinP4.kVIWu1eX0CFG19iZ8yfGXedyPo6Wh1CKTGLk_3Qwrg.blA; path=/; expires=Tue, 15-Oct-24 18:52:34 GMT; domain=.api.openai.com; HttpOnly; Secure; SameSite=None, _cfuvid=IVTqysqHo4VUVJ.tVTcGg0rnXGWTbSSzX5mcUVrw8BU-1729016554732-0.0.1.1-604800000; path=/; domain=.api.openai.com; HttpOnly; Secure; SameSite=None',
    'strict-transport-security': 'max-age=31536000; includeSubDomains; preload',
    'x-content-type-options': 'nosniff',
    'x-ratelimit-limit-requests': '30000',
    'x-ratelimit-limit-tokens': '150000000',
    'x-ratelimit-remaining-requests': '29999',
    'x-ratelimit-remaining-tokens': '149999978',
    'x-ratelimit-reset-requests': '2ms',
    'x-ratelimit-reset-tokens': '0s',
    'x-request-id': 'req_59339f8163ef5bd3f0308a212611dfea'
  },
  request_id: 'req_59339f8163ef5bd3f0308a212611dfea',
  error: {
    message: "Invalid parameter: messages with role 'tool' must be a response to a preceeding message with 'tool_calls'.",
    type: 'invalid_request_error',
    param: 'messages.[0].role',
    code: null
  },
  code: null,
  param: 'messages.[0].role',
  type: 'invalid_request_error',
  attemptNumber: 1,
  retriesLeft: 6
}
有关工具调用的更多详细信息,请参阅本指南。
故障排除
以下内容可能有助于解决此错误
- 如果您使用的是自定义执行器,而不是像 LangGraph 的 ToolNode或旧版 LangChain AgentExecutor 这样的预构建执行器,请验证您是否为每个工具调用调用并返回一个工具的结果。
- 如果您正在使用少样本工具调用示例以及您手动创建的消息,并且您想要模拟失败,您仍然需要传回一个 ToolMessage,其内容表明该失败。