LLM大语言模型(十):LangChain自定义Agent使用自定义的LLM

背景

独立部署ChatGLM3-6B并提供HTTP API能力。

自定义LLM封装对ChatGLM3-6B的访问。

创建一个简单的Agent来使用自定义的LLM。

自行封装LLM(MyChatGLM)

上一篇文章LLM大语言模型(九):LangChain封装自定义的LLM-CSDN博客

已经介绍过如何在LangChain里封装自定义的LLM。

本文对本地部署的ChatGLM3-6B进行了简单的封装。

import requests
import json
from typing import Any, List, Optional
from langchain.llms.base import LLM
from langchain_core.callbacks import CallbackManagerForLLMRun


class MyChatGLM(LLM):
    model: str = "chatglm3-6b"
    url: str = "http://localhost:8000/v1/chat/completions"

    # def __init__(self):
    #     super().__init__()

    @property
    def _llm_type(self) -> str:
        return "MyChatGLM"

    def _resp_process_mock(self,input:str,resp:str):
        final_answer_json = {
            "action": "Final Answer",
            "action_input": input
        }
        return f"""
Action: 
```
{json.dumps(final_answer_json, ensure_ascii=False)}
```"""

    def _call(self, prompt: str, stop: Optional[List[str]] = None, run_manager: Optional[CallbackManagerForLLMRun] = None, **kwargs: Any) -> str:
        data = {}
        data["model"] = self.model
        lst = []
        lst.append({"role":"user","content":prompt})
        data["messages"] = lst
        resp = self.doRequest(data)
        return self._resp_process_mock(prompt,resp)


    def doRequest(self,payload:dict) -> str:
        # 请求头
        headers = {"content-type":"application/json"}
        # json形式,参数用json
        res = requests.post(self.url,json=payload,headers=headers)
        return res.text

mllm = MyChatGLM()
print(mllm._llm_type)
# mllm._llm_type = "haha" _llm_type该属性是无法被修改的
print(mllm("hello world!"))

_call()方法的实现

本示例是个简单的QA,没有记录history。

_call()方法内部就是通过HTTP POST请求调用本地部署的ChatGLM3-6B服务。

_resp_process_mock()方法

这个是对LLM返回的结果进行了格式化的封装,直接返回action: Final Answer。

为什么这样返回,下文有解释。

自定义Agent

Agent使用的是LangChain的Structured chat类型的Agent,执行结构化的chat能力。

Structured chat类型的Agent支持多个Tool的输入,本文示例未考虑引入tool,所以在_resp_process_mock()里直接返回action: Final Answer。

action: Final Answer表示chat过程中使用tool的推理执行过程已经结束。(详见下文)

from langchain import hub
from langchain.agents import AgentExecutor, create_structured_chat_agent
from langchain_community.tools.tavily_search import TavilySearchResults
from langchain_core.prompts import ChatPromptTemplate, MessagesPlaceholder
from my_chatglm3 import MyChatGLM

if __name__ == "__main__":
    # tools = [TavilySearchResults(max_results=1)]
    tools = []
    prompt = hub.pull("hwchase17/structured-chat-agent")
    # Choose the LLM to use
    llm = MyChatGLM()

    # Construct the agent
    agent = create_structured_chat_agent(llm, tools, prompt)
    # Create an agent executor by passing in the agent and tools
    agent_executor = AgentExecutor(agent=agent, tools=tools, verbose=True, handle_parsing_errors=True)
    agent_executor.invoke({"input": "我心情不好,给我讲个笑话逗我开心"})

ChatPromptTemplate structured-chat-agent

使用的是hwchase17/structured-chat-agent,其结构如下:

System: Respond to the human as helpfully and accurately as possible. You have access to the following tools:


Use a json blob to specify a tool by providing an action key (tool name) and an action_input key (tool input).
Valid \"action\" values: \"Final Answer\" or 
Provide only ONE action per $JSON_BLOB, as shown:
```\n{\n  \"action\": $TOOL_NAME,\n  \"action_input\": $INPUT\n}\n```
Follow this format:
Question: input question to answer
Thought: consider previous and subsequent steps
Action:
```
$JSON_BLOB
```
Observation: action result
... (repeat Thought/Action/Observation N times)
Thought: I know what to respond
Action:
```
{
  \"action\": \"Final Answer\",
  \"action_input\": \"Final response to human\"
}

Begin! Reminder to ALWAYS respond with a valid json blob of a single action. Use tools if necessary. Respond directly if appropriate. Format is Action:```$JSON_BLOB```then Observation

Human: 我心情不好,给我讲个笑话逗我开心
 (reminder to respond in a JSON blob no matter what)

第一段:声明System信息,类似我们使用LLM对话时的prompt engineering,指定角色等context信息。

第二段:声明如何使用tool以及推理过程,tool本文不涉及后续再写。注意对推理过程的约束,推理结束的标志是action: Final Answer,如果LLM给Agent返回的结果一直没有action: Final Answer,会导致Agent一直推理下去进入“死循环”。

这也是为什么_resp_process_mock()方法直接就返回action: Final Answer,一轮对话就结束就完事。

第三段:声明输出格式。

第四段:Human用户的输入

Agent执行结果

> Entering new AgentExecutor chain...

Action:
```
{"action": "Final Answer", 
"action_input": "{\"model\":\"chatglm3-6b\",\"id\":\"\",\"object\":\"chat.completion\",\"choices\":[{\"index\":0,\"message\":{\"role\":\"assistant\",\"content\":\"{\\n  \\\"action\\\": \\\"Final Answer\\\",\\n  \\\"action_input\\\": \\\"A joke for you: Why was the math book sad? Because it had too many problems.\\\"\\n}\",\"name\":null,\"function_call\":null},\"finish_reason\":\"stop\"}],\"created\":1712419428,\"usage\":{\"prompt_tokens\":297,\"total_tokens\":339,\"completion_tokens\":42}}"}
```

> Finished chain.

可以看到这里的推理过程,只有一个action: Final Answer。

action_input这里直接返回了LLM的原始回答。

其中的A joke for you: Why don't scientists trust atoms? Because they make up everything! 这个就是LLM的回答。

 参考

  1. LLM大语言模型(九):LangChain封装自定义的LLM-CSDN博客
  2. LLM大语言模型(八):ChatGLM3-6B使用的tokenizer模型BAAI/bge-large-zh-v1.5-CSDN博客
  3. LLM大语言模型(七):部署ChatGLM3-6B并提供HTTP server能力
  4. LLM大语言模型(四):在ChatGLM3-6B中使用langchain_chatglm3-6b langchain-CSDN博客
  5. LLM大语言模型(一):ChatGLM3-6B本地部署-CSDN博客

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

基于SSM+Jsp+Mysql的个性化影片推荐系统

开发语言:Java框架:ssm技术:JSPJDK版本:JDK1.8服务器:tomcat7数据库:mysql 5.7(一定要5.7版本)数据库工具:Navicat11开发软件:eclipse/myeclipse/ideaMaven包…

[数据结构]栈和队列结构的简单制作

一、栈 1.1栈的概念以及结构 栈:一种特殊的线性表,其只允许在固定的一端进行插入和删除元素操作。进行数据插入和删除操作的一端 称为栈顶,另一端称为栈底。 栈中的数据元素遵守后进先出LIFO(Last In First Out)的原…

Vant DropdownMenu 下拉菜单带搜索功能

Vant DropdownMenu 下拉菜单带搜索功能 效果图&#xff1a; 上代码&#xff1a; <van-dropdown-menu active-color"#E33737"><van-dropdown-item ref"dropdownItem"><template #title><span>{{ dropdownItem.text }}</span…

蓝桥杯2022年第十三届省赛真题-最少刷题数

solution&#xff08;通过50%&#xff09; 忽略了存在分数相同的情况&#xff0c;若从p位置开始有若干个相同分数的无需再多刷&#xff0c;但是在p位置前若干个&#xff08;含p位置&#xff09;分数相同则都需要多刷一道题。 #include<iostream> #include<algorithm…

运动想象 (MI) 分类学习系列 (7) :CMO-CNN

运动想象分类学习系列:CMO-CNN 0. 引言1. 主要贡献2. 提出的算法3. 数据增强策略4. 结果4.1 学科内分类4.2 跨学科分类4.3 数据增强策略4.4 网络可视化4.4.1 短连接可视化4.4.2 滤波器可视化4.4.3 中间特征的可视化 5. 总结欢迎来稿 论文地址&#xff1a;https://www.sciencedi…

金铲铲单机版含教程,仅支持S1\S6\S11赛季

金铲铲单机版&#xff0c;官方的单机版&#xff0c;支持S3/S6/S11赛季&#xff0c; 我自己玩了两把&#xff0c;可以加金币/加血/设置GM权限等&#xff0c; 我猜测是开发者测试版本&#xff0c; 金铲铲单机版含教程&#xff0c;仅支持S1\S6\S11赛季 网盘自动获取 链接&#xff…

实现WAF对CC攻击的零误封防护:关键技术解析与实践

一、引言 Web应用防火墙&#xff08;WAF&#xff09;作为网站安全的重要防线&#xff0c;其在防御CC&#xff08;Challenge Collapsar&#xff0c;即挑战黑洞&#xff0c;一种分布式拒绝服务攻击&#xff09;攻击中的效能至关重要。然而&#xff0c;精准识别并有效拦截CC攻击的…

CUDA执行模型

CUDA执行模型概述 一般来说&#xff0c;执行模型会提供一个操作视图&#xff0c;说明如何在特定的计算架构上执行指令。CUDA执行模型揭示了GPU并行架构的抽象视图&#xff0c;使我们能够据此分析线程的并发。 GPU架构概述 GPU架构是围绕一个流式多处理器&#xff08;SM&…

掌握内容时效性:Kompas.ai如何帮你赢在起跑线上

在这个快速变化的数字时代&#xff0c;内容的时效性成为了品牌和媒体机构在竞争中脱颖而出的关键。时效性强的内容能够迅速吸引受众的注意力&#xff0c;提高品牌的可见度和影响力。本文将深入探讨时效性内容的重要性&#xff0c;展示Kompas.ai如何利用实时数据和趋势分析为用户…

8.string库函数的用法以及string的模拟实现

1. 为什么学习string类&#xff1f; C语言中的字符串 C语言中&#xff0c;字符串是以\0结尾的一些字符的集合&#xff0c;为了操作方便&#xff0c;C标准库中提供了一些str系列的库函数&#xff0c;但是这些库函数与字符串是分离开的&#xff0c;不太符合OOP的思想&#xff0…

RTX RTOS操作实例分析之---邮箱(mailbox)

0 Preface/Foreword 1 邮箱&#xff08;mailbox&#xff09; 1.1 mailbox ID定义 static osMailQId app_mailbox NULL; 1.2 定义mailbox结构体变量 #define osMailQDef(name, queue_sz, type) \ static void *os_mail_p_##name[2]; \ const char mail_##name[] #name; \ con…

mysql双机热备

MySQL双机热备&#xff1a;保障数据库高可用性的关键技术 在当今信息化社会中&#xff0c;数据库作为企业信息系统的核心组成部分&#xff0c;其高可用性和数据安全性至关重要。MySQL作为广泛应用的开源关系型数据库管理系统&#xff0c;其双机热备技术成为保障数据库稳定运行…

4.9QT

完善对话框&#xff0c;点击登录对话框&#xff0c;如果账号和密码匹配&#xff0c;则弹出信息对话框&#xff0c;给出提示”登录成功“&#xff0c;提供一个Ok按钮&#xff0c;用户点击Ok后&#xff0c;关闭登录界面&#xff0c;跳转到其他界面 如果账号和密码不匹配&#xf…

苹果商店审核指南:确保Flutter应用顺利通过审核的关键步骤

引言 Flutter是一款由Google推出的跨平台移动应用开发框架&#xff0c;其强大的性能和流畅的用户体验使其备受开发者青睐。然而&#xff0c;开发一款应用只是第一步&#xff0c;将其成功上架到苹果商店才是实现商业目标的关键一步。本文将详细介绍如何使用Flutter将应用程序上…

数字时代电子账单邮件群发:简便、高效、环保

电子账单已经在许多行业得到广泛应用&#xff0c;通过邮件群发发送电子账单简便、高效、环保&#xff0c;以下是一些通常使用电子账单的行业&#xff1a; 1.银行和金融服务&#xff1a;银行、信用合作社、金融科技公司等机构通常通过电子账单向客户提供账户摘要、交易明细、利息…

Python-VBA函数之旅-bool函数

目录 1、bool函数 1-1、Python&#xff1a; 1-2、VBA&#xff1a; 2、相关文章&#xff1a; 个人主页&#xff1a;非风V非雨-CSDN博客 bool函数(Boolean Function)用于将给定的值转换为布尔值(True或False)。常见的应用场景有&#xff1a; 1、条件判断&#xff1a;bool()…

每日一题 — 无重复字符的最长子串

解法一&#xff1a;暴力枚举 先固定一个left&#xff0c;让right向右遍历遇到重复的字符&#xff0c;让left加一然后right返回&#xff0c;重新遍历 解法二&#xff1a; 滑动窗口(在解法一的基础上进行优化) 还是先固定一个left在起始位置&#xff0c;让right从起始位置开始向…

使用docker制作Android镜像(实操可用)

一、安装包准备 1、准备jdk 下载地址&#xff1a;Java Downloads | Oracle 注意版本&#xff01;&#xff01;&#xff01;&#xff01;&#xff01;&#xff01; 我下载的jdk17&#xff0c;不然后面构建镜像报错&#xff0c;就是版本不对 2、准备安装的工具包 ttps://dev…

Java多线程实战-从零手搓一个简易线程池(四)线程池生命周期状态流转实现

&#x1f3f7;️个人主页&#xff1a;牵着猫散步的鼠鼠 &#x1f3f7;️系列专栏&#xff1a;Java全栈-专栏 &#x1f3f7;️本系列源码仓库&#xff1a;多线程并发编程学习的多个代码片段(github) &#x1f3f7;️个人学习笔记&#xff0c;若有缺误&#xff0c;欢迎评论区指正…

Playwright安装和基本使用(ui/web自动化)

1.简介 Playwright是2021年微软开源的一个项目「playwright-python」。针对 Python 语言的纯自动化工具&#xff0c;它可以通过单个API自动执行 Chromium&#xff0c;Firefox 和 WebKit 浏览器&#xff0c;同时支持以无头模式、有头模式运行。 Playwright&#xff08;Git&…