
如何用AI進行情感分析
另外, 本次開發的運行環境是 Intel Mac ,其他 操作系統 也可以。 下載模型等可能需要梯子。
https://www.langchain.com/langchain
Langchain 是當前 大模型 應用開發的主流框架之一,旨在幫助開發者構建和部署基于大型語言模型( LLM )的應用。它提供了一系列的工具和接口,使得與LLM交互變得簡單。通過 Langchain,開發者可以輕松創建定制的高級應用,如 聊天機器人 、問答系統和多種智能應用。
Langchain 的核心在于其“鏈”概念,這是一個模塊化的組件系統,包括 Model I/O (模型輸入輸出)、Retrieval(數據檢索)、Chains(鏈)、Agents(代理)、Memory( 內存 )、和 Callbacks( 回調 )。這些組件可靈活組合,以支持復雜的應用邏輯。
Model I/O 模塊負責處理與語言模型的直接交互,包括發送請求和解析響應。Retrieval 模塊用于增強語言模型的回答能力,通過向量數據庫檢索相關信息來支持回答生成。Chains 模塊則是多個組件的集成,用于構建更復雜的應用邏輯。
Langchain 的生態系統還包括 LangSmith、LangGraph 和 LangServe 等工具,這些工具能幫助開發者高效管理從原型到生產的各個階段,以便優化 LLM 應用。
Ollama 是一個開箱即用的用于在本地運行 大模型 的框架。它的主要功能和特點包括:
支持多種大型語言模型 :Ollama 支持包括 通義千問、Llama 2、Mistral 和 Gemma 等在內的多種大型語言模型,這些模型可用于不同的應用場景。
易于使用 :Ollama 旨在使用戶能夠輕松地在本地環境中啟動和運行 大模型 ,適用于 macOS 、Windows 和 Linux 系統,同時支持 cpu 和 gpu 。
模型庫 :Ollama 提供了一個模型庫,用戶可以從中下載不同的模型。這些模型有不同的參數和大小,以滿足不同的需求和硬件條件。Ollama 支持的模型庫可以通過 https://ollama.com/library 進行查找。
自定義模型 :用戶可以通過簡單的步驟自定義模型,例如修改模型的溫度參數來調整創造性和連貫性,或者設置特定的系統消息。
API 和集成 :Ollama 還提供了 REST API ,用于運行和管理模型,以及與其他應用程序的集成選項。
社區貢獻 :Ollama 社區貢獻豐富,包括多種集成插件和界面,如 Web 和桌面應用、 Telegram 機器人、Obsidian 插件等。
總的來說,Ollama 是一個為了方便用戶在本地運行和管理大型語言模型而設計的框架,具有良好的可擴展性和多樣的使用場景。
后面在捏 Bot 的過程中需要使用 Ollama,我們需要先安裝,訪問以下鏈接 進行下載安裝。
安裝完之后,確保 ollama 后臺服務已啟動(在 mac 上啟動 ollama 應用程序即可,在 linux 上可以通過 ollama serve 啟動)。我們可以通過 ollama list 進行確認,當我們還沒下載模型的時候,正常會顯示空:
可以通過 ollama 命令下載模型,
# 模型列表參考:https://ollama.com/library$ ollama pull [model]
目前,我下載了 4 個模型:
幾個模型簡介如下:
Gemma:Gemma 是由 Google 推出的輕量級模型,Google 表示,“Gemma 2B 和 7B 與其他開放式模型相比,在其規模上實現了同類最佳的性能?!?本次開發,下載的是 7B 模型。
Mistral:Mistral 是由歐洲法國 Mistral AI 團隊推出的 大模型 ,該模型采用了分組查詢注意力(GQA)以實現更快的推斷速度。本次開發,下載的是 7B 模型。
Mixtral:Mixtral 也是由 Mistral AI 團隊推出的 大模型 ,但 Mixtral 是一個 8*7B 的 MoE 模型,在大多數 基準測試 中都優于 Llama 2 70B 和 GPT-3.5 。
Qwen:Qwen(通義千問)是由阿里巴巴推出的 大模型 ,本次開發,下載的是 7B 模型。
巧婦難為無米之炊 。不管是獲取日常新聞,還是獲取 A 股行情,都需要有穩定靠譜的 數據源 。大家可能第一時間會想到爬蟲,但自己去搭建和維護這樣一個爬蟲系統還是比較麻煩的。有沒有其他更好的方式呢?
這就需要用到「上古神器」 RSS 了!
大家可能會覺得 RSS 已經過時了?,F如今,打開手機,今日頭條、微博、微信等 APP 時不時就會給你推送最新的資訊,日常生活工作好像沒有用到 RSS 的場景。
確實,大部分情況下,我們想要獲取資訊,手機 APP 基本夠用了。
但是,如果你想針對一些特定的需求,需要從某些網站上獲取最新通知或相關信息呢?
比如,
獲取 https://openai.com/blog 的最新更新
獲取 https://www.producthunt.com 每天的熱門產品
獲取 https://github.com/trending 每天的熱門開源項目
在這種情況下,我們可能會把網站添加到書簽欄,然后時不時就會打開看一下,這種做法無疑是比較低效的,一旦網站變多,更是不現實。
如果我們能把真正想要關注的信息匯聚在同一個平臺上,并且一旦有更新,就能第一時間在各種終端(如電腦、手機、Kindle 等)收到提醒,那豈不是美哉。
這里,我給大家推薦一個寶藏項目:
感謝 RSSHub 這個開源項目,它給各種各樣的網站生成了 RSS 源,堪稱「 萬物皆可 RSS 」。
你能想到的大部分社交媒體(如 微博、Twitter、知乎等)、傳統媒體(如央視新聞、路透社等)和金融媒體(如財聯社、東方財富、格隆匯等),都能夠配合 RSSHub,進行訂閱。
通過 RSSHub 以及其他渠道,我個人維護了一個訂閱源,如下:
感興趣的讀者, 關注本公眾號,然后發送 rss ,即可下載我打包好的 RSS 訂閱源。
那么,有了 RSS 訂閱源,我們就可以通過 Python 解析 RSS 訂閱源來實時獲取相關數據。
有了數據,就意味著成功了一半。
創建 python 虛擬環境 ,并安裝相關庫,我安裝的是當前最新的庫,版本如下:
ollama:0.1.8
langchain:0.1.14
faiss-cpu:1.8.0 (如果有 gpu ,則安裝gpu版本)
gradio:4.25.0
feedparser:6.0.11
sentence-transformers:2.6.1
lxml:5.2.1
conda create -n finance_bot python=3.10conda activate finance_botpip install ollama langchain faiss-cpu gradio feedparser sentence-transformers lxml
加載所需的庫和模塊。
import ollamaimport feedparserimport gradio as gr
from lxml import etree
from langchain.vectorstores import FAISS
from langchain.docstore.document import Document
from langchain.text_splitter import RecursiveCharacterTextSplitter
from langchain.embeddings.huggingface import HuggingFaceEmbeddings
其中,
feedparse 用于解析 RSS 訂閱源
ollama 用于在 python 程序中跑 大模型 ,使用前請確保 ollama 服務已經開啟并下載好模型
下面函數用于從指定 的 RSS 訂閱 url 提 取內容,這里只是給了一個 url,如果需要接收多個 url,只要稍微改動即可。然后,通過一個專門的文本拆分器將長文本拆分成較小的塊,并附帶相關的元數據如標題、發布日期和鏈接。最終,這些文檔被合并成一個列表并返回,可用于進一步的數據處理或信息提取任務。
import feedparser
from lxml import etree
from some_text_splitting_library import RecursiveCharacterTextSplitter # 假設這是某個文本拆分庫
def get_content(url):
"""
使用 feedparser 庫解析提供的 URL,通常用于讀取 RSS 或 Atom 類型的數據流。
"""
# 解析 URL 數據
data = feedparser.parse(url)
# 初始化文檔列表
docs = []
# 遍歷解析后的數據條目
for news in data['entries']:
# 使用 lxml 的 etree 通過 xpath 提取干凈的文本內容
summary = etree.HTML(text=news['summary']).xpath('string(.)')
# 初始化文檔拆分器,設定塊大小和重疊大小
text_splitter = RecursiveCharacterTextSplitter(
chunk_size=1000,
chunk_overlap=200,
length_function=len
)
# 拆分文檔
split_docs = text_splitter.create_documents(
texts=[summary],
metadatas=[{k: news[k] for k in ('title', 'published', 'link')}]
)
# 將拆分后的文檔合并到主列表
docs.extend(split_docs)
# 返回解析后的數據和文檔列表
return data, docs
這里,我們使用文本向量模型 bge-m3 。
https://huggingface.co/BAAI/bge-m3
bge-m3 是智源研究院 發布的新一代通用向量模型,它具有以下特點:
支持超過100種語言的語義表示及檢索任務,多語言、跨語言能力全面領先( M ulti-Lingual)
最高支持8192長度的輸入文本,高效實現句子、段落、篇章、文檔等不同粒度的檢索任務( M ulti-Granularity)
同時集成了稠密檢索、稀疏檢索、多向量檢索三大能力,一站式支撐不同語義檢索場景( M ulti-Functionality)
從 hf 下載好模型之后,假設放置在某個路徑 /path/to/bge-m3,通過下面函數,利用 FAISS 創建一個高效的向量存儲。
from some_embedding_library import HuggingFaceEmbeddings # 假設這是某個嵌入向量庫
from some_vector_store_library import FAISS # 假設這是某個向量存儲庫
def create_docs_vector(docs):
"""
為文檔列表創建向量表示,并存儲到向量數據庫中。
參數:
docs (list): 文檔列表,每個文檔應包含文本內容和元數據。
返回:
vector_store: 向量存儲對象,可用于后續的相似性搜索等操作。
"""
# 初始化嵌入模型
embeddings = HuggingFaceEmbeddings(
model_name="/path/to/bge-m3",
encode_kwargs={'normalize_embeddings': True}
)
# 創建向量存儲對象
vector_store = FAISS.from_documents(docs, embeddings)
# 返回向量存儲對象
return vector_store
基于用戶的問題,從向量數據庫中檢索相關段落,并根據設定的閾值進行過濾,最后讓模型參考上下文信息回答用戶的問題,從而實現 RAG。
def rag_chain(question, vector_store, model='qwen', threshold=0.3):
"""
實現一個基于檢索增強生成(Retrieval-Augmented Generation, RAG)的問答鏈。
參數:
question (str): 用戶提出的問題。
vector_store (FAISS): 向量存儲對象,用于檢索相關文檔。
model (str): 使用的模型名稱,默認為 'qwen'。
threshold (float): 相似度閾值,用于過濾相關性較低的文檔,默認為 0.3。
返回:
tuple: 包含模型生成的回答和檢索到的上下文內容。
"""
# 從向量數據庫中檢索與問題相關的文檔
related_docs = vector_store.similarity_search_with_relevance_scores(question)
# 過濾掉相似度小于設定閾值的文檔
related_docs = list(filter(lambda x: x[1] > threshold, related_docs))
# 格式化檢索到的文檔
context = "\n\n".join([f"[citation:{i}] {doc[0].page_content}" for i, doc in enumerate(related_docs)])
# 保存文檔的元數據,如 title、link 等
metadata = {str(i): doc[0].metadata for i, doc in enumerate(related_docs)}
# 構建系統提示詞
system_prompt = (
f"""
當你收到用戶的問題時,請編寫清晰、簡潔、準確的回答。
你會收到一組與問題相關的上下文,每個上下文都以參考編號開始,如[citation:x],其中x是一個數字。
請使用這些上下文,并在適當的情況下在每個句子的末尾引用上下文。
你的答案必須是正確的,并且使用公正和專業的語氣寫作。請限制在1024個tokens之內。
不要提供與問題無關的信息,也不要重復。
不允許在答案中添加編造成分,如果給定的上下文沒有提供足夠的信息,就說“缺乏關于xx的信息”。
請用參考編號引用上下文,格式為[citation:x]。
如果一個句子來自多個上下文,請列出所有適用的引用,如[citation:3][citation:5]。
除了代碼和特定的名字和引用,你的答案必須用與問題相同的語言編寫,如果問題是中文,則回答也是中文。
這是一組上下文:
{context}
"""
)
# 構建用戶提示詞
user_prompt = f"用戶的問題是:{question}"
# 調用模型生成回答
response = ollama.chat(
model=model,
messages=[
{'role': 'system', 'content': system_prompt},
{'role': 'user', 'content': user_prompt}
]
)
# 打印系統提示和用戶提示(用于調試)
print(system_prompt + user_prompt)
# 返回模型生成的回答和檢索到的上下文
return response['message']['content'], context
最后,通過 gradio 創建網頁 UI ,并進行評測。
if __name__ == "__main__":
# 初始化 HuggingFace 嵌入模型
hf_embedding = HuggingFaceEmbeddings(
model_name="/path/to/bge-m3",
encode_kwargs={'normalize_embeddings': True}
)
# 財聯社 RSS 鏈接
url = "https://rsshub.app/cls/depth/1003"
try:
# 嘗試解析 RSS 鏈接
data, docs = get_content(url)
except Exception as e:
print(f"解析 RSS 鏈接時遇到問題:{e}")
print("請檢查鏈接的合法性,或稍后重試。")
exit(1) # 如果解析失敗,則退出程序
# 創建向量存儲
vector_store = create_docs_vector(docs, hf_embedding)
# 創建 Gradio 界面
import gradio as gr
interface = gr.Interface(
fn=lambda question, model, threshold: rag_chain(question, vector_store, model, threshold),
inputs=[
gr.Textbox(lines=2, placeholder="請輸入你的問題...", label="問題"),
gr.Dropdown(['gemma', 'mistral', 'mixtral', 'qwen:7b'], label="選擇模型", value='gemma'),
gr.Number(label="檢索閾值", value=0.3)
],
outputs=[
gr.Text(label="回答"),
gr.Text(label="相關上下文")
],
title="資訊問答Bot",
description="輸入問題,我會查找相關資料,然后整合并給你生成回復"
)
# 運行界面
interface.launch()
生成的 Web UI 如下:
對于同樣的問題和上下文,我基于 Qwen-7b、Gemma、Mistral、Mixtral 和 GPT-4 分別進行了多次測試。下面是一些 case:
主要結論(只是針對有限的幾次測試,個人主觀評判)如下:
?? GPT-4 表現最好, 指令 遵循能力很強,在回答的時候能附上引用段落編號
?? Mixtral 表現第二,但沒有在回答的時候附上引用
?? Qwen-7b 表現第三,也沒有在回答的時候附上引用
?? Gemma 表現一般,而且回答里面有一些幻覺
?? Mistral 表現一般,使用英文回復,不過 在回答的時候附上了引用 段落編號
1. 本文展示了如何使用 Langchain 和 Ollama 技術棧在本地部署一個資訊問答機器人,同時結合 RSSHub 来處理和提供資訊。
2. 上下文 數據質量和大模型的性能決定了 RAG 系統性能的上限 。
3. RAG 通過結合檢索技術和生成模型來提升答案的質量和相關性,可以 緩解大模型幻覺、信息滯后的問題,但并不意味著可以消除 。
4. 對于期望在本地環境利用 AI 技術來搭建 RAG 系統的用戶來說,本文提供了一個具有實際操作價值的參考方案。