当前位置: 首页 > news >正文

探秘 LangChain 函数定义

在构建基于大语言模型的应用时,LangChain 作为强大的开发框架,提供了丰富多样的定义函数方式,帮助开发者更灵活地与大语言模型交互,实现复杂功能。本文将详细介绍 Python 函数、注解形式、Pydantic 方式、TypedDict 方式和 BaseTool 这几种在 LangChain 中定义函数的方法。
下面代码示例是基于LangChain 0.3.21版本。

一、Python 函数基础定义

Python 函数是最基础、最直观的定义方式。在 LangChain 中,通过简单的 Python 函数定义,就可以实现与大语言模型的交互逻辑。例如,定义一个简单的函数,用于让大语言模型控制灯的开关:

from langchain.chat_models import init_chat_model
from langchain.schema import HumanMessage, AIMessage

def controllLight(status: bool): 
   """用于控制灯的开关,若为True则为开灯,若为False则为关灯

    Args:
        status: 灯的状态
    """
   print(f"light status : {status}")

llm = init_chat_model(model="qwen2.5", model_provider = 'ollama')
tools = [controllLight]
llm_with_tools = llm.bind_tools(tools)
query = "关闭灯"
messages = [HumanMessage(query)]
resp = llm_with_tools.invoke(messages)

print(resp.tool_calls)

if isinstance(resp, AIMessage):
    print('这是AIMessage')
    print(resp.tool_calls[0].get("args"))
else:
    print('不是AIMessage')

# 不能直接调用tool。需要手动解析响应获取参数status值后,再手动调用controllLight函数

二、注解形式

@tool装饰器是定义自定义工具最简单的方式。默认情况下,该装饰器会将函数名作为工具名称,但也可以通过传入一个字符串作为第一个参数来覆盖默认名称。此外,该装饰器会将函数的文档字符串作为工具的描述,因此**必须提供**文档字符串。

from langchain_core.tools import tool
from langchain.chat_models import init_chat_model
from langchain.schema import HumanMessage

@tool
def controllLight(status: bool): 
   """用于控制灯的开关,若为True则为开灯,若为False则为关灯
    """
   print(f"light status : {status}")

llm = init_chat_model(model="qwen2.5", model_provider = 'ollama')
tools = [controllLight]
llm_with_tools = llm.bind_tools(tools)
query = "打开灯"
messages = [HumanMessage(query)]
resp = llm_with_tools.invoke(messages)

print(resp.tool_calls)

query = "关闭灯"
messages = [HumanMessage(query)]
resp = llm_with_tools.invoke(messages)

print(resp.tool_calls)


三、Pydantic

Pydantic 是用于数据验证和设置管理的库,在 LangChain 中,使用 Pydantic 方式定义函数可以更严格地验证输入数据的类型和格式,同时提供更丰富的数据处理功能。


from langchain.chat_models import init_chat_model
from langchain.schema import HumanMessage
from pydantic import BaseModel, Field


class controllLight(BaseModel):
    """用于控制灯的开关,若为True则为开灯,若为False则为关灯
    """
    status: bool = Field(..., description="light status")

llm = init_chat_model(model="qwen2.5", model_provider = 'ollama')
tools = [controllLight]
llm_with_tools = llm.bind_tools(tools)
query = "打开灯"
messages = [HumanMessage(query)]
resp = llm_with_tools.invoke(messages)
print(resp.tool_calls)

query = "关闭灯"
messages = [HumanMessage(query)]
resp = llm_with_tools.invoke(messages)
print(resp.tool_calls)


Pydantic 不仅能验证数据类型,还能进行数据转换。例如,如果传入的length值不是整数,Pydantic 会尝试将其转换为整数(如果可能的话),若无法转换则会抛出验证错误。这种数据验证和转换功能,使得在处理复杂输入数据时更加可靠和安全。

四、TypedDict

Python的TypedDict是一种特殊的字典类型,用于定义具有固定键和特定值类型的字典。在 LangChain 中使用TypedDict方式定义函数,可以清晰地指定函数参数的结构和类型。


from langchain.chat_models import init_chat_model
from langchain.schema import HumanMessage
from typing_extensions import Annotated, TypedDict


class controllLight(TypedDict):
    """用于控制灯的开关,若为True则为开灯,若为False则为关灯"""
    status: Annotated[bool, ..., "light status"]

llm = init_chat_model(model="qwen2.5", model_provider = 'ollama')
tools = [controllLight]
llm_with_tools = llm.bind_tools(tools)
query = "打开灯"
messages = [HumanMessage(query)]
resp = llm_with_tools.invoke(messages)

print(resp.tool_calls)

query = "关闭灯"
messages = [HumanMessage(query)]
resp = llm_with_tools.invoke(messages)

print(resp.tool_calls)


TypedDict相对灵活,在实际使用中,可以根据需要添加或修改字典的键和值类型,以适应不同的业务场景。同时,它也便于与其他数据结构和函数进行集成,提高代码的可扩展性。

五、BaseTool

BaseTool是 LangChain 中用于定义工具的基类,通过继承BaseTool类,可以将自定义的函数封装为工具,方便在代理(Agent)等场景中使用。

from typing import Optional
from langchain_core.callbacks import  CallbackManagerForToolRun
from langchain_core.tools import BaseTool
from pydantic import BaseModel, Field
from langchain.chat_models import init_chat_model
from langchain.schema import HumanMessage
from langchain.agents import Tool

class ControllLight(BaseModel):
    status: bool = Field(..., description="light status")


# Note: It's important that every field has type hints. BaseTool is a
# Pydantic class and not having type hints can lead to unexpected behavior.
class CustomLigthControlTool(BaseTool):
    name: str = "LigthControl"
    description: str = "用于控制灯的开关,若为True则为开灯,若为False则为关灯"
    return_direct: bool = True

    def _run(
        self, status: bool
    ) -> str:
        """control light."""
        return status
    
tool = CustomLigthControlTool()

tools = [
    Tool(
        name=tool.name,
        func=tool.run,
        description=tool.description
    )
]

llm = init_chat_model(model="qwen2.5", model_provider = 'ollama')
# tools = [controllLight]
llm_with_tools = llm.bind_tools(tools)
query = "关闭灯"
messages = [HumanMessage(query)]
resp = llm_with_tools.invoke(messages)
#vscode没有自动提示tool_calls
print(resp)


总结

LangChain 中定义函数的多种方式各有特点和适用场景。Python 函数基础定义简单直接;注解形式有助于明确类型和添加描述;Pydantic 方式提供强大的数据验证和转换功能;TypedDict 方式能灵活定义参数结构;BaseTool 方式则方便将函数封装为工具用于复杂场景。开发者可以根据具体的业务需求和项目特点,选择合适的方式定义函数,从而更高效地构建基于大语言模型的应用。

参考

How to use chat models to call tools | 🦜️🔗 LangChain

How to return artifacts from a tool | 🦜️🔗 LangChain

How to create tools | 🦜️🔗 LangChain

相关文章:

  • Java 性能优化:从原理到实践的全面指南
  • #systemverilog# 关于基于systemveriog验证平台的RTL+TB文件编译顺序问题的讨论
  • c++11--std::forwaord--完美转发
  • zk源码-7.ZAB协议和数据存储二
  • arm_math.h、arm_const_structs.h 和 arm_common_tables.h
  • 游戏引擎学习第217天
  • Day14:关于MySQL的索引——创、查、删
  • 【腾讯云智】20250329笔试算法题
  • QT聊天项目开发DAY02
  • NIPS2024论文 End-to-End Ontology Learning with Large Language Models
  • SpringBoot-Web开发
  • 网络空间安全(56)Laravel框架讲解
  • NoSQL入门指南:Redis与MongoDB的Java实战
  • gdb调试之.gdbinit 文件的用法
  • 最大子序和问题——动态规划/贪心算法解决
  • 2025年AI语音克隆工具全面评估与选型指南
  • Redis-基本概念
  • shield.io网站|markdown中适用的“徽标”
  • 使用ADB工具分析Android应用崩溃原因:以闪动校园为例
  • Gateway-网关-分布式服务部署
  • 首次公布!我国空间站内发现微生物新物种
  • 海昏侯博物馆展览上新,“西汉帝陵文化展”将持续展出3个月
  • 刘强东坐镇京东一线:管理层培训1800人次,最注重用户体验
  • 陕西旱情实探:大型灌区农业供水有保障,大旱之年无旱象
  • 紫光集团原董事长赵伟国一审被判死缓
  • 沙青青评《通勤梦魇》︱“人机组合”的通勤之路