LangChain+Ollama+DeepSeek AI應用開發全鏈路認知:從模型包裝器到提示詞模版 Agent
lang Chain 基本認知
在開源項目中,它這樣介紹自己:
LangChain 是一個用于開發由大型語言模型(LLMs)驅動的應用程序的框架。對于這些應用,LangChain 簡化了整個應用生命周期:
- 開源庫: 使用 LangChain 的開源組件和第三方集成構建您的應用程序。使用 LangGraph 構建具有流處理和人機交互支持的帶狀態代理。
- 生產化: 使用 LangSmith 檢查、監控和評估您的應用程序,以便您可以不斷進行優化并充滿信心地進行部署。
- 部署: 使用 LangGraph 平臺將您的 LangGraph 應用程序轉換為生產就緒的API和助手。LangGraph是一個用于構建具有LLMs的狀態和多主體應用程序的庫,用于創建代理和多代理工作流。
對應的項目地址:
- langchain: https://github.com/langchain-ai/langchain
- langgraph: https://github.com/langchain-ai/langgraph
- langsmith: https://github.com/langchain-ai/langsmith-sdk
這里我們只關注 langchain ,langgraph 和 langsmith 在之后的博文和小伙伴分享
Lang Chain 應用場景: 問答系統,數據處理與管理,Agent ,RAG 等
lang Chain 架構
lang Chain 通過 組件和鏈提供基礎能力,類似我們常常畫的流程圖,工作流引擎一樣。
組件: 組件是一個具有明確功能和用途的單元。 類似流程圖中的處理框,組件包括提示工程模版, LLM模型包裝器、聊天模型包裝器等以及和數據增強相關的一系列工具和接口。可以把它們看作數據處理流水線上的各個工作站。每個組件都有其特定的職責,如處理數據的輸入輸出、轉化數據格式。
鏈: 鏈是將各種組件連接在一起,它確保組件之間的無縫集成和在程序運行環境中的高效調用。
Lang Chain 核心模塊
1.模型 I/O(Model IO)
LangChain 提供了與任何大語言模型均適配的模型包裝器(模型 I/0 的功能)分為 模型包裝器(LLM) 和聊天模型包裝器(Chat Model)。
LangChain 自身并不提供大語言模型而是提供統一的模型接口。模型包裝器這種包裝方式允許開發者與不同模型平臺底層的 API進行交互,從而簡化了大語言模型的調用,降低了開發者的學習成本。此外,其輸出解析器也能幫助開發者從模型輸出中提取所需的信息。
模型包裝器的提示詞模板功能使得開發者可以模板化、動態選擇和管理模型輸人
2.數據增強(Data Connection)
許多LLM 應用需要的用戶特定數據并不在模型的訓練集中。LangChain 提供了加載、轉換、存儲和査詢數據的構建塊。開發者可以利用文檔加載器從多個來源加載文檔,通過文檔轉換器進行文檔切割、轉換等操作。矢量存儲和數據檢索工具則提供了對嵌人數據的存儲和查詢功能。
3.鏈( Chain)
單獨使用LLM 對于簡單應用可能是足夠的,但面對復雜的應用往往需要將多個 LLM 模型包裝器或其他組件進行鏈式連接。LangChain 為此類鏈式應用提供了接口。 有點類似于設計模式中的構建者,按需 build ,每次都返回實例本身
4.記憶(Memory)
LangChain 提供了多種工具幫助開發者為系統添加記憶功能。記憶功能可以獨立使用,也可以無縫集成到鏈中。記憶模塊需要支持兩個基本操作,即讀取和寫入。
在每次運行中,鏈首先從記憶模塊中讀取數據,然后在執行核心邏輯后將當前運行的輸人和輸出寫入記憶模塊,以供未來引用。通俗的講,就是會申請一塊內存存房歷史會話數據。
5.Agent
核心思想是利用LLM 選擇操作序列。即把之后的組件調用的決策權交給 LLM,在鏈中,操作序列是硬編碼的,而在代理(Agent)代理中,大語言模型被用作推理引擎,確定執行哪些操作,以及它們的執行順序。
6.回調處理器(Callback)
LangChain 提供了一個回調系統,允許開發者在LLM應用的各個階段對狀態進行干預。這對于日志記錄、監視、流處理等任務非常有用。通過API提供的回調參數,開發者可以訂閱這些事件。
Demo 實戰
理論學了那么多,我看幾個簡單的Demo 認識一下。
我們通過 Ollama 在本地部署 DeepSeek-R1 蒸餾模型,通過 langChain 調用。
下載模型,啟動 Ollama 服務。
PS C:\Users\Administrator> ollama list
NAME ID SIZE MODIFIED
deepseek-r1:latest 0a8c26691023 4.7 GB 3 seconds ago
deepseek-r1:32b 38056bbcbb2d 19 GB 2 weeks ago
deepseek-r1:14b ea35dfe18182 9.0 GB 2 weeks ago
deepseek-r1:8b 28f8fd6cdc67 4.9 GB 2 weeks ago
bge-m3:latest 790764642607 1.2 GB 2 weeks ago
PS C:\Users\Administrator> ollama serve
Error: listen tcp 127.0.0.1:11434: bind: Only one usage of each socket address (protocol/network address/port) is normally permitted.
PS C:\Users\Administrator> ollama serve
2025/03/09 01:22:39 routes.go:1187: INFO server config env="map[CUDA_VISIBLE_DEVICES: GPU_DEVICE_ORDINAL: HIP_VISIBLE_DEVICES: HSA_OVERRIDE_GFX_VERSION: HTTPS_PROXY: HTTP_PROXY: NO_PROXY: OLLAMA_DEBUG:false OLLAMA_FLASH_ATTENTION:false OLLAMA_GPU_OVERHEAD:0 OLLAMA_HOST:http://127.0.0.1:11434 OLLAMA_INTEL_GPU:false OLLAMA_KEEP_ALIVE:5m0s OLLAMA_KV_CACHE_TYPE: OLLAMA_LLM_LIBRARY: OLLAMA_LOAD_TIMEOUT:5m0s OLLAMA_MAX_LOADED_MODELS:0 OLLAMA_MAX_QUEUE:512 OLLAMA_MODELS:C:\\Users\\Administrator\\.ollama\\models OLLAMA_MULTIUSER_CACHE:false OLLAMA_NOHISTORY:false OLLAMA_NOPRUNE:false OLLAMA_NUM_PARALLEL:0 OLLAMA_ORIGINS:[http://localhost https://localhost http://localhost:* https://localhost:* http://127.0.0.1 https://127.0.0.1 http://127.0.0.1:* https://127.0.0.1:* http://0.0.0.0 https://0.0.0.0 http://0.0.0.0:* https://0.0.0.0:* app://* file://* tauri://* vscode-webview://*] OLLAMA_SCHED_SPREAD:false ROCR_VISIBLE_DEVICES:]"
time=2025-03-09T01:22:39.303+08:00 level=INFO source=images.go:432 msg="total blobs: 14"
time=2025-03-09T01:22:39.304+08:00 level=INFO source=images.go:439 msg="total unused blobs removed: 0"
time=2025-03-09T01:22:39.306+08:00 level=INFO source=routes.go:1238 msg="Listening on 127.0.0.1:11434 (version 0.5.7)"
time=2025-03-09T01:22:39.306+08:00 level=INFO source=routes.go:1267 msg="Dynamic LLM libraries" runners="[cuda_v12_avx rocm_avx cpu cpu_avx cpu_avx2 cuda_v11_avx]"
time=2025-03-09T01:22:39.306+08:00 level=INFO source=gpu.go:226 msg="looking for compatible GPUs"
time=2025-03-09T01:22:39.306+08:00 level=INFO source=gpu_windows.go:167 msg=packages count=1
time=2025-03-09T01:22:39.308+08:00 level=INFO source=gpu_windows.go:183 msg="efficiency cores detected" maxEfficiencyClass=1
time=2025-03-09T01:22:39.308+08:00 level=INFO source=gpu_windows.go:214 msg="" package=0 cores=12 efficiency=4 threads=20
time=2025-03-09T01:22:39.448+08:00 level=INFO source=types.go:131 msg="inference compute" id=GPU-e65029a6-c2f9-44b1-bd76-c12e4083fa4c library=cuda variant=v12 compute=8.6 driver=12.8 name="NVIDIA GeForce RTX 3060" total="12.0 GiB" available="11.0 GiB"
LLMs 模型包裝器
下面為一個 基本的 Demo,使用 llm 模型包裝器,進行預測推理,
- invoke 是一個通用方法,用于同步調用模型、工具或組件的主要功能。它的核心作用是向目標對象傳遞輸入數據并獲取輸出結果。
- stream 是 LangChain 等大語言模型(LLM)框架中用于流式逐塊生成文本的核心方法。它的核心作用是:實時獲取模型輸出的片段(chunk),適用于需要逐步展示生成內容、降低延遲感知或處理長文本的場景。
#!/usr/bin/env python
# -*- encoding: utf-8 -*-
"""
@File : demo.py
@Time : 2025/03/09 01:13:15
@Author : Li Ruilong
@Version : 1.0
@Contact : liruilonger@gmail.com
@Desc : LangChain Demo
"""
# here put the import lib
#pip install langchain langchain-community ollama -i https://pypi.tuna.tsinghua.edu.cn/simple
from langchain_community.llms import Ollama
# 初始化 Ollama 連接
llm = Ollama(
base_url="http://localhost:11434", # Ollama 默認端口
model="deepseek-r1:latest",
temperature=0.3, # 控制創造性(0-1)
num_ctx=4096 # 上下文長度
)
# 單次對話
response = llm.invoke("LLM 是什么?")
print("回答:", response)
print("===========================================================")
# 流式輸出(適合長文本)
for chunk in llm.stream("LLM 如何學習?"):
print(chunk, end="", flush=True)
下面為 invoke 輸出結果
LLM 是 "Large Language Model" 的縮寫,即大型語言模型。這類模型由深度學習驅動,能夠模擬人類-like 思維過程,并且能夠生成和理解自然語言文本。
### 主要特點
1. **復雜性**:通常包含數百億參數。
2. **規模**:參數數量多,計算資源要求高。
3. **訓練數據**:依賴海量文本數據進行微調或預訓練。
4. **任務**:包括文本生成、問答、翻譯等。
.....................
prompts 提示詞模版
提示詞模板 這里使用 PromptTemplate 模塊,這是一個最基本的實現,下面Demo 中
# 創建提示模板
prompt = PromptTemplate(
input_variables=["topic"],
template="用中文寫一首關于 {topic} 的五言絕句:"
)
input_variables 用于定義變量參數,template 用于定義模版
#!/usr/bin/env python
# -*- encoding: utf-8 -*-
"""
@File : demo copy 2.py
@Time : 2025/03/09 03:19:59
@Author : Li Ruilong
@Version : 1.0
@Contact : liruilonger@gmail.com
@Desc : None
"""
# here put the import lib
# here put the import lib
#pip install langchain langchain-community ollama -i https://pypi.tuna.tsinghua.edu.cn/simple
from langchain.chains import LLMChain
from langchain_community.llms import Ollama
from langchain_core.prompts import PromptTemplate
# 初始化模型
llm = Ollama(model="deepseek-r1")
# 創建提示模板
prompt = PromptTemplate(
input_variables=["topic"],
template="用中文寫一首關于 {topic} 的五言絕句:"
)
# 構建 Chain
chain = LLMChain(llm=llm, prompt=prompt)
# 執行調用
print(chain.run("秋天的楓葉"))
輸出結果:
<think>
好的,用戶讓我用中文寫一首關于秋天楓葉的五言絕句。首先,我得理解用戶的需求,他們可能想表達對秋天的贊美或者懷念。五言絕句結構緊湊,每句五個字,押韻,所以需要 簡潔有力。
接下來,考慮秋天楓葉的特點:紅葉、蕭瑟、自然的變化。想到楓葉的顏色變化,紅葉象征著成熟和熱情。我需要用一些生動的詞語來描繪楓葉的狀態,比如“染”、“飛舞”等。
然后,考慮整體意境。秋天不僅是季節變換,還有一種寧靜或深遠的感覺。可能加入一些自然元素,如山色、風霜,來增強畫面感。
結構上,四句每句五個字,押韻。首句點明主題,中間兩句描繪景象,末句升華主題。比如:
第一句:“紅葉正秋染”,引出季節和顏色變化。
第二句:“山色起風霜”,描繪環境的變化和寒意。
第三句:“一片飛舞地”,形容紅葉的狀態。
第四句:“滿城換新裝”,表現秋天帶來的變化。
這樣組合起來,整首詩既有畫面感,又表達了對秋天的熱愛。最后檢查押韻是否合適,確保每句末尾字的平仄和諧。
總的來說,這首詩通過描繪紅葉的顏色和動態,以及整體環境的變化,傳達出秋天的美麗和成熟。
</think>
《題陶山楓》
紅葉正秋染,山色起風霜。
一片飛舞地,滿城換新裝。
PS C:\Users\Administrator\Documents\GitHub\LangChainDemo>
Agent Demo
相對于于傳統的方式,Agent 提供了記憶功能和決策功能。
我們先來看一個記憶功能的 Demo。
#!/usr/bin/env python
# -*- encoding: utf-8 -*-
"""
@File : demo_memory.py
@Time : 2025/03/09 03:21:59
@Author : Li Ruilong
@Version : 1.0
@Contact : liruilonger@gmail.com
@Desc : None
"""
# here put the import lib
# here put the import lib
#pip install langchain langchain-community ollama -i https://pypi.tuna.tsinghua.edu.cn/simple
from langchain.chains import ConversationChain
from langchain.memory import ConversationBufferWindowMemory
from langchain_community.llms import Ollama
llm = Ollama(model="deepseek-r1")
# 保留最近3輪對話歷史
memory = ConversationBufferWindowMemory(k=3)
conversation = ConversationChain(llm=llm, memory=memory)
# 多輪對話示例
print(conversation.run("幫我寫一個斐波那契數列的Python函數"))
print(conversation.run("添加類型注解"))
print(conversation.run("優化時間復雜度"))
下面為 Agent 的輸出。
<think>
嗯,用戶想讓我幫他寫一個斐波那契數列的Python函數。首先,我需要確認他具體想要什么樣的斐波那契數列。常見的有兩種版本:一種是從第0項開始,另一種是從第1項開始。
............
<think>
當然!讓我為您添加類型注解到斐波那契數列函數中。以下是帶有具體類型的Python函數:
..............................
<think>
嗯,用戶想讓我幫他優化斐波那契數列函數的時間復雜度。首先,我需要了解當前的實現方法是什么樣的。之前的回復提供了一個迭代版本,時間復雜度是O(n),這對大多數用途 來說已經足夠高效了。
...................
下面為一個帶記憶和決策功能的 Agent Demo
#!/usr/bin/env python
# -*- encoding: utf-8 -*-
"""
@File : demo_agent.py
@Time : 2025/03/09 03:46:56
@Author : Li Ruilong
@Version : 1.0
@Contact : liruilonger@gmail.com
@Desc : None
"""
# here put the import lib
# here put the import lib
from langchain_community.llms import Ollama
from langchain_community.chat_models import ChatOllama
from langchain.agents import AgentType, initialize_agent, Tool
from langchain.memory import ConversationBufferWindowMemory
from langchain_community.tools import WikipediaQueryRun
from langchain_community.utilities import WikipediaAPIWrapper
# 自定義文學分析工具(無需API)
class BookQuotesTool:
@staticmethod
def search_quotes(book_title: str, author: str = "木心") -> str:
"""模擬文學語錄檢索(實際可接入本地知識庫)"""
quotes_db = {
"素履之往": [
"生命好在無意義,才容得下各自賦予意義。",
"所謂無底深淵,下去,也是前程萬里。",
"歲月不饒人,我亦未曾饒過歲月。"
]
}
return"\n".join(quotes_db.get(book_title, ["暫未收錄該作品語錄"]))
# 配置本地模型
llm = Ollama(model="deepseek-r1:latest", temperature=0.3)
chat_model = ChatOllama(model="deepseek-r1:latest")
# 初始化記憶系統
memory = ConversationBufferWindowMemory(
memory_key="chat_history",
k=5,
return_messages=True
)
# 構建定制化工具集
tools = [
Tool(
name="LiteratureSearch",
func=lambda query: BookQuotesTool.search_quotes("素履之往"),
description="用于檢索木心《素履之往》的經典語錄"
),
WikipediaQueryRun(
api_wrapper=WikipediaAPIWrapper(top_k_results=1, lang="zh")
)
]
# 創建帶文學分析能力的Agent
agent = initialize_agent(
tools,
chat_model,
agent=AgentType.CHAT_CONVERSATIONAL_REACT_DESCRIPTION,
memory=memory,
verbose=True,
handle_parsing_errors=True,
max_iterations=3# 限制搜索深度
)
# 測試用例
queries = [
"列舉《素履之往》中關于時間的哲理語句",
"這本書里如何闡述生命的意義?",
"將第二句語錄用英文翻譯"
]
for q in queries:
print(f"問題:{q}")
print(agent.run(q))
print("\n" + "="*50 + "\n")
下面為輸出結構,我們可以看到 第一個到第二個問題,體現記憶功能,第二個問題,到第三個問題是由第二個問題的輸出,決策第三個問題的答案。
問題:列舉《素履之往》中關于時間的哲理語句
C:\Users\Administrator\Documents\GitHub\LangChainDemo\demo\demo_agent.py:78: LangChainDeprecationWarning: The method `Chain.run` was deprecated in langchain 0.1.0 and will be removed in 1.0. Use :meth:`~invoke` instead.
print(agent.run(q))
> Entering new AgentExecutor chain...
<think>
好,我現在要回答用戶的問題:“列舉《素履之往》中關于時間的哲理語句”。首先,我需要理解用戶的需求。他們想要找到《素履之往》中的時間相關的哲理句子。
接下來,我會回想一下《素履之往》的內容。這是一部哲學著作,主要討論生活態度和處世之道。作者在這本書中強調的是內心修持的重要性,而時間并不是特別受重視的一方面 。因此,我需要確認是否有關于時間的直接論述。
如果找不到直接提到時間的句子,我可以考慮其他方法。例如,通過分析作者的觀點來間接理解他對時間的看法。但通常情況下,這種書更注重內在修養而非時間管理或哲學中的 時間概念。
綜上所述,可能《素履之往》中并沒有專門討論時間的哲理句子。因此,我應該建議用戶如果沒有找到相關的內容,可以嘗試查閱相關的注釋或學術評論,了解是否有學者對其中 的時間主題有解讀。
</think>
> Finished chain.
由于《素履之往》主要關注的是人的日常生活態度和處世之道,而時間并不是其核心討論的主題,因此可以推測書中并未專門列出關于時間的哲理語句。為了更全面地了解,您可 以查閱相關注釋或學術評論以獲取對時間主題的解讀。
==================================================
問題:這本書里如何闡述生命的意義?
> Entering new AgentExecutor chain...
<think>
好的,現在我要分析用戶的問題:“這本書里如何闡述生命的意義?” 用戶提到的是《素履之往》,而我之前已經告訴過他們,這本書主要討論的是處世態度和生活態度,并沒有專門探討時間或其他主題的哲理語句。所以,我應該建議他們查閱相關的注釋或學術評論來了解書中關于生命意義的內容。
接下來,用戶要求列舉關于時間的哲理語句,但由于《素履之往》并沒有涉及時間主題,所以最好的辦法是引導他們去尋找相關資料。我需要提醒用戶,如果他們想了解更多關于 生命的意義,可以參考其他資源,比如注釋、評論或學術研究。
最后,按照指示,我應該輸出一個JSON格式的指令,告訴用戶使用文學搜索工具來查找相關的語錄。這樣他們就能找到更多的信息了。
</think>
{
"action": "LiteratureSearch",
"action_input": "《素履之往》中關于生命意義的經典語錄有哪些?"
}
Observation: 生命好在無意義,才容得下各自賦予意義。
所謂無底深淵,下去,也是前程萬里。
歲月不饒人,我亦未曾饒過歲月。
Thought:<think>
...............................
> Finished chain.
==================================================
問題:將第二句語錄用英文翻譯
> Entering new AgentExecutor chain...
<think>
Alright, I need to help the user translate the second sentence of "素履之往" into English. First, let me recall what that sentence is about.
From what I remember, the second sentence translates something like "The journey of life is best traveled alone." That's a pretty common translation, so it makes sense if it's from this book.
Now, to make sure I'm accurate, I'll think through why that would be an appropriate translation. The wording in Chinese emphasizes independence and personal experience, which aligns with the English phrase about traveling alone for growth.
I should also consider if there are any nuances or alternative translations suggested by experts, but from what I know, this is a widely accepted version.
</think>
{
"action": "Final Answer",
"action_input": "The journey of life is best traveled alone."
}
> Finished chain.
The journey of life is best traveled alone.
==================================================
PS C:\Users\Administrator\Documents\GitHub\LangChainDemo>
Lang Chain 表達式
類似 Linux 中的管道操作,LangChain 中也可以通過管道符鏈接組構成一些常見表達式。比如 提示詞模板+模型包裝器,提示詞模板+模型包裝器+輸出解析器
下面是一個 基礎 Demo
#!/usr/bin/env python
# -*- encoding: utf-8 -*-
"""
@File : demo_prompts.py
@Time : 2025/03/09 03:17:01
@Author : Li Ruilong
@Version : 1.0
@Contact : liruilonger@gmail.com
@Desc : None
"""
# here put the import lib
#pip install langchain langchain-community ollama -i https://pypi.tuna.tsinghua.edu.cn/simple
from langchain_community.llms import Ollama
from langchain.prompts import ChatPromptTemplate
# 初始化 Ollama 連接
llm = Ollama(
base_url="http://localhost:11434", # Ollama 默認端口
model="deepseek-r1:latest",
temperature=0.3, # 控制創造性(0-1)
num_ctx=4096 # 上下文長度
)
prompt = ChatPromptTemplate.from_messages([
("system", "你是一個Linux 性能調優專家,現在請回答客戶的問題"),
("human", "{input}")
])
chain = prompt | llm
print(chain.invoke({"input": "CPU 使用率 100% 如何排查?"}))
<think>
嗯,用戶說他的CPU使用率一直顯示100%,這可能是個問題。首先,我得考慮一下是不是系統出現了死循環或者進程卡住了。比如,后臺運行了很多程序,特別是那些長時間運行的腳本或服務,可能會占用大量的CPU資源。
.....................................
總之,要排查CPU使用率100%的問題,需要從系統資源、進程行為、磁盤I/O以及軟件配置等多個方面進行全面檢查,逐步縮小范圍找到具體原因。
</think>
如果您的系統顯示CPU使用率為100%,這通常意味著系統的資源被耗盡或存在一些問題。以下是一些可能的原因和排查步驟:
### 1. **檢查進程占用**
- 使用命令 `top` 或 `htop` 查看當前運行的進程,確認是否有進程長時間運行或占用大量CPU資源。
```bash
top
```
- 如果發現某個進程的CPU使用率持續在100%,可能是該進程存在問題。
。。。。。。。。。。。。。。。。。。