LangChain实战——实现多轮对话 + Function Calling

随着大语言模型(LLMs)的迅猛发展,“Function Calling”(函数调用)逐渐成为一个重要的能力,它使得模型不仅能聊天,还能像“中控大脑”一样调用外部函数完成具体任务,比如查天气、调用数据库、控制机器人等。

本篇文章将以一个完整可运行的 LangChain 示例为背景,手把手教你如何:

  • 定义外部工具函数(Tools)
  • 将函数注册到 LLM
  • 构建带有多轮消息历史的对话流
  • 自动识别并调用工具完成任务
  • 再将结果交由模型处理,给出最终回复

一、什么是 Function Calling?

Function Calling 是指模型根据上下文,自动生成调用特定函数的指令(如 JSON 结构的函数名 + 参数),然后由程序调用真实的函数执行,最终再将结果交还给模型生成最终答复。

LangChain 对 Function Calling 的支持非常完善,封装了 OpenAI、Qwen 等兼容 Function Calling 的模型接口,并提供工具注册、调用与上下文维护机制。

二、项目结构预览

我们实现的是一个简单的对话助手,支持两个工具:

  1. get_weather(city: str):返回城市天气
  2. add(a: int, b: int):返回两个数的和

代码结构如下:

├── main.py      # 主程序,包含模型初始化、工具绑定、消息循环

三、代码讲解

下面逐步解析代码中的关键部分。

1. 定义工具函数

使用 LangChain 提供的 @tool 装饰器即可将普通函数注册为 Tool:

from langchain_core.tools import tool@tool
def get_weather(city: str) -> str:"""返回指定城市的天气信息"""return f"{city} 今天天气晴,28°C,湿度30%"@tool
def add(a: int, b: int) -> int:"""加法函数,返回两个整数的和"""return a + b

LangChain 会自动基于函数签名和 docstring 为模型构建 JSON schema,模型即可调用它们。


2. 初始化模型

使用 Qwen 的 Function Calling 接口:

from langchain_openai import ChatOpenAIllm = ChatOpenAI(base_url="https://dashscope.aliyuncs.com/compatible-mode/v1",api_key="your_secret_key",model="qwen-turbo",temperature=0
)

Qwen 模型支持 Function Calling,且支持阿里云 API 兼容模式。


3. 绑定工具到模型

通过 bind_tools 把工具绑定到模型上:

llm_with_tools = llm.bind_tools([get_weather, add])

绑定后,模型就具备了识别调用这两个工具的能力。


4. 构建对话循环(含工具调用与多轮上下文)

from langchain_core.messages import HumanMessage, AIMessage, ToolMessage
import jsonmessages = [AIMessage(content="你好!我是你的AI助手,可以帮你查天气、做加法,有什么可以帮你的?")
]
available_tools = {"get_weather": get_weather, "add": add}while True:user_input = input("你:").strip()if user_input.lower() in {"exit", "quit", ""}:print("再见!")breakmessages.append(HumanMessage(content=user_input))response = llm_with_tools.invoke(messages)if response.tool_calls:print("检测到工具调用:")print(json.dumps(response.tool_calls, indent=2, ensure_ascii=False))messages.append(response)for tool_call in response.tool_calls:tool_func = available_tools.get(tool_call["name"])if tool_func:tool_result = tool_func.invoke(tool_call)messages.append(tool_result)print(f"执行 {tool_call['name']}{tool_result.content}")else:messages.append(response)print("AI:", response.content)continuefinal_response = llm_with_tools.invoke(messages)messages.append(final_response)print("AI:", final_response.content)

🤖 工作流程解析:

  1. 用户输入问题,如“北京天气如何?”
  2. 模型识别需要调用 get_weather(city=北京)
  3. 返回 tool_calls,代码中通过 invoke() 实际执行函数
  4. 工具返回结果后,构造成 ToolMessage 添加进对话上下文
  5. 再次调用模型生成基于工具结果的自然语言回答

四、运行效果演示

你:北京天气如何?
检测到工具调用:
[{"name": "get_weather","args": {"city": "北京"},"id": "call_acfbc5447fa142899d4771","type": "tool_call"}
]
执行 get_weather → 北京 今天天气晴,28°C,湿度30%
AI:  北京今天天气晴朗,温度是28°C,湿度为30%

五、核心机制解析

1. 工具函数封装为 Tool 对象

LangChain 使用 ToolMessage 封装工具执行的返回值,供下一次模型使用。

ToolMessage(tool_call_id=..., content="返回结果")

2. invoke() 自动处理消息历史

模型接收完整的消息序列(系统消息、Human消息、AI消息、Tool消息),并根据上下文判断是否执行函数或直接回复。


六、总结

本文以一个简洁易懂的例子,演示了如何使用 LangChain 实现 Function Calling:

  • ✅ 支持多轮对话与上下文记忆
  • ✅ 模型自动识别是否需要工具调用
  • ✅ 工具结果可参与后续推理
  • ✅ 可快速拓展更多工具,如数据库查询、图像生成、邮件发送等

七、参考资料

  • LangChain 官方文档
  • Qwen DashScope
  • OpenAI Function Calling Guide

附完整项目代码

import jsonfrom langchain_core.messages import HumanMessage, AIMessage, ToolMessage
from langchain_core.tools import tool
from langchain_openai import ChatOpenAI# Step 1:定义工具函数
@tool
def get_weather(city: str) -> str:"""返回指定城市的天气信息"""return f"{city} 今天天气晴,28°C,湿度30%"@tool
def add(a: int, b: int) -> int:"""加法函数,返回两个整数的和"""return a + b# Step 2:初始化模型
llm = ChatOpenAI(base_url="https://dashscope.aliyuncs.com/compatible-mode/v1",api_key="your_secret_key",model="qwen-turbo",temperature=0
)# Step 3:绑定工具
llm_with_tools = llm.bind_tools([get_weather, add])# Step 4:初始化多轮消息历史
messages = [AIMessage(content="你好!我是你的AI助手,可以帮你查天气、做加法,有什么可以帮你的?")
]# Step 5:开始多轮对话循环
available_tools = {"get_weather": get_weather, "add": add}while True:user_input = input("你:").strip()if user_input.lower() in {"exit", "quit", ""}:print("再见!")break# 添加用户输入messages.append(HumanMessage(content=user_input))# 发送当前上下文给模型response = llm_with_tools.invoke(messages)# print(type(response))# print(response)# 判断是否需要调用工具if response.tool_calls:print("检测到工具调用:")# print(type(response.tool_calls))# print(response.tool_calls)print(json.dumps(response.tool_calls, indent=2, ensure_ascii=False))# 把 tool_call 消息添加到对话历史messages.append(response)# 执行所有工具调用并添加结果for tool_call in response.tool_calls:tool_name = tool_call["name"]# print(tool_call["args"]["city"])# print(type(tool_call["args"]["city"]))tool_func = available_tools.get(tool_name)if tool_func:tool_result = tool_func.invoke(tool_call)messages.append(tool_result)print(f"执行 {tool_name}{tool_result.content}")else:print(f"未找到工具:{tool_name}")else:# 如果没有 tool_call,直接是 AI 回答messages.append(response)print("AI:", response.content)continue# 工具执行完后再次交给模型生成最终回答final_response = llm_with_tools.invoke(messages)messages.append(final_response)print("AI: ", final_response.content)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/bicheng/90857.shtml
繁体地址,请注明出处:http://hk.pswp.cn/bicheng/90857.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

湖南(源点咨询)市场调研 如何在行业研究中快速有效介入 起头篇

行业研究从业人员经常需要在承接研究案子后快速的摸清委托方所在行业。而俗话说,隔行如隔山,快速了解行业,主要用于行业分析报告及为市场细分准入进行前期铺垫,要想摸清一个行业,需要长期持续的跟踪。了解一个行业&…

【c++】从 “勉强能用” 到 “真正好用”:中文问答系统的 200 行关键优化——关于我用AI编写了一个聊天机器人……(16)

先看核心结论:两段代码的本质区别如果用一句话总结两段代码的差异:前者是 “带中文支持的问答系统”,后者是 “真正适配中文的问答系统”。具体来说,两段代码的核心功能都是 “加载问答数据→接收用户输入→匹配答案”&#xff0c…

VR 技术在污水处理领域的创新性应用探索​

在广州,VR 污水处理技术的应用可谓是多点开花。首先,在污水处理流程模拟方面,工程师们利用 VR 技术创建了高度逼真的污水处理厂三维模型,将污水处理的整个流程,从预处理去除大颗粒杂质和悬浮物,到初级处理通…

深度学习暑期科研项目(两个月发EI论文)

深度学习暑期科研项目(8周发EI论文) 哈尔滨工业大学博士的六大选题对本科生而言,越早接触系统的科研训练开始上手科研项目,就越能在未来的升学求职中占据很大的优势。暑假是提升个人简历、丰富科研经历的最佳时期!哈尔…

【RH134 问答题】第 1 章 提高命令行运行效率

目录#!/bin/bash 是什么意思?PATH 变量有什么重要作用?echo 命令的作用是什么?解释下列正则表达式的含义简述正则表达式和 shell 模式匹配的区别,在 shell 命令使用正则表达式的时候需要注意什么?#!/bin/bash 是什么意…

OpenCV(02)图像颜色处理,灰度化,二值化,仿射变换

【OpenCV(01)】基本图像操作、绘制,读取视频 目录图像颜色加法灰度化二值化仿射变换图像颜色加法 颜色加法 import cv2 as cv import numpy as np#读图 cao cv.imread(E:\hqyj\code\opencv\images\cao.png) pig cv.imread(E:\hqyj\code\o…

嵌入式——单片机的独立按键

一、目的功能通过开发板上的独立按键k1控制d1指示灯亮灭,k1一次亮再按一次灭。二、硬件原理图三、消抖理解(一)核心原理:当事件被重复触发时,设置一个延迟,只有在该时间内没有新的事件被触发,才…

机器学习的工作流程

🌟 欢迎来到AI奇妙世界! 🌟 亲爱的开发者朋友们,大家好!👋 我是人工智能领域的探索者与分享者,很高兴在CSDN与你们相遇!🎉 在这里,我将持续输出AI前沿技术、实…

聚类里面的一些相关概念介绍阐述

一、性能度量外部指标:聚类结果与某个“参考模型”进行比较;系数: ,其中的 表示样本是否属于某类簇; 指数:,其中 表示样本在两个聚类结果中都是同一类簇, 表示在其中一个聚类结果中…

mmap机制

先看这个 MMAP 机制通俗易懂-CSDN博客 一句话 **mmap(memory map)是操作系统提供的“把文件或设备直接映射到进程虚拟地址空间”的机制,Java 里对应 `MappedByteBuffer`。** --- ### 1. 技术本质 - 系统调用:`mmap()`(POSIX)、`CreateFileMapping`(Windows)。 …

嵌入式硬件篇---驱动板

制作 ESP32 驱动板的核心是 “搭建 ESP32 与外设之间的桥梁”—— 因为 ESP32 的 GPIO 引脚输出电流很小(最大 20mA),无法直接驱动大功率设备(如电机、继电器、电磁阀等),驱动板的作用就是放大电流 / 功率&…

UniappDay01

1.技术架构2.创建uniapp项目 通过HBuilderX创建 官网安装创建uniapp vue3项目安装uniapp vue3的编译器在工具栏启动微信小程序开启服务端口模拟器窗口分离和置顶 通过命令行创建 3.pages.json和tabbar案例 pages.json用来配置路由,导航栏,tabbar等页面类…

子空间投影,投影矩阵,最小二乘法

一、子空间投影 1.1 投影与误差向量b 在 向量a 上的投影即 a 上离 b 最近的点: paTbaTaa p \frac{a^T b}{a^Ta}a paTaaTb​a 我们记 误差 e b - p,显然误差e 和 a 是正交的。 1.2 投影矩阵向量b 在子空间S上的投影是S中离b 最近的向量p。 我们做如下推…

基于FPGA的SPI控制FLASH读写

基于FPGA的SPI控制FLASH读写 文章目录基于FPGA的SPI控制FLASH读写一、SPI简介二、FLASH_M25P16简介信号描述功能操作注意时序三、设计思路框图设计状态机设计四、上板验证1、读ID2、读数据3、扇区擦除写数据五、总结六、代码一、SPI简介 SPI是Serial Peripheral interface的缩…

Pytest 参数化进阶:掌握 parametrize 的多种用法

概述 在自动化测试中,@pytest.mark.parametrize 不仅仅能用来为测试函数提供多组输入数据,还能配合其他功能实现更复杂的测试逻辑。本文将带你深入了解 @pytest.mark.parametrize 的多种常见用法,助你在不同场景下写出更高效、更清晰的测试代码 基础用法回顾:单个参数化 …

K8S 九 安全认证 TLS

目录第九章 安全认证访问控制概述认证管理授权管理 RBACRBACRolerules中的参数RoleBinding9.4 准入控制其他K8S的TLS是什么(DeepSeek)1. 加密通信2. 身份认证(Authentication)3. 数据完整性K8s 中 TLS 的具体应用**1. API Server …

积分兑换小程序Java

某个学校为了激励学生踊跃参加一些社会实践活动,会对参与者给予一些校园积分,学生们获得校园积分后可以使用校园积分在指定的老师那兑换一些学习用具,当前可兑换的物品和对应的积分数量如下:铅笔1分橡皮2分作业本3分文具盒5分为了…

函数指针示例

使用函数指针来调用 printf。下面是对代码的详细解释&#xff1a;&#x1f4c4; 源代码解析#include <stdio.h>int main() {int (*myshow)(const char *, ...); // 声明一个函数指针&#xff0c;指向可变参数函数printf("hello world!\n");myshow printf; /…

不坑盒子突然不见了怎么办?

如果你安装后之前一切正常&#xff0c;突然某天在Office的功能区看不到不坑盒子了&#xff0c;这种是插件被禁用了&#xff0c;重装安装插件、Office都是不能解决的&#xff0c;必须按下面的方法解决。WPS中1.随便打开一个文档&#xff0c;点击文件-选项-信任中心&#xff0c;最…

Java面试全栈通关:从微服务到AI的技术深度解析

Java面试全栈通关&#xff1a;从微服务到AI的技术深度解析 面试现场&#xff1a;大厂技术终面室 面试官&#xff1a;谢飞机同学&#xff0c;今天我们将从基础到架构&#xff0c;全面考察你的Java技术栈掌握程度。请真实展示你的技术水平。 谢飞机&#xff1a;&#xff08;挺胸抬…