<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12

      LangChain框架入門06:手把手帶你玩轉LCEL表達

      在前面幾篇文章中,我們已經掌握了LangChain的核心組件:提示詞模板、大語言模型、輸出解析器。細心的讀者可能發現,在使用這些組件時,經常會看到類似 prompt | llm | parser 這樣的鏈式操作。這就是今天重點介紹的LCEL(LangChain Expression Language)表達式。

      在平時開發中,經常需要將多個組件組合起來形成完整的處理流程,將上一個組件的輸出作為下一個組件的輸入,在不使用LCEL表達式之前,就會寫出這種代碼:使用 invoke() 進行層層嵌套,這就好比早期 JS 中的回調地獄,結構混亂、難以維護,并且出現錯誤很難判斷是哪一步出了問題。

      # 1.構建提示詞
      prompt = ChatPromptTemplate.from_messages([
          ("system", "你是一個資深文學家"),
          ("human", "請簡短賞析{name}這首詩,并給出評價")
      ])
      
      # 2.創建模型
      llm = ChatOpenAI()
      # 3.創建字符串輸出解析器
      parser = StrOutputParser()
      
      # 4.調用模型返回結果
      result = parser.invoke(
          llm.invoke(
              prompt.invoke({"name": "江雪"})
          )
      )
      

      而LCEL讓這個過程變得簡潔直觀,通過管道符號進行連接,可以很輕松地構建出功能強大的AI應用。

      文中所有示例代碼:https://github.com/wzycoding/langchain-study

      一、什么是LCEL表達式

      LCEL(LangChain Expression Language)是LangChain框架的表達式語言,它提供了一種聲明式的方式來構建復雜的數據處理鏈。通過LCEL,我們可以使用管道符號 | 將不同的組件連接起來,形成一個完整的數據處理鏈。

      LCEL有以下優點:

      1、代碼更加簡潔:用管道符號連接組件,代碼更加簡潔易讀

      2、可任意組合:任意Runnable組件都可以自由組合,構建復雜的處理邏輯

      3、統一接口規范:所有Runnable組件都遵循統一的接口規范

      4、方便監控與調試:LangChain內置了日志和監控功能,方便調試和優化

      下面是使用LCEL表達式的案例:

      # 1.構建提示詞
      prompt = ChatPromptTemplate.from_messages([
          ("system", "你是一個資深文學家"),
          ("human", "請簡短賞析{name}這首詩,并給出評價")
      ])
      
      # 2.創建模型
      llm = ChatOpenAI()
      # 3.創建字符串輸出解析器
      parser = StrOutputParser()
      
      # 4.構建鏈
      chain = prompt | llm | parser
      
      # 5.執行鏈
      print(f"輸出結果:{chain.invoke({'name': '題西林壁'})}")
      

      顯而易見,LCEL寫法更加簡潔,而且表達了清晰的數據流向:輸入經過提示詞模板處理,然后將PromptValue傳遞給大語言模型,最后將大語言模型輸出的Message傳遞給輸出解析器,經過輸出解析器解析得到最終結果。

      二、什么是Runnable組件

      在深入LCEL之前,首先需要理解Runnable接口。Runnable是LangChain中所有可執行組件的基礎接口,它定義了組件應該具備的標準方法。前面介紹的LangChain組件如提示詞模板、模型、輸出解析器等,都實現了Runnable接口,這就是為什么這些組件可以使用管道符進行連接的原因。

      在Runnable接口中定義了以下核心方法:

      invoke(input):同步執行,處理單個輸入,最常用的方法

      batch(inputs):批量執行,處理多個輸入,提升處理效率

      stream(input):流式執行,逐步返回結果,經典的使用場景是大模型是一點點輸出的,不是一下返回整個結果,可以通過 stream() 方法,進行流式輸出

      ainvoke(input):異步執行,用于高并發場景

      三、RunnableBranch條件分支

      在LangChain中提供了類RunnableBranch來完成LCEL中的條件分支判斷,它可以根據輸入的不同采用不同的處理邏輯,具體示例如下,在下方示例中程序會根據用戶輸入中是否包含‘日語’、‘韓語’等關鍵詞,來選擇對應的提示詞進行處理。根據判斷結果,再執行不同的邏輯分支。

      import dotenv
      from langchain_core.output_parsers import StrOutputParser
      from langchain_core.prompts import ChatPromptTemplate
      from langchain_core.runnables import RunnableBranch
      from langchain_openai import ChatOpenAI
      
      # 讀取env配置
      dotenv.load_dotenv()
      
      
      def judge_language(inputs):
          """判斷語言種類"""
          query = inputs["query"]
          if "日語" in query:
              return "japanese"
          elif "韓語" in query:
              return "korean"
          else:
              return "english"
      
      
      # 1.構建提示詞
      english_prompt = ChatPromptTemplate.from_messages([
          ("system", "你是一個英語翻譯專家,你叫小英"),
          ("human", "{query}")
      ])
      
      japanese_prompt = ChatPromptTemplate.from_messages([
          ("system", "你是一個日語翻譯專家,你叫小日"),
          ("human", "{query}")
      ])
      
      korean_prompt = ChatPromptTemplate.from_messages([
          ("system", "你是一個韓語翻譯專家,你叫小韓"),
          ("human", "{query}")
      ])
      
      # 2.創建模型
      llm = ChatOpenAI()
      # 3.創建字符串輸出解析器
      parser = StrOutputParser()
      
      # 4.構建鏈分支結構,默認分支為英語
      chain = RunnableBranch(
          (lambda x: judge_language(x) == "japanese", japanese_prompt | llm | parser),
          (lambda x: judge_language(x) == "korean", korean_prompt | llm | parser),
          (english_prompt | llm | parser)
      )
      
      # 5.執行鏈
      print(f"輸出結果:{chain.invoke({'query': '請你用韓語翻譯這句話:“我愛你”。并且告訴我你叫什么'})}")
      

      執行結果如下,根據執行結果,執行的是韓語分支。

      輸出結果:“我愛你”用韓語是:“???” (Saranghae)。
      
      我叫小韓,很高興為你服務!??
      

      四、RunnableLambda函數轉換為可執行組件

      LangChain還提供了類RunnableLambda,它可以非常方便的將函數轉換為可執行組件,如下示例,將字符個數統計函數包裝成一個RunnableLambda,并參與鏈執行。

      import dotenv
      from langchain_core.output_parsers import StrOutputParser
      from langchain_core.prompts import ChatPromptTemplate
      from langchain_core.runnables import RunnableLambda
      from langchain_openai import ChatOpenAI
      
      # 讀取env配置
      dotenv.load_dotenv()
      
      
      def character_counter(text):
          """統計輸出字符個數"""
          return len(text)
      
      
      # 1.構建提示詞
      prompt = ChatPromptTemplate.from_messages([
          ("system", "你是一個資深文學家"),
          ("human", "請以{subject}為主題寫一首古詩")
      ])
      
      # 2.創建模型
      llm = ChatOpenAI()
      # 3.創建字符串輸出解析器
      parser = StrOutputParser()
      
      # 4.構建鏈
      chain = prompt | llm | parser | RunnableLambda(character_counter)
      
      # 5.執行鏈
      print(f"輸出結果:{chain.invoke({'subject': '大雪'})}")
      

      執行結果:

      輸出結果:67
      

      五、RunnableParallel并行處理

      在某些需求中,為了提高執行效率,可能會有兩個鏈并行執行的情況,比如同時進行古詩創作和解答數學題。RunnableParallel能讓多個鏈并行處理,最終同時返回結果。

      5.1 并行處理

      RunnableParallel基礎用法示例如下,RunnableParallel中需要傳入一個字典結構,key是這個鏈的標識,value是具體鏈信息,RunnableParallel本身也是一個可執行組件,因此也可以調用invoke方法,最終執行后,返回的依然是一個字典,key依然是鏈的標識,value是鏈執行的結果。

      import dotenv
      from langchain_core.output_parsers import StrOutputParser
      from langchain_core.prompts import ChatPromptTemplate
      from langchain_core.runnables import RunnableParallel
      from langchain_openai import ChatOpenAI
      
      # 讀取env配置
      dotenv.load_dotenv()
      
      # 1.構建提示詞
      chinese_prompt = ChatPromptTemplate.from_messages([
          ("system", "你是一個資深文學家"),
          ("human", "請以{subject}為主題寫一首古詩")
      ])
      
      math_prompt = ChatPromptTemplate.from_messages([
          ("system", "你是一個資深數學家"),
          ("human", "請你給出數學問題:{question}的答案")
      ])
      
      # 2.創建模型
      llm = ChatOpenAI()
      # 3.創建字符串輸出解析器
      parser = StrOutputParser()
      
      # 4.創建并行鏈
      parallel_chain = RunnableParallel({
          "chinese": chinese_prompt | llm | parser,
          "math": math_prompt | llm | parser
      })
      
      # 5.執行鏈
      print(f"輸出結果:{parallel_chain.invoke({'subject': '春天', 'question': '24和16最大公約數是多少?'})}")
      

      執行結果:

      輸出結果:{'chinese': '好的,以下是我為春天主題創作的古詩:\n\n**春晨**\n\n柳垂翠影映江天,  \n風拂桃花氣馥蘭。  \n溪水悠悠行不息,  \n鶯歌燕舞入夢間。\n\n朝霞初照翠峰低,  \n芳草萋萋染綠池。  \n心隨春光漫游遠,  \n醉臥花間夢未已。\n\n這首詩描繪了春天早晨的景象,柳樹垂枝,桃花盛開,百鳥歡歌,心隨春風游走的寧靜與美好。你覺得怎么樣?', 'math': '24 和 16 的最大公約數 (GCD) 可以通過輾轉相除法求得。我們可以一步一步地計算:\n\n1. 24 ÷ 16 = 1 余 8\n2. 16 ÷ 8 = 2 余 0\n\n當余數為 0 時,除數 8 就是最大公約數。\n\n所以,24 和 16 的最大公約數是 **8**。'}
      

      5.2 RunnableParallel參數傳遞

      上面介紹了RunnableParallel如何進行鏈的并行執行,下面示例展示了模擬在和大語言模型交互之前,先檢索文檔的操作,通過RunnableParallel將執行結果作為提示詞模板的輸入參數,將輸出結果繼續向下傳遞。

      相當于傳遞給提示詞模板的參數從最開始的一個question,又增加了一個檢索文檔結果的參數retrieval_info,并且,這里使用了簡寫方式,在LCEL表達式中,使用字典結構包裹并在管道符兩側的,都會自動包裝成RunnableParallel。

      from operator import itemgetter
      
      import dotenv
      from langchain_core.output_parsers import StrOutputParser
      from langchain_core.prompts import ChatPromptTemplate
      from langchain_openai import ChatOpenAI
      
      # 讀取env配置
      dotenv.load_dotenv()
      
      
      def retrieval_doc(question):
          """模擬知識庫檢索"""
          print(f"檢索器接收到用戶提出問題:{question}")
          return "你是一個憤怒的語文老師,你叫Bob"
      
      
      # 1.構建提示詞
      prompt = ChatPromptTemplate.from_messages([
          ("system", "{retrieval_info}"),
          ("human", "{question}")
      ])
      
      # 2.創建模型
      llm = ChatOpenAI()
      # 3.創建字符串輸出解析器
      parser = StrOutputParser()
      
      # 4.構建鏈
      chain = {
                  "retrieval_info": lambda x: retrieval_doc(x["question"]),
                  "question": itemgetter("question")
              } | prompt | llm | parser
      
      # 5.執行鏈
      print(f"輸出結果:{chain.invoke({'question': '你是誰,能否幫我寫一首詩?'})}")
      

      執行結果:

      檢索器接收到用戶提出問題:你是誰,能否幫我寫一首詩?
      輸出結果:我是誰?我是Bob,一個憤怒的語文老師!你要寫詩?我看看你的水平如何,來來來,給我個主題吧,最好能高大上一點,不然我真的會很生氣的!
      

      六、RunnablePassthrough數據傳遞

      RunnablePassthrough是一個相對特殊的組件,它的作用是將輸入數據原樣傳遞到下一個可執行組件,同時還能對傳遞的數據進行數據重組。在構建復雜鏈時非常有用。

      6.1 數據傳遞基礎用法

      RunnablePassthrough()進行原樣輸出很簡單,乍一看起來這個類看起來作用不大,實際上它在用來占位、調試中,都有一定作用,如下示例,將參數直接原樣傳遞給下一個可運行組件。

      import dotenv
      from langchain_core.output_parsers import StrOutputParser
      from langchain_core.prompts import ChatPromptTemplate
      from langchain_core.runnables import RunnablePassthrough
      from langchain_openai import ChatOpenAI
      
      # 讀取env配置
      dotenv.load_dotenv()
      
      # 1.構建提示詞
      prompt = ChatPromptTemplate.from_messages([
          ("system", "你是一個資深文學家"),
          ("human", "請簡短賞析{name}這首詩,并給出評價")
      ])
      
      # 2.創建模型
      llm = ChatOpenAI()
      # 3.創建字符串輸出解析器
      parser = StrOutputParser()
      
      # 4.構建鏈
      chain = RunnablePassthrough() | prompt | llm | parser
      
      # 5.執行鏈
      print(f"輸出結果:{chain.invoke({'name': '題西林壁'})}")
      

      執行結果:

      輸出結果:《題西林壁》是蘇軾的經典之作,通過描繪西林寺的景象,表達了作者對于自然、人生以及自身處境的深刻感悟。
      
      詩中寫道:“不識廬山真面目,只緣身在此山中。”這兩句通過廬山的景象,傳達了一個哲理:人常常因為局限于眼前的事物,無法看清事物的全貌。用廬山作為象征,既反映了自然的壯麗,也暗示了人生的復雜與迷茫。作者通過這句詩,提出了“跳出事物的框架,方能看到真相”的思想,極富哲理。
      
      整首詩結構簡潔,語言凝練,感情真摯,既描寫了景色,又引發了對人生和思維局限的深刻反思。它不僅是對廬山美景的寫照,更是對人生困境的警示。
      
      **評價:**這首詩具有很高的哲理性和藝術性,語言簡練卻富有深意,值得每一位讀者細細品味。蘇軾以“廬山”作比,既能展現山水的美,又能寄托哲理思考,展現了其深厚的文化底蘊。
      

      6.2 數據重組

      RunnablePassthrough最強大的功能是可以重新組織數據結構,為后續鏈執行做準備,示例如下,我們改寫了之前使用RunnableParallel進行檢索的示例,通過RunnablePassthrough.assign()方法也能達到目的,可以向入參中添加新的屬性,下面示例添加了檢索結果屬性retrieval_info,將新的數據繼續向下傳遞。

      import dotenv
      from langchain_core.output_parsers import StrOutputParser
      from langchain_core.prompts import ChatPromptTemplate
      from langchain_core.runnables import RunnablePassthrough
      from langchain_openai import ChatOpenAI
      
      # 讀取env配置
      dotenv.load_dotenv()
      
      
      def retrieval_doc(inputs):
          """模擬知識庫檢索"""
          print(f"檢索器接收到用戶提出問題:{inputs['question']}")
          return "你是一個憤怒的語文老師,你叫Bob"
      
      
      # 1.構建提示詞
      prompt = ChatPromptTemplate.from_messages([
          ("system", "{retrieval_info}"),
          ("human", "{question}")
      ])
      
      # 2.創建模型
      llm = ChatOpenAI()
      # 3.創建字符串輸出解析器
      parser = StrOutputParser()
      
      # 4.構建鏈
      chain = RunnablePassthrough.assign(retrieval_info=retrieval_doc) | prompt | llm | parser
      
      # 5.執行鏈
      print(f"輸出結果:{chain.invoke({'question': '你是誰,能否幫我寫一首詩?'})}")
      

      執行結果:

      檢索器接收到用戶輸入信息:你是誰,能否幫我寫一首詩?
      輸出結果:我是Bob,一個憤怒的語文老師!你敢讓我寫詩?這可是件嚴肅的事,不能隨便糊弄!好吧,既然你要我寫,那我就寫。寫詩,得有情感,得有深度。你給我一個主題,看看你能承受我給你帶來的震撼!
      

      七、總結

      通過本文的學習,我們深入了解了LCEL表達式的強大功能。LCEL不僅僅是一種語法糖,更代表了LangChain框架的設計思想:通過標準化的接口和組合式的設計,讓復雜的AI應用開發變得簡單便捷。掌握了LCEL表達式,你已經具備了構建復雜AI應用的基礎能力,后續將繼續深入介紹LangChain的核心模塊和高級用法,敬請期待。

      posted @ 2025-08-04 09:32  大志說編程  閱讀(320)  評論(0)    收藏  舉報
      主站蜘蛛池模板: 强开小雪的嫩苞又嫩又紧| 天天操夜夜操| 国产成人精品永久免费视频| 日本亚洲欧洲无免费码在线| 亚洲精品自拍在线视频| 日韩亚洲国产中文字幕欧美| 熟女蜜臀av麻豆一区二区| 亚洲国产天堂一区二区三区| 欧美日产国产精品| 亚洲AV旡码高清在线观看| 商南县| 自拍偷在线精品自拍偷免费| 四虎精品永久在线视频| 国产精品成人无码久久久| 国产成人亚洲日韩欧美| 四虎国产精品永久免费网址| 国产成人av大片大片| 亚洲精品一区| 国产一区二区黄色激情片| 国产精品久久无中文字幕| 国产95在线 | 亚洲| 影视先锋av资源噜噜| 国产精品三级爽片免费看| 国产精品人妻在线观看| 国产成人高清精品免费软件| 国产99久久精品一区二区| 加勒比无码人妻东京热| 精品国产午夜福利在线观看| 深夜精品免费在线观看| 蜜桃无码一区二区三区| 亚洲国产良家在线观看| 中文字幕乱码视频32| 亚洲午夜av一区二区| 视频一本大道香蕉久在线播放| 精品中文人妻中文字幕| 少妇人妻88久久中文字幕| 亚洲人成网站77777在线观看| 国产午夜精品福利免费看| 久久永久视频| 国产片一区二区三区视频| 18禁裸乳无遮挡啪啪无码免费|