对话界面 - 医疗诊所

对话界面如聊天机器人和虚拟助手可用于增强客户的用户体验。聊天机器人使用自然语言处理(NLP)和机器学习算法来理解和响应用户查询。聊天机器人可用于各种应用,如客户服务、销售和电子商务,以向用户提供快速高效的响应。它们可通过网站、社交媒体平台和消息应用等各种渠道访问。在本笔记本中,我们将使用亚马逊Bedrock中的两个流行的基础模型(FM),Claude V3 Sonnet和Llama 3 8b,来构建一个聊天机器人。

设置:ChatBedrock简介

支持以下功能

  1. Bedrock中的多个模型
  2. Converse API
  3. 工具绑定功能
  4. 与LangGraph流程集成的能力
import warnings
import os
import textwrap
import boto3
import sys
from io import StringIO
from botocore.config import Config
from dotenv import load_dotenv

warnings.filterwarnings('ignore')
load_dotenv()

my_config = Config(
    region_name = 'us-west-2',
    signature_version = 'v4',
    retries = {
        'max_attempts': 10,
        'mode': 'standard'
    }
)

aws_access_key_id = os.getenv("AWS_ACCESS_KEY")
aws_secret_access_key = os.getenv("AWS_ACCESS_SECRET")

boto3_bedrock = boto3.client('bedrock-runtime',
                      aws_access_key_id=aws_access_key_id,
                      aws_secret_access_key=aws_secret_access_key,
                    config=my_config
                      )

warnings.filterwarnings('ignore')

def print_ww(*args, width: int = 100, **kwargs):
    """Like print(), but wraps output to `width` characters (default 100)"""
    buffer = StringIO()
    try:
        _stdout = sys.stdout
        sys.stdout = buffer
        print(*args, **kwargs)
        output = buffer.getvalue()
    finally:
        sys.stdout = _stdout
    for line in output.splitlines():
        print("\n".join(textwrap.wrap(line, width=width)))

LangChain表达式语言(LCEL):

根据LangChain的说法:“LangChain表达式语言,或LCEL,是一种声明性的方式来轻松组合链条。LCEL从一开始就是为了支持将原型投入生产而设计的,无需进行任何代码更改,从最简单的"提示+LLM"链条到最复杂的链条(我们已经看到人们成功地在生产中运行了包含数百个步骤的LCEL链条)。”

在本教程中,我们将使用LangChain表达式语言来定义和调用我们的聊天机器人。

聊天机器人架构

聊天机器人可以有各种形状和大小,这完全取决于其用例。有些模型旨在返回一般信息。其他可能针对特定受众,因此其推论可能会限制在特定的语气上。还有一些可能需要相关的上下文来为用户提供有见地的响应。最强大的聊天机器人将从所有架构中汲取灵感,并在此基础上构建。以下是一些流行的聊天机器人类型。

  1. 聊天机器人(朴素) - 使用FM模型训练知识的零射聊天机器人。
  2. 使用提示的聊天机器人 - 模板驱动 - 带有某些上下文的聊天机器人,提供在提示模板中。
  3. 带有角色的聊天机器人 - 具有定义角色的聊天机器人,如职业教练和人类互动。
  4. 上下文感知聊天机器人 - 通过生成嵌入来传递外部文件中的上下文。

在这个演示中,我们将构建一个利用各种提示架构的聊天机器人。

聊天机器人:朴素方法(无上下文)

最简单的聊天机器人形式是仅通过回答问题或完成任务来响应用户。这些聊天机器人的核心是使用他们接受训练的知识来模仿人类文本。

#modelId = "anthropic.claude-3-sonnet-20240229-v1:0" #"anthropic.claude-v2"
modelId = 'meta.llama3-8b-instruct-v1:0'

messages_list=[
    { 
        "role":'user', 
        "content":[{
            'text': "什么是量子力学?"
        }]
    },
    { 
        "role":'assistant', 
        "content":[{
            'text': "它是一门描述物质和能量如何以离散能量值相互作用的物理学分支"
        }]
    },
    { 
        "role":'user', 
        "content":[{
            'text': "你能更详细地解释一下离散能量吗?"
        }]
    }
]

    
response = boto3_bedrock.converse(
    messages=messages_list, 
    modelId='meta.llama3-8b-instruct-v1:0',
    inferenceConfig={
        "temperature": 0.5,
        "maxTokens": 100,
        "topP": 0.9
    }
)
response_body = response['output']['message']['content'][0]['text'] \
        + '\n--- 延迟: ' + str(response['metrics']['latencyMs']) \
        + 'ms - 输入tokens:' + str(response['usage']['inputTokens']) \
        + ' - 输出tokens:' + str(response['usage']['outputTokens']) + ' ---\n'

print(response_body)


def invoke_meta_converse(prompt_str,boto3_bedrock ):
    modelId = "meta.llama3-8b-instruct-v1:0"
    messages_list=[{ 
        "role":'user', 
        "content":[{
            'text': prompt_str
        }]
    }]
  
    response = boto3_bedrock.converse(
        messages=messages_list, 
        modelId=modelId,
        inferenceConfig={
            "temperature": 0.5,
            "maxTokens": 100,
            "topP": 0.9
        }
    )
    response_body = response['output']['message']['content'][0]['text']
    return response_body


invoke_meta_converse("什么是量子力学", boto3_bedrock)   
在经典物理中,能量通常被认为是连续的,这意味着它可以在某个范围内取任何值。例如,一个滚动的球的能量可以被认为是从零到最大值连续变化的。

相比之下,量子力学引入了离散能量水平或能量量子化的概念。这意味着能量只能取特定的、不同的值,而不是连续的。这些离散能量水平通常被称为"能量本征值"。

思考
--- 延迟: 1335ms - 输入tokens:58 - 输出tokens:100 ---






'\n\n量子力学是物理学的一个基本理论,描述了物质和能量在最小尺度上,如原子和亚原子粒子,的行为。它提供了一个新的、不同的框架来理解物理现象,并且在解释广泛的实验结果和做出准确预测方面取得了令人难以置信的成功。\n\n量子力学的核心是波粒二象性的概念,它暗示粒子,如电子,可以根据观察方式表现出波动性和粒子性。'

使用ChatBedrockHumanMessage对象来包装我们的消息并调用LLM

from langchain_aws.chat_models.bedrock import ChatBedrock
from langchain_core.messages import HumanMessage

model_parameter = {"temperature": 0.0, "top_p": .5, "max_tokens_to_sample": 2000}
model_id = "meta.llama3-8b-instruct-v1:0"
bedrock_llm = ChatBedrock(
    model_id=model_id,
    client=boto3_bedrock,
    model_kwargs=model_parameter, 
    beta_use_converse_api=True
)

messages = [
    HumanMessage(
        content="西雅图WA的天气如何"
    )
]
bedrock_llm.invoke(messages)

AIMessage(content="\n\n西雅图,华盛顿州以其温和潮湿的气候而闻名,全年降雨量丰沛。以下是西雅图典型的天气模式:\n\n1. 降雨:西雅图以其大雨而闻名,平均年降雨量约37英寸(94厘米)。11月至3月为最多雨的月份,平均每月有15-20个多雨天。\n2. 温度:西雅图的平均温度从1月(最冷月)的35°F(2°C)到7月(最热月)的77°F(25°C)。全年平均温度约50°F(10°C)。\n3. 阳光:西雅图每年平均有154个晴天,7月和8月最多阳光。然而,阳光常被云雾遮蔽,直射阳光较少。\n4. 雾:西雅图以冬季的雾而闻名,有时连续几天都笼罩在雾中,尤其是在早晨。\n5. 风:西雅图以强风而闻名,尤其是在冬季。城市可能出现高达40英里/小时(64公里/小时)的阵风。\n6. 雪:西雅图很少有大雪,平均年降雪量约6英寸(15厘米)。1月通常是最多雪的月份,平均1-2英寸(2.5-5厘米)。\n7. 夏季:西雅图的夏季(6-8月)温和宜人,平均高温在23-30°C之间。但城市偶尔也会出现热浪,气温高达32°C以上。\n8. 冬季:西雅图的冬季(12-2月)凉爽潮湿,平均低温在2-7°C之间。城市偶尔也会出现冷空气,气温短暂下降到-7°C以下。\n\n总的来说,西雅图的天气以温和、大雨和阴郁的天气为特征。访问该市时,尤其是在冬季,准备好多层衣服和防水服装是很重要的。", response_metadata={'ResponseMetadata': {'RequestId': '2a706be7-6635-43a6-b88d-a28c044b8a3d', 'HTTPStatusCode': 200, 'HTTPHeaders': {'date': 'Sun, 15 Sep 2024 18:07:18 GMT', 'content-type': 'application/json', 'content-length': '2211', 'connection': 'keep-alive', 'x-amzn-requestid': '2a706be7-6635-43a6-b88d-a28c044b8a3d'}, 'RetryAttempts': 0}, 'stopReason': 'end_turn', 'metrics': {'latencyMs': 6164}}, id='run-2ea19fcc-2fa0-4245-be6f-91b30ed75e15-0', usage_metadata={'input_tokens': 22, 'output_tokens': 472, 'total_tokens': 494})

带有角色的聊天机器人:添加提示模板,零射

获得事实性的响应很重要,但在构建聊天机器人时需要考虑的另一个方面是在向用户提供响应时使用的语气。提示是一种强大的方式,可以指示模型回答问题的语气和方法。

  1. 我们可以将提示定义为消息列表,所有模式都期望SystemMessage,然后交替使用HumanMessage和AIMessage
  2. 聊天模板中定义的变量需要作为字典发送到链中,键为变量名
  3. 我们可以将模板定义为(“system”, “message”)元组,或使用SystemMessage类
  4. invoke创建一个最终结果对象<class ‘langchain_core.prompt_values.ChatPromptValue'>,变量已替换为其值
from langchain_core.prompts import ChatPromptTemplate, MessagesPlaceholder
from langchain_core.runnables import RunnablePassthrough
from langchain_core.output_parsers import StrOutputParser

prompt = ChatPromptTemplate.from_messages( 
    [
        ("system", "你是一个海盗。尽可能好地回答以下问题。"),
        ("human", "{input}"),
    ]
)

pirate_chain = (
    RunnablePassthrough()
    | prompt
    | bedrock_llm
    | StrOutputParser()
)
print_ww(pirate_chain.invoke({"input":"德克萨斯州的天气如何?"})) 

啊,吓我一跳!作为一个海盗,我更关心大海上的天气,而不是陆地上的。但是,我有一个伙伴去过德克萨斯,他告诉我那里是个好地方,阳光充足!他说夏天热干,像热带岛屿一样,冬天温和,像和煦的海风。

不过,我要警告你,伙计,德克萨斯的天气像海妖的歌声一样难以捉摸!你永远不知道什么时候会有一场暴风雨在地平线上酝酿。所以,如果你打算去德克萨斯,一定要做好准备,迎接任何天气!

少量样本方法提示:选择合适的提示

聊天机器人可以是自动化工作流程和传递准确信息的强大工具,但有时构建聊天机器人最困