大模型私有化部署实践(七):AGENT

273 阅读5分钟

专栏

AGENT简介

  • LLM大模型相关的智能体是一种利用大型语言模型(LLM)进行复杂任务执行的人工智能系统。这些智能体通过结合LLM与关键模块,如规划和记忆,来自主感知环境、理解用户请求、做出决策并执行相应动作。LLM在这些智能体中充当“大脑”的角色,负责管理完成任务或响应用户请求所需的一系列操作。

  • LLM大模型智能体具有广泛的应用范围,包括智能客服、代码生成、游戏开发、艺术创作以及企业决策支持等领域。它们能够处理各种复杂的自然语言处理任务,如文本生成、翻译、问答等,并可以调用外部工具或API来扩展其功能。

AGENT基本组成

  • 在基于 LLM 的智能体中,LLM 的充当着智能体的“大脑”的角色,同时还有 3 个关键部分:

  • 规划(Planning)  : 智能体会把大型任务分解为子任务,并规划执行任务的流程;智能体会对任务执行的过程进行思考和反思,从而决定是继续执行任务,或判断任务完结并终止运行。

  • 记忆(Memory) : 短期记忆,是指在执行任务的过程中的上下文,会在子任务的执行过程产生和暂存,在任务完结后被清空。长期记忆是长时间保留的信息,一般是指外部知识库,通常用向量数据库来存储和检索。

  • 工具使用(Tool use)  为智能体配备工具 API,比如:计算器、搜索工具、代码执行器、数据库查询工具等。有了这些工具 API,智能体就可以是物理世界交互,解决实际的问题。 1.png

ReAct

  • ReAct是一种将推理和行动与LLMs结合的通用范式。ReAct通过Prompt的设计,为大语言模型制定了一个任务生成的口头推理和执行行动的过程。这使得大语言模型应用在执行动态推理的同时,能够创建、维护和调整行动计划,并与外部环境进行交互,将附加信息纳入推理过程;这种通用范式会引导大语言模型重复以下两个操作:1. 思考一步应该做什么? 2. 根据上一步的想法采取行动,并获取行动的结果

2.png

体验智能体

LangChain

  • 实践, 我的大模型是通过vllm部署的openai接口,这里通过http调用, 下面实践例子只是为了体验智能体功能,tools相对function call更灵活,可以定义多个tool, 只调用部分,function call只适合固定调用场景
import json
import os
from datetime import date
from typing import Any, List, Optional

import requests
from cryptography.hazmat.backends import default_backend
from cryptography.hazmat.primitives import padding
from cryptography.hazmat.primitives.ciphers import Cipher, algorithms, modes
from langchain.agents import tool, initialize_agent, AgentType
from langchain.llms.base import LLM
from langchain_core.callbacks import CallbackManagerForLLMRun
from pydantic import Field  # 引入 Field


# 自定义 LLM 类,使用 send_vllm_and_get_resp 方法
class CustomVLLM(LLM):
    model: str = Field(default="your-model-name", description="模型名称")  # 显式定义 model 字段
    system_prompt: str = Field(default="你是一个有用的助手。", description="系统提示词")  # 显式定义 system_prompt 字段
    api_url: str = Field(default="https://your-vllm-api-endpoint",
                         description="vLLM 的 HTTP 接口地址")  # 显式定义 api_url 字段

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

    def _call(self, prompt: str, stop: Optional[List[str]] = None,
              run_manager: Optional[CallbackManagerForLLMRun] = None, **kwargs: Any) -> str:
        # 调用 send_vllm_and_get_resp 方法
        return self.send_vllm_and_get_resp(prompt, self.system_prompt, self.api_url)

    def send_vllm_and_get_resp(self, content: str, system: str, url: str) -> str:
        """
        调用 vLLM 的 HTTP 接口并获取响应。
        :param content: 用户输入内容
        :param system: 系统提示词
        :param url: vLLM 的 HTTP 接口地址
        :return: 模型生成的文本
        """
        headers = {
            'Content-Type': 'application/json'
        }
        messages = [
            {'role': 'system', 'content': system},
            {'role': 'user', 'content': content}
        ]
        data = {
            "model": self.model,
            "messages": messages
        }
        response = requests.post(url, headers=headers, data=json.dumps(data), timeout=(30.0, 360.0))
        if response.status_code == 200:
            return json.loads(response.text)['choices'][0]['message']['content']
        else:
            raise Exception(f"vLLM API 调用失败: {response.status_code}, {response.text}")


# 加密数据
def encrypt_message(message):
    # 生成一个随机的密钥和初始化向量
    key = os.urandom(32)  # AES-256需要一个32字节的密钥
    iv = os.urandom(16)  # AES需要一个16字节的初始化向量

    # 使用PKCS7填充数据
    padder = padding.PKCS7(algorithms.AES.block_size).padder()
    padded_data = padder.update(message.encode()) + padder.finalize()

    cipher = Cipher(algorithms.AES(key), modes.CBC(iv), backend=default_backend())
    encryptor = cipher.encryptor()
    ct = encryptor.update(padded_data) + encryptor.finalize()
    return ct


@tool(return_direct=True)  # 使用 return_direct=True 避免多输入问题
def time_encrypt(*args) -> str:
    """
    ATE自制日期加密工具
    """
    print('舒服舒服水电费是的防守打法')
    return str(encrypt_message(str(date.today())))


if __name__ == '__main__':
    # 初始化自定义 LLM
    llm = CustomVLLM(
        model="Qwen/Qwen-72B-AWQ",  # 替换为你的模型名称
        system_prompt="你是一个有用的助手。",  # 系统提示词
        api_url="http://xxxx/v1/chat/completions"  # 替换为你的 vLLM HTTP 接口地址
    )

    # 初始化智能体
    agent = initialize_agent(
        tools=[time_encrypt],  # 工具列表
        llm=llm,  # 自定义 LLM
        agent=AgentType.STRUCTURED_CHAT_ZERO_SHOT_REACT_DESCRIPTION,  # 智能体类型
        verbose=True  # 打印详细日志
    )

    # 运行智能体
    response = agent.run("帮我把今天日期通过ATE加密返回给我")
    print(response)
  • 输出
> Entering new AgentExecutor chain...

Action:

{
  "action": "time_encrypt",
  "action_input": {}
}
舒服舒服水电费是的防守打法

Observation: b'\x11\xb6M\x88\x1f\x88~+P\x13\x90\xfb\xeb\xa9AN'


> Finished chain.
b'\x11\xb6M\x88\x1f\x88~+P\x13\x90\xfb\xeb\xa9AN'

Qwen-Agent

  • 具体实践可参考Qwen-Agent, 里面各种例子example教你使用各种复杂的智能体

参考文章