项目名称:AI-AGENT夏季训练营 — RAG智能对话机器人
报告日期:2024年8月18日
项目负责人:shark688
项目概述:
随着金融市场的日益复杂化和信息量的爆炸性增长,投资者、分析师及企业管理人员在快速准确地获取并理解上市公司年报中的关键信息时面临巨大挑战。传统的手工查阅和数据分析方式不仅效率低下,而且容易遗漏重要细节或误解数据背后的含义。因此,开发一款高效、智能的金融年报问答助手成为市场迫切需求。
该Rag智能对话机器人能允许用户可通过自然语言提问,能准确理解问题意图,并从海量年报数据中快速检索、整合相关信息,给出准确、简洁的答案。支持复杂查询,如跨年度对比、行业趋势分析等。
技术方案与实施步骤
- 模型选择: 优先选择NVDIA官网中较好的大模型以及向量模型(也可以选择OpenAI),好的向量模型创建出的向量库更加精确,能够为大模型提供更好的文档检索。 RAG模型能够增强大模型功能,使得大模型基于本地知识库来返回对应的答案。
- 数据的构建:
- 使用pdfplumber对PDF进行处理,提取出PDF中的文本以及表格
- 将上一步提取出的文本使用LangChain的textspliter来对文本进行处理,分割成块
- 将分割成的块提交给NVDIA向量模型,基于返回数据创建向量库
实施步骤:
环境搭建
- 基于python3.9版本创建的虚拟环境
- 使用pip工具安装langchain,matplotlib,faiss-cpu等库
- 在pycharm中代码运行
pip install langchain-nvidia-ai-endpoints
pip install jupyterlab
pip install langchain_core
pip install langchain
pip install openai
pip install langchain-community
pip install faiss-cpu==1.7.2
代码实现
1.PDF处理:
将PDF处理为向量模型能够理解的文本类型
def extract_text(pdf_path):
text = []
with pdfplumber.open(pdf_path) as pdf:
for page in pdf.pages:
page_text = page.extract_text()
page_text = page_text.replace('\n', ' ')
text.append(page_text)
return text
2.数据清洗及处理
将文本分成块,太长的数据不易大模型理解,同时去掉冗余字符(例如换行符,标点符号等)
def spilt_text_by_tool(texts):
answer = []
answer_metadatas = []
text_splitter = CharacterTextSplitter(chunk_size=400, separator=" ")
i = 0
for text in texts:
i+=1
page = f"第{i}页"
splits = text_splitter.split_text(text)
answer.extend(splits)
answer_metadatas.extend([{"source": page}] * len(splits))
return answer,answer_metadatas
3.生成向量数据库
根据划分好的数据,提交给NVDIA向量模型,创建向量数据库(保存在本地)
def text_to_embedder(docs,metadatas):
embedder = NVIDIAEmbeddings(model="nvidia/nv-embedqa-mistral-7b-v2")
store = FAISS.from_texts(docs, embedder, metadatas=metadatas)
store.save_local('../faiss_data/nv_embedding')
4.加载向量数据库
若已事先创好向量库,则直接加载,若没有,则先创建
def load_to_embedder():
embedder = NVIDIAEmbeddings(model="nvidia/nv-embedqa-mistral-7b-v2")
store = FAISS.load_local("../faiss_data/nv_embedding", embedder, allow_dangerous_deserialization=True)
retriever = store.as_retriever()
return retriever
5.使用大模型
向大模型提交自己设定的Prompt和向量库数据进行问答
ps.可以事先去学习一下prompt相关知识
def chat_to_AI(question):
nvapi_key = "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"
llm = ChatNVIDIA(model="meta/llama-3.1-8b-instruct", nvidia_api_key=nvapi_key, max_tokens=512)
retriever = load_to_embedder()
system_prompt = (
"system",
"所有回答的问题应严格基于接下来的文档内容:\n<Documents>\n{context}\n</Documents>",
)
AI_prompt = (
"system",
'''你是一名精通金融行业相关知识的金融分析师,同时拥有良好的文档分析能力,回答格式应遵循以下示例:
原文位置: <仅返回是什么文档的第几页>
内容分析: <额外对相关原文的内容进行适当分析>'''
)
prompt = ChatPromptTemplate.from_messages(
[
system_prompt,
AI_prompt,
("user", "{question}"),
]
)
chain = (
{"context": retriever, "question": RunnablePassthrough()}
| prompt
| llm
| StrOutputParser()
)
return chain.invoke(question)
到这一步就可以测试代码啦
if __name__ == '__main__':
result = chat_to_AI("公司作为 IDC 行业的龙头企业应该以国家什么战略和上海市什么战略为导向")
print(result)
测试与调优
- 测试过程: 刚开始测试时返回结果并不理想,返回的数据并不正确,因此更换了向量模型和大模型,并且重新编写了Prompt之后,优化了效果。
- 测试用例设计: 分为细节问题和概括性问题,细节问题具体到文档中有明显提及,概括性问题指的是问该文档某些数据的扩展问题
项目成果与展示
应用场景展示
随着金融市场的日益复杂化和信息量的爆炸性增长,投资者、分析师及企业管理人员在快速准确地获取并理解上市公司年报中的关键信息时面临巨大挑战。传统的手工查阅和数据分析方式不仅效率低下,而且容易遗漏重要细节或误解数据背后的含义。金融年报问答助手能够将繁杂庞大的数据基于用户的问题,精确到数据原文位置返回用户想要的结果。
功能演示
细节问题:
模型正确返回原文内容,并指出处于原pdf第几页
概括性问题:
问题与解决方案
将PDF转换为文本
- 问题分析: 创建向量库需要文本数据,然而输入形式是pdf,因此需要进行处理
- 解决措施: 阅读LangChain官方文档,发现有许多技术能够实现,进行技术选型,发现pdfplumber不仅能够提取文字,还能提取表格,因此选用pdfplumber
大模型返回效果不理想
- 问题分析: 大模型返回的结果并不规范,达不到想要的结果
- 解决措施:使用更加强力的向量模型来创建向量库,并且使用更好的大模型来对话
项目总结与展望:
- 项目评估: 市场前景广阔,技术可行性高,然而如何在文本量大之后依旧保证回答问题的准确度是个大问题。
- 未来方向:
- 技术优化:持续优化模型,提升问答准确率和响应速度;不断优化Prompt来深化财务数据分析能力。
- 用户体验:优化用户界面,提升交互便捷性
- 数据整合:构建金融知识图谱,提升信息关联性和深度。
附件与参考资料
LangChain官方文档:https://python.langchain.com.cn/
pdfplumber官网: https://pypi.org/project/pdfplumber