精品欧美一区二区三区在线观看 _久久久久国色av免费观看性色_国产精品久久在线观看_亚洲第一综合网站_91精品又粗又猛又爽_小泽玛利亚一区二区免费_91亚洲精品国偷拍自产在线观看 _久久精品视频在线播放_美女精品久久久_欧美日韩国产成人在线

LangChain V1.0 深度解析:手把手帶你跑通全新智能體架構

人工智能
LangChain V1.0 在代碼使用層面表現為“更統一、更可控、更生產就緒” —— 以 create_agent() 為核心入口,以 middleware 為擴展機制,以標準 message 塊與統一接口為基礎,為構建現代 LLM agent 系統提供了清晰、穩定的框架。所以下面的課程里,我們就一起來看看,如何基于最新版的 Agent 創建機制實現智能體的快速搭建吧!

LangChain V1.0 簡介

終于,萬眾矚目的 LangChain V1.0 版本正式發布了!

那對于最新的 V1.0 版本而言,其最顯著的代碼層面變化集中在 create_agent() 方法。如果你之前沒有用過舊版本的LangChain,那么以下關于更新內容的介紹可以跳過不看。

首先,create_agent() 變成了構建 agent 的標準入口,它封裝了底層 LangGraph 的 graph 執行機制,將“模型調用 → 決策工具 → 執行工具 → 返回結果”這一閉環流程封裝在一個高階接口中。所以們在文檔中也可以看到這樣一句話:

create_agent is the standard way to build agents in LangChain 1.0

其次,原來在早期版本中需要手動配置 prompts、 hook 、狀態定義等細節,在 V1.0 中這些被抽象為 middleware 機制(如 before_model、wrap_tool_call 等),開發者可以通過傳 middleware 數組把通用邏輯拼入,而不需改原 agent 核心邏輯。這大大的方便了開發者能夠打造真正應用于生產的智能體(過去很多時候用 LangChain 的 create_react_agent 往往打造的只是一個“玩具”而已)。

再者,參數命名和入口路徑也發生了遷移:如 prompt 變為 system_prompt。這意味著我們不需要再從 hub (已經移出核心框架遷移至 langchain-classic )里去輸入大段的提示詞了,只需要傳入系統提示詞就夠了,LangChain 后臺會自動幫我們組合成完整的提示詞引導模型的行為。

除此之外,舊的 create_react_agent() 和 AgentExecutor 被替換并遷移至 langchain-classic 。同時過去的傳統鏈(比如 LLMChain )和傳統記憶方式(比如 CoversationBufferMemory) 也被遷移至 langchain-classic 。

這些改動意味著:如果你之前基于較早版本開發,遷移到 V1.0 將需要重構部分 import 路徑、參數名稱、狀態定義方式、 agent 構建方式等。并且最好將其升級為最新的鏈(LCEL)和記憶(RunnableWithMessageHistory() 或 InMemorySaver())等方法。

總的來說,LangChain V1.0 在代碼使用層面表現為“更統一、更可控、更生產就緒” —— 以 create_agent() 為核心入口,以 middleware 為擴展機制,以標準 message 塊與統一接口為基礎,為構建現代 LLM agent 系統提供了清晰、穩定的框架。所以下面的課程里,我們就一起來看看,如何基于最新版的 Agent 創建機制實現智能體的快速搭建吧!

前期準備

在正式開始之前,我們需要準備幾個事情。第一個就是安裝最新版的 LangChain。

pip install -U langchain langgraph langchain-community dashscope arxiv

然后就是到阿里云獲取一下 API_Key,并且最好將其設置到環境變量之中(DASHSCOPE_API_KEY)。

那獲取到了密鑰后,只要能夠成功運行以下代碼就代表以準備完成:

from langchain_community.chat_models import ChatTongyi
from langchain_core.messages import HumanMessage
import os

# 初始化模型
llm = ChatTongyi(api_key=os.environ.get("DASHSCOPE_API_KEY"))

# 發送消息
response = llm.invoke([HumanMessage(content="你好,請用一句話介紹一下你自己。")])

print(response.content)

快速搭建智能體

一、智能體簡介

首先我們可以在官方文檔看到 create_agent 的 graph 形式:

圖片圖片

從本質上來說,create_agent 打造的就是一個基礎的 ReAct Agent 的形式,就是我們把問題傳給大模型,然后讓大模型思考需要使用什么工具(action),然后調用完工具獲取到的結果(observation)返回給大模型。接著大模型再去不斷的重復這個循環直到其認為已經搜集到足夠的信息或者完成指定的任務后,就會退出這個循環(finish)并給出最終的回復。

那在這個場景下,create_agent 需要我們準備以下幾個基本的組件:

  1. 模型(也就是前面的 ChatTongyi )
  2. 工具庫(內置工具或自建工具)
  3. 記憶(幫助模型直到當前進行到哪一步)
  4. 提示詞(引導模型)

那我們下面就來一個個的看看如何創建這些基本的組件并快速搭建一個智能體!

導入模型

那首先我們還是像前面一樣準備好模型:

from langchain_community.chat_models import ChatTongyi
import os
llm = ChatTongyi(api_key=os.environ.get("DASHSCOPE_API_KEY"))

這里的模型我們選擇 ChatTongyi 的主要原因不僅僅只是我們這個課程一直都用, 還因為在 LangChain 里其實就屬通義千問的適配性最好,而且其還支持工具調用,具體后面我們會提到。

二、導入工具

前面提到 LangChain 里主要有兩種方式導入工具,一種是內置工具,另外一種是自行創建,那我們分別進行闡述一下。

(1)內置工具

根據LangChain的官方文檔[1],目前 LangChain 提供支持的有以下幾類工具:

  • 搜索工具:用于在線搜索,包括 Bing、Google、DuckDuckGo 等搜索接口。返回內容一般包括:URL、標題、摘要等。
  • 代碼輔助工具:支持 Python、JavaScript 等語言的代碼執行環境,可用于復雜計算或文件處理。
  • 生產力工具:用于對接 Gmail、Office365、Slack、Jira 等辦公/協作平臺,實現任務自動化。
  • 網頁瀏覽:用于瀏覽網頁、交互操作、信息抓取(如Hyperbrowser 等)。
  • 數據庫:支持與數據庫交互,包括 SQL、Spark SQL 等數據庫的讀取與操作。
  • 其他常用工具:維基百科、ArXiv、Python REPL。

由于網絡的原因,其實大部分的內置工具我們是用不了的,只有一些特定的工具我們能夠使用,包括論文查詢工具 arxiv、計算器工具 llm-math、維基百科 wikipedia 以及執行 python 代碼的 python_repl 。

假如我們要導入這些內置工具的話,我們需要使用 langchain_community 里的 load_tools 方法進行載入。

from langchain_community.agent_toolkits.load_tools import load_tools
tools = load_tools(["arxiv"])

假如我們需要導入多個工具的話,我們可以在后面不斷添加(部分依賴語言模型來執行計算或生成代碼需要傳入一個 LLM 實例)。例如:

tools = load_tools(["arxiv","llm-math", "wikipedia"], llm=llm)

除此之外,load_tools這個方法還有一個實參是 allow_dangerous_tools,具體是在本地執行代碼、讀寫文件等(如python_repl工具)是需要開啟,因為運行 python 代碼可能會涉及刪除文件等操作。例如:

tools = load_tools(["python_repl"], llm=llm, allow_dangerous_tools=True)

(2)自定義工具

自定義工具其實本質上就是定義一個函數,比如現在我有一個基于 eval() 的計算器工具函數 calculate:

def calculate(what):
    return str(eval(what))

print(calculate("3 + 7 * 2"))   # 返回 17
print(calculate("10 / 4"))      # 返回 2.5

假如我希望將其改造為一個 LangChain 所支持的工具的話我需要在函數上方加上一個 @tool 裝飾器:

from langchain.tools import tool

@tool
def calculate(what):
    return str(eval(what))

然后呢!還需要加上介紹函數相關信息的文檔字符串以及輸入輸出參數說明:

from langchain.tools import tool

@tool
def calculate(what: str) -> str:
    """
    calculate:
    e.g. calculate: 4 * 7 / 3
    Runs a calculation and returns the number - uses Python so be sure to use floating point syntax if necessary
    """
    return str(eval(what))

當然其實我們除了函數的文檔字符串以外,還可以添加輸入輸出參數的具體信息,比如我們可以通過 Pydantic 添加了一個輸入參數的介紹信息,然后通過 @tool 中的 args_schema 將這部分信息載入:

from pydantic import BaseModel, Field

class CalcInput(BaseModel):
    """Input for math calculation"""
    what: str = Field(descriptinotallow="A mathematical expression, e.g., '4 * 7 / 3'")
    
from langchain.tools import tool

@tool(args_schema=CalcInput)
def calculate(what: str) -> str:
    """
    calculate:
    e.g. calculate: 4 * 7 / 3
    Runs a calculation and returns the number - uses Python so be sure to use floating point syntax if necessary
    """
    return str(eval(what))

這樣的話這個工具在載入到 Agent 的時候就會創建成 Function Calling 的格式將這些信息傳給 LLM 進行參考使用:

functions = [
    {
        "name": "calculate",
        "description": "Runs a calculation and returns the number - uses Python so be sure to use floating point syntax if necessary",
        "parameters": {
            "type": "object",
            "properties": {
                "what": {
                    "type": "string",
                    "description": "A mathematical expression to evaluate, e.g. '4 * 7 / 3'"
                }
            },
            "required": ["what"]
        }
    }
]

(3)工具的組合

在定義好多個自定義工具后,我們可以將其組裝在一起傳給 Agent ,比如:

tools = [calculate, average_dog_weight]

但是假如我們想要的 LangChain 的內置工具一起傳入的話,我們的寫法需要變為:

tools = load_tools(["arxiv"] + [calculate, average_dog_weight])

那在后續的內容里,為了簡化整個流程,我們這里就選用 arxiv 作為智能體的工具進行演示(需要先安裝 arxiv,這在前期準備中已經完成):

from langchain_community.agent_toolkits.load_tools import load_tools
tools = load_tools(["arxiv"])

三、構建短期記憶

在前面講 LCEL 的內容里我們提到了,為了能夠包裹一個 runnable 的組件,我們所使用的是 RunnableWithMessageHistory 的記憶方法。但是由于現在智能體的創建是基于 LangGraph 實現的,因此我們所使用的記憶方法就不再是這個了,而是使用 InMemorySaver() 的方法實現短期記憶的存儲。

所謂的短期記憶呢,其實指的是只保存的是保存當前對話輪次、臨時上下文,用于連續對話或局部推理。那 InMemorySaver() 的作用是在圖(Graph)執行的過程中,保存 agent 的對話、狀態、工具調用等信息,讓系統在一次會話(session)中能“記住”先前的輸入輸出。

短期記憶的信息只存在與內存中(RAM),一旦程序關閉、刷新或重啟,數據就會消失。假如我們需要構建長期的記憶,我們需要把記憶存儲到數據庫中,在后面的進階內容中我們會更進一步的講述到。

那創建這個記憶的方法也非常的簡單,就是像之前的 CoversationBufferMemory 一樣創建后就會自動的保存所有的信息了:

from langgraph.checkpoint.memory import InMemorySaver 

memory = InMemorySaver()

那在這個短期記憶里會怎么保存我們的記憶呢?其實和之前的類似,比如我們在與大模型對話的過程中常見的就有幾類信息:

  • 系統提示詞(通常是第一條信息,用于引導模型整體的行為)
  • 用戶提示詞(用戶發出的問題)
  • 模型提示詞(模型對于用戶問題的回復或調用工具的指令)
  • 工具提示詞(在模型發出執行工具的指令后返回的信息)

那這個短期記憶就會把這些所有的信息都保存到 AgentState 當中,這個 AgentState 其實一個用于管理 Agent 當前狀態的結構(Schema),其默認格式大概是這樣的:

{"messages": [...],
  "thread_model_call_count": 1,
  "run_model_call_count": 1}

那這里面最重要的其實就是 "messages" (其他都是一些輔助的元數據),這里就保存了智能體在每個時間點上需要記住的所有上下文信息。比如像這樣簡單的一問一答(當然這里面有很多的元數據也會保存起來):

[HumanMessage(cnotallow="hi! I'm bob", additional_kwargs={}, response_metadata={}, id='beb6e2ba-c211-4283-a5d6-78566f567c86'), 

AIMessage(cnotallow="Hello Bob! It's nice to meet you. How can I assist you today?", additional_kwargs={}, response_metadata={'model_name': 'qwen-max', 'finish_reason': 'stop', 'request_id': 'aa493e36-a2d8-40ac-abc6-18d7d31735f7', 'token_usage': {'input_tokens': 227, 'output_tokens': 17, 'prompt_tokens_details': {'cached_tokens': 0}, 'total_tokens': 244}}, id='lc_run--ca2c7e95-ff30-46a6-8019-293b186f0bf7-0')]

那后續我們講到記憶的剪裁以及刪除等高級操作其實本質上都是對這個 AgentState 進行操作。

四、提示詞模版及智能體組裝

在前面的 LangChain 課程中我們是提到了兩種提示詞模版,一種是 PromptTemplate ,另一種是 ChatPromptTemplate 。前者簡單直接,適合單輪指令或單輸入;而后者支持多角色消息(System / Human / AI / Tool),并且可嵌入進 LCEL 表達式鏈,是 v1.0 的推薦寫法。

那在 create_agent 中,其實有一個和前面 create_react_agent 最大的不同點是我們不需要使用一大段的提示詞模版去引導模型進行回復了。比如說之前我們需要傳入一個像 LangChain Hub 上 hwchase17/react-chat 這樣的提示詞了:

Assistant is a large language model trained by OpenAI.

Assistant is designed to be able to assist with a wide range of tasks, from answering simple questions to providing in-depth explanations and discussions on a wide range of topics. As a language model, Assistant is able to generate human-like text based on the input it receives, allowing it to engage in natural-sounding conversations and provide responses that are coherent and relevant to the topic at hand.

Assistant is constantly learning and improving, and its capabilities are constantly evolving. It is able to process and understand large amounts of text, and can use this knowledge to provide accurate and informative responses to a wide range of questions. Additionally, Assistant is able to generate its own text based on the input it receives, allowing it to engage in discussions and provide explanations and descriptions on a wide range of topics.

Overall, Assistant is a powerful tool that can help with a wide range of tasks and provide valuable insights and information on a wide range of topics. Whether you need help with a specific question or just want to have a conversation about a particular topic, Assistant is here to assist.

TOOLS:
------

Assistant has access to the following tools:

{tools}

To use a tool, please use the following format:
"""

Thought: Do I need to use a tool? Yes Action: the action to take, should be one of [{tool_names}] Action Input: the input to the action Observation: the result of the action

"""

When you have a response to say to the Human, or if you do not need to use a tool, you MUST use the format:
"""

Thought: Do I need to use a tool? No Final Answer: [your response here]

"""

Begin!

Previous conversation history:
{chat_history}

New input: {input}
{agent_scratchpad}

在這個提示詞里我們可以看到其主要劃分為五部分:

  • 系統角色與能力設定
  • 工具介紹
  • 工具調用方式(ReAct 核心)
  • 無需工具時的結束協議
  • 運行時上下文注入(形成 ReAct 閉環)

那模型在運行時就會學著這里面的實現方式,比如在需要工具的時候輸出:

Thought: Do I need to use a tool? Yes
Action: the action to take, should be one of [{tool_names}]
Action Input: the input to the action

然后 LangChain 通過正則表達式的解析去執行對應的工具返回結果寫到 Observation 里:

action_match = re.search(r"Action: (.*)", text)
input_match = re.search(r"Action Input: (.*)", text)

但是這樣的方法有兩個問題,一個是假如某些模型的指令跟隨能力相對比較弱一些,可能沒有辦法在多輪對話中一直保持這樣輸出的模式。一旦模版輸出錯誤了,那就可能沒有辦法去解析了導致報錯。另一個問題是其實這種模版有很多,其實也不通用,所以整體也不太方便。

因此 LangChain V0.3 開始就重構了 Agent 層,從而讓開發者只描述能力,而不是再造 prompt。所以我們只需要輸入模型、工具列表、記憶以及系統提示詞(會在每一次傳入給模型時才傳入,不會放入記憶中)。然后在調用的時候傳入用戶提示詞,這樣 LangChain 會自動幫你構建完整的提示詞上下文。

那假如我們沒有直接在提示詞里告訴大模型具有有哪些工具,每個工具怎么使用的話,那大模型怎么知道要用什么呢?其實這個時候就要講到的是 LangChain 中的 bind_tools 方法。這個方法要求模型支持 OpenAI 的工具調用格式 Function Calling。在國內的大模型廠家中,明確說了模型支持 Function Calling 也就只有通義千問。這也是為什么在 LangChain 的所有課程中我們都是用 ChatTongyi 來進行演示的。

那什么是 Function Calling 呢?其實很簡單,Function Calling 是大模型在對話過程中調用外部工具函數的能力,它允許模型在無法直接回答問題時,返回一個函數調用請求(結構化的JSON)。然后開發者需要手動解析這個請求,執行對應的函數,并將結果傳回給模型,以生成最終答案。并在最后把結果返回給模型得到最終的回復。

比如說在 OpenAI 官方的這張圖就很好的解釋了 Function Calling 的運行過程:

第一步:把工具的信息以及問題傳給模型

第二步:由于模型支持工具調用,就會返回一個調用請求

第三步:開發者解析調用請求并執行

第四步:將調用請求的結果返回給大模型

第五步:返回最終的回復

圖片

那在 LangChain 里的話,當我們的工具載入到了 create_agent 中時,其實就會自動的將工具注冊為 Function Calling 的格式,并且每次調用的時候都會傳給模型讓其選擇。然后假如模型決定要調用工具的時候,就會發出類似下面的這段請求:

{
  "role": "assistant",
  "content": "",
  "tool_calls": [
    {
      "name": "get_weather",
      "arguments": {"city": "廣州"},
      "id": "tool_call_1"
    }
  ]
}

我們可以看到這里的 content 是空的,代表模型其實并沒有回復任何的內容,只不過是發出了一個 “tool_calls” ,然后里面寫入了對應函數的名稱,傳入的參數以及一些元數據。然后在 create_agent 內部就會自動的去解析這部分的內容。

假如模型已經獲取到了必要的信息,那其回復的內容應該就是下面這樣的:

{
  "role": "assistant",
  "content": "廣州的天氣是25度,祝你出行愉快",
  "tool_calls": []
}

這樣的方式就能夠讓模型更加準確的表達其執行的內容。而且 JSON 格式的內容也是更加的通用,所以 Function Calling 這個類似于 HTTPS 協議一樣的工具也被大量的推行。

好了,扯得好像有點遠,那既然我們不需要輸入完整的提示詞了,我們只需要輸入系統提示詞就足夠了,那我們要在哪里去寫入呢?其實當我們準備好前面的模型、工具及記憶以后,我們就在創建 create_agent 中寫入就行,比如像下面這樣:

from langchain.agents import create_agent

agent = create_agent(model=llm, 
                     tools=tools, 
                     system_prompt="You are a helpful assistant", 
                     checkpointer=memory)

這樣我們就把我們想要傳入的系統提示詞給寫入進去了。

五、調用智能體

那我們組裝好了一個智能體了以后,下一步我們就是去調用智能體并且獲取回復了。那本質上就是我們發送了一個用戶提示詞給到整體,比如像下面這樣:

{"messages": [{"role": "user", "content": "請使用 arxiv 工具查詢論文編號 1605.08386"}]}

這里我們就定義了一個字典,然后往 messages 信息里傳入了一個列表,這個列表里目前就是一條用戶提問的信息。當然我們也可以往這個列表里面添加更多的信息進去,這個就是看大家具體的需求了。

除了傳入用戶提問的問題以外呢,還有一個需要額外指定一個 記憶定位標識。這就好比我們在使用 conda 創建虛擬環境時,會為每個項目單獨建立一個環境,以避免依賴沖突。同樣地,在對話系統中,我們也希望不同用戶或不同任務的記憶彼此獨立,不會相互干擾。為此,我們可以通過傳入一個唯一的 thread_id(線程 ID)來區分不同的會話上下文。例如,下面的配置中,我們指定了 "user_1" 作為當前對話的標識:

cnotallow={"configurable": {"thread_id": "user_1"}}

這樣,系統就會在內存中為 "user_1" 維護一份獨立的對話記憶。如果下一次調用時仍然使用相同的 thread_id,模型就能“接著上次聊”;而如果換成一個新的 ID(例如 "user_2"),那么之前的記憶不會被繼承,相當于開啟了一場全新的對話。

準備好了這兩個以后呢,我們就可以使用 LangChain 中最常用的調用方法 .invoke() 去對智能體進行調用了,具體的方法如下:

result1 = agent.invoke({"messages": [{"role": "user", "content": "請使用 arxiv 工具查詢論文編號 1605.08386"}]}, cnotallow={"configurable": {"thread_id": "user_1"}})
print(result1)

這樣我們就可以成功的對模型進行調用了,調用的結果如下:

{'messages': [HumanMessage(cnotallow='請使用 arxiv 工具查
詢論文編號 1605.08386', additional_kwargs={}, response_metadata={}, id='804b6b57-a615-4797-996e-70a6822d7eeb'), AIMessage(cnotallow='', additional_kwargs={'tool_calls': [{'function': {'arguments': '{"query": "1605.08386"}', 'name': 'arxiv'}, 'id': 'call_1257191a65e448d1840fed', 'index': 0, 'type': 'function'}]}, response_metadata={'model_name': 'qwen-turbo', 'finish_reason': 'tool_calls', 'request_id': '6274123b-3ef1-4e83-85e8-3e1be634cf6c', 'token_usage': {'input_tokens': 232, 'output_tokens': 28, 'prompt_tokens_details': {'cached_tokens': 0}, 'total_tokens': 260}}, id='lc_run--5eddaf4e-bc5a-4f8b-8802-b6f6ed45b1c1-0', tool_calls=[{'name': 'arxiv', 'args': {'query': '1605.08386'}, 'id': 'call_1257191a65e448d1840fed', 'type': 'tool_call'}]), ToolMessage(cnotallow='Published: 2016-05-26\nTitle: Heat-bath random walks with Markov bases\nAuthors: Caprice Stanley, Tobias Windisch\nSummary: Graphs on lattice points are studied whose edges come from a finite set of\nallowed moves of arbitrary length. We show that the diameter of these graphs on\nfibers of a fixed integer matrix can be bounded from above by a constant. We\nthen study the mixing behaviour of heat-bath random walks on these graphs. We\nalso state explicit conditions on the set of moves so that the heat-bath random\nwalk, a generalization of the Glauber dynamics, is an expander in fixed\ndimension.', name='arxiv', id='fa8a6ea5-0e38-42b7-b846-8e872b302f3f', tool_call_id='call_1257191a65e448d1840fed'), AIMessage(cnotallow='論文編號 1605.08386 的標題是《Heat-bath random walks with Markov bases》。該論文于 2016 年 5 月 26 日發表,作者是 Caprice Stanley 和 Tobias Windisch。\n\n這篇論文研究了由有限的允許移動集生成的格點圖,這些移動可以是任意長度的。論文展示了在固定整數矩陣的纖維上,這些圖的直徑可以被常數從上面限制。然后研究了這些圖上的熱浴隨機游走的混合行為。此外,還給出了移動集的顯式條件,以確保熱浴隨機游走(Glauber 動力學的一種推廣)在固定維度下是一個擴展器。', additional_kwargs={}, response_metadata={'model_name': 'qwen-turbo', 'finish_reason': 'stop', 'request_id': 'f75c75a1-35ca-4bbb-bc71-ea9dd4233986', 'token_usage': {'input_tokens': 416, 'output_tokens': 156, 'prompt_tokens_details': {'cached_tokens': 0}, 'total_tokens': 572}}, id='lc_run--f0bf855c-4315-4559-b598-e4f4b74e5f05-0')]}

這里其實就把整個 agent 的運行過程都給打印出來了,包括:

  • 用戶輸入:
HumanMessage(cnotallow='請使用 arxiv 工具查詢論文編號 1605.08386')
  • 模型調用工具:
AIMessage(
  cnotallow='',
  additional_kwargs={
    'tool_calls': [
      {
        'function': {'name': 'arxiv', 'arguments': '{"query": "1605.08386"}'},
        'id': 'call_1257191a65e448d1840fed',
        'type': 'function'
      }
    ]
  },
  response_metadata={'finish_reason': 'tool_calls', 'model_name': 'qwen-turbo', ...}
)
  • 工具執行并返回結果:
ToolMessage(
  name='arxiv',
  cnotallow='Published: 2016-05-26\nTitle: Heat-bath random walks with Markov bases\nAuthors: Caprice Stanley, Tobias Windisch\nSummary: ...',
  tool_call_id='call_1257191a65e448d1840fed'
)
  • 模型整合工具結果并生成回復:
AIMessage(cnotallow='論文編號 1605.08386 的標題是《Heat-bath random walks with Markov bases》。該論文于 2016 年 5 月 26 日發表...')
  • 最后輸出 finish_reasnotallow='stop’ 表示任務完成。

這其實也是 ReAct Agent 的一個基本流程,假如我們要直接取最后一條信息作為輸出的話,我們可以在打印的時候進行指定:

print(result1["messages"][-1].content)

這個時候就只會回復下面的內容:

論文編號 1605.08386 的標題是《Heat-bath random walks with Markov bases》。該論文于 2016 年 5 月 26 日發表,作者是 Caprice Stanley 和 Tobias Windisch。\n\n這篇論文研究了由有限的允許移動集生成的格點圖,這些移動可以是任意長度的。論文展示了在固定整數矩陣的纖維上,這些圖的直徑可以被常數從上面限制。然后研究了這些圖上的熱浴隨機游走的混合行為。此外,還給出了移動集的顯式條件,以確保熱浴隨機游走(Glauber 動力學的一種推廣)在固定維度下是一個擴展器。

六、完整代碼

完整的代碼如下所示:

from langchain_community.chat_models import ChatTongyi
import os
llm = ChatTongyi(api_key=os.environ.get("DASHSCOPE_API_KEY"))

from langchain_community.agent_toolkits.load_tools import load_tools
tools = load_tools(["arxiv"])

from langgraph.checkpoint.memory import InMemorySaver 

memory = InMemorySaver()

from langchain.agents import create_agent

agent = create_agent(model=llm, 
                     tools=tools, 
                     system_prompt="You are a helpful assistant", 
                     checkpointer=memory)

result1 = agent.invoke({"messages": [{"role": "user", "content": "請使用 arxiv 工具查詢論文編號 1605.08386"}]}, cnotallow={"configurable": {"thread_id": "user_1"}})
print(result1["messages"][-1].content)

總結

總的來說,這節課我們完整講解了 LangChain V1.0 智能體(Agent)創建的全新機制。新版的核心在于 create_agent() 方法,它取代了舊版的 create_react_agent() 和 AgentExecutor,成為構建智能體的標準入口。其底層基于 LangGraph 執行機制,將“模型調用 → 工具決策 → 工具執行 → 結果整合”這一完整閉環封裝成統一流程,大幅提升了代碼的簡潔性與可維護性。

可以看到,LangChain V1.0 在設計上更加“工程化”和“生產可用”,讓智能體的構建更加輕量、結構更清晰。那在下一節課中,我們將基于本節內容進一步優化智能體的交互能力——包括引入多工具協作、增強記憶管理與上下文控制,打造一個更接近真實應用的多輪智能體。

參考資料

[1] LangChain的官方文檔: https://python.langchain.com/docs/integrations/tools/

責任編輯:武曉燕 來源: 機制流
相關推薦

2023-03-29 10:02:36

2023-01-30 09:27:57

開發自動化配置

2022-08-11 07:32:51

Starter自動裝配

2021-12-15 07:24:57

人工神經網絡翻譯

2022-11-07 18:36:03

組件RPC框架

2009-08-26 16:37:04

ibmdwRational

2011-05-03 15:59:00

黑盒打印機

2011-01-10 14:41:26

2025-05-07 00:31:30

2021-07-14 09:00:00

JavaFX開發應用

2020-12-13 11:38:09

Go語言clac包

2021-01-08 10:24:32

Python項目基礎

2010-04-29 09:49:26

代碼提示SQL Server

2021-06-07 09:35:11

架構運維技術

2011-03-02 14:31:05

WebMatrix

2009-08-25 16:47:32

統一通信視頻會議策略規劃

2011-02-22 13:46:27

微軟SQL.NET

2021-02-26 11:54:38

MyBatis 插件接口

2021-12-28 08:38:26

Linux 中斷喚醒系統Linux 系統

2023-04-26 12:46:43

DockerSpringKubernetes
點贊
收藏

51CTO技術棧公眾號

中文av字幕一区| 夜夜爽av福利精品导航| 国产suv精品一区二区883| 7777精品久久久大香线蕉| 国产精品视频一区二区高潮| 在线播放av网址| 国产免费a视频| av中文字幕在线播放| 成人羞羞动漫| 高清在线观看av| 国产www视频| 奇米777日韩| 亚洲精品tv| 成人在线免费视频观看| 亚洲精品喷潮一区二区三区| av在线免费网站| 成人sese在线| 国产精品国产三级国产aⅴ浪潮| 国产av无码专区亚洲av毛网站| 欧美1区2区3区4区| 欧美精品aⅴ在线视频| 日本少妇高潮喷水视频| 麻豆传媒视频在线| 久久色视频免费观看| 不卡一区二区三区视频| 中文字幕乱码人妻二区三区| 亚洲人成免费| 成年无码av片在线| 国产免费无遮挡吸奶头视频| 中文字幕一区二区三区中文字幕 | 紧身裙女教师波多野结衣| 林ゆな中文字幕一区二区| 9191成人精品久久| 欧美伦理片在线看| 欧美三级网站| 亚洲国产视频直播| 可以免费看的黄色网址| 中文字幕日本在线| 国产色爱av资源综合区| 久久riav二区三区| 好吊色视频一区二区| 精品一区二区三区在线播放视频| 日韩av电影免费观看高清| 精品亚洲永久免费| 欧美日韩mv| 久久久精品视频在线观看| 国产农村妇女精品一区| 精品黄色一级片| 亚洲视频精品在线| 爱爱的免费视频| 婷婷成人在线| 国产视频在线观看一区二区| 制服丝袜第一页在线观看| 亚洲精品一区国产| 精品久久国产老人久久综合| 性色av浪潮av| 试看120秒一区二区三区| 91精品国产高清一区二区三区蜜臀| 成年人在线观看视频免费| 麻豆免费版在线观看| 午夜一区二区三区视频| 国产精品va在线观看无码| 色呦呦呦在线观看| 亚洲一区二区视频在线观看| 男人添女荫道口喷水视频| 性网站在线观看| 亚洲一级在线观看| 99热自拍偷拍| 怡红院成人在线| 欧美三级在线播放| 8x8x成人免费视频| 日韩欧美一级| 亚洲国产中文字幕久久网| 亚洲国产第一区| 你懂的一区二区三区| 欲色天天网综合久久| av在线免费播放网址| 伊人久久大香线蕉精品组织观看| 欧美人与性动交| 国产精品第九页| 久久激情视频| 成人妇女免费播放久久久| 99久久久国产精品无码免费 | 国产亚洲成精品久久| 国产成人极品视频| 影音先锋国产资源| 国产乱理伦片在线观看夜一区| 成人午夜电影在线播放| 五月天婷婷在线观看| 国产亚洲自拍一区| 青草全福视在线| 草草在线视频| 欧美日韩视频在线一区二区| 欧美性猛交乱大交| 日本亚洲不卡| 精品国产一区二区三区久久狼5月 精品国产一区二区三区久久久狼 精品国产一区二区三区久久久 | 天堂在线观看av| 国产三级欧美三级| 狠狠干视频网站| 欧美www.| 精品国产不卡一区二区三区| 日韩中文字幕有码| 午夜精品久久久久99热蜜桃导演 | www污在线观看| 欧美xxxxxx| 制服.丝袜.亚洲.中文.综合| 日本一区二区在线免费观看| 水蜜桃久久夜色精品一区| 欧美精品videos| 夜夜狠狠擅视频| 99精品桃花视频在线观看| 一道本在线观看视频| 亚洲最大网站| 日韩欧美一卡二卡| 国产精品久久久久久成人| 欧美日韩网址| 成人高h视频在线| 猫咪在线永久网站| 亚洲一区二区av电影| 91国内在线播放| 亚洲警察之高压线| 久久久久久久久久久久久久久久久久av| 国产精品无码粉嫩小泬| 99riav久久精品riav| 欧美性受黑人性爽| 国精品产品一区| 亚洲美女福利视频网站| 国产精品第一页在线观看| 狠狠色丁香久久婷婷综合丁香| 欧美一区二区视频17c| аⅴ资源天堂资源库在线| 欧美精品色一区二区三区| 丁香花五月婷婷| 亚洲一区二区三区高清| 国产精品99久久久久久久| 国产精品扒开做爽爽爽的视频| 欧美性生交大片免费| 老司机免费视频| 亚洲午夜极品| 成人免费观看网站| 亚洲淫性视频| 日韩亚洲欧美高清| 日日骚一区二区三区| 久88久久88久久久| 亚洲精品在线免费看| 偷拍精品精品一区二区三区| 亚洲精品久久久久久久久久久久久 | 亚洲va天堂va欧美ⅴa在线| 中文字幕在线不卡视频| 中文字幕天天干| 波多野结衣在线观看一区二区三区| 欧美中文在线字幕| 欧美大片aaa| 色哟哟国产精品免费观看| 熟女人妻在线视频| 亚洲欧美日韩国产综合精品二区| 激情视频在线观看一区二区三区| 99thz桃花论族在线播放| 亚洲大胆人体在线| 中文字幕精品三级久久久| 91麻豆蜜桃一区二区三区| 国产素人在线观看| 真实原创一区二区影院| 国产精品igao视频| 日本在线免费看| 日韩欧美国产综合| 日韩黄色在线视频| 久久久午夜精品理论片中文字幕| 日韩视频在线免费看| 成人国产精品一级毛片视频| 国产日韩中文字幕| 亚洲妇熟xxxx妇色黄| 亚洲国语精品自产拍在线观看| 久久久久久久久久久影院 | 少妇被躁爽到高潮无码文| 国产成人综合视频| 97国产在线播放| 精品国产91乱码一区二区三区四区| 国产精自产拍久久久久久蜜| a级影片在线观看| 亚洲国产精品成人va在线观看| 黄色在线免费观看| 最近日韩中文字幕| 国产一卡二卡三卡四卡| 久久久久久自在自线| 亚洲免费精品视频| 91蝌蚪精品视频| 国产精品露脸av在线| av色综合久久天堂av色综合在| 亚洲国产成人精品久久| 超碰在线免费97| 一区二区三区在线影院| 深爱五月激情网| 激情综合色丁香一区二区| 国产精品无码人妻一区二区在线| 第一社区sis001原创亚洲| 2022国产精品| 亚洲承认视频| 久久男人av资源网站| 国产小视频在线| 日韩欧美一区二区久久婷婷| 亚洲视频 欧美视频| 亚洲精品视频一区二区| 波多野结衣一本| 国产馆精品极品| 亚洲人辣妹窥探嘘嘘| 亚洲精品资源| 黄色录像特级片| 成人av资源电影网站| 国产综合av一区二区三区| av在线国产精品| 国产精品99久久久久久www| sm久久捆绑调教精品一区| 日韩中文字幕在线免费观看| 手机福利小视频在线播放| 777午夜精品视频在线播放| 中文字幕69页| 午夜av一区二区三区| 福利所第一导航| 国产精品久久久久久一区二区三区| 网站免费在线观看| 国产成人精品一区二| 久久久久久久久久一区二区| 先锋影音国产一区| 国产日本在线播放| 女人色偷偷aa久久天堂| 亚洲 国产 日韩 综合一区| 日韩伦理一区二区三区| 成人女人免费毛片| 国产精品亚洲四区在线观看| 国产精品综合不卡av| 日韩av超清在线观看| 欧美综合国产精品久久丁香| 国产精品蜜臀| 欧美激情videos| 久久av色综合| 久久久国产视频91| 国内外激情在线| 久久久国产精品视频| 高h视频在线观看| 久久夜色精品国产| 欧美性天天影视| 精品国产一区二区三区久久| 日韩三级影院| www.亚洲天堂| 菠萝菠萝蜜在线视频免费观看| 久久精品视频亚洲| 黄色免费在线网站| 久久这里只有精品99| a视频在线播放| 久久99精品久久久久久琪琪| 伊人电影在线观看| 国内揄拍国内精品少妇国语| 2020国产在线| 青青久久av北条麻妃海外网| 欧美极品videos大乳护士| 欧美亚洲国产视频| 忘忧草在线www成人影院| 日韩美女福利视频| 成人国产一区| 成人久久精品视频| 日韩精品一区二区三区中文字幕| 欧美群妇大交群中文字幕| 免费一级特黄录像| 葵司免费一区二区三区四区五区| 男人日女人下面视频| 性久久久久久| 亚洲无吗一区二区三区| 麻豆精品视频在线| 日本一二三四区视频| 国产69精品久久99不卡| 天天躁日日躁狠狠躁av麻豆男男| www.成人在线| 一级黄色性视频| 国产精品久久精品日日| 顶臀精品视频www| 亚洲高清免费观看| 亚洲婷婷综合网| 欧美日韩国产乱码电影| 亚洲免费视频网| 亚洲美女视频网站| 日本欧美在线视频免费观看| 精品中文字幕在线2019| 国产精品69xx| 国产精品1234| av日韩一区| 欧美精品一区二区视频| 久久人人99| 给我免费播放片在线观看| 日本中文在线一区| 精品国产午夜福利在线观看| 91免费版在线| 国产极品美女在线| 欧美日韩美女视频| 国产精品玖玖玖| 日韩精品视频三区| 免费av不卡| 91高清视频在线免费观看| 久久亚洲人体| 国产综合18久久久久久| 国产高清久久| 国产无套内射久久久国产| 国产精品一区二区久久不卡 | 欧美激情亚洲综合一区| 成人天堂yy6080亚洲高清 | 特黄特色欧美大片| 欧美性受xxxx黑人猛交88| 久久国产精品亚洲77777| 999热精品视频| 国产三级一区二区| 91香蕉在线视频| 日韩欧美一级在线播放| 国产网站在线播放| 911国产网站尤物在线观看| av日韩在线免费观看| 日日夜夜精品网站| 一本久久综合| 一起草最新网址| 国产精品女上位| 亚洲国产av一区二区三区| 精品国免费一区二区三区| 青青草原在线免费观看视频| 日韩精品一级中文字幕精品视频免费观看 | 麻豆精品视频在线观看视频| 国产又黄又粗又猛又爽的视频 | 国产亚洲人成a一在线v站| 678在线观看视频| 92国产精品久久久久首页 | av电影在线观看一区| 加勒比婷婷色综合久久| 欧美日韩一区视频| 黄色小视频在线免费观看| 7m第一福利500精品视频| 天堂精品久久久久| 欧美aaa在线观看| 久久99精品久久久| 五月激情四射婷婷| 欧美性欧美巨大黑白大战| 裸体xxxx视频在线| 97超碰色婷婷| 日韩人体视频| 日日橹狠狠爱欧美超碰| 成人av综合在线| 国产午夜福利精品| 精品国产乱码久久久久久图片| 丝袜美腿av在线| 99国产在线观看| 国精品一区二区| 国内精品免费视频| 亚洲成人综合网站| 亚洲毛片欧洲毛片国产一品色| 欧美激情精品久久久久久免费印度 | 色噜噜狠狠色综合欧洲selulu| 天堂√在线中文官网在线| 91黑丝高跟在线| 在线成人动漫av| 天天操天天爽天天射| 国产精品区一区二区三区| 91久久久久久久久久久久| 色婷婷av一区二区三区久久| 一区二区三区| 2022中文字幕| www.一区二区| 久久久久久久久久成人| 中文字幕日韩欧美| 91成人在线网站| 欧美日韩视频免费| 91影院在线观看| 久久午夜鲁丝片| 久久精品视频导航| 果冻天美麻豆一区二区国产| 欧美 国产 综合| 亚洲国产成人午夜在线一区| 亚洲综合一区中| 欧美福利视频网站| 亚洲婷婷影院| 色戒在线免费观看| 动漫3d精品一区二区三区乱码| 国内精品视频免费| 久久国产日韩| 日本中文在线视频| 亚洲激情成人网| 日本精品裸体写真集在线观看| 中文字幕中文字幕在线中一区高清| 国产精品一区二区你懂的| 日韩福利片在线观看| 中文在线不卡视频| 一区二区三区亚洲变态调教大结局 | 国产精品乱码视频| 久久亚洲欧洲| 丝袜 亚洲 另类 欧美 重口| 欧美精品一区二区三| 日韩欧美精品一区二区综合视频| 男人的天堂视频在线| 2024国产精品视频| av中文字幕观看| 国产成人高清激情视频在线观看| 这里只有精品在线| 女人又爽又黄免费女仆| 日韩欧美一级精品久久|