完整内容请看文末最后的推广群
基于大模型的竞赛智能客服机器人构建
摘要
随着国内学科和技能竞赛的增多,参赛者对竞赛相关信息的需求不断上升,但传统人工客服存在效率低、成本高、服务不稳定和用户体验差的问题。因此,设计一款智能客服机器人,利用人工智能技术为赛事提供实时、高效、精准的信息查询服务,成为了迫切的需求。该机器人需具备回答基础信息查询、进行统计分析查询以及处理开放性问题的能力,同时支持竞赛数据的实时更新,确保信息的时效性和准确性。
为了解决问题一,我们采用了自动化的文本提取和自然语言处理方法,首先通过PyPDF2提取PDF文件中的文本,然后利用OpenAI API解析文本,同时基于正则表达式提取出赛事的关键信息,如赛项名称、赛道、发布时间等,并将其保存为结构化的CSV文件。在处理过程中,我们面临了PDF格式不一致和信息提取的挑战,通过优化模型提示和文本清洗,确保了提取结果的准确性和一致性。
问题二的模型通过利用PDF文本提取、自然语言处理技术和Chromadb向量数据库构建了一个智能客服机器人,能够高效地从竞赛文档中提取并存储关键信息,进而实现用户查询的实时回答。该模型在处理标准化查询时表现出色,能够自动化提取竞赛信息并生成准确的回答。
问题三的模型是在问题二的基础上进行扩展,主要任务是处理新增和变更的竞赛PDF文档。该模型通过提取新增和更新的PDF文件中的文本信息,进行清洗、分块和嵌入生成后,将其更新到现有的知识库中,确保知识库包含最新的竞赛数据,使得智能客服系统能够实时响应用户查询并提供最新的竞赛信息。
最后通过前端搭建和后端接口调用, 构建竞赛智能客服机器人, 通过知识库构建、查询处理、响应生成以及系统的部署完成机器人的构建。
关键词:PyPDF2;OpenAI API;大模型;自然语言处理;PDF文本提取;向量数据库;嵌入表示(embedding); Chromadb数据库; 智能客服机器人
目录
基于大模型的竞赛智能客服机器人构建 1
摘要 1
一、 问题重述 3
1.1 问题背景 3
1.2 要解决的问题 3
二、 问题分析 5
2.1 任务一的分析 5
2.2 任务二、三的分析 6
三、 问题假设 8
四、 模型原理 9
4.1 关键词识别 9
4.2 中文文本分析 11
五、 模型建立与求解 11
5.1问题一建模与求解 11
5.2问题二、三建模与求解 18
5.3智能客服机器人系统构建 22
六、 模型评价与推广 26
6.1模型的评价 26
6.1.1模型缺点 26
6.1.2模型缺点 26
6.2 模型推广 27
七、 参考文献 29
附录【自行黏贴】 30
二、 问题分析
2.1任务一的分析
问题一要求我们从提供的18个竞赛规程PDF文档中提取出关键信息,并将其结构化保存为CSV格式。竞赛规程文档包含了赛事的详细信息,如赛事名称、赛道、发布时间、报名时间、主办单位和官网链接等,我们需要准确提取这些信息,并处理不同文档格式和内容的差异。为了解决这个问题,我们采用了自动化的数据提取方法,结合PDF文本提取和OpenAI的自然语言处理能力。
首先,我们利用PyPDF2库提取PDF文档中的文本。PDF文件的文本结构常常存在格式化问题,因此需要通过清洗和格式化来保证文本的连续性和可读性。接着,使用OpenAI API解析文本,提取出我们需要的信息。在这一过程中,我们构造了详细的提示(Prompt),确保模型能够理解并提取出赛事的关键信息,包括赛项名称、赛道、发布时间、报名时间、主办单位和官网链接等。OpenAI模型通过自然语言处理的强大能力,从文本中抽取出结构化的数据,并将其转化为JSON格式。
在处理过程中,我们面临了一些挑战,例如PDF文件中有时包含扫描图像或特殊字符,这些情况会影响文本的提取质量。此外,不同文档可能采用不同的表述方式,导致字段提取的准确性有所不同。为了应对这些问题,我们在模型提示中规定了详细的规则,并通过推测填补无法明确提取的信息(例如使用文档中出现的时间或组织单位的上下文信息)。在输出结果时,如果某些字段无法准确提取,我们会将其标记为空或进行补充说明,确保输出的格式一致。
最终,所有提取的信息被批量处理并保存为CSV格式,以便后续分析和使用。每个PDF文件的处理结果都包含文件名、赛项名称、赛道、发布时间、报名时间、主办单位和官网等字段。通过这种方法,我们能够高效、自动化地完成大量文档的数据提取工作,并确保结果的准确性和结构一致性。
2.2任务二、三的分析
问题二的目标是利用人工智能技术,结合提供的竞赛数据,设计并实现一个智能客服机器人,以便为用户提供实时、高效、精准的竞赛信息查询服务。为了完成这一任务,我们构建了一个基于自然语言处理和向量数据库的系统,来处理并回答竞赛相关问题。该系统的核心包括文本处理、知识库构建和信息检索三个主要部分。
模型的构建从PDF文档的处理开始,通过使用pdfminer.six库提取竞赛相关的文本信息。由于竞赛文档通常包含大量的竞赛规则、任务描述和赛事信息,因此必须对这些长文本进行预处理。我们采用了文本清洗技术,去除掉无用的字符、空格和HTML标签,以保证文本质量。之后,使用AutoTokenizer对文本进行分词,并将文本分割成若干个块,确保每个块的token数量不超过模型的处理限制。这一过程有效地处理了长文档中可能出现的token溢出问题,并保证了模型输入的有效性。
在完成PDF文档的文本提取和处理后,下一步是构建智能客服机器人的知识库。为了确保机器人能够高效地响应用户查询,我们使用了Chromadb数据库来存储处理后的竞赛信息。通过对每个文本块生成嵌入(embedding),使得每个块能够在向量空间中具有语义上的表示。我们使用了AsyncOpenAI生成嵌入表示,并通过Chromadb存储这些嵌入。知识库的构建是一个异步过程,通过批量处理PDF文档并将嵌入结果添加到数据库中,使得机器人能够从庞大的信息库中快速检索相关内容。
为了实现实时的竞赛信息查询,我们通过CompetitionAgent类实现了一个基于用户输入的查询响应机制。当用户输入问题时,系统会首先通过向量检索从知识库中找到相关上下文,并利用OpenAI的生成模型生成答案。这个过程是通过查询嵌入和生成嵌入的相似度来实现的。系统能够有效地提取与问题相关的竞赛信息,并通过基于上下文的生成模型提供详细回答。机器人不仅能够回答基础的竞赛查询,还能够处理一些统计分析类和开放性问题。
问题三的任务是在问题二的基础上,处理新增和变更的竞赛PDF文档,并将其更新到现有的智能客服机器人系统中。通过从新增或更新的PDF中提取竞赛信息、清洗文本并生成嵌入,系统能够将这些新的或更新的数据集成到知识库中。这样,智能客服系统能够保持最新的竞赛信息,并继续高效地回答用户查询。
模型的核心在于自动化处理新增和变更数据,通过将新的竞赛信息嵌入现有知识库来更新系统。用户查询时,系统可以通过嵌入检索到相关的竞赛数据,并利用生成模型给出准确的回答。这个过程确保了系统始终能够提供及时和准确的竞赛信息,避免了人工更新的繁琐。
该任务的关键挑战在于如何高效地处理和更新竞赛文档,以及确保系统能够无缝地集成新数据。通过简化的问题三模型,通过处理新增和变更的PDF数据,并将其更新到现有的大模型中,使得系统能够继续为用户提供实时的服务,提升了系统的灵活性和可扩展性。
任务 1:竞赛数据整理
目标:从18个竞赛规程PDF文件中提取基本竞赛信息,并保存到 result_1.xlsx。
解题思路:
PDF 解析:
使用 pdfplumber 或 PyMuPDF 提取 PDF 文本内容。
处理文本分段问题,确保数据完整提取。
信息提取:
采用 正则表达式 识别并提取竞赛名称、赛道、发布时间、报名时间、组织单位和官网信息。
采用 NLP 技术,如 spaCy 或 NLTK 进行信息分类和结构化。
数据整理与存储:
将提取的数据存储为 Pandas DataFrame,并按表格要求格式化。
最终导出为 result_1.xlsx。
# ---- 提取赛道名称 ----# 方案1:匹配"专项赛"关键词track_match = re.search(r'(.+?专项赛)', text)# 方案2:匹配标题行if not track_match:track_match = re.search(r'参\s*赛\s*手\s*册\s*\n(.+?)\n', text)if track_match:info["赛道"] = track_match.group(1).replace("参 赛 手 册", "").strip()# ---- 提取发布时间 ----date_match = re.search(r'(\d{4}\s*年\s*\d{1,2}\s*月)(?!.*\d{4}\s*年)', text)if date_match:info["发布时间"] = date_match.group(1).replace(" ", "")# ---- 提取报名时间 ----reg_date_match = re.search(r'报名时间[::]\s*(\d{4}\s*年\s*\d{1,2}\s*月\s*\d{1,2}\s*日\s*[-至]\s*\d{1,2}\s*月\s*\d{1,2}\s*日)', text)if reg_date_match:info["报名时间"] = reg_date_match.group(1).replace(" ", "")# ---- 提取官网 ----website_match = re.search(r'(https?://[^\s\)\]\'"]+)', text)if website_match:info["官网"] = website_match.group(1).split(',')[0].strip()
任务 2:智能客服机器人构建
目标:基于竞赛规程文档,搭建智能客服机器人,能够回答用户问题。
解题思路:
知识库构建:
解析所有竞赛文件,建立竞赛信息知识库(使用 SQLite 或 Pinecone 向量数据库)。
为数据索引,以便高效查询。
问答系统设计:
关键词匹配:基于 BM25 或 TF-IDF 找出与用户问题最相关的竞赛信息。
自然语言理解(NLU):使用 BERT 或 GPT 进行语义匹配,提高准确率。
问题分类:
基本查询:直接匹配数据库信息(如竞赛报名时间)。
数据统计分析:使用 SQL 或 Pandas 进行统计(如“人工智能相关竞赛有多少?”)。
开放性问题:利用 LLM(如 ChatGPT)生成回答。
机器人回答问题并存储:
================== 第四步:主流程 ==================
def main():
# 1. 创建知识库knowledge_df = create_knowledge_base()knowledge_df.to_excel("knowledge_base.xlsx", index=False)print("已创建知识库文件: knowledge_base.xlsx")# 2. 创建测试问题questions_df = create_test_questions()questions_df.to_excel("test_questions.xlsx", index=False)print("已创建测试问题文件: test_questions.xlsx")# 3. 初始化机器人bot = CompetitionChatbot(knowledge_df)# 4. 处理问题并保存结果results = []for _, row in questions_df.iterrows():result = bot.answer_question(row['问题'])results.append({"问题编号": f"C{row['问题序号']:04d}","问题": result["问题"],"关键点": result["关键点"],"回答": result["回答"]})result_df = pd.DataFrame(results)result_df.to_excel("chatbot_answers.xlsx", index=False)print("已生成回答文件: chatbot_answers.xlsx")# 5. 打印示例问答print("\n示例问答:")print(result_df[['问题编号', '问题', '回答']].to_markdown(index=False))
任务 3:知识库更新与管理
目标:设计机制,使客服机器人能够实时更新竞赛数据。
解题思路:
新增赛事文件的处理:
解析 19_.pdf、20_.pdf、21_***.pdf,提取新增竞赛信息并更新知识库。
变更信息的处理:
解析 07_***.pdf(变更文件)。
对比数据库中的旧数据,识别变更项并更新知识库。
自动更新机制:
定期监测新文件,通过 Cron Job 或 定时任务 触发更新程序。
重新运行问答系统,使用最新数据生成 result_3.xlsx。
def update_from_pdf(self, pdf_path, update_type="新增"):"""从PDF文件更新知识库:param pdf_path: PDF文件路径:param update_type: 更新类型("新增"或"变更")"""try:# 从PDF提取信息(复用问题一的代码)new_info = self._extract_info_from_pdf(pdf_path)if update_type == "新增":self.knowledge_base = pd.concat([self.knowledge_base, new_info], ignore_index=True)note = f"新增竞赛: {new_info['赛项名称'].iloc[0]} {new_info['赛道'].iloc[0]}"else:# 查找并更新现有记录mask = (self.knowledge_base['赛项名称'] == new_info['赛项名称'].iloc[0]) & \(self.knowledge_base['赛道'] == new_info['赛道'].iloc[0])idx = self.knowledge_base[mask].indexif len(idx) > 0:self.knowledge_base.loc[idx[0]] = new_info.iloc[0]note = f"更新竞赛: {new_info['赛项名称'].iloc[0]} {new_info['赛道'].iloc[0]}"else:self.knowledge_base = pd.concat([self.knowledge_base, new_info], ignore_index=True)note = f"未找到匹配竞赛,已新增: {new_info['赛项名称'].iloc[0]} {new_info['赛道'].iloc[0]}"# 保存新版本new_hash = self._calculate_dataframe_hash(self.knowledge_base)self._save_version(version_note=note, data_hash=new_hash)return True, noteexcept Exception as e:return False, f"更新失败: {str(e)}"