使用 SLM 从头开始​​构建 ReAct Agent

使用 slm 从头开始​​构建 react agent

在这篇文章中,我将演示如何使用小语言模型 (slm) 创建函数调用代理。利用 slm 可以带来一系列好处,特别是与 lora 适配器等工具配合使用时,可以实现高效的微调和执行。虽然大型语言模型 (llm) 功能强大,但它们可能会占用大量资源且速度缓慢。另一方面,slm 更加轻量级,使其非常适合硬件资源有限的环境或低延迟至关重要的特定用例。

通过将slmlora适配器结合使用,我们可以将推理和函数执行任务分开以优化性能。例如,模型可以使用适配器执行复杂的函数调用,并在没有适配器的情况下处理推理或思考任务,从而节省内存并提高速度。这种灵活性非常适合构建函数调用代理等应用程序,而无需大型模型所需的基础设施。

此外,slm 可以轻松扩展以在计算能力有限的设备上运行,这使其成为优先考虑成本和效率的生产环境的理想选择。在此示例中,我们将使用通过 unsloth 在 salesforce/xlam-function-calling-60k 数据集上训练的自定义模型,演示如何利用 slm 创建高性能、低资源的 ai 应用程序.

此外,这里讨论的方法可以扩展到更强大的模型,例如llama 3.1-8b,它具有内置的函数调用功能,在需要更大的模型时提供平滑的过渡。

1. 使用 unsloth 启动模型和分词器

我们首先使用 unsloth 设置模型和标记器。在这里,我们定义最大序列长度为 2048,尽管这个长度是可以调整的。我们还启用4 位量化来减少内存使用量,非常适合在内存较低的硬件上运行模型。

from unsloth import fastlanguagemodelmax_seq_length = 2048 # choose any! we auto support rope scaling internally!dtype = none # none for auto detection. float16 for tesla t4, v100, bfloat16 for ampere+load_in_4bit = true # use 4bit quantization to reduce memory usage. can be false.model, tokenizer = fastlanguagemodel.from_pretrained(    model_name = "akshayballal/phi-3.5-mini-xlam-function-calling",    max_seq_length = max_seq_length,    dtype = dtype,    load_in_4bit = load_in_4bit,)fastlanguagemodel.for_inference(model);

2. 实施受控发电的停止标准

为了确保代理在函数调用后暂停执行,我们定义了停止条件。当模型输出关键字“pause”时,这将停止生成,从而允许代理获取函数调用的结果。

from transformers import stoppingcriteria, stoppingcriterialistimport torchclass keywordsstoppingcriteria(stoppingcriteria):    def __init__(self, keywords_ids:list):        self.keywords = keywords_ids    def __call__(self, input_ids: torch.longtensor, _: torch.floattensor, **kwargs) -> bool:        if input_ids[0][-1] in self.keywords:            return true        return falsestop_ids = [17171]stop_criteria = keywordsstoppingcriteria(stop_ids)

3. 定义函数调用工具

接下来,我们定义代理在执行期间将使用的函数。这些python函数将充当代理可以调用​​的“工具”。返回类型必须明确,并且函数应包含描述性文档字符串,因为代理将依赖于此来选择正确的工具。

def add_numbers(a: int, b: int) -> int:    """    this function takes two integers and returns their sum.    parameters:    a (int): the first integer to add.    b (int): the second integer to add.    """    return a + b def square_number(a: int) -> int:    """    this function takes an integer and returns its square.    parameters:    a (int): the integer to be squared.    """    return a * adef square_root_number(a: int) -> int:    """    this function takes an integer and returns its square root.    parameters:    a (int): the integer to calculate the square root of.    """    return a ** 0.5

4. 为代理生成工具描述

这些函数描述将被构造成一个字典列表。代理将使用这些来了解可用的工具及其参数。

tool_descriptions = []for tool in tools:    spec = {        "name": tool.__name__,        "description": tool.__doc__.strip(),        "parameters": [            {                "name": param,                "type": arg.__name__ if hasattr(arg, '__name__') else str(arg),            } for param, arg in tool.__annotations__.items() if param != 'return'        ]    }    tool_descriptions.append(spec)tool_descriptions

这就是输出的样子

[{'name': 'add_numbers',  'description': 'this function takes two integers and returns their sum.    parameters:    a (int): the first integer to add.    b (int): the second integer to add.',  'parameters': [{'name': 'a', 'type': 'int'}, {'name': 'b', 'type': 'int'}]}, {'name': 'square_number',  'description': 'this function takes an integer and returns its square.    parameters:    a (int): the integer to be squared.',  'parameters': [{'name': 'a', 'type': 'int'}]}, {'name': 'square_root_number',  'description': 'this function takes an integer and returns its square root.    parameters:    a (int): the integer to calculate the square root of.',  'parameters': [{'name': 'a', 'type': 'int'}]}]

5. 创建代理类

然后我们创建代理类,它将系统提示、函数调用提示、工具和消息作为输入,并返回代理的响应。

__call__ 是使用消息调用代理时调用的函数。它将消息添加到消息列表并返回代理的响应。execute 是被调用以生成代理响应的函数。它使用模型来生成响应。function_call 是被调用以生成代理响应的函数。它使用函数调用模型来生成响应。

import astclass agent:    def __init__(        self, system: str = "", function_calling_prompt: str = "", tools=[]    ) -> none:        self.system = system        self.tools = tools        self.function_calling_prompt = function_calling_prompt        self.messages: list = []        if self.system:            self.messages.append({"role": "system", "content": system})    def __call__(self, message=""):        if message:            self.messages.append({"role": "user", "content": message})        result = self.execute()        self.messages.append({"role": "assistant", "content": result})        return result    def execute(self):        with model.disable_adapter():  # disable the adapter for thinking and reasoning            inputs = tokenizer.apply_chat_template(                self.messages,                tokenize=true,                add_generation_prompt=true,                return_tensors="pt",            )            output = model.generate(                input_ids=inputs,                max_new_tokens=128,                stopping_criteria=stoppingcriterialist([stop_criteria]),            )            return tokenizer.decode(                output[0][inputs.shape[-1] :], skip_special_tokens=true            )    def function_call(self, message):        inputs = tokenizer.apply_chat_template(            [                {                    "role": "user",                    "content": self.function_calling_prompt.format(                        tool_descriptions=tool_descriptions, query=message                    ),                }            ],            tokenize=true,            add_generation_prompt=true,            return_tensors="pt",        )        output = model.generate(input_ids=inputs, max_new_tokens=128, temperature=0.0)        prompt_length = inputs.shape[-1]        answer = ast.literal_eval(            tokenizer.decode(output[0][prompt_length:], skip_special_tokens=true)        )[            0        ]  # get the output of the function call model as a dictionary        print(answer)        tool_output = self.run_tool(answer["name"], **answer["arguments"])        return tool_output    def run_tool(self, name, *args, **kwargs):        for tool in self.tools:            if tool.__name__ == name:                return tool(*args, **kwargs)

6. 定义系统和函数调用提示

我们现在定义两个关键提示:

系统提示:智能体推理和工具使用的核心逻辑,遵循react模式。函数调用提示:通过传递相关工具描述和查询来启用函数调用。

system_prompt = f"""you run in a loop of thought, action, pause, observation.at the end of the loop you output an answeruse thought to describe your thoughts about the question you have been asked.use action to run one of the actions available to you - then return pause.observation will be the result of running those actions. stop when you have the answer. your available actions are:{tools}example session:question: what is the mass of earth times 2?thought: i need to find the mass of earthaction: get_planet_mass: earthpause observation: 5.972e24thought: i need to multiply this by 2action: calculate: 5.972e24 * 2pauseobservation: 1,1944×10e25if you have the answer, output it as the answer.answer: {{1,1944×10e25}}.pausenow it's your turn:""".strip()function_calling_prompt = """you are a helpful assistant. below are the tools that you have access to.  ### tools: {tool_descriptions} ### query: {query} """

7. 实现react循环

最后,我们定义了一个循环,使代理能够与用户交互,执行必要的函数调用,并返回正确的答案。

import redef loop_agent(agent: Agent, question, max_iterations=5):    next_prompt = question    i = 0    while i < max_iterations:        result = agent(next_prompt)        print(result)        if "Answer:" in result:            return result        action = re.findall(r"Action: (.*)", result)        if action:            tool_output= agent.function_call(action)            next_prompt = f"Observation: {tool_output}"            print(next_prompt)        else:            next_prompt = "Observation: tool not found"        i += 1    return resultagent = Agent( system=system_prompt, function_calling_prompt=function_calling_prompt, tools=tools)loop_agent(agent, "what is the square root of the difference between 32^2 and 54");

结论

按照此分步指南,您可以使用使用 unslothlora 适配器 训练的自定义模型创建函数调用代理。这种方法确保高效的内存使用,同时保持强大的推理和函数执行能力。

通过将此方法扩展到更大的模型或自定义代理可用的功能来进一步探索。

以上就是使用 SLM 从头开始​​构建 ReAct Agent的详细内容,更多请关注创想鸟其它相关文章!

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 chuangxiangniao@163.com 举报,一经查实,本站将立刻删除。
发布者:程序猿,转转请注明出处:https://www.chuangxiangniao.com/p/1350130.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2025年12月13日 13:58:58
下一篇 2025年12月13日 13:59:08

相关推荐

  • 搜索-搜索插入位置

    我做了search-35。搜索插入位置 这是问题:给定一个不同整数的排序数组和一个目标值,如果找到目标则返回索引。如果不是,则返回按顺序插入时所在的索引。 您必须编写一个运行时间复杂度为 o(log n) 的算法。 示例1: 输入:nums = [1,3,5,6],target = 5输出:2示例2…

    好文分享 2025年12月13日
    000
  • 使用 Pangea X 释放 Python 自由职业机会

    介绍 2024年,对Python开发者的需求持续激增,为自由职业者创造了大量的机会。然而,如果没有合适的资源,在自由职业领域的探索可能会令人畏惧。这就是 Pangea X 发挥作用的地方。作为一个致力于将企业与才华横溢的数据专业人士联系起来的平台,Pangea X 对于希望提升职业生涯并获得利润丰厚…

    2025年12月13日
    000
  • python怎么做爬虫

    爬虫是一种自动化程序,用于从互联网上提取和存储数据。Python 是进行网络爬取的理想语言,因为它具有丰富的开源库,易于学习,可扩展、可维护,并且支持多线程和并发。构建 Python 爬虫包括:安装必要库(BeautifulSoup 和 Requests)、发送 HTTP 请求、解析 HTML、存储…

    2025年12月13日
    000
  • python怎么反爬虫

    Python 提供多种反爬虫技术来阻止网络爬虫抓取数据:使用 robots.txt 阻止访问:通过创建 robots.txt 文件并指定 Disallow 规则。使用 HTTP 标头指示爬虫行为:如 Request-Rate 和 Retry-After,限制请求频率和重试间隔。使用身份验证和令牌:为…

    2025年12月13日
    000
  • python怎么学爬虫

    学习 Python 爬虫的步骤包括:掌握 Python 基础、了解 HTML 和 CSS、学习爬虫原理、实践和项目、持续学习。 学习 Python 爬虫 如何从头开始学习 Python 爬虫? 学习 Python 爬虫需要遵循以下步骤: 1. 掌握 Python 基础 立即学习“Python免费学习…

    2025年12月13日
    000
  • python 爬虫怎么赚钱

    利用 Python 爬虫赚钱的方法包括:收集和出售特定行业数据,进行市场研究。开发和出售使他人轻松使用爬虫的工具,如 Web 爬虫库和 API。提供自定义爬虫服务,帮助企业收集数据或执行任务。收集数据并将其转化为有价值的见解,出售给客户。与企业合作,集成爬虫到业务流程或开发定制解决方案。 Pytho…

    2025年12月13日
    000
  • python爬虫怎么跳

    Python 爬虫可以运用以下技术跳过反爬机制: 1. 用户代理伪装 2. IP 代理池 3. 延迟请求 4. Cookies 和 Session 5. 模拟浏览器行为 6. 使用反爬框架 7. 遵守网站规则 8. 使用分布式爬虫 9. 自定义请求头 10. 人机识别绕过。 Python 爬虫如何跳…

    2025年12月13日
    000
  • python怎么爬虫子

    Python凭借其丰富的库和语法灵活性,是网络爬取的理想选择。爬虫步骤:1. 安装库:Requests、BeautifulSoup、lxml;2. 发送请求;3. 解析响应;4. 提取数据。最佳实践:尊重机器人协议,适度爬取,处理异常,使用代理或头文件,利用并发。 Python爬虫:获取网站数据的强…

    2025年12月13日
    000
  • python爬虫怎么选

    针对不同爬取需求推荐 Python 爬虫:速度和效率:Scrapy(速度、可扩展性)爬取策略:BFS(探索所有当前链接)、DFS(深度探索一条路径)、并发爬取(同时启动多个爬取过程)内存占用:Scrapy(中等,可优化)、Beautiful Soup(较小)、lxml(较大)扩展性:Scrapy(模…

    2025年12月13日
    000
  • 爬虫python怎么用

    Python 爬虫是一种利用 Python 自动化从网站提取数据的工具。步骤如下:安装 bs4、requests、lxml 库。使用 requests 库连接到目标网站。使用 bs4 库解析 HTML。通过标签、CSS 选择器或正则表达式提取数据。清理、转换和存储提取的数据。最佳实践包括尊重 rob…

    2025年12月13日
    000
  • python社区版怎么下载_怎么下载python社区版

    答案:要下载 Python 社区版,请访问 Python 官方网站并根据您的操作系统选择和下载安装程序。详细步骤:访问 Python 官方网站。选择与您的操作系统相对应的平台。下载安装程序。运行安装程序。选择安装选项。按照安装程序提示完成安装。通过命令行验证安装。 如何下载 Python 社区版 步…

    2025年12月13日
    000
  • 怎么免费下载python软件

    您可以访问 Python 官方网站并下载与您的操作系统兼容的版本。安装程序将引导您完成安装过程,并需要您将 Python 路径添加到环境变量中以在命令行中使用 Python。 如何免费下载 Python 软件 步骤 1:访问官方网站 访问 Python 官方网站 https://www.python…

    2025年12月13日
    000
  • pycharm官网怎么找老版本

    如何下载 PyCharm 旧版本?直接从官网下载:访问官网,选择 “Previous versions” 部分,选择版本后点击 “Download”。从第三方网站下载:访问第三方软件下载网站,搜索 “PyCharm” 并选择所需…

    2025年12月13日
    000
  • python付费和免费的区别

    Python 付费版与免费版的区别:支持和维护: 付费版提供商业支持和更新,而免费版由社区支持。安全性: 付费版提供增强安全性,而免费版虽有基本措施,但缺乏高级功能。性能: 付费版提供性能优化,而免费版仅提供核心功能。许可: 付费版限制修改,而免费版允许自由使用和修改。目标受众: 付费版适合企业和需…

    2025年12月13日
    000
  • python3.6下载安装教程

    Python 3.6 安装教程:下载安装程序:访问 Python 官网下载与操作系统兼容的安装程序。运行安装程序:双击安装程序,选择“添加 Python 3.6 到 PATH”选项。验证安装:在命令行输入“python –version”,输出显示“Python 3.6”则安装成功。安装…

    2025年12月13日
    000
  • pycharm现在还有社区版吗

    是的,PyCharm 社区版仍然可用,这是一个免费、开源的 Python IDE,提供代码编辑、重构、调试和单元测试等功能。与专业版相比,它缺少数据库工具和远程开发工具等高级功能,但非常适合初学者、业余开发者和小型项目。 PyCharm 社区版现状 PyCharm 还有社区版吗? 是的,PyChar…

    2025年12月13日
    000
  • python3.8怎么下载安装

    如何在不同操作系统上安装 Python 3.8:下载 Python 3.8: 访问官方网站,选择与操作系统匹配的版本并下载安装程序。Windows 安装: 双击安装程序,自定义安装,勾选 “添加 Python 3.8 到 PATH”,点击 “安装”。M…

    2025年12月13日
    000
  • python3.9.1怎样下载

    要下载 Python 3.9.1,请访问 Python 官网、找到对应操作系统的下载链接、点击链接下载安装程序、运行安装程序并按照提示完成安装,最后通过终端或命令提示符验证已安装版本。 如何下载 Python 3.9.1 步骤: 1. 前往 Python 官网 访问 Python 官网:https:…

    2025年12月13日
    000
  • 探索漂亮股票:分析历史数据并使用 Python 制定交易策略

    在本博客中,我们将探讨如何使用 python 和 yfinance 库分析五家 nifty 50 公司的股票价格。我们将介绍如何获取历史股票数据、计算每日百分比变化以及绘制移动平均线。最后,我们将使用移动平均线交叉开发一个简单的交易策略并回测其性能。这篇文章非常适合金融分析初学者和 python 爱…

    2025年12月13日
    000
  • 微笑检测器和照片捕捉

    概述微笑检测器和照片捕捉应用程序利用 OpenCV 和 Haar 级联通过网络摄像头进行实时面部和微笑检测。当检测到微笑时,程序会捕获照片并使用带时间戳的文件名保存,从而使用户可以轻松创建微笑照片集。 具有实时人脸检测功能:使用 Haar 级联实时检测人脸。微笑检测:识别检测到的面孔中的微笑。照片捕…

    2025年12月13日
    000

发表回复

登录后才能评论
关注微信