🚀 NestJS + LangChain 实战:用 Tool 构建可调用真实系统能力的 AI Agent

在很多 AI 应用中,大模型不仅需要回答问题,还需要 调用真实系统能力

例如:

  • 查询天气
  • 查询数据库
  • 查询审批流程
  • 查询企业知识库

如果模型只是聊天,它只能根据训练数据猜答案。

但如果模型能够 调用系统能力(Tool),就可以获得真实数据。

例如:

用户提问:

北京今天天气怎么样

AI 自动:

调用天气 API → 获取真实天气 → 返回结果

这就是 AI Agent + Tool 架构

本文将通过一个 NestJS + LangChain + 和风天气 API 的真实项目,讲清楚:

  • LangChain Tool 的原理
  • 如何把 NestJS Service 封装成 Tool
  • 如何使用 Agent 调度 Tool
  • 完整项目代码结构
  • 为防止看不明确 附赠详细源码入口
  • 第一章:入口

一、LangChain Tool 是什么?

在 LangChain 中:

Tool 本质上是一个可以被模型调用的函数。

例如:

tool(
  async ({ location }) => {
    return `${location} 当前天气晴`
  },
  {
    name: "weather_now",
    description: "查询城市实时天气",
    schema: z.object({
      location: z.string()
    })
  }
)

Tool 有三个关键属性:

字段 作用
name 工具名称
description 说明何时调用
schema 参数结构

二、Tool 调用原理

当用户输入:

北京今天天气

LangChain 会把 Tool 信息发送给模型(写好的内部方法):

weather_now
weather_3d
weather_7d

模型推理后可能返回:

{
 "tool_call": {
   "name": "weather_now",
   "arguments": {
     "location": "北京"
   }
 }
}

LangChain 捕获这个调用:

模型
 ↓
LangChain
 ↓
执行 Tool
 ↓
返回结果
 ↓
模型生成回答

三、项目整体架构

本项目采用 五层架构

QweatherService
   ↓
Weather Tool
   ↓
ToolsService (Agent)
   ↓
ChatService
   ↓
ChatController

如果按运行流程:

HTTP 请求
   ↓
ChatController
   ↓
ChatService
   ↓
ToolsService
   ↓
Agent
   ↓
Tool
   ↓
QweatherService
   ↓
天气 API

四、QweatherService:实现天气能力

文件:

qweather.service.ts

这一层负责:

调用和风天气 API。

示例代码:

@Injectable()
export class QweatherService {

  async getWeatherNow(location: string) {

    const res = await axios.get(
      "https://devapi.qweather.com/v7/weather/now",
      {
        params: {
          key: process.env.QWEATHER_API_KEY,
          location
        }
      }
    )

    return res.data.now
  }

}

返回数据:

{
 "temp": "22",
 "text": "多云",
 "humidity": "45"
}
在这里插入代码片

五、封装 Tool

文件:

weather-now.tool.ts
export const createWeatherNowTool =
(qweatherService: QweatherService) => {

  return tool(

    async ({ location }) => {

      const city =
      await qweatherService.lookupCity(location)

      const now =
      await qweatherService.getWeatherNow(city.id)

      return `
				城市:${city.name}
				天气:${now.text}
				温度:${now.temp}`

    },

    {
      name: "weather_now",
      description: "查询某个城市的实时天气",

      schema: z.object({
        location: z.string()
      })

    }

  )

}

执行流程:

Tool
 ↓
调用 QweatherService
 ↓
获取天气
 ↓
返回结果

六、ToolsService:创建 Agent

文件:

tools.service.ts
@Injectable()
export class ToolsService {

  private agent?: ReturnType<typeof createAgent>

  constructor(
    private readonly qweatherService: QweatherService
  ) {}

  private getAgent() {

    if (!this.agent) {

      const weatherNowTool =
        createWeatherNowTool(this.qweatherService)

      this.agent = createAgent({

        model: createChatModel(),

        tools: [weatherNowTool],

        systemPrompt: `
当用户询问实时天气必须调用 weather_now
`

      })
    }

    return this.agent
  }

}

Agent 的作用:

理解问题
 ↓
选择 Tool
 ↓
执行 Tool
 ↓
生成回答

七、ChatService 调用 Agent

文件:

chat.service.ts
@Injectable()
export class ChatService {

  constructor(
    private readonly toolsService: ToolsService
  ) {}

  async ask(question: string) {

    return this.toolsService.ask(question)

  }

}

调用链:

ChatService
 ↓
ToolsService
 ↓
Agent
 ↓
Tool
 ↓
Service

八、Controller 暴露接口

文件:

chat.controller.ts
@Get("ask/:question")
ask(@Param("question") question: string) {

  return this.chatService.ask(question)

}

访问:

GET /chat/ask/北京天气

九、🔥 Agent 调用时序图

WeatherAPI QweatherService Tool Agent ToolsService ChatService Controller User WeatherAPI QweatherService Tool Agent ToolsService ChatService Controller User 请求天气 ask() ask() invoke() weather_now getWeatherNow() 请求天气 返回天气 返回结果 AI回答

十、为什么模型能自动选择 Tool?

原因有三个:

1 Tool name

weather_now
weather_3d
weather_7d

2 Tool description

查询实时天气
查询未来3天天气

3 systemPrompt

当用户询问实时天气调用 weather_now

模型通过 语义匹配 选择 Tool。


总结

LangChain Tool 的核心思想:

把系统能力封装成模型可以调用的函数。

完整调用链:

Controller
 ↓
ChatService
 ↓
ToolsService
 ↓
Agent
 ↓
Tool
 ↓
Service
 ↓
API

通过这种方式,大模型就可以 调用真实系统能力,而不仅仅是聊天


Logo

AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。

更多推荐