赞
踩
ERNIE Bot Agent的LangChain插件目前包含如下组件:
ErnieBot:大语言模型,用于完成文本补全任务。
ErnieBotChat:聊天模型,用于完成对话补全任务。
ErnieEmbeddings:文本嵌入模型,用于生成文本的向量表示。
!pip install erniebot-agent langchain
执行如下代码,填写access token并敲击回车键:
这里提供两种access token的输入方式:
'''
官方文档中提到的access token导入方式
'''
import getpass
access_token = getpass.getpass(prompt="Access token: ")
'''
本文使用的access导入方式,任选一个即可
'''
import erniebot
erniebot.api_type = "aistudio"
erniebot.access_token = ""
ErnieBot是LangChain大语言模型组件,可用于完成文本补全任务。
这里使用的是ERNIE-SPEED模型,可以参考文档千帆大模型平台选择合适的模型
from erniebot_agent.extensions.langchain.llms import ErnieBot
llm = ErnieBot(aistudio_access_token=erniebot.access_token, model="ernie-speed")
question = "What does SFINAE mean in C++ template metaprogramming?"
print(llm(question))
SFINAE 是 C++ 中一个非常重要的概念,全称为 "Substitution Failure Is Not An Error"。在模板元编程中,这个概念尤其重要。让我们深入了解下它的含义。
在 C++ 中,当你在一个函数模板中使用模板参数时,如果模板实例化过程中某些类型替换失败(比如函数参数类型不匹配等),那么这种替换失败并不会导致编译错误。这就是 SFINAE 的核心概念。也就是说,替换失败并不等于编程错误。取而代之的结果是忽略失败的实例化(特定的类型替换)并选择其它匹配更好的版本进行替换,这样的处理实际上保护了编译器在进行函数选择时不因为单纯的类型替换失败而抛出错误。这就是所谓的“静默替代失败”。这种机制使得 C++ 能够进行灵活的函数重载解析和模板匹配。
举个例子来说明这个概念:假设你有一个包含函数模板的代码,试图以不同方式对类型进行处理,因为一种或多种方式对某个特定的类型不兼容或不适用时(比如说编译器不能直接操作复杂的静态变量模板实例化)。在这种情况下,SFINAE 允许编译器忽略这些失败的尝试并继续尝试其他方式。这实际上是一种在编译时动态选择不同实现的方法,是模板元编程的核心思想之一。具体来说,C++中的“策略调用”、“替换语义”(或者更专业的称作特化移除/Substitution for pattern removal)都是通过这种原则来实现的。而且它与自动的类型推演在构造匿名代码和实现内联运算符时会相遇较多交集或者一并称为参数的临时部分覆盖以方便更好的区分规则来达到类似于无复制初始化等高效写法而具有重要意义,可以有效确保不同运算符在某些语言构造中更加稳定的使用以及高效代码实现等目的。
from langchain.prompts import PromptTemplate
from langchain.chains import LLMChain
template = "Tell me a joke about {content}."
prompt = PromptTemplate(template=template, input_variables=["content"])
llm_chain = LLMChain(prompt=prompt, llm=llm)
content = "rabbits"
print(llm_chain.run(content=content))
好的,我给你讲个关于兔子的笑话:
有一天,一只兔子走进了一个酒吧,对酒保说:“给我一杯啤酒。”酒保惊讶地问:“你怎么会喝酒呢?你是一只兔子呀。”兔子回答道:“医生说我得了眼部肿瘤需要三杯酒缓解。其他顾客也表示听说我每天可以喝更多的东西缓解喉咙痛或其他病。”另一只聪明的兔子问道:“那兔子的眼睛在哪儿?”那只喝酒的兔子答道:“在我手上!”
question = "Please write a Python program that checks if an integer is a prime number."
answer = await llm.agenerate([question])
print(answer)
generations=[[Generation(text='当然,以下是一个简单的Python程序,用于检查一个整数是否为质数:\n\n\n```python\ndef is_prime(n):\n if n <= 1:\n return False\n elif n == 2:\n return True\n else:\n if n % 2 == 0:\n return False # 所有偶数(除了2)都不是质数\n else:\n for i in range(3, int(n**0.5)+1, 2): # 从奇数开始,直到n的平方根,步长为2(因为已知除了偶数和小于n的平方根的因数外,其他的因数都大于平方根)\n if n % i == 0: # 如果存在因数,则不是质数\n return False\n return True # 如果循环结束都没有找到因数,则是质数\n\nnum = int(input("请输入一个整数以检查是否为质数:")) # 输入整数进行检验\nif is_prime(num): # 如果是质数则输出信息并返回True,否则输出信息并返回False\n print("输入的整数是质数。")\nelse:\n print("输入的整数不是质数。")\n```\n这个程序首先检查输入的整数是否小于或等于1(质数定义为大于1的数),然后检查它是否是偶数(除了2以外的所有偶数都不是质数)。然后程序会检查从第一个奇数开始的所有可能的因数(所有的质数都能写成两个数的乘积),一直到这个数的平方根。如果这个过程中没有找到一个能整除该数的除数,那么这个数就是一个质数。因为对于一个非素数的大整数n,要么它有一个小于等于sqrt(n)的因子,要么它是两个大于sqrt(n)的数的乘积。由于后者不可能存在小于sqrt(n)的乘积关系式的情况下假设等于对进行判定的时间长度也是间隔在两个完全未知的极差值区间下进行检验会极大的消耗时间复杂度并且并没有效率,所以直接取根号是一个高效的筛选手段。')]] llm_output=None run=[RunInfo(run_id=UUID('56b09fde-74b6-4041-9ea1-424b18177e3f'))]
question = "What is the difference between capybara and kiwi?"
for chunk in llm.stream(question):
print(chunk, end="", flush=True)
print("")
Capybara and kiwi are two different animals. Capybara is a mammal in the rodent family, which is also known as the South American giant mouse or aquatic rabbit, with features such as being very sociable, semi-aquatic, and often living in groups. On the other hand, kiwi refers to several species of birds belonging to the kiwi family in the modern avian class. They are generally characterized by being flightless birds that have special adaptations to dark environments. The differences between them mainly include:
1. Categories: Capybara belongs to mammal; kiwi belongs to bird.
2. Habitat: Capybara mainly lives in Central and South America; kiwi is native to New Zealand.
3. Appearance: Capybara is large in size, with a big head and ears that can stand upright, with hair on the ears; kiwi is relatively small in size and has a brown body with soft fur on the surface.
In addition, these two animals also have differences in behavior and ecology. For example, capybaras are very sociable animals that live in groups, while kiwifruit birds are more solitary and prefer to live alone or in pairs. They also have different feeding habits and environments.
In short, capybara and kiwi are two different animals with different characteristics and living environments.
ErnieBotChat是LangChain聊天模型组件,可用于完成文本补全任务。
from erniebot_agent.extensions.langchain.chat_models import ErnieBotChat
chat = ErnieBotChat(aistudio_access_token=erniebot.access_token, model="ernie-speed")
from langchain_core.messages import HumanMessage
message = HumanMessage(content="What does SFINAE mean in C++ template metaprogramming?")
print(chat([message]))
content='SFINAE 是 C++ 中一个非常重要的概念,全称为 "Substitution Failure Is Not An Error"。在模板元编程中,这个概念尤为重要。让我们深入了解它的含义。\n\n在 C++ 中,当我们处理模板函数或模板类时,编译器会尝试将特定的类型或值代入模板参数以解析模板实例化。如果代入成功,那么编译器会继续生成代码。但如果代入失败(例如由于某些约束条件不满足),按照常规理解,这通常会导致编译错误。然而,在 SFINAE 的原则下,这种代入失败并不会导致编译错误。相反,它仅仅是排除了某些特定的模板实例化,而不是产生一个全局错误。\n\n让我们通过一个简单的例子来理解这个概念:\n\n假设你有以下两个函数模板:\n\n\n```cpp\ntemplate <typename T>\nvoid foo(T t) { /* 函数体 */ }\n\ntemplate <typename T>\nvoid foo(T t, typename std::enable_if<std::is_integral<T>::value, bool>::type = true) { /* 仅适用于整数的函数实现 */ }\n```\n在这种情况下,第二个 `foo` 函数仅在 `T` 为整数类型时被选择(因为 `std::is_integral<T>::value` 为 `true`)。如果你尝试传递一个非整数类型给 `foo` 函数,那么第二个函数模板的实例化会失败(根据 SFINAE 原则)。但这并不会导致编译错误,因为第一个 `foo` 函数模板可以接受所有类型的参数。这就是 SFINAE 的魔力所在。它允许我们在模板元编程中灵活地处理不同类型和条件,而不会导致不必要的编译错误。\n\n在复杂的模板元编程场景中,SFINAE 可以帮助我们在编译时根据类型特性或约束条件动态选择适当的函数或类模板实现。这对于编写泛型代码和处理不同类型的特殊情况非常有用。' response_metadata={'token_usage': {'prompt_tokens': 15, 'completion_tokens': 372, 'total_tokens': 387}, 'model_name': 'ernie-speed', 'finish_reason': 'stop'} id='run-b4688d99-ab56-4c0f-9ac9-01c01934bd38-0'
from langchain.prompts import ChatPromptTemplate
message = "Tell me a joke about {content}."
prompt = ChatPromptTemplate.from_messages([("human", message)])
chain = prompt | chat
print(chain.invoke({"content": "rabbits"}))
content='好的,这是一个关于兔子的笑话:\n\n有一天,一只兔子走进了一家酒吧,对酒保说:“给我一杯啤酒。”酒保惊讶地说:“兔子也会喝酒?”兔子回答:“为什么兔子不能喝酒?我也是一个有品位的人。”酒保笑了笑,给他一杯啤酒。兔子喝了一口,突然跳了起来:“太棒了!这就是我所需要的!我更喜欢有品位的生活!”然后它拿出了一根胡萝卜庆祝。' response_metadata={'token_usage': {'prompt_tokens': 7, 'completion_tokens': 81, 'total_tokens': 88}, 'model_name': 'ernie-speed', 'finish_reason': 'stop'} id='run-6edf1ed2-16b9-4aab-904b-8053fd665c55-0'
from langchain_core.messages import HumanMessage
message = HumanMessage(content="Please write a Python program that checks if an integer is a prime number.")
response = await chat.agenerate([[message]])
print(response)
generations=[[ChatGeneration(text='当然,以下是一个简单的Python程序,用于检查一个整数是否为质数:\n\n\n```python\ndef is_prime(n):\n if n <= 1:\n return False # 质数定义为大于1的自然数,所以小于等于1的数不是质数\n if n == 2:\n return True # 2是唯一的偶数质数\n if n % 2 == 0: # 所有大于2的偶数都不是质数\n return False\n i = 3 # 从奇数开始检查是否为质数,因为偶数中只有2是质数\n while i * i <= n: # 优化检查过程,只需要检查到根号n即可\n if n % i == 0: # 如果n能被i整除,则不是质数\n return False\n i += 2 # 只检查奇数,因为偶数除了2以外都不是质数\n return True # 如果循环结束没有找到除数,那么n是质数\n\n# 测试函数\nnum = int(input("请输入一个整数:")) # 获取用户输入的整数\nif is_prime(num):\n print(f"{num}是质数。") # 输出质数的结果\nelse:\n print(f"{num}不是质数。") # 输出非质数的结果\n```\n这个程序首先定义了一个函数 `is_prime` 来检查一个整数是否为质数。然后,它会提示用户输入一个整数,并使用这个函数来检查输入的整数是否为质数。最后,它会输出相应的结果。', generation_info={'finish_reason': 'stop'}, message=AIMessage(content='当然,以下是一个简单的Python程序,用于检查一个整数是否为质数:\n\n\n```python\ndef is_prime(n):\n if n <= 1:\n return False # 质数定义为大于1的自然数,所以小于等于1的数不是质数\n if n == 2:\n return True # 2是唯一的偶数质数\n if n % 2 == 0: # 所有大于2的偶数都不是质数\n return False\n i = 3 # 从奇数开始检查是否为质数,因为偶数中只有2是质数\n while i * i <= n: # 优化检查过程,只需要检查到根号n即可\n if n % i == 0: # 如果n能被i整除,则不是质数\n return False\n i += 2 # 只检查奇数,因为偶数除了2以外都不是质数\n return True # 如果循环结束没有找到除数,那么n是质数\n\n# 测试函数\nnum = int(input("请输入一个整数:")) # 获取用户输入的整数\nif is_prime(num):\n print(f"{num}是质数。") # 输出质数的结果\nelse:\n print(f"{num}不是质数。") # 输出非质数的结果\n```\n这个程序首先定义了一个函数 `is_prime` 来检查一个整数是否为质数。然后,它会提示用户输入一个整数,并使用这个函数来检查输入的整数是否为质数。最后,它会输出相应的结果。', response_metadata={'token_usage': {'prompt_tokens': 15, 'completion_tokens': 332, 'total_tokens': 347}, 'model_name': 'ernie-speed', 'finish_reason': 'stop'}, id='run-ca18985d-95f2-4f20-99c2-a7ce185af6ae-0'))]] llm_output={} run=[RunInfo(run_id=UUID('ca18985d-95f2-4f20-99c2-a7ce185af6ae'))]
from langchain_core.messages import HumanMessage
message = HumanMessage(content="What is the difference between capybara and kiwi?")
for chunk in chat.stream([message]):
print(chunk.content, end="", flush=True)
print("")
Capybara and kiwi are two different animals. Capybara is a mammal in the rodent family, while kiwi is a bird in the kiwi family. They are different species and have different characteristics and behaviors.
Capybara are large rodents that live in South America, particularly in the grassland and marsh areas of Central and South America. They are excellent swimmers and often live in aquatic environments. Capybaras are very social animals and live in groups, with the largest groups including up to hundreds of individuals.
Kiwi birds are small flightless birds that are native to New Zealand. They are known for their unique appearance, with soft fur on their body and large heads with powerful beak and beak tip feather-like bristles. Kiwi birds are nocturnal and live in forests and other habitats that are typically dark. They also tend to be solitary animals and prefer to avoid contact with other kiwi birds unless they are breeding pairs.
In summary, capybara and kiwi are different animals with different behaviors and characteristics.
ErnieEmbeddings是LangChain文本嵌入模型组件,可用于生成文本的向量表示。
from erniebot_agent.extensions.langchain.embeddings import ErnieEmbeddings
embeddings = ErnieEmbeddings(aistudio_access_token=erniebot.access_token)
text = "This is a test document."
query_result = embeddings.embed_query(text)
print(len(query_result))
384
texts = ["doc1", "doc2"]
docs_result = embeddings.embed_documents(texts)
print(len(docs_result))
for res in docs_result:
print(len(res))
2
384
384
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。