AI大模型探索之路-实战篇:智能化IT领域搜索引擎之知乎网站数据获取(流程优化)

系列篇章💥

No.文章
1AI大模型探索之路-实战篇:智能化IT领域搜索引擎的构建与初步实践
2AI大模型探索之路-实战篇:智能化IT领域搜索引擎之GLM-4大模型技术的实践探索
3AI大模型探索之路-实战篇:智能化IT领域搜索引擎之知乎网站数据获取(初步实践)
4AI大模型探索之路-实战篇:智能化IT领域搜索引擎之知乎网站数据获取(函数封装)
5AI大模型探索之路-实战篇:智能化IT领域搜索引擎之知乎网站数据获取(流程优化)
6AI大模型探索之路-实战篇:智能化IT领域搜索引擎之github网站在线搜索
7AI大模型探索之路-实战篇:智能化IT领域搜索引擎之HuggingFace网站在线搜索

目录

  • 系列篇章💥
  • 一、前言
  • 二、总体概览
  • 三、流程优化
    • 1、文件名优化
    • 2、重新改造搜索服务
    • 3、构建判别模型
    • 4、搜索词优化
    • 5、外部函数流程优化
  • 四、全流程代码总结
    • 1、大模型客户端创建
    • 2、google搜索函数
    • 3、创建文件名称函数
    • 4、知乎内容查询函数
    • 5、大模型判断函数
    • 6、关键词获取函数
    • 7、问题答案获取函数
    • 8、funcation calling函数信息生成器
    • 9、大模型调用函数
    • 10、最外层的结果查询函数
  • 结语


一、前言

在上一篇文章中,我们对智能搜索中涉及的核心函数进行了精心的封装,为智能化IT领域搜索引擎的实现奠定了坚实基础。本文将致力于智能搜索流程中相关函数和工具的进一步优化与整理,旨在提升整个搜索引擎的效率和用户体验。

二、总体概览

本章将重点关注智能搜索流程的优化,通过简化函数调用流程、消除冗余代码、优化算法效率等手段,进一步提升搜索引擎的性能。同时,我们将对使用的工具方法进行改造升级,确保它们能够更好地支持当前的搜索功能。

三、流程优化

在流程优化环节,我们将对数据获取、处理、索引和搜索等关键环节进行细致入微的调整。通过采用更高效的数据结构、更先进的算法和更合理的系统架构,我们希望能够在保证搜索准确性的前提下,大幅度提高搜索速度,降低系统资源消耗。

1、文件名优化

文件名里有特殊字符的,在创建文件的时候会创建失败

def windows_create_name(s, max_length=255):"""将字符串转化为符合Windows文件/文件夹命名规范的名称。参数:- s (str): 输入的字符串。- max_length (int): 输出字符串的最大长度,默认为255。返回:- str: 一个可以安全用作Windows文件/文件夹名称的字符串。"""# Windows文件/文件夹名称中不允许的字符列表forbidden_chars = ['<', '>', ':', '"', '/', '\\', '|', '?', '*']# 使用下划线替换不允许的字符for char in forbidden_chars:s = s.replace(char, '_')# 删除尾部的空格或点s = s.rstrip(' .')# 检查是否存在以下不允许被用于文档名称的关键词,如果有的话则替换为下划线reserved_names = ["CON", "PRN", "AUX", "NUL", "COM1", "COM2", "COM3", "COM4", "COM5", "COM6", "COM7", "COM8", "COM9", "LPT1", "LPT2", "LPT3", "LPT4", "LPT5", "LPT6", "LPT7", "LPT8", "LPT9"]if s.upper() in reserved_names:s += '_'# 如果字符串过长,进行截断if len(s) > max_length:s = s[:max_length]return s

文件名测试

# 测试
input_str = "这是一个包含不允许的字符,如 <, >, :, \, /, |, ?, * 等的很长的字符串..."
print(windows_create_name(input_str))

输出:

这是一个包含不允许的字符,如 _, _, _, _, _, _, _, _ 等的很长的字符串

2、重新改造搜索服务

def get_search_text(q, url):cookie = "q_c1=3c10baf5bd084b3cbfe7eece648ba243|1704976541000|1704976541000; _zap=086350b3-1588-49c4-9d6d-de88f3faae03; d_c0=AGCYfYvO_RePTvjfB1kZwPLeke_N5AM6nwo=|1704949678; _xsrf=qR1FJHlZ9dvYhhoj4SUj43SAIBUwPOqm; __snaker__id=wNWnamiJKBI0kzkI; q_c1=d44e397edb6740859a7d2a0d4155bfab|1706509753000|1706509753000; Hm_lvt_98beee57fd2ef70ccdd5ca52b9740c49=1706509695,1706589529,1706765465,1708650963; z_c0=2|1:0|10:1713167971|4:z_c0|80:MS4xOGRHQVNnQUFBQUFtQUFBQVlBSlZUYjZqOTJaLXVDSjdRSmJKMHgyVEhxTE13UGN1TUJBdHZnPT0=|15b2c2ece393ac4ea374d9b36cde5af7304f8ee7632e060fe6835bfadb5e4132; KLBRSID=9d75f80756f65c61b0a50d80b4ca9b13|1713170212|1713167958"user_agent = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36"title = Nonecode_ = Falseheaders = {'authority': 'www.zhihu.com','accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7','accept-language': 'zh-CN,zh;q=0.9,en;q=0.8','cache-control': 'max-age=0','cookie': cookie,'upgrade-insecure-requests': '1','user-agent':user_agent,}# 普通问答地址if 'zhihu.com/question' in url:res = requests.get(url, headers=headers).textres_xpath = etree.HTML(res)title = res_xpath.xpath('//div/div[1]/div/h1/text()')[0]text_d = res_xpath.xpath('//div/div/div/div[2]/div/div[2]/div/div/div[2]/span[1]/div/div/span/p/text()')# 专栏地址elif 'zhuanlan' in url:headers['authority'] = 'zhaunlan.zhihu.com'res = requests.get(url, headers=headers).textres_xpath = etree.HTML(res)title = res_xpath.xpath('//div[1]/div/main/div/article/header/h1/text()')[0]text_d = res_xpath.xpath('//div/main/div/article/div[1]/div/div/div/p/text()')code_ = res_xpath.xpath('//div/main/div/article/div[1]/div/div/div//pre/code/text()')  # 特定回答的问答网址elif 'answer' in url:res = requests.get(url, headers=headers).textres_xpath = etree.HTML(res)title = res_xpath.xpath('//div/div[1]/div/h1/text()')[0]text_d = res_xpath.xpath('//div[1]/div/div[3]/div/div/div/div[2]/span[1]/div/div/span/p/text()')if title == None:return Noneelse:title = windows_create_name(title)# 创建问题答案正文text = ''for t in text_d:txt = str(t).replace('\n', ' ')text += txt# 如果有code,则将code追加到正文的追后面if code_:for c in code_:co = str(c).replace('\n', ' ')    text += coencoding = tiktoken.encoding_for_model("gpt-3.5-turbo")     json_data = [{"link": url,"title": title,"content": text,"tokens": len(encoding.encode(text))}]with open('./auto_search/%s/%s.json' % (q, title), 'w') as f:json.dump(json_data, f)return title

3、构建判别模型

为了让大模型调用流程更稳定,创建一个判别模型

import random
import stringdef generate_random_key(length=30):return ''.join(random.choice(string.ascii_letters + string.digits) for _ in range(length))

定义模型判断函数

def identify_model(q):# 创建密钥sk = generate_random_key()# 调用模型进行判别response = client.chat.completions.create(model="glm-4",messages=[{"role": "system", "content": "你是一个用户问题判断器,专门用于判别你是否知道用户当前问题的答案。\如果不知道,请回答“%s”,若知道,请正常回答" % sk},{"role": "user", "content": "请问,GPT-3.5微调总共分为几步?"},{"role": "assistant", "content": "%s" % sk},{"role": "user", "content": q}])res = response.choices[0].message.contentif sk in res or '对不起' in res or '抱歉' in res or '超出知识库' in res:return(True)else:return(res)

判断函数测试(询问大模型知识库知道的问题)

q = '请问什么是机器学习?'
print(identify_model(q))

输出:

机器学习是人工智能(AI)的一个分支,它赋予计算机从数据中学习的能力,使其能够通过经验改进处理任务的能力。机器学习算法利用统计学方法,让计算机系统在不需要进行显式编程的情况下,通过识别数据中的模式和特征来自动改进其性能。它广泛应用于各种领域,包括语音识别、图像处理、医学诊断、推荐系统等。机器学习主要包括监督学习、非监督学习、半监督学习和强化学习等几种方法。

判断函数测试(询问大模型知识库不知道的问题)

q = '介绍一下北京今天的天气'
print(identify_model(q))  

输出:

True

判断函数测试

q = '介绍一下DB-GPT项目?'
print(identify_model(q))

输出:

DB-GPT是一个开源项目,旨在通过结合大型语言模型(LLMs)和数据库技术,实现数据处理的自动化和优化。这个项目的核心是利用本地部署的大模型来与数据和环境进行交互,以此保护数据隐私和安全。DB-GPT支持在独立私有环境中部署,可以根据业务需求进行模块化部署,确保大模型的能力在私域内是绝对私有、安全和可控的。

该项目主要具有以下特点:

  1. 数据安全和隐私保护:通过本地化部署,避免了数据泄露的风险,确保用户数据的安全和隐私。

  2. 全流程自动化:整合了数据摄取、结构化和访问等多个流程,通过增强型大型语言模型来优化这些流程。

  3. 多模型框架:基于RAG框架设计,采用了多源RAG、自适应上下文学习等技术,提供了面向服务的多模型框架。

  4. 知识库构建与处理:原生支持知识库的构建和处理,通过langchain提供私域知识库问答能力。

  5. 插件模式:支持Auto-GPT等插件,提高了与数据交互的效率。

  6. 文本转SQL细化调整:包含文本转SQL任务的语言模型,能够更好地理解和处理自然语言查询。

  7. 多源知识整合:能够整合多源知识库,支持双语查询和生成数据分析。

DB-GPT的架构包括多个关键模块,例如用于知识构建、知识检索、自适应交互式编程和响应生成的模块,这些模块协同工作,以提高性能和效率。

项目的代码在GitHub上开源,地址是:https://github.com/eosphoros-ai/DB-GPT。该项目鼓励社区参与和贡献,共同推动数据库与大型语言模型结合的技术发展。

4、搜索词优化

用户提出的问题并不一定是最适合在知乎上进行搜索的关键词,例如用户提问“我想要知道“GPT-3.5微调总共需要几步”,此时应该将其转化为更加准确凝练的关键词并输入到知乎上进行搜索,方可提高搜索结果准确性。这里我们也完全可以让大模型自主将用户提的问题转化为适合在知乎上进行搜索的搜索关键词。当然,为达此目的,我们需要首先测试大模型是否知道知乎,以及大模型是否知道如何设计搜索关键词:
1)测试大模型是否知道知乎

response = client.chat.completions.create(model="glm-4",messages=[{"role": "user", "content": "你知道什么是知乎么?"}])
response.choices[0].message.content

输出:

'当然知道。知乎是中国领先的知识分享和社交平台,以问答的形式构建了一个信息分享、经验交流、意见互动的在线社区。它由北京智者天下科技有限公司运营,成立于2011年1月26日,其名称寓意在文言文中“知道吗”。\n\n知乎的目标是构建一个高质量的问答社区,让用户可以找到解决问题的答案,同时也能分享自己的知识与见解。随着时间的推移,知乎逐渐发展成为一个综合性内容平台,不仅提供问答服务,还涵盖了图文、音频、视频等多种内容形式。\n\n用户可以在知乎上提出问题,其他用户则可以回答问题或者对已有的回答进行评论。知乎的社区氛围以认真、专业和友善著称,吸引了大量专业人士和领域专家参与讨论。\n\n根据提供的信息,知乎在2019年完成了F轮融资,并推出了包括“盐选会员”在内的多项服务。到了2024年,知乎进一步拓展了其业务范围,不仅在社区建设上持续发力,还推出了结合AI技术的功能,如“发现·AI搜索”,以及“海盐计划6.0:航海家”和“灯塔计划”等项目,旨在通过技术赋能,提升用户体验,并推动平台持续进化。\n\n截至2020年12月,知乎拥有超过4400万条问题和2.4亿条回答,月活跃付费用户数超过250万,显示了其强大的用户基础和商业潜力。知乎不仅是一个问答社区,更是一个内容创作和知识分享的重要平台。'

2)咨询大模型设计关键词有什么方法

response = client.chat.completions.create(model="glm-4",messages=[{"role": "user", "content": "我如果想在知乎上搜索一些问题的答案,在设计搜索关键词方面,有什么技巧么?"}])
response.choices[0].message.content

输出:

'在设计搜索关键词以便在知乎上找到满意的问题答案时,以下是一些有用的技巧:\n\n1. **明确搜索意图**:\n   - 在开始搜索前,明确你想要解决的问题或者你感兴趣的话题。\n   - 确定你的搜索目标是寻找具体信息、教程、观点对比还是案例分析。\n\n2. **选择准确的关键词**:\n   - 选择与问题主题密切相关的关键词。\n   - 使用专业术语或行话,如果适用,以获取更精准的结果。\n   - 考虑使用同义词或近义词,以扩大搜索范围。\n\n3. **组合关键词**:\n   - 使用组合关键词来提高搜索的针对性。例如,如果你的问题是关于“数据分析工具”,可以组合成“数据分析工具比较”、“数据分析软件推荐”等。\n   - 尝试不同的组合方式,如“最佳”、“如何”、“教程”、“区别”等,以找到不同角度的答案。\n\n4. **利用长尾关键词**:\n   - 长尾关键词通常更具体,竞争也较小,可以帮助你找到更精确的信息。例如,“Python数据分析入门教程”就比单独的“Python”更具体。\n\n5. **避免过度堆砌关键词**:\n   - 过度堆砌关键词可能导致搜索结果不准确,降低搜索效率。\n\n6. **利用知乎的搜索提示**:\n   - 知乎的搜索栏通常会有相关搜索提示,可以参考这些提示来调整和优化你的关键词。\n\n7. **注意关键词的顺序**:\n   - 有时关键词的顺序也会影响搜索结果,尝试不同的顺序来获得更准确的搜索结果。\n\n8. **检查拼写和语法**:\n   - 确保关键词的拼写和语法正确,以免影响搜索效果。\n\n9. **使用高级搜索选项**:\n   - 如果知乎支持高级搜索,利用这些功能,如时间筛选、用户筛选等,来进一步优化搜索结果。\n\n通过上述技巧,你可以设计出更有效的搜索关键词,提高在知乎上找到高质量答案的几率。'

3)咨询大模型怎么设计关键词

response = client.chat.completions.create(model="glm-4",messages=[{"role": "user", "content": "例如,我想要知道“GPT-3.5微调总共需要几步”,\现在围绕这个问题在知乎上进行搜索,应该怎样设计这个问题的搜索关键词呢?"}])
response.choices[0].message.content

输出:

'若要在知乎上搜索关于“GPT-3.5微调总共需要几步”的信息,可以设计以下关键词进行搜索:\n\n1. GPT-3.5 微调流程\n2. GPT-3.5定制步骤\n3. GPT-3.5模型训练几步走\n4. GPT-3.5 Turbo 微调指南\n5. GPT-3.5自定义模型步骤\n6. GPT-3.5训练数据生成与微调流程\n7. GPT-3.5 RAG混合方法步骤\n\n以下是一些可能的搜索短语:\n\n- “GPT-3.5微调需要哪些步骤?”\n- “如何对GPT-3.5进行定制训练?”\n- “GPT-3.5从数据生成到微调的流程介绍”\n- “OpenAI GPT-3.5微调流程详解”\n- “GPT-3.5 Turbo训练与微调步骤”\n\n组合这些关键词和短语,可以更准确地找到关于GPT-3.5微调步骤的相关讨论和答案。在搜索时,也可以根据需要添加一些限定词,比如“2023”,“最新指南”等,以获取最新的信息。'

4)让大模型帮忙提取问题关键词

response = client.chat.completions.create(model="glm-4",messages=[{"role": "system", "content": "你专门负责将用户的问题转化为知乎网站搜索关键词,只返回一个你认为最合适的搜索关键词即可"},{"role": "user", "content": "请问,GPT-3.5微调总共分为几步?"},{"role": "assistant", "content": "GPT-3.5微调流程"},{"role": "user", "content": "请问ChatGPT企业版都有哪些功能?"}])
response.choices[0].message.content

5)封装关键词设计的函数

def convert_keyword(q):"""将用户输入的问题转化为适合在知乎上进行搜索的关键词"""response = client.chat.completions.create(model="glm-4",messages=[{"role": "system", "content": "你专门负责将用户的问题转化为知乎网站搜索关键词,只返回一个你认为最合适的搜索关键词即可"},{"role": "user", "content": "请问,GPT-3.5微调总共分为几步?"},{"role": "assistant", "content": "GPT-3.5微调流程"},{"role": "user", "content": q}])q = response.choices[0].message.contentreturn q

6)基于关键词设计函数,智能助手函数

def get_answer(q):"""智能助手函数,当你无法回答某个问题时,调用该函数,能够获得答案:param q: 必选参数,询问的问题,字符串类型对象:return:某问题的答案,以字符串形式呈现"""# 调用转化函数,将用户的问题转化为更适合在知乎上进行搜索的关键词q = convert_keyword(q)# 默认搜索返回10个答案print('正在接入谷歌搜索,查找和问题相关的答案...')results = google_search(query=q, num_results=2, site_url='https://zhihu.com/')# 创建对应问题的子文件夹folder_path = './auto_search/%s' % qif not os.path.exists(folder_path):os.makedirs(folder_path)# 单独提取links放在一个list中print('正在读取搜索的到的相关答案...')num_tokens = 0content = ''for item in results:url = item['link']title = get_search_text(q, url)with open('./auto_search/%s/%s.json' % (q, title), 'r') as f:jd = json.load(f)num_tokens += jd[0]['tokens']if num_tokens <= 12000:content += jd[0]['content']else:breakprint('正在进行最后的整理...')return(content)

5、外部函数流程优化

而既然是依据“密钥”来判断是否调用搜索功能,那么该外部函数的调用就不能再使用此前定义的auto function calling功能了,而是需要我们手动来调用这个外部函数(即接收到密钥时一定要调用外部函数)

functions_list=[get_answer]
tools = auto_functions(functions_list)
tools

在这里插入图片描述

1)外部函数调用测试

response = client.chat.completions.create(model="glm-4",messages=[{"role": "user", "content": "今天的北京天气如何?"},],tools=tools,tool_choice={"type": "function", "function": {"name": "get_answer"}},  )
response.choices[0].message

在这里插入图片描述

2)优化前的大模型调用

def run_conversation(messages, functions_list=None, model="glm-4", function_call="auto"):"""能够自动执行外部函数调用的对话模型:param messages: 必要参数,字典类型,输入到Chat模型的messages参数对象:param functions_list: 可选参数,默认为None,可以设置为包含全部外部函数的列表对象:param model: Chat模型,可选参数,默认模型为glm-4:return:Chat模型输出结果"""# 如果没有外部函数库,则执行普通的对话任务if functions_list == None:response = client.chat.completions.create(model=model,messages=messages,)response_message = response.choices[0].messagefinal_response = response_message.content# 若存在外部函数库,则需要灵活选取外部函数并进行回答else:# 创建functions对象tools = auto_functions(functions_list)# 创建外部函数库字典available_functions = {func.__name__: func for func in functions_list}# 第一次调用大模型response = client.chat.completions.create(model=model,messages=messages,tools=tools,tool_choice=function_call, )response_message = response.choices[0].messagetool_calls = response_message.tool_callsif tool_calls:#messages.append(response_message)messages.append(response.choices[0].message.model_dump())for tool_call in tool_calls:function_name = tool_call.function.namefunction_to_call = available_functions[function_name]function_args = json.loads(tool_call.function.arguments)## 真正执行外部函数的就是这儿的代码function_response = function_to_call(**function_args)messages.append({"role": "tool","content": function_response,"tool_call_id": tool_call.id,}) ## 第二次调用模型second_response = client.chat.completions.create(model=model,messages=messages,tools=tools) # 获取最终结果print(second_response.choices[0].message)final_response = second_response.choices[0].message.contentelse:final_response = response_message.contentreturn final_response

3)优化后的智能机器人逻辑编写

def auto_search_answer(q):# 调用判别模型res = identify_model(q)if res == True:messages = [{"role": "user", "content": q}]res =run_conversation(messages=messages, functions_list=[get_answer], model="glm-4", function_call={"type": "function", "function": {"name": "get_answer"}})return(res)
auto_search_answer("北京2024年5月1日的天气如何?")

在这里插入图片描述

auto_search_answer("什么是大模型?")

输出:

'大模型指的是参数规模极大、计算能力极强、能够处理非常复杂任务的人工智能模型。通常这些模型的参数量达到百亿、千亿甚至更多,例如GPT-3、天工3.0等。大模型具有卓越的理解能力、生成能力和泛化能力,能够应用于多种场景,如图像识别、自然语言处理、音乐生成等,为人工智能在各个领域的应用提供了强大的支持。随着算力的提升和算法的发展,大模型在推动人工智能技术进步方面发挥着越来越重要的作用。'

四、全流程代码总结

对整个智能搜索的代码进行全面的梳理和总结,为后续的其他技术平台的搜索提供清晰的指导。

1、大模型客户端创建

import os
import openai
from openai import OpenAI
import glob
import shutilimport numpy as np
import pandas as pdimport json
import io
import inspect
import requests
import re
import random
import stringfrom googleapiclient.discovery import build
from google.oauth2.credentials import Credentials
from google_auth_oauthlib.flow import InstalledAppFlow
import base64from bs4 import BeautifulSoup
import dateutil.parser as parser
import tiktoken
from lxml import etree## 初始化客户端
api_key = os.getenv("ZHIPUAI_API_KEY")from zhipuai import ZhipuAI
client = ZhipuAI(api_key=api_key)

2、google搜索函数

def google_search(query, num_results=10, site_url=None):api_key = os.getenv("GOOGLE_SEARCH_API_KEY")cse_id = os.getenv("CSE_ID")url = "https://www.googleapis.com/customsearch/v1"# API 请求参数if site_url == None:params = {'q': query,          'key': api_key,      'cx': cse_id,        'num': num_results   }else:params = {'q': query,         'key': api_key,      'cx': cse_id,        'num': num_results,  'siteSearch': site_url}# 发送请求response = requests.get(url, params=params)response.raise_for_status()# 解析响应search_results = response.json().get('items', [])# 提取所需信息results = [{'title': item['title'],'link': item['link'],'snippet': item['snippet']} for item in search_results]return results

3、创建文件名称函数

def windows_create_name(s, max_length=255):"""将字符串转化为符合Windows文件/文件夹命名规范的名称。参数:- s (str): 输入的字符串。- max_length (int): 输出字符串的最大长度,默认为255。返回:- str: 一个可以安全用作Windows文件/文件夹名称的字符串。"""# Windows文件/文件夹名称中不允许的字符列表forbidden_chars = ['<', '>', ':', '"', '/', '\\', '|', '?', '*']# 使用下划线替换不允许的字符for char in forbidden_chars:s = s.replace(char, '_')# 删除尾部的空格或点s = s.rstrip(' .')# 检查是否存在以下不允许被用于文档名称的关键词,如果有的话则替换为下划线reserved_names = ["CON", "PRN", "AUX", "NUL", "COM1", "COM2", "COM3", "COM4", "COM5", "COM6", "COM7", "COM8", "COM9", "LPT1", "LPT2", "LPT3", "LPT4", "LPT5", "LPT6", "LPT7", "LPT8", "LPT9"]if s.upper() in reserved_names:s += '_'# 如果字符串过长,进行截断if len(s) > max_length:s = s[:max_length]return s

4、知乎内容查询函数

def get_search_text(q, url):cookie = "q_c1=3c10baf5bd084b3cbfe7eece648ba243|1704976541000|1704976541000; _zap=086350b3-1588-49c4-9d6d-de88f3faae03; d_c0=AGCYfYvO_RePTvjfB1kZwPLeke_N5AM6nwo=|1704949678; _xsrf=qR1FJHlZ9dvYhhoj4SUj43SAIBUwPOqm; __snaker__id=wNWnamiJKBI0kzkI; q_c1=d44e397edb6740859a7d2a0d4155bfab|1706509753000|1706509753000; Hm_lvt_98beee57fd2ef70ccdd5ca52b9740c49=1706509695,1706589529,1706765465,1708650963; z_c0=2|1:0|10:1713167971|4:z_c0|80:MS4xOGRHQVNnQUFBQUFtQUFBQVlBSlZUYjZqOTJaLXVDSjdRSmJKMHgyVEhxTE13UGN1TUJBdHZnPT0=|15b2c2ece393ac4ea374d9b36cde5af7304f8ee7632e060fe6835bfadb5e4132; KLBRSID=9d75f80756f65c61b0a50d80b4ca9b13|1713170212|1713167958"user_agent = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36"  code_ = Falseheaders = {'authority': 'www.zhihu.com','accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7','accept-language': 'zh-CN,zh;q=0.9,en;q=0.8','cache-control': 'max-age=0','cookie': cookie,'upgrade-insecure-requests': '1','user-agent':user_agent,}# 普通问答地址if 'zhihu.com/question' in url:res = requests.get(url, headers=headers).textres_xpath = etree.HTML(res)title = res_xpath.xpath('//div/div[1]/div/h1/text()')[0]text_d = res_xpath.xpath('//*[@id="root"]/div/main/div/div/div[3]/div[1]/div/div[2]/div/div/div/div[2]/span[1]/div/div/span/p/text()')# 专栏地址elif 'zhuanlan' in url:headers['authority'] = 'zhaunlan.zhihu.com'res = requests.get(url, headers=headers).textres_xpath = etree.HTML(res)title = res_xpath.xpath('//div[1]/div/main/div/article/header/h1/text()')[0]text_d = res_xpath.xpath('//div/main/div/article/div[1]/div/div/div/p/text()')code_ = res_xpath.xpath('//div/main/div/article/div[1]/div/div/div//pre/code/text()')  # 特定回答的问答网址elif 'answer' in url:res = requests.get(url, headers=headers).textres_xpath = etree.HTML(res)title = res_xpath.xpath('//div/div[1]/div/h1/text()')[0]text_d = res_xpath.xpath('//div[1]/div/div[3]/div/div/div/div[2]/span[1]/div/div/span/p/text()')# 创建问题答案正文text = ''for t in text_d:txt = str(t).replace('\n', ' ')text += txt# 如果有code,则将code追加到正文的追后面if code_:for c in code_:co = str(c).replace('\n', ' ')    text += coencoding = tiktoken.encoding_for_model("gpt-3.5-turbo")     json_data = [{"link": url,"title": title,"content": text,"tokens": len(encoding.encode(text))}]with open('./auto_search/%s/%s.json' % (q, title), 'w') as f:json.dump(json_data, f)return title

5、大模型判断函数

import random
import stringdef generate_random_key(length=30):return ''.join(random.choice(string.ascii_letters + string.digits) for _ in range(length))def identify_model(q):# 创建密钥sk = generate_random_key()# 调用模型进行判别response = client.chat.completions.create(model="glm-4",messages=[{"role": "system", "content": "你是一个用户问题判断器,专门用于判别你是否知道用户当前问题的答案。\如果不知道,请回答“%s”,若知道,请正常回答" % sk},{"role": "user", "content": "请问,GPT-3.5微调总共分为几步?"},{"role": "assistant", "content": "%s" % sk},{"role": "user", "content": q}])res = response.choices[0].message.contentif sk in res or '对不起' in res or '抱歉' in res or '超出知识库' in res:return(True)else:return(res)

6、关键词获取函数

def convert_keyword(q):"""将用户输入的问题转化为适合在知乎上进行搜索的关键词"""response = client.chat.completions.create(model="glm-4",messages=[{"role": "system", "content": "你专门负责将用户的问题转化为知乎网站搜索关键词,只返回一个你认为最合适的搜索关键词即可"},{"role": "user", "content": "请问,GPT-3.5微调总共分为几步?"},{"role": "assistant", "content": "GPT-3.5微调流程"},{"role": "user", "content": q}])q = response.choices[0].message.contentreturn q

7、问题答案获取函数

def get_answer(q):"""智能助手函数,当你无法回答某个问题时,调用该函数,能够获得答案:param q: 必选参数,询问的问题,字符串类型对象:return:某问题的答案,以字符串形式呈现"""# 调用转化函数,将用户的问题转化为更适合在知乎上进行搜索的关键词q = convert_keyword(q)# 默认搜索返回10个答案print('正在接入谷歌搜索,查找和问题相关的答案...')results = google_search(query=q, num_results=2, site_url='https://zhihu.com/')# 创建对应问题的子文件夹folder_path = './auto_search/%s' % qif not os.path.exists(folder_path):os.makedirs(folder_path)# 单独提取links放在一个list中print('正在读取搜索的到的相关答案...')num_tokens = 0content = ''for item in results:url = item['link']title = get_search_text(q, url)with open('./auto_search/%s/%s.json' % (q, title), 'r') as f:jd = json.load(f)num_tokens += jd[0]['tokens']if num_tokens <= 12000:content += jd[0]['content']else:breakprint('正在进行最后的整理...')return(content)

8、funcation calling函数信息生成器

def auto_functions(functions_list):"""Chat模型的functions参数编写函数:param functions_list: 包含一个或者多个函数对象的列表;:return:满足Chat模型functions参数要求的functions对象"""def functions_generate(functions_list):# 创建空列表,用于保存每个函数的描述字典functions = []# 对每个外部函数进行循环for function in functions_list:# 读取函数对象的函数说明function_description = inspect.getdoc(function)# 读取函数的函数名字符串function_name = function.__name__system_prompt = '以下是某的函数说明:%s,输出结果必须是一个JSON格式的字典,只输出这个字典即可,前后不需要任何前后修饰或说明的语句' % function_descriptionuser_prompt = '根据这个函数的函数说明,请帮我创建一个JSON格式的字典,这个字典有如下5点要求:\1.字典总共有三个键值对;\2.第一个键值对的Key是字符串name,value是该函数的名字:%s,也是字符串;\3.第二个键值对的Key是字符串description,value是该函数的函数的功能说明,也是字符串;\4.第三个键值对的Key是字符串parameters,value是一个JSON Schema对象,用于说明该函数的参数输入规范。\5.输出结果必须是一个JSON格式的字典,只输出这个字典即可,前后不需要任何前后修饰或说明的语句' % function_nameresponse = client.chat.completions.create(model="glm-4",messages=[{"role": "system", "content": system_prompt},{"role": "user", "content": user_prompt}])json_str=response.choices[0].message.content.replace("```json","").replace("```","")json_function_description=json.loads(json_str)json_str={"type": "function","function":json_function_description}functions.append(json_str)return functions## 最大可以尝试4次max_attempts = 4attempts = 0while attempts < max_attempts:try:functions = functions_generate(functions_list)break  # 如果代码成功执行,跳出循环except Exception as e:attempts += 1  # 增加尝试次数print("发生错误:", e)if attempts == max_attempts:print("已达到最大尝试次数,程序终止。")raise  # 重新引发最后一个异常else:print("正在重新运行...")return functions

9、大模型调用函数

def run_conversation(messages, functions_list=None, model="glm-4", function_call="auto"):"""能够自动执行外部函数调用的对话模型:param messages: 必要参数,字典类型,输入到Chat模型的messages参数对象:param functions_list: 可选参数,默认为None,可以设置为包含全部外部函数的列表对象:param model: Chat模型,可选参数,默认模型为glm-4:return:Chat模型输出结果"""# 如果没有外部函数库,则执行普通的对话任务if functions_list == None:response = client.chat.completions.create(model=model,messages=messages,)response_message = response.choices[0].messagefinal_response = response_message.content# 若存在外部函数库,则需要灵活选取外部函数并进行回答else:# 创建functions对象tools = auto_functions(functions_list)# 创建外部函数库字典available_functions = {func.__name__: func for func in functions_list}# 第一次调用大模型response = client.chat.completions.create(model=model,messages=messages,tools=tools,tool_choice=function_call, )response_message = response.choices[0].messagetool_calls = response_message.tool_callsif tool_calls:#messages.append(response_message)messages.append(response.choices[0].message.model_dump())for tool_call in tool_calls:function_name = tool_call.function.namefunction_to_call = available_functions[function_name]function_args = json.loads(tool_call.function.arguments)## 真正执行外部函数的就是这儿的代码function_response = function_to_call(**function_args)messages.append({"role": "tool","content": function_response,"tool_call_id": tool_call.id,}) ## 第二次调用模型second_response = client.chat.completions.create(model=model,messages=messages,tools=tools) # 获取最终结果print(second_response.choices[0].message)final_response = second_response.choices[0].message.contentelse:final_response = response_message.contentreturn final_response

10、最外层的结果查询函数

def auto_search_answer(q):# 调用判别模型res = identify_model(q)if res == True:messages = [{"role": "user", "content": q}]res =run_conversation(messages=messages, functions_list=[get_answer], model="glm-4", function_call={"type": "function", "function": {"name": "get_answer"}})return(res)

结语

随着本章的结束,我们已经成功实现了知乎网站数据的智能搜索,并将其整合到了我们的智能化IT领域搜索引擎中。这一成果不仅提升了搜索引擎的数据覆盖范围和准确性,也为后续的开发工作奠定了坚实的基础。然而,我们仍需认识到,搜索引擎的优化和升级是一个持续不断的过程。因此,在接下来的工作中,下一篇章我们将完成Github网站搜索的接入。

在这里插入图片描述

🎯🔖更多专栏系列文章:AIGC-AI大模型探索之路

😎 作者介绍:我是寻道AI小兵,资深程序老猿,从业10年+、互联网系统架构师,目前专注于AIGC的探索。
📖 技术交流:建立有技术交流群,可以扫码👇 加入社群,500本各类编程书籍、AI教程、AI工具等你领取!
如果文章内容对您有所触动,别忘了点赞、⭐关注,收藏!加入我,让我们携手同行AI的探索之旅,一起开启智能时代的大门!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/bicheng/28148.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

linux笔记8--安装软件

文章目录 1. PMS和软件安装的介绍2. 安装、更新、卸载安装更新ubuntu20.04更新镜像源&#xff1a; 卸载 3. 其他发行版4. 安装第三方软件5. 推荐 1. PMS和软件安装的介绍 PMS(package management system的简称)&#xff1a;包管理系统 作用&#xff1a;方便用户进行软件安装(也…

【深度学习】解析Vision Transformer (ViT): 从基础到实现与训练

之前介绍&#xff1a; https://qq742971636.blog.csdn.net/article/details/132061304 文章目录 背景实现代码示例解释 训练数据准备模型定义训练和评估总结 Vision Transformer&#xff08;ViT&#xff09;是一种基于transformer架构的视觉模型&#xff0c;它最初是由谷歌研究…

blender bpy将顶点颜色转换为UV纹理vertex color to texture

一、关于环境 安装blender的bpy&#xff0c;不需要额外再安装blender软件。在python控制台中直接输入pip install bpy即可。 二、关于代码 本文所给出代码仅为参考&#xff0c;禁止转载和引用&#xff0c;仅供个人学习。 本文所给出的例子是https://download.csdn.net/downl…

BerkeleyDB练习

代码; #include <db.h> #include <stdio.h>int main() {DB *dbp;db_create(&dbp, NULL, 0);printf("Berkeley DB version: %s\n", db_version(NULL, NULL, NULL));dbp->close(dbp, 0);return 0; } 编译运行

4-异常-log4j配置日志滚动覆盖出现日志丢失问题

4-异常-log4j配置日志打印滚动覆盖出现日志丢失问题(附源码分析) 更多内容欢迎关注我&#xff08;持续更新中&#xff0c;欢迎Star✨&#xff09; Github&#xff1a;CodeZeng1998/Java-Developer-Work-Note 技术公众号&#xff1a;CodeZeng1998&#xff08;纯纯技术文&…

XGBoost预测及调参过程(+变量重要性)--血友病计数数据

所使用的数据是血友病数据&#xff0c;如有需要&#xff0c;可在主页资源处获取&#xff0c;数据信息如下&#xff1a; 读取数据及数据集区分 数据预处理及区分数据集代码如下&#xff08;详细预处理说明见上篇文章--随机森林&#xff09;&#xff1a; import pandas as pd im…

异常封装类统一后端响应的数据格式

异常封装类 如何统一后端响应的数据格式 1. 背景 后端作为数据的处理和响应&#xff0c;如何才能和前端配合好&#xff0c;能够高效的完成任务&#xff0c;其中一个比较重要的点就是后端返回的数据格式。 没有统一的响应格式&#xff1a; // 第一种&#xff1a; {"dat…

探索开源世界:2024年值得关注的热门开源项目推荐

文章目录 每日一句正能量前言GitCode成立背景如何使用GitCode如何把你现有的项目迁移至 GitCode&#xff1f;热门开源项目推荐actions-poetry - 管理 Python 依赖项的 GitLab CI/CD 工具项目概述技术分析应用场景特点项目地址 Spider - 网络爬虫框架项目简介技术分析应用场景项…

【RabbitMQ】异步消息及Rabbitmq安装

https://blog.csdn.net/weixin_73077810/article/details/133836287 https://www.bilibili.com/video/BV1mN4y1Z7t9/ 同步调用和异步调用 如果我们的业务需要实时得到服务提供方的响应&#xff0c;则应该选择同步通讯&#xff08;同步调用&#xff09;。 如果我们追求更高的效…

Jupyter Notebook简介

目录 1.概述 2.诞生背景 3.历史版本 4.安装 5.卸载 6.如何使用 7.菜单和菜单项 8.示例 9.未来展望 10.总结 1.概述 Jupyter Notebook是一种基于Web的交互式计算环境&#xff0c;主要用于数据分析、数据科学、机器学习以及探索性编程等领域。允许用户在单个文档中编写…

批量文本编辑神器:一键拆分每行内容,高效实现批量处理与保存,让文本编辑更高效快捷!

在信息化快速发展的今天&#xff0c;文本编辑已经成为我们工作、学习和生活中不可或缺的一部分。然而&#xff0c;面对大量的文本内容&#xff0c;如何高效地进行编辑和处理&#xff0c;成为了许多人面临的难题。今天&#xff0c;我要向大家介绍一款批量文本编辑神器&#xff0…

【C#】图形图像编程

实验目标和要求&#xff1a; 掌握C#图形绘制基本概念&#xff1b;掌握C#字体处理&#xff1b;能进行C#图形图像综合设计。 运行效果如下所示&#xff1a; 1.功能说明与核心代码 使用panel为画板&#xff0c;完成以下设计内容&#xff1a; 使用pen绘制基础图形&#xff1b;使…

【MYSQL】MYSQL操作库

1.数据库字符编码集/数据库校验集 当我们在数据库中保存数据时&#xff0c;需要存和取时候编码一致&#xff0c;比方说你用汉语保存的数据&#xff0c;当你读的时候为了避免乱码问题&#xff0c;也必须用汉语读&#xff0c;这就叫做数据库字符编码集一致。 当我们进行查找&…

C语言的结构体与联合体

引言 C语言提供了结构体和联合体两种聚合数据类型&#xff0c;使得程序员可以创建包括多个数据类型的复杂数据结构。结构体用于将不同类型的数据组合成一个单元&#xff0c;而联合体用于在同一存储空间中存储不同类型的数据。本篇文章将详细介绍C语言中的结构体和联合体&#x…

快消品经销商如何进行有效的团队激励?

很多经销商会面临员工工作不积极、吃大锅饭的现象&#xff0c;导致企业人力成本浪费严重&#xff0c;工作效率也得不到提升&#xff0c;因此经销商老板们必须进行一些绩效考核&#xff0c;然后开展一些有效的激励政策&#xff0c;这样通过提成激励来提高员工的积极性。 1、梳理…

探地雷达正演模拟,基于时域有限差分方法,四

突然发现第三章后半部分已经讲了使用接收记录成像的问题&#xff0c;所以这一章只讲解简单的数据分析。 &#xff08;均以宽角法数据为例子&#xff0c;剖面法数据处理方式都是相同的&#xff09;假设&#xff0c;我们现在已经获得了一个GPR记录&#xff0c;可以是常用的.sgy格…

有关排序的算法

目录 选择法排序 冒泡法排序 qsort排序&#xff08;快速排序&#xff09; qsort排序整型 qsort排序结构体类型 排序是我们日常生活中比较常见的问题&#xff0c;这里我们来说叨几个排序的算法。 比如有一个一维数组 arr[8] {2,5,3,1,7,6,4,8},我们想要把它排成升序&#…

StarNet实战:使用StarNet实现图像分类任务(一)

文章目录 摘要安装包安装timm 数据增强Cutout和MixupEMA项目结构计算mean和std生成数据集 摘要 https://arxiv.org/pdf/2403.19967 论文主要集中在介绍和分析一种新兴的学习范式——星操作&#xff08;Star Operation&#xff09;&#xff0c;这是一种通过元素级乘法融合不同子…

VS2022 使用C++访问 mariadb 数据库

首先,下载 MariaDB Connector/C++ 库 MariaDB Products & Tools Downloads | MariaDB 第二步,安装后 第三步,写代码 #include <iostream> #include <cstring> #include <memory> #include <windows.h>#include <mariadb/conncpp.hpp>…

使用 Python 进行测试(6)Fake it...

总结 如果我有: # my_life_work.py def transform(param):return param * 2def check(param):return "bad" not in paramdef calculate(param):return len(param)def main(param, option):if option:param transform(param)if not check(param):raise ValueError(…