LangChain內置工具包和聯網搜索

目錄

一、什么是智能體?工具包又是什么?

二、智能體(Agent)的出現是為了解決哪些問題?

三、LangChain里面創建工具方式

?3.1??@tool 裝飾器:用來定義一個簡單的工具函數,, 可以直接給函數加上這個裝飾器,讓函數成為可調用的工具

3.2?StructuredTool

3.3?繼承BaseTool子類進行創建工具?

四、LangChain工具包

4.1 如何使用內置工具包【聯網搜索例子】

4.2 內置工具包整合LLM

4.3工具包調用Log

五、LangChain智能體執行引擎AgentExecutor


導讀:本文圍繞如何利用LangChain構建一個能夠通過自然語言與MySQL數據庫交互的AI智能體展開,詳細介紹了從問題理解到SQL生成、執行再到結果解析的完整流程。文章首先強調了該智能體的核心能力:將用戶提出的自然語言問題轉化為結構化查詢語句(如“統計每個地區的銷量”),并自動連接數據庫執行查詢。在此基礎上,系統還能將原始數據以更易理解的方式呈現給用戶(例如將數值結果轉換為自然語言描述)。此外,智能體具備自動修正SQL語法錯誤的能力,提高了系統的魯棒性和用戶體驗。技術實現上使用了LangChain中的SQLDatabaseToolkitcreate_sql_agent工具,結合LLM(如Qwen)進行推理與決策,實現了端到端的數據交互流程

一、什么是智能體?工具包又是什么?

  • 智能體是一種具備自主決策能力的AI系統,通過感知環境、分析信息、調用工具、執行動作的閉環過程完成任務

  • 智能體 = 大語言模型(LLM) + 工具(Tools) + 記憶(Memory)

智能體類比就是:一個具備自主決策能力的虛擬助手,能根據目標自主調用工具完成任務

二、智能體(Agent)的出現是為了解決哪些問題?

  • 大模型的短板:雖然大語言模型(LLM)擅長文本生成,但缺乏:

    • 實時數據獲取能力(如天氣/股票)、精確數學計算能力

    • 專業領域知識(如法律/醫療)、外部系統對接能力

  • Tool工具就是解決這類問題的,通過Tool機制,好比給大模型插入翅膀

大白話解釋: 你可以把“工具”理解為你在寫程序時定義的一個個方法或函數。比如在 Java 或 Python 中,你經常會封裝一些功能,用來完成特定的任務。如果這個方法是用來調用外部服務的 API(比如高德地圖的開放接口),那它就是一個“工具”。

以高德地圖為例,如果你想獲取某個地點的數據,可能需要向高德提供的 API 發送請求。這時候你就可以在 Python 中寫一個方法,讓它去調用這個 API,然后把結果返回給你。只要在這個方法上加上特定的注解(比如 @tool),它就會被識別為一個“工具”,可以在系統中被自動發現和使用。

簡單來說,這個“工具”就是幫你干活的小助手,它可以聯網、調用外部接口、執行任務,最終幫你拿到想要的信息或者完成某個操作。

三、LangChain里面創建工具方式

  • @tool裝飾器

    • 通過簡單的@tool裝飾器或StructuredTool即可實現,適用于大多數用例,

    • @tool但不能同時有同步和異步的方法,只能單獨使用

  • LangChain Runnables

    • 接受字符串或字典輸入的LangChain Runnables使用as_tool方法轉換為工具

    • 允許為參數指定名稱、描述和其他模式信息;

  • 繼承BaseTool類:

    • 通過從BaseTool進行子類化來定義自定義工具,提供了對工具定義的最大控制,但需要編寫更多的代碼。

?3.1??@tool 裝飾器:用來定義一個簡單的工具函數,, 可以直接給函數加上這個裝飾器,讓函數成為可調用的工具

from langchain_core.tools import tool@tool
def multiply(a: int, b: int) -> int:"""把傳遞的兩個參數相乘"""return a * bprint("工具名稱:", multiply.name)
print("工具描述:", multiply.description)
print("工具參數:", multiply.args)
print("工具返回值:", multiply.return_direct)
print("工具詳細的schema:", multiply.args_schema.model_json_schema())print(multiply.invoke({"a": 2, "b": 3}))
# 定義了一個 `multiply` 工具,用于兩個數字相乘,并在調用時顯示該工具的名稱、描述和參數列表。

3.2?StructuredTool

  • 是LangChain中用于定義結構化參數工具的基類,相比普通@tool裝飾器,它支持:

    • 嚴格的參數模式定義(基于Pydantic模型)

    • 多參數輸入校驗

    • 自動生成工具調用示例

  • 適用場景:需要多個輸入參數或復雜參數類型的工具

from pydantic import BaseModel, Field
from langchain_core.tools import StructuredTool# 定義輸入參數的數據結構
class CalculatorInput(BaseModel):a: int = Field(description="第一個數字")b: int = Field(description="第二個數字")# 定義計算函數
def multiply(a: int, b: int) -> int:"""Multiply two numbers."""return a * b
# 封裝工具
calculator = StructuredTool.from_function(func=multiply,name="Calculator",description="用于計算兩個數字的乘積",args_schema=CalculatorInput,return_direct=True,
)
print("工具名稱:", calculator.name)
print("工具描述:", calculator.description)
print("工具參數:", calculator.args)
print("工具返回值:", calculator.return_direct)
print("工具詳細的schema:", calculator.args_schema.model_json_schema())# 調用工具
print("工具調用結果:", calculator.invoke({"a": 2, "b": 3}))

3.3?繼承BaseTool子類進行創建工具?

from pydantic import BaseModel, Field
from typing import Type
from langchain_core.tools import BaseTool
from pydantic import BaseModelclass CalculatorInput(BaseModel):a: int = Field(description="第一個參數")b: int = Field(description="第二個參數")class CustomCalculatorTool(BaseTool):name: str = "Calculator"description: str = "當你需要計算數學問題時候使用"args_schema: Type[BaseModel] = CalculatorInputreturn_direct: bool = Truedef _run(self, a: int, b: int) -> str:"""使用工具."""return a * bcalculator = CustomCalculatorTool()
print("工具名稱:", calculator.name)
print("工具描述:", calculator.description)
print("工具參數:", calculator.args)
print("工具返回值:", calculator.return_direct)
print("工具詳細的schema:", calculator.args_schema.model_json_schema())
print(calculator.invoke({"a": 2, "b": 3}))

@tool 用的會多一些~

四、LangChain工具包

為了方便開發者快速使用各種主流工具,LangChain官方加入了很多內置工具,開箱即用

所有工具都是 BaseTool 的子類,且工具是 Runnable可運行組件,支持 invoke、stream 等方法進行調用
也可以通過 name、 description、args、 returu_direct 等屬性來獲取到工具的相關信息
如果內置工具包不滿足,即可以自定義工具
地址:https://python.langchain.com/docs/integrations/tools/

4.1 如何使用內置工具包【聯網搜索例子】

選擇對應的工具->安裝依賴包->編寫代碼實戰

搜索工具:選擇 SearchApi,注冊時100次免費搜索,注冊賬號獲取 APIKEY

代碼實操:

import os# 從langchain_community.utilities模塊中導入SearchApiAPIWrapper類,用于封裝搜索API
from langchain_community.utilities import SearchApiAPIWrapper# 設置環境變量SEARCHAPI_API_KEY,用于認證搜索API的密鑰
os.environ["SEARCHAPI_API_KEY"] = "UVWAsik11111111"# 實例化SearchApiAPIWrapper對象,用于調用搜索API
search = SearchApiAPIWrapper()# 調用run方法執行搜索操作,參數為查詢騰訊股價的中文字符串
result = search.run("今天騰訊的股價是多少")# 輸出搜索結果
print(result)

4.2 內置工具包整合LLM

這種是相對原始調用工具方式,下面章節會講經常用的簡便方式.這種是方便理解工具調用的底層方式

# 基于LangChain 0.3.x的SearchApi工具實戰(需安裝依賴)
# pip install langchain-core langchain-openai langchain-communityfrom langchain_community.utilities import SearchApiAPIWrapper
from langchain_core.tools import tool
from langchain_openai import ChatOpenAI
from langchain_core.messages import ToolMessage
from langchain_core.runnables import RunnablePassthrough
from langchain_core.prompts import ChatPromptTemplateimport os
from langchain_core.tools import tool
from pydantic import Field
import loggingos.environ["LANGCHAIN_TRACING_V2"] = "true"
os.environ["LANGCHAIN_API_KEY"] = "lsv2_pt_da11ddbcbb1111111111"
os.environ["LANGSMITH_ENDPOINT"] = "https://api.smith.langchain.com"
os.environ["LANGSMITH_PROJECT"] = "nnw_agent-search-llm"
logging.basicConfig(level=logging.DEBUG)
# ======================
# 第一步:配置搜索工具
# ======================
# 注冊SearchAPI獲取密鑰:https://www.searchapi.io/# 設置SearchAPI的API密鑰
os.environ["SEARCHAPI_API_KEY"] = "UVWAs1111111111"
# 實例化SearchApiAPIWrapper對象,用于調用搜索API
search = SearchApiAPIWrapper()# ======================
# 第二步:定義搜索工具
# ======================
@tool("web_search", return_direct=True)
def web_search(query: str) -> str:"""當需要獲取實時信息、最新事件或未知領域知識時使用,輸入應為搜索關鍵詞"""try:results = search.results(query)  # 獲取前3條結果return "\n\n".join([f"來源:{res['title']}\n內容:{res['snippet']}"for res in results["organic_results"]])except Exception as e:return f"搜索失敗:{str(e)}"# ======================
# 第三步:綁定LLM創建Agent
# ======================
# 初始化大模型
llm = ChatOpenAI(model_name="qwen-plus",base_url="https://dashscope.aliyuncs.com/compatible-mode/v1",api_key="sk-005c3c25f6d0111111111",temperature=0.7,
)# 創建聊天提示模板
prompt = ChatPromptTemplate.from_messages([("system","你是一個AI助手,名稱叫老王,請根據用戶輸入的查詢問題,必要時可以調用工具幫用戶解答",),("human", "{query}"),]
)# 定義工具字典
tool_dict = {"web_search": web_search}# 從字典中提取工具列表
tools = [tool_dict[tool_name] for tool_name in tool_dict]# 綁定工具到大模型
llm_with_tools = llm.bind_tools(tools=tools)# 創建運行鏈
chain = {"query": RunnablePassthrough()} | prompt | llm_with_tools# 定義查詢
query = "今天北京天氣如何?"# 執行鏈并獲取響應
resp = chain.invoke({"query": query})
print(resp)# 判斷是否需要調用工具 content=''不一定需要調用,根據tool_calls進行判斷
# ======================
# 第四步:獲取工具調用
# ======================
tool_calls = resp.tool_calls
if len(tool_calls) <= 0:print(f"不需要調用工具:{resp.content}")
else:# 將歷史消息合并,包括用戶輸入和AI輸出history_messages = prompt.invoke(query).to_messages()history_messages.append(resp)print(f"歷史消息:{history_messages}")# 循環調用工具for tool_call in tool_calls:tool_name = tool_call.get("name")tool_args = tool_call.get("args")tool_resp = tool_dict[tool_name].invoke(tool_args)print(f"一次調用工具:{tool_name},參數:{tool_args},結果:{tool_resp}")# 將工具調用結果添加到歷史消息中history_messages.append(ToolMessage(tool_call_id=tool_call.get("id"), name=tool_name, content=tool_resp))print(f"歷史消息:{history_messages}")resp = llm_with_tools.invoke(history_messages)print(f"最終結果:{resp}")print(f"調用工具后的結果:{resp.content}")

4.3工具包調用Log

工具調用輸入和輸出

將用戶輸入的自然語言和工具列表一起輸送給大模型 --> 讓大模型進行語義理解 --> 然后大模型將需要調用的工具發送給agent -->agent進行工具調用 --> 工具調用結果同輸入的自然語言問題和提示詞等一起再送給大模型-->大模型經過最終整理后返回處理結果

五、LangChain智能體執行引擎AgentExecutor

為什么需要 AgentExecutor?

問題:當智能體(Agent)需要執行多步操作(如多次調用工具、循環推理)時,開發者需手動處理:
執行循環:根據模型輸出決定是否繼續調用工具。
錯誤處理:捕獲工具調用或模型解析中的異常。
流程控制:限制最大迭代次數,防止無限循環。
日志記錄:追蹤每一步的輸入、輸出和中間狀態。

痛點:
代碼冗余:重復編寫循環和錯誤處理邏輯。
維護成本高:復雜任務中難以保證流程穩定性。
可觀測性差:難以調試多步驟執行過程

通過上面的例子就可以知道 寫起來很麻煩 還要手動調用工具。

create_tool_calling_agent?

  • 是 LangChain 0.3 新增的智能體創建方法, 要求模型直接返回工具調用參數(如 JSON 格式),減少中間解析錯誤。

  • 結構化工具調用:顯式調用工具并傳遞結構化參數(支持復雜數據類型)

  • 多步驟任務處理:適合需要按順序調用多個工具的場景

  • 精準控制:通過自定義 Prompt 模板指導 Agent 行為

from langchain_openai import ChatOpenAI
from langchain.agents import create_tool_calling_agent, Tool, AgentExecutor
from langchain.tools import tool
from datetime import datetime
from langchain_core.prompts import ChatPromptTemplate# 定義獲取當前日期的工具函數
@tool
def get_current_date() -> str:"""獲取當前日期"""formatted_date = datetime.now().strftime("%Y-%m-%d")return f"The current date is {formatted_date}"# 定義搜索航班的工具函數
@tool
def search_flights(from_city: str, to_city: str, date: str) -> str:"""根據城市和日期搜索可用航班"""return f"找到航班:{from_city} -> {to_city},日期:{date},價格:¥1200"# 定義預訂航班的工具函數
@tool
def book_flight(flight_id: str, user: str) -> str:"""預訂指定航班"""return f"用戶 {user} 成功預訂航班 {flight_id}"# 定義獲取股票價格的函數
def get_stock_price(symbol) -> str:return f"The price of {symbol} is $100."# 創建工具列表,包括獲取股票價格、搜索航班、預訂航班和獲取當前日期的工具
tools = [Tool(name="get_stock_price", func=get_stock_price, description="獲取指定的股票價格"),search_flights,book_flight,get_current_date,
]# 初始化大模型
llm = ChatOpenAI(model_name="qwen-plus",base_url="https://dashscope.aliyuncs.com/compatible-mode/v1",api_key="sk-005cxxxxxx",temperature=0.7,
)# 定義聊天提示模板
prompt = ChatPromptTemplate.from_messages([("system", "你是一個AI助手,必要時可以調用工具回復問題"),("human", "我叫老王,經常出差,身份證號是 33333333333333"),# ("placeholder", "{chat_history}"),("human", "{input}"),("placeholder", "{agent_scratchpad}"),]
)# 創建代理 專為工具調用優化的智能體,支持結構化輸出。
agent = create_tool_calling_agent(llm, tools, prompt)# 初始化代理執行器 , verbose=True可以看到思考明細, return_intermediate_steps返回中間結果
agent_executor = AgentExecutor(agent=agent, tools=tools, verbose=True, return_intermediate_steps=True
)# 運行代理并獲取結果
result = agent_executor.invoke({"input": "蘋果股票是多少?根據我的行程,幫我查詢下明天的航班,從合肥去北京,并定機票"}
)
print(f"最終結果:{result}")

LLM大模型訪問MySQL業務數據庫文章瀏覽閱讀1k次,點贊25次,收藏16次。創建能通過自然語言與SQL數據庫交互的AI智能體,自動生成/執行SQL查詢并解析結果核心能力:將用戶問題(如“統計每個地區的銷量”)轉化為 SQL 查詢語句。連接數據庫執行 SQL,默認只讀模式防止數據誤修改。將數據庫返回的原始數據(如)轉換為用戶友好的回答(如“總銷售額為 $3500”)。自動修正 SQL 語法錯誤或邏輯問題(如字段名拼寫錯誤)。LangChain 中專門用于連接 SQL 數據庫并集成相關操作工具的模塊包#使用 SQLDatabase.from_uri 連接數據庫,自動讀取表結構。_大模型 讀取 mysql數據庫 回答 https://blog.csdn.net/wnn654321/article/details/148933263?這是一個完整的例子,使用的create_sql_agent SQLDatabaseToolkit(langchain定義的工具)

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/web/87867.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/87867.shtml
英文地址,請注明出處:http://en.pswp.cn/web/87867.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

用c++做游戲開發至少要掌握哪些知識?

成長路上不孤單&#x1f60a;&#x1f60a;&#x1f60a;&#x1f60a;&#x1f60a;&#x1f60a; 【14后&#x1f60a;///C愛好者&#x1f60a;///持續分享所學&#x1f60a;///如有需要歡迎收藏轉發///&#x1f60a;】 今日分享關于用C做游戲開發的相關內容&#xff01; 關…

vue3使用summernote

一、安裝 npm install summernote-vue jquery summernote bootstrap popperjs/core二、summernoteEditor.vue <template><div ref"editorRef"></div> </template><script setup> import {ref, onMounted, onBeforeUnmount, watch} f…

低代碼平臺的性能測試實踐與挑戰

一、引言 近年來&#xff0c;低代碼平臺&#xff08;Low-Code Platform&#xff09;正在快速改變企業軟件開發方式。Gartner 預測&#xff0c;到 2025 年&#xff0c;超過 70% 的應用開發將基于低代碼或無代碼技術。通過“拖拉拽建模 圖形化邏輯 一鍵發布”&#xff0c;企業…

Stereolabs ZED系列與ZED X立體相機系列對比:如何根據項目需求選擇?

Stereolabs是全球領先的三維視覺技術公司&#xff0c;專注于為機器人、自動化和空間感知等領域提供高性能視覺解決方案。其ZED立體相機系列包括ZED和ZED X兩大系列&#xff0c;分別針對多場景三維感知和工業級應用設計&#xff0c;為企業和開發者提供了豐富的選擇。ZED系列&…

Spring Boot登錄認證實現學習心得:從皮膚信息系統項目中學到的經驗

前言 最近通過一個皮膚信息管理系統的項目實踐&#xff0c;深入學習了Spring Boot框架中登錄認證功能的實現方式。這個項目涵蓋了從后端配置到前端集成的完整流程&#xff0c;讓我對現代Web應用的安全機制有了更深刻的理解。本文將分享我在這個過程中的學習心得和技術要點。 …

【初階數據結構】雙向鏈表

文章目錄 雙向鏈表1.申請節點2.鏈表初始化3.尾插4.打印鏈表5.頭插6.尾刪7.頭刪8.查找9.指定位置插入10.刪除pos節點11.鏈表的銷毀12.程序源碼 雙向鏈表 鏈表分類 8種 (帶頭/不帶頭 單向/雙向 循環/循環) 最常用兩種 單鏈表(不帶頭單向不循環鏈表) 雙向鏈表&#xff08;帶頭雙向…

從 Prompt 管理到人格穩定:探索 Cursor AI 編輯器如何賦能 Prompt 工程與人格風格設計(下)

六、引入 Cursor AI 編輯器的開發流程革新 在整個系統開發過程中&#xff0c;我大量采用了 Cursor 編輯器作為主要的開發環境&#xff0c;并獲得以下關鍵收益&#xff1a; 具備 AI 補全與代碼聯想功能&#xff1a;支持通過內置 Copilot 模型對 Python、FastAPI、YAML、JSON 等…

Spark運行架構

Spark框架的核心是一個計算引擎&#xff0c;整體來說&#xff0c;它采用了標準master-slave的結構 ?如下圖所示&#xff0c;它展示了一個Spark執行時的基本結構&#xff0c;圖形中的Driver表示master&#xff0c;負責管理整個集群中的作業任務調度&#xff0c;圖形中的Executo…

基于未合入PR創建增量patch的git管理方法

目錄前言準備操作步驟精準移植基礎PR到本地分支修改代碼鴻蒙編譯、調試、測試具體編譯指令、測試步驟這里帶過&#xff0c;這不是本文論述重點創建diff文件工作倉庫應用最新patch總結前言 作為程序員&#xff0c;多人協同開發同一個需求是正常的。即使是自己一個人搞需求&…

git真正更新項目

背景 Fetch all remote后flutter代碼都拉下來&#xff0c;都是Android項目應用不上&#xff1b;git–>update project才生效&#xff01;&#xff01;&#xff01;

AI時代如何拓展Web前端開發的邊界

文章目錄 1 從“頁面仔”到“智能體驗構建者”——前端的變與不變2 AI 如何重塑 Web 前端&#xff1a;從開發到用戶體驗的革命2.1 AI 賦能開發效率&#xff1a;前端工程師的“超級外掛”2.1.1 智能代碼輔助與生成2.1.2 自動化測試與 Bug 定位 2.2 AI 提升用戶體驗&#xff0c;構…

chrome webdrive異常處理-session not created falled opening key——仙盟創夢IDE

注冊表錯誤 :EKKOK:chromeinstallerut1 Lgoogle update settings.cc:26b falled opening key .( e\Update\ClientStateMedium 8A69D345-D564-463c-AFF1-A69D9E530F96} to set usagestats 連接超時 disconnected: received Inspector.detached eventfailed to check if windo…

【Java EE初階 --- 多線程(進階)】JUC

樂觀學習&#xff0c;樂觀生活&#xff0c;才能不斷前進啊&#xff01;&#xff01;&#xff01; 我的主頁&#xff1a;optimistic_chen 我的專欄&#xff1a;c語言 &#xff0c;Java 歡迎大家訪問~ 創作不易&#xff0c;大佬們點贊鼓勵下吧~ 文章目錄 JUC組件ReentrantLock與s…

免費靜態網站搭建

免費靜態網站搭建 內容簡介搭建步驟GitHub倉庫創建Jekyll安裝使用Jekyll安裝指南Jekyll快速搭建測試Jekyll后續玩法 內容簡介 &#x1f6a9;Tech Contents&#xff1a;GithubPage/Jekyll/Custom URLs &#x1f431;GitHub Pages&#xff1a;靜態網站托管服務&#xff0c;自動將…

MySQL 8.0 OCP 1Z0-908 題目解析(21)

題目81 Choose two. Examine the modified output: mysql> SHOW SLAVE STATUS\G *************************** 1. row ***************************Slave_IO_Running: YesSlave_SQL_Running: YesSeconds_Behind_Master: 1612Seconds_Behind_Master value is steadily gro…

Web前端開發-HTML、CSS

文章目錄是什么&#xff1f;HTML快速入門VS Code開發工具基礎標簽&樣式新浪新聞-標題標題排版標題樣式標題樣式-1標題樣式-2超鏈接新浪新聞-正文新浪新聞-正文排版新浪新聞-頁面布局表格標簽表單標簽表單標簽-表單項是什么&#xff1f; HTML快速入門 VS Code開發工具 基礎標…

Vue.js狀態管理: Vuex在大型項目中的實際應用

# Vue.js狀態管理: Vuex在大型項目中的實際應用 ## 一、Vuex核心架構與大型項目適配 ### 1.1 狀態管理&#xff08;State Management&#xff09;的本質需求 在復雜前端系統中&#xff0c;組件間的數據傳遞成本隨項目規模呈指數級增長。根據Vue官方統計&#xff0c;超過500個組…

C++開發:結構體作為函數形參的值傳遞與引用傳遞

筆者定義了一個結構體變量&#xff0c;用于作為函數的形參&#xff0c;定義如下&#xff1a;struct CardParameters {float* Average nullptr;int averageSize 0; }; 需求描述&#xff1a;結構體變量作為函數的形參&#xff0c;在函數體中給指針變量分配內存空間并賦值&#…

【unity小技巧】在 Unity 中將 2D 精靈添加到 3D 游戲中,并實現陰影投射效果,實現類《八分旅人》《饑荒》等等的2.5D游戲效果

注意&#xff1a;考慮到unity小技巧的內容比較多&#xff0c;我將該內容分開&#xff0c;并全部整合放在【unity小技巧】專欄里&#xff0c;感興趣的小伙伴可以前往逐一查看學習。 文章目錄 前言實戰1、在3D場景中&#xff0c;新建一些不同形狀的2D圖片2、我們新建一個Lit材質3…

Rust 內存結構:深入解析

Rust 的內存管理系統是其核心特性之一&#xff0c;結合了手動內存管理的效率與自動內存管理的安全性。以下是 Rust 內存結構的全面解析&#xff1a; 內存布局概覽 ----------------------- | 代碼段 (Text) | 只讀&#xff0c;存儲可執行指令 ----------------------…