简介
连雨不知春去,一晴方觉夏深。
小伙伴们好,我是微信公众号《小窗幽记机器学习》的小编:卖锅盔的小男孩。汇总下之前撰写的ChatGPT Prompt工程和应用系列文章:
- 04:ChatGPT Prompt编写指南
- 05:如何优化ChatGPT Prompt?
- 06:ChatGPT Prompt实践:文本摘要&推断&转换
- 07:ChatGPT Prompt实践:以智能客服邮件为例
- 08:ChatGPT Prompt实践:如何用ChatGPT构建点餐机器人?
- 09:基于ChatGPT构建智能客服系统(query分类&安全审核&防注入)
- 10:如何编写思维链Prompt?以智能客服为例
- 11:LangChain危矣?亲测ChatGPT函数调用功能:以天气问答为例
- 12:实测OpenAI函数调用功能:以数据库问答为例
- 13:如何链接多个Prompt处理复杂任务?以智能客服为例(附完整代码)
- 14:构建端到端智能客服(附完整代码)
紧接前文LangChain专题的预热文章:
今天这篇小作文是LangChain实践专题的第2篇,简单介绍LangChain的用途及如何利用LangChain将ChatGPT和搜索引擎(Google)结合起来,从而实现一个极简的联网版ChatGPT。此前,ChatGPT无法联网,虽然现在OpenAI已经为ChatGPT增加联网和插件功能,但是这些功能仅限于面向ChatGPT Plus用户。 对于非Plus用户,LangChain是一个不错的选择。此外,对于其他LLM模型,包括API接口和私有化部署的模型LangChain也都是支持的。简而言之,LangChain是一个用于开发LLM(大型语言模型)应用程序的框架,主要拥有2个能力:
- 将 LLM 模型与外部数据源进行连接
- 将 LLM 模型进行交互
下面用实例说明如何使用LangChain及其及如何基于LangChain将ChatGPT和搜索引擎(Google)结合起来,从而实现一个极简的联网ChatGPT。如需完整代码,请在微信公众号:《小窗幽记机器学习》上添加小编微信。
更多、更新文章欢迎关注微信公众号:小窗幽记机器学习。后续会持续整理模型加速、模型部署、模型压缩、LLM、AI艺术等系列专题,敬请关注。
环境和设置
由于本文使用的LLM是openai的ChatGPT
pip install openai
pip install langchain
pip install google-search-results
import os
os.environ["OPENAI_API_KEY"] = "你的api key"
os.environ['HTTP_PROXY'] = "如果需要的话,设置你的代理"
os.environ['HTTPS_PROXY'] = "如果需要的话,设置你的代理"
使用openai api
具体model列表可以参考openai官方的model清单https: //platform.openai.com/docs/models)和LangChain的说明
https: //python.langchain.com/en/latest/_modules/langchain/llms/openai.html。以下用gpt-3.5-turbo
(即ChatGPT)、text-davinci-003
进行测试。
text-davinci-003
# text-davinci-003
from langchain.llms import OpenAI
llm = OpenAI(model_name="text-davinci-003",max_tokens=512)
llm("某国企领导上班时间牵着女下属在成都逛街,请模仿鲁迅的风格嘲讽一下这件事")
输出结果如下:
'\n\n今天,这位某国企领导在成都逛街,把自己的女下属牵着手,他们比牛犊还要温馨。这实在是一件令人叹为观止的事情,可以说是绝无仅有。这位领导,可能觉得自己是一个模仿富人的乞丐,而他的女下属,把自己当成了一个他可以玩弄的玩具。可是,当他们在街头晃悠的时候,他们忘记了自己本该负责的工作,忘记了他们拥有的社会责任。他们不曾想到,自己的行为可能会引起公众的反感,也不曾想到,这样的行为会为国家带来恶劣的影响。看来,这位领导以及他的女下属,都需要给自己一个明确的提醒:上班时间,不要乱逛街!'
ChatGPT
from langchain.llms import OpenAI
llm = OpenAI(model_name="gpt-3.5-turbo",max_tokens=1024)
llm("某国企领导上班时间牵着女下属在成都逛街,请模仿鲁迅的风格嘲讽一下这件事")
输出结果如下:
'我根本无法想象一个国企领导居然可以如此肆无忌惮,公然牵着女下属在工作时间里闲逛成都市区的街头巷尾!这种行为实在是无耻至极,可谓是奇耻大辱,令人无法容忍!\n\n这位领导简直就是一个颠倒黑白、藐视法纪的恶棍,他不仅没有对自己的职责和权力有任何的敬畏之心,更是肆意妄为,放纵自己的私欲。这个女下属也是不知天地高低,居然肆无忌惮地跟着这个领导做出这种不当行为,实在是些许可悲可叹。\n\n这个领导的所作所为,更是公众道德的败坏,是对社会文明和政治伦理的亵渎。想必,正义之神不会放过这种肆意蹂躏公权的无耻之徒,他必将受到人心和法律的双重谴责!'
通过 google 搜索并返回答案
由于小编并不是openai的Plus用户,那么如果想要让ChatGPT联网,该如何操作呢?接下来我们试试让OpenAI API联网搜索,并返回答案。
这里需要借助 Serpapi 来进行实现,Serpapi 提供了 google 搜索的 api 接口。首先需要到 Serpapi官网上注册一个用户,并复制Serpapi给我们生成 api key,然后将api key设置到环境变量里面去。
import os
os.environ["SERPAPI_API_KEY"] = '你的api key'
微博今日热搜
import os
# os.environ["OPENAI_API_KEY"] = '你的api key'
os.environ["SERPAPI_API_KEY"] = 'XXXX'
from langchain.agents import load_tools
from langchain.agents import initialize_agent
from langchain.llms import OpenAI
from langchain.agents import AgentType
from langchain.agents import tool
from datetime import date
@tool
def time(text: str) -> str:
"""Returns todays date, use this for any \
questions related to knowing todays date. \
The input should always be an empty string, \
and this function will always return todays \
date - any date mathmatics should occur \
outside this function."""
return str(date.today())
# 加载 OpenAI 模型
llm = OpenAI(temperature=0,max_tokens=2048)
# 加载 serpapi 工具
tools = load_tools(["serpapi"])
# 工具加载后都需要初始化,verbose 参数为 True,会打印全部的执行详情
agent = initialize_agent(tools + [time], llm, agent=AgentType.ZERO_SHOT_REACT_DESCRIPTION, verbose=True)
# 运行 agent
agent.run("今天是几号? 今天微博的热搜话题有哪些?")
日志结果如下:
> Entering new chain...
I need to know the date and then search for the hot topics on Weibo
Action: time
Action Input: ""
Observation: 2023-07-04
Thought: I need to search for the hot topics on Weibo
Action: Search
Action Input: "Weibo hot topics"
Observation: https://s.weibo.com/top/summary?cate=realtimehot
Thought: I now know the final answer
Final Answer: 今天是2023年7月4日,微博的热搜话题可以在https://s.weibo.com/top/summary?cate=realtimehot查看。
> Finished chain.
最终输出结果:
'今天是2023年7月4日,微博的热搜话题可以在https://s.weibo.com/top/summary?cate=realtimehot查看。'
此外,可以根据返回的 URL 进一步对网页的内容进行爬取。后续会补充一篇小作文介绍如何对给定的URL做网页问答,感兴趣的小伙伴可以留意关注下。
搜索示例1: 以坤坤为例
model_name="gpt-3.5-turbo-16k"
llm = ChatOpenAI(model_name=model_name, temperature=0)
# 加载 serpapi 工具
tools = load_tools(["serpapi"])
# 工具加载后都需要初始化,verbose 参数为 True,会打印全部的执行详情
agent = initialize_agent(tools + [time], llm, agent=AgentType.ZERO_SHOT_REACT_DESCRIPTION, verbose=True)
# 运行 agent
agent.run("坤坤会去踩缝纫机吗?")
日志信息如下:
> Entering new chain...
I don't understand the question because it is in a language I am not familiar with.
Action: Search
Action Input: "坤坤会去踩缝纫机吗?"
Observation: 蔡徐坤进去踩缝纫机了吗. 凡凡进去踩缝纫机了我是不是可以取代他出道了#帅就.
Thought:I still don't understand the question because the search results are in a language I am not familiar with.
Action: Search
Action Input: "坤坤会去踩缝纫机吗? English translation"
Observation: English Translation of “坤” | The official Collins Simplified-English Dictionary online. Over 100000 English translations of Chinese words and phrases.
Thought:I still don't have enough information to answer the question.
Action: Search
Action Input: "坤坤 踩缝纫机"
Observation: 坤坤会不会进去踩缝纫机呢? 我觉得不会。毕竟不是每个女的都姓毒。 但狗仔能成群结队实名爆他,显而易见是想整死他。就看他怎么应对了。
Thought:I still don't have enough information to answer the question.
Action: Search
Action Input: "坤坤 踩缝纫机 事件"
Observation: UU_Frank:坤坤事件挺大啊,要进去踩缝纫机了[吃瓜群众] - 掘金.
Thought:I still don't have enough information to answer the question.
Action: Search
Action Input: "坤坤 踩缝纫机 事件 解释"
Observation: 不知道凡凡在里面踩缝纫机嘛#吴亦凡事件#皮皮搞笑. @A狗头 · 被造黄谣?大 ... 选秀天花板:坤坤实力超强,这首《PPAP》你打. 03:52. 6.4万. 选秀天花板:坤 ...
Thought:I still don't have enough information to answer the question.
Action: Search
Action Input: "坤坤 踩缝纫机 事件 最新消息"
Observation: 谣言不可信:被戏称蔡三分的蔡徐坤与c女士在KTV厕所内大战,时长1086秒。看得网友鼻血直流! 6.15最新料!网红程女士事件升级了!大量#不雅.
Thought:I still don't have enough information to answer the question.
Action: Search
Action Input: "坤坤 踩缝纫机 事件 最新消息 2021"
Observation: 蔡徐坤回应说,自己两年前处于单身状态,与C女士有过交往,双方之间的私事已经在2021年妥善解决,彼此也没有进一步纠葛。
Thought:I now know the final answer
Final Answer: I still don't have enough information to answer the question.
> Finished chain.
最终输出结果如下:
"I still don't have enough information to answer the question."
搜索示例2: 以凡凡为例
model_name="gpt-3.5-turbo-16k"
llm = ChatOpenAI(model_name=model_name, temperature=0)
# 加载 serpapi 工具
tools = load_tools(["serpapi"])
# 工具加载后都需要初始化,verbose 参数为 True,会打印全部的执行详情
agent = initialize_agent(tools, llm, agent=AgentType.ZERO_SHOT_REACT_DESCRIPTION, verbose=True)
# 运行 agent
agent.run("凡凡还有多久出狱?")
日志结果如下:
> Entering new chain...
I don't understand the language of the question. I should use a translation tool to understand it.
Action: Search
Action Input: "凡凡出狱时间"
Observation: 昔日顶流,一跃成为人人喊打的阶下囚,应了那句老话,报应迟早会来的,也许会迟到,但从未缺席。 而这个案子里的一些细节也让人愤怒。 经查明,吴亦凡在20年11月到12月这一个月内,就在自己住所先后将三名女性灌醉,强行与其发生了关系。
Thought:The search results seem to be about a specific person named "吴亦凡" and some criminal activities. It doesn't provide a clear answer to the question. I should try a different search query.
Action: Search
Action Input: "吴亦凡 出狱时间"
Observation: 因为吴亦凡被判处13年有期徒刑,理论上他的出狱时间应该是2034年7月30日,但实际上,他肯定也享有获得减刑的权利和条件,所以说他的出狱时间肯定要早于实际判刑时间,但要说他到底会提前多长时间出狱呢? 这个肯定无法提前获知,这要根据他狱中的表现,及负责他减刑的法院法官的认知和实践习惯。
Thought:The search results indicate that the release date for 吴亦凡 is theoretically July 30, 2034, but it is possible for him to be released earlier due to the possibility of parole or sentence reduction. However, the exact time of his release cannot be determined in advance and will depend on his behavior in prison and the discretion of the court judge responsible for his sentence reduction.
Final Answer: The exact release date for 吴亦凡 is uncertain and may be earlier than the theoretical date of July 30, 2034, depending on various factors.
> Finished chain.
最终输出结果如下:
'The exact release date for 吴亦凡 is uncertain and may be earlier than the theoretical date of July 30, 2034, depending on various factors.'
此外,搜索引擎的结果存在时效性,不同时间的返回结果可能不一样。
直接通过百度api
此外,本文也在LangChain中尝试使用serpapi 的百度API,但是发现效果并不理想。但是如果直接使用 serpapi 的百度API:https://serpapi.com/baidu-search-api,其实是可以符合预期的结果。示例如下:
from serpapi import BaiduSearch
params = {
"engine": "baidu",
"q": "吴亦凡还有多久出狱",
"api_key": "XXXX"
}
search = BaiduSearch(params)
results = search.get_dict()
print(results['answer_box'])
输出结果如下:
[{'position': 1, 'type': 'organic_result', 'title': '最快只需五年吴亦凡就能出狱', 'snippet': '更多\ue613', 'link': 'https://weibo.com/6919252154/MhheW57L2', 'source': '微博'}]
经过分析,有两方面的原因,其一,LangChain对中文支持不够友好;其二, LangChain 目前对于搜索返回结果的后处理不够完善,尚未能够综合多个返回结果提取出更准确的答案。
小结
本文简要介绍LangChain的用途,并以使用OpenAI API为例, 说明LangChain对于OpenAI API的兼容和使用。此外,还以LangChain结合谷歌搜索为例演示如何将LLM和网络搜索进行结合。从测试示例的日志可以看出,整体对中文支持尚不够友好,需要后续进一步完善。另一方面,LangChain对搜索引擎返回结果的后处理不够,需要进一步综合、兼容更多可能性,从而提取出更好准确的结果。