Skip to main content
单元测试在隔离环境中测试智能体中细小、确定性的部分。通过用内存中的假模型(也称为测试夹具)替换真实的 LLM,您可以编写精确的响应(文本、工具调用和错误),从而使测试快速、免费且可重复,无需 API 密钥。

使用 fakeModel 模拟聊天模型

fakeModel 是一个构建器风格的假聊天模型,允许您编写精确的响应(文本、工具调用、错误)并断言模型接收的内容。它扩展自 BaseChatModel,因此可以在任何需要真实模型的地方使用。

快速开始

创建一个模型,使用 .respond() 排队响应,然后调用。每次 invoke() 调用会按顺序消耗下一个排队的响应:
如果模型被调用的次数多于排队的响应数量,它会抛出一个描述性错误:

工具调用响应

.respond() 通过传递带有 tool_callsAIMessage 来支持工具调用:
.respondWithTools() 是实现相同功能的简写。无需构建完整的 AIMessage,只需提供工具名称和参数:
id 字段是可选的。如果省略,会自动生成一个唯一 ID。
.respond().respondWithTools() 可以按任意顺序自由混合使用。这对于测试智能体循环特别有用,在这种循环中,模型在工具调用和文本响应之间交替进行。

模拟错误

在特定轮次出错

.respond() 传递一个 Error 会使模型在该特定调用时抛出错误。错误可以出现在序列中的任何位置:

每次调用都出错

.alwaysThrow() 使每次调用都抛出错误,无论队列如何。这对于测试错误处理和重试逻辑很有用:

使用工厂函数实现动态响应

.respond() 也接受一个函数,该函数根据输入消息计算响应。函数接收完整的消息数组,并返回一个 BaseMessage 或一个 Error
工厂函数也可以返回错误:
每个函数都是一个单独的队列条目,只消耗一次。要为多个轮次重用相同的动态逻辑,请排队多个 respond 函数调用。

结构化输出

对于使用 .withStructuredOutput() 的代码,使用 .structuredResponse() 配置假返回值:
传递给 .withStructuredOutput() 的模式会被忽略。模型始终返回使用 .structuredResponse() 配置的值。这使测试专注于应用程序逻辑而非解析。

断言模型接收的内容

fakeModel 记录每次调用,包括传递给模型的消息和选项。这类似于传统测试框架中的间谍或模拟对象:
即使模型抛出错误,调用也会被记录:

bindTools 一起使用

像 LangChain 智能体和 LangGraph 这样的智能体框架在内部调用 model.bindTools(tools)fakeModel 会自动处理这一点。绑定的模型与原始模型共享相同的响应队列和调用记录,因此无需特殊设置:

后续步骤

了解如何使用真实模型提供商 API 测试您的智能体,请参阅集成测试