对话式人工智能

使用 NVIDIA NIM 和 LangChain 创建自定义 Slackbot LLM 智能体

在现代商业的动态世界中,通信和高效的工作流对成功至关重要,人工智能(AI)解决方案已经成为竞争优势。

AI 智能体基于先进的 大语言模型 (LLM)构建,并由 NVIDIA NIM 提供支持,能够以无缝方式提高工作效率和信息流。NIM 是 NVIDIA AI Enterprise 的一部分,是一套易于使用的微服务,旨在跨云、数据中心和工作站安全、可靠地部署高性能 AI 模型推理。

通过利用 NIM 微服务的强大功能,企业可以利用 API Catalog 中的模型 ,快速构建超越简单自动化的 智能 Slackbot 。这表明 API Catalog 可用于生产部署。这些 Slackbot 成为宝贵的虚拟助手,能够处理各种任务——从回答基本查询到解决复杂问题,甚至生成创意内容。这不仅可以节省时间和资源,还可以打造更具协作性和高效的工作环境。

在本文中,我将逐步指导您使用 NVIDIA NIM 和 LangChain 针对特定用例创建自定义 Slackbot 智能体。

Slackbot 功能和架构 

Slackbot 的初始实施支持通过 Slack 通道、线程和聊天机器人个人信息进行交互。支持这种交互的主要模型是 llama-3_1-405b-instruct ,可以访问外部工具来增强响应。这些工具涉及调用和预处理外部端点。

Slackbot 的主要特性包括:

  • 多渠道支持: Slackbot 可以受邀参加任何渠道,并回答与该渠道上下文相关的查询。
  • 通过标记进行交互 : 要开始对话,用户需要标记机器人并提出一个综合问题。机器人会在同一个频道中标记用户,并在一个主题中回复。
  • 可自定义的回答 :Slackbot 可能会跟进澄清问题,或使用外部工具生成回答。它还支持私人消息。

对于架构(图 1),Amazon EC2 用作项目的主要主机,Amazon Aurora PostgreSQL 用作跟踪人类-AI Slack 交互的数据库。其他云提供商如 Microsoft Azure 或 Google Cloud 也可作为替代方案。

在内存管理方面,DynamoDB 与 LangChain 的 DynamoDBChatMessageHistory 相结合,用于跟踪先前的用户交互。

创建 Slackbot 智能体的分步指南 

以下是在 AWS 上部署 Slackbot 的步骤:

  • 安装所需的库
  • 定义主智能体
  • 设置 DynamoDB 进行内存管理
  • 配置对话式内存
  • 定义基于关键字的工具用法
  • 完成智能体
  • 在 Amazon Aurora PostgreSQL 中保存交互

预备知识 

在开始构建 Slackbot 之前,请确保:

安装所需的库包括以下内容:

openai
boto3
slack_bolt
slack-sdk
langchain
python-dotenv
langchain-community
langchain-nvidia-ai-endpoints
python-dotenv
langchainhub

您还需要以下资源:

安装所需的库 

在设置代理之前,请确保安装了必要的库,例如 LangChain、 LangChain NVIDIA AI 端点 、Slack SDK 等:

pip install openai boto3 slack_bolt slack-sdk langchain python-dotenv langchain-community langchain-nvidia-ai-endpoints langchainhub

定义主智能体 

接下来,定义用于用户交互的主要 Slack 功能,并将 NIM 模型集成为主代理

from slack_bolt import App
from slack_bolt.adapter.socket_mode import SocketModeHandler
from dotenv import load_dotenv
from langchain.agents import AgentExecutor, create_react_agent
from langchain.memory import ConversationBufferWindowMemory
from langchain_core.prompts import PromptTemplate
from langchain_nvidia_ai_endpoints import ChatNVIDIA

def agent(user_id, thread_id, channel_name, message_text):
    try:
        llm = ChatNVIDIA(
            model="meta/llama-3.1-405b-instruct",
            temperature=0.1,
            top_p=1,
            max_tokens=2000,
        )

使用 Meta 的 Llama-3 模型,该模型支持代理任务。在同一函数中,声明 代理工具 ,这是 AI 代理用于完成超出其固有能力的任务的外部资源。这些工具可以具有任意范围,前提是它们具有有效的 API 端点:

tools = [
            CalculatorTool(),
            CopilotTool(),
            BrowsingTool(),
	     ... #Other Tools
]

设置 DynamoDB 进行内存管理 

要跟踪代理交互,请初始化 DynamoDB 表并配置会话内存:

# Specify the region where the table is created
boto3.setup_default_session(region_name='us-east-2')

# Initialize DynamoDBChatMessageHistory
session_id = channel_name  # Use channel_name as session ID
history = DynamoDBChatMessageHistory(table_name="SessionTable", session_id=session_id)

配置对话式内存 

将聊天消息历史记录集成到 agent 的对话内存中:

conversational_memory = ConversationBufferWindowMemory(
     memory_key='chat_history',
     k=10,
     return_messages=True,
     input_key='input',
     output_key='output',
     chat_memory=history
  )

定义基于关键字的工具用法 

您可以添加基于关键字的触发器,以提示机器人使用特定工具。

# Check for specific hashtags and use the corresponding tool
if "%intro" in message_text.lower():
    result = INTRO_MESSAGE
 elif "%gtc24" in message_text.lower():
     selected_tool = GTCFAQTool()
     result = selected_tool._run(message_text)
...
else:
# Read the template from prompt.txt file
      with open('prompt.txt', 'r') as file:
            template = file.read()

 prompt = PromptTemplate.from_template(template)

要提示您的特定用例,请查看 LangChain Hub

完成智能体 

ReACT 是一个框架,其中大型语言模型(LLM)将推理与行动相结合。使用它根据所提供的示例解决任务。使用预定义的变量创建 ReACT 代理和代理执行程序:

# LLM is the NIM agent, with ReACT prompt and defined tools
react_agent = create_react_agent(
       llm=llm,
       tools=tools,
       prompt=prompt
)

# Connect to DB for memory, add react agent and suitable exec for Slack
agent_executor = AgentExecutor(
        agent=react_agent,
        tools=tools,
        verbose=True,
        handle_parsing_errors=True,
        return_intermediate_steps=True,
        memory=conversational_memory
)

在 Amazon Aurora PostgreSQL 中保存交互 

将交互保存在 Amazon Aurora PostgreSQL 数据库的预定义函数中:

save_conversation(user_id, thread_id, channel_name, message_text, result)
return result

您可以根据给定用例向代理流添加各种错误处理机制。

  • 为工具失败时的自定义消息添加异常处理程序。
  • 工具执行时间过长的超时消息
  • 让用户知道该工具失败的错误消息

配置 Slack 交互 

设置权限并安装所需库后,加载环境变量并初始化 Slack 应用。请确保使用正确的标点符号,并将任何名称、LLM 模型和公式替换为原始内容中的英文版本。如果翻译内容看起来像是 LLM 模型名称,请使用原始内容。

# Load environment variables
load_dotenv(".env")

# Initialize Slack app
app = App(token=os.getenv('SLACK_BOT_TOKEN'))

如要配置任何预定义消息、常量和长提示,请添加文本格式的文件,并分别调用它们。

# Constant examples
MAX_BLOCK_CHARS = 3000 #Slack char limit
MESSAGE_FOLDER = "messages"

def load_message(file_name):
    file_path = os.path.join(MESSAGE_FOLDER, file_name)
    with open(file_path, 'r') as file:
        return file.read()

#Example loading automatic message
INTRO_MESSAGE = load_message('greeting_message.txt')

通信处理方式有多种,包括用于提及应用的自定义事件、向 Slack 发布和发送消息,以及在消息超过字符限制时将其拆分成多个块。

要使代理能够处理直接消息,请设置事件监听器:

# Add event listener for direct messages
@app.event("message")
def handle_direct_message_events(body, say, logger):
    event = body['event']
    if event.get('channel_type') == 'im':
        user_id = event['user']
        thread_id = event.get('ts')
        channel_name = event['channel']   # Use the user ID as channel_name
        text = event['text'].strip()
    
        response = agent_with_timeout(user_id, thread_id, channel_name, text)
    
        if response is not None:
            post_message_to_slack(channel_name, response, thread_id, user_id)

为智能体创建自定义工具 

要添加自定义工具,请为每个工具提供清晰的名称和详细说明,以扩展 LangChain BaseTool 类:

class CustomTool(BaseTool):
    name = "Custom Tool"
    description = """
    Tool used to fetch information
			... 
    """

请确保描述全面,并包含在提示中使用的示例。之后,将该工具附加到智能体的工具集。

您还可以针对各种场景自定义工具行为,例如使用正则表达式模式来匹配 Slack 的界面布局,用于编码块。

这种方法可确保每个工具都针对特定需求进行定制,并增强 agent 的通用性。

管理智能体交互和内存 

要存储代理用户交互,请连接到 Amazon Aurora PostgreSQL 数据库实例。

DB_NAME = os.getenv('DB_NAME')
DB_USER = os.getenv('DB_USER')
DB_PASSWORD = os.getenv('DB_PASSWORD')
DB_HOST = os.getenv('DB_HOST')
DB_PORT = os.getenv('DB_PORT')

一些核心功能有助于管理数据库功能。您可以手动创建数据库或使用脚本实现流程自动化。以下代码示例显示了一个用于保存代理人-人类对话的函数:

# Function to save a conversation
def save_conversation(user_id, thread_id, channel_name, message_text, response):
    try:
        conn = psycopg2.connect(
            dbname=DB_NAME,
            user=DB_USER,
            password=DB_PASSWORD,
            host=DB_HOST,
            port=DB_PORT
        )
        c = conn.cursor()
        
        c.execute("""INSERT INTO history (user_id, thread_id, channel_name,    message_text, response)
                     VALUES (%s, %s, %s, %s, %s)""",
                  (user_id, thread_id, channel_name, message_text, response))
        
        conn.commit()
        conn.close()
        print("Conversation saved successfully")
    except psycopg2.Error as e:
        print("Error saving conversation:", e)

在此函数中,关键交互详细信息(例如用户 ID、通道名称和消息)存储在数据库中,以供日后参考。

对于内存管理,请使用 DynamoDB 跟踪对话会话并维护上下文。

# Initialize the DynamoDB resource using the IAM role credentials in the Ohio region
dynamodb = boto3.resource('dynamodb', region_name='us-east-2')

# Create the DynamoDB table
table = dynamodb.create_table(
    TableName='SessionTable',
    KeySchema=[
        {
            'AttributeName': 'SessionId',
            'KeyType': 'HASH'  # Partition key
        }
    ],
    AttributeDefinitions=[
        {
            'AttributeName': 'SessionId',
            'AttributeType': 'S'
        }
    ],
    BillingMode='PAY_PER_REQUEST'
)

后续步骤和增强功能 

要进一步优化 Slackbot,请考虑以下增强功能:

继续探索自定义 Slackbots 之外的其他机器人 

AI 智能体正在通过自动执行任务、优化流程和提高生产力来转变企业应用。 NVIDIA NIM 微服务 提供了一种无缝集成多个代理和工具的方式,使企业能够创建定制的 AI 驱动解决方案。

在本文中,我演示了如何使用 NIM AI 端点 创建具有自定义工具的端到端 Slackbot 智能体。这一解决方案增强了简单的 Slack 界面,使其能够处理更复杂的任务并解决独特的挑战。

有关更多示例,请查看 官方/NVIDIA/GenerativeAIExamples GitHub 库 。有关使用 NIM 微服务和 LangChain 构建的更多信息,请参阅 NVIDIA AI LangChain 端点。

 

 

 

标签