精品欧美一区二区三区在线观看 _久久久久国色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技術棧公眾號

亚洲午夜在线电影| 久久国产麻豆精品| 日韩精品在线免费观看| 在线观看的毛片| a级网站在线播放| av成人老司机| 91精品国产综合久久香蕉最新版| 久久高清无码视频| 欧美精选一区二区三区| 欧美岛国在线观看| 激情视频免费网站| 波多野结衣中文字幕久久| 国产日本亚洲高清| 91久久大香伊蕉在人线| 日日夜夜狠狠操| 国产精品a级| 深夜福利一区二区| 网站免费在线观看| 电影91久久久| 欧美性色欧美a在线播放| 丰满的少妇愉情hd高清果冻传媒 | 久久精品国产亚洲aⅴ| 久久久久久欧美| 日本 欧美 国产| 亚洲警察之高压线| 欧美精品一区二区三区久久久 | 91福利精品在线观看| 一区二区高清免费观看影视大全| 四虎永久国产精品| 欧美美乳在线| 不卡影院免费观看| 99国产在线视频| 一级黄色免费片| 日本欧美在线看| 欧洲成人免费视频| 国产一级淫片a| 国产在线成人| 九九热99久久久国产盗摄| 在线免费看视频| 国产成人ay| 亚洲欧美日韩精品久久亚洲区| 曰本三级日本三级日本三级| 亚洲视频资源| 欧美人xxxx| 五月婷婷之综合激情| 日韩网站中文字幕| 日本久久一区二区三区| 国产亚洲天堂网| 日本蜜桃在线观看视频| 亚洲成a人v欧美综合天堂| 91黄色在线看| 激情av在线| 亚洲网友自拍偷拍| 免费毛片网站在线观看| sm在线观看| 黄网站色欧美视频| 欧美日韩在线视频一区二区三区| 超碰资源在线| 欧美日韩国产色视频| 日韩中文字幕在线视频观看| 蜜桃麻豆影像在线观看| 精品福利一区二区| www.四虎成人| 欧洲成人一区| 欧美一区二区私人影院日本| 欧美体内she精高潮| 日韩高清一区| 亚洲国产高清高潮精品美女| 制服丝袜第二页| 久久99影视| 色偷偷av亚洲男人的天堂| 人人干在线观看| 欧美理论在线| 欧美在线国产精品| 亚洲视屏在线观看| 国模大尺度一区二区三区| 99久久99久久精品国产片| 天堂av中文字幕| 久久美女艺术照精彩视频福利播放| 欧美美乳视频网站在线观看| 成人动漫在线播放| 亚洲免费伊人电影| 久在线观看视频| 久久精品黄色| 欧美va日韩va| 亚洲图片另类小说| 亚洲成人一区| 欧美一区亚洲一区| 国产精选久久久| 92国产精品观看| 中文字幕一区二区三区四区五区| 怡红院红怡院欧美aⅴ怡春院| 激情久久av一区av二区av三区| 日本成人中文字幕在线| 精品欧美视频| 亚洲精品一区中文| 538任你躁在线精品视频网站| 雨宫琴音一区二区在线| 国产精品免费一区豆花| 精品人妻一区二区三区四区不卡| 2023国产精品视频| 国产奶头好大揉着好爽视频| 欧亚av在线| 91精品国产色综合久久久蜜香臀| 中文字幕丰满孑伦无码专区| 影音先锋日韩在线| 国产福利视频一区| 色wwwwww| 亚洲美女免费在线| 国产福利影院在线观看| 久久365资源| 久久精品青青大伊人av| caoporn国产| 成人免费av在线| 五月天男人天堂| 亚洲综合电影| 亚洲国产精久久久久久久| 亚洲精品久久久久久国| 欧美资源在线| 国产高清自拍一区| caoporn免费在线视频| 精品视频一区三区九区| 91视频啊啊啊| 精品96久久久久久中文字幕无| 国产精品入口福利| 欧美高清电影在线| 亚洲www啪成人一区二区麻豆| 手机在线视频一区| 色喇叭免费久久综合网| 国产成人精品在线播放| 无码国产伦一区二区三区视频| 亚洲精品午夜久久久| 制服丝袜中文字幕第一页| 国模精品一区| 国产成人鲁鲁免费视频a| 欧美男男同志| 色哟哟精品一区| 亚洲第一黄色网址| 一区二区国产精品| 国产日韩一区二区| 成年网站在线视频网站| 精品久久五月天| 久久精品www| 国产成人av一区二区| 成人午夜视频免费观看| 国产精品3区| 欧美精品在线免费播放| 国产浮力第一页| 亚洲制服欧美中文字幕中文字幕| 一级黄色高清视频| 午夜精品婷婷| 国产美女在线精品免费观看| 成人性生交大片免费看网站 | 国产精品一区二区久久| jizz日韩| 3atv一区二区三区| 久草视频中文在线| 99精品国产91久久久久久| 久久久久久久中文| 免费成人高清在线视频theav| 日韩免费在线视频| 3d成人动漫在线| 91精品久久久久久蜜臀| 成年人av电影| www.在线欧美| 国产精品无码av无码| 国产欧美一区| 成人在线国产精品| 国产偷倩在线播放| 亚洲免费视频观看| 丰满人妻一区二区三区四区| 成人欧美一区二区三区在线播放| 中文字幕乱妇无码av在线| 亚洲激情欧美| 日韩欧美视频第二区| 成人午夜888| 97国产suv精品一区二区62| 精品99又大又爽又硬少妇毛片| 欧美色大人视频| 私库av在线播放| 91视频.com| 亚洲精品20p| 亚洲电影成人| 一级二级三级欧美| 成人av影音| 国产精品久久久久久久久久小说| av片在线观看| 国产视频久久久| 国产精品毛片久久久久久久av| 亚洲一区在线观看网站| 日韩毛片无码永久免费看| 国产精品一二三| 日本成人在线免费视频| 欧美精选在线| 日韩一区二区电影在线观看| 综合久久av| 欧美一级高清免费播放| 黄色的网站在线观看| 日韩高清中文字幕| 97caocao| 一本大道久久精品懂色aⅴ| 侵犯稚嫩小箩莉h文系列小说| 99久久久国产精品| 三级黄色片免费看| 日韩国产精品久久久久久亚洲| 97碰在线视频| 国产精品福利在线观看播放| 九九九九九精品| 久久国产精品美女| 国产精品久久久久久久一区探花 | 成人欧美一区二区三区黑人| 成入视频在线观看| 久久综合免费视频| 国产乱视频在线观看| 亚洲国产精品99| 国产极品久久久| 欧美欧美欧美欧美| 成人公开免费视频| 狠狠色噜噜狠狠狠狠97| 九九久久免费视频| 亚洲视频 欧洲视频| 国产sm调教视频| 91日韩在线专区| 理论片大全免费理伦片| 国产美女一区二区三区| 香港日本韩国三级网站| 新狼窝色av性久久久久久| 免费视频爱爱太爽了| 香蕉视频官网在线观看日本一区二区| 日本不卡一区| 亚洲成a人片77777在线播放| 亚洲在线免费看| crdy在线观看欧美| 国产综合香蕉五月婷在线| 99re66热这里只有精品4| 51久久精品夜色国产麻豆| 9765激情中文在线| 久久久久久久爱| 羞羞视频在线观看免费| 久久这里只有精品99| 午夜毛片在线| 色偷偷av亚洲男人的天堂| 在线观看麻豆| 日韩日本欧美亚洲| 欧美三级理伦电影| 色琪琪综合男人的天堂aⅴ视频| 激情小说 在线视频| 一区二区三区视频免费在线观看| 欧美理论在线观看| 亚洲欧美激情在线视频| 国产中文字幕在线| 中文字幕v亚洲ⅴv天堂| 免费a级在线播放| 久久精品一区中文字幕| a视频在线观看免费| 欧美人在线观看| 高清精品在线| 人人澡人人澡人人看欧美| 日韩成人影音| 91久久国产综合久久91精品网站| 95精品视频| 国产精品一区二区在线观看| 任你弄精品视频免费观看| 欧美动漫一区二区| 日韩欧美精品| 色一情一乱一乱一区91| 亚洲黄色高清| 免费日韩视频在线观看| 六月丁香婷婷色狠狠久久| 热久久久久久久久| av欧美精品.com| 一区二区三区伦理片| 一区在线中文字幕| 久久久久久久九九九九| 天天色天天操综合| 中国一级特黄视频| 日韩一区二区免费在线观看| 开心激情综合网| 国产午夜精品一区理论片飘花| 日本视频在线观看| 久久久久久国产免费| 户外露出一区二区三区| 成人在线视频网站| 老汉色老汉首页av亚洲| 亚洲成人在线视频网站| 激情综合视频| 超碰在线播放91| 成人avav影音| 18啪啪污污免费网站| 亚洲r级在线视频| 国产精品xxxxxx| 亚洲第一国产精品| 在线视频三区| 国产91精品久| 一区中文字幕电影| 亚洲国产成人不卡| 一区二区动漫| 国产老头和老头xxxx×| 久久精品一二三| 久久精品免费av| 欧美美女直播网站| 噜噜噜在线观看播放视频| 久久夜色精品国产| 主播大秀视频在线观看一区二区| 国产精品v欧美精品v日韩| 日本不卡二三区| 欧美一区二区三区爽大粗免费| 韩国av一区二区三区在线观看| 国产jjizz一区二区三区视频| 亚洲自拍偷拍图区| 国产精品人妻一区二区三区| 亚洲欧美在线免费观看| 搞黄网站在线看| 91九色国产社区在线观看| 国产一区二区欧美| 免费观看美女裸体网站| 国产精品一区免费视频| 99久久99久久精品免费看小说.| 精品日韩中文字幕| 欧美一级淫片aaaaaa| 久久亚洲欧美日韩精品专区| 国产韩日精品| 欧洲亚洲一区| 性色一区二区三区| 性色av蜜臀av浪潮av老女人| 一区二区三区欧美视频| 国产精品爽爽久久| 最新91在线视频| 亚洲电影有码| 色噜噜狠狠一区二区三区| 蜜乳av另类精品一区二区| 中文字幕5566| 疯狂欧美牲乱大交777| 污视频在线免费| 91精品国产91久久久久福利| 国产精品自在| 黄色一级片在线看| 成人深夜视频在线观看| 国产在线一区视频| 亚洲第一福利视频| 91破解版在线观看| 国产伦精品一区二区三区高清| 欧美成人有码| 欧美做受高潮中文字幕| 亚洲国产精品久久艾草纯爱| 亚洲乱码国产乱码精品精软件| 欧美裸体xxxx极品少妇| 97se亚洲国产一区二区三区| 成人免费毛片在线观看| 波多野结衣中文字幕一区| 欧美bbbbbbbbbbbb精品| 日韩精品视频免费专区在线播放| 9i看片成人免费高清| 日韩精品一区二区三区丰满 | 国产精品视频不卡| 成人羞羞视频在线看网址| 国产福利在线免费| 亚洲欧美日韩国产综合| 亚洲av无码乱码在线观看性色| 久久免费视频在线观看| 亚洲福利天堂| 欧美成人福利在线观看| 亚洲男同性恋视频| 欧美熟妇另类久久久久久不卡| 91高清免费在线观看| 狠狠色丁香婷婷综合影院| 亚洲天堂av一区二区| 亚洲精品久久嫩草网站秘色| 欧美一区二不卡视频| 日本精品一区二区三区在线播放视频 | 成人欧美一区二区三区黑人一| 91精品国产综合久久福利软件| 中文在线免费| 久中文字幕一区| 久久精品免费看| 国产亚洲色婷婷久久99精品| 日韩成人性视频| 国产福利91精品一区二区| 久久久天堂国产精品| 久久午夜免费电影| 92久久精品一区二区| 97涩涩爰在线观看亚洲| 日韩1区在线| 在线播放av网址| 色噜噜狠狠色综合中国| 国产激情在线| 蜜桃导航-精品导航| 国内外成人在线视频| 日本一级黄色大片| 最近2019年手机中文字幕| 伊人久久大香线蕉av超碰| 黄色成人免费看| 亚洲午夜一区二区三区| av网站在线播放| 国产精品免费区二区三区观看| 日韩精品乱码av一区二区| 国产亚洲精品码| 日韩视频一区在线| 亚洲日本三级| 熟妇高潮一区二区|