LangChain【6】之輸出解析器:結構化LLM響應的關鍵工具

文章目錄

  • 一 LangChain輸出解析器概述
    • 1.1 什么是輸出解析器?
    • 1.2 主要功能與工作原理
    • 1.3 常用解析器類型
  • 二 主要輸出解析器類型
    • 2.1 Pydantic/Json輸出解析器
    • 2.2 結構化輸出解析器
    • 2.3 列表解析器
    • 2.4 日期解析器
    • 2.5 Json輸出解析器
    • 2.6 xml輸出解析器
  • 三 高級使用技巧
    • 3.1 自定義解析邏輯
    • 3.2 重試與錯誤處理
    • 3.3 多模式解析
  • 四 實際應用示例
    • 4.1 構建問答系統
    • 4.2 性能優化建議
  • 五 總結

一 LangChain輸出解析器概述

  • LangChain輸出解析器是LangChain框架中的核心組件,主要用于將大型語言模型(LLM)生成的非結構化文本轉換為結構化數據格式。它允許開發者定義期望的輸出結構,并通過提示工程指導LLM生成符合該格式的響應。輸出解析器在驗證和轉換模型輸出時發揮著關鍵作用,確保數據能夠無縫集成到應用程序的工作流程中。

1.1 什么是輸出解析器?

輸出解析器是LangChain框架中的一類組件,專門負責兩大功能:

  1. 指令格式化:指導LLM如何格式化其輸出
  2. 結果解析:將LLM的文本響應轉換為結構化格式
    與直接使用原始API調用相比,輸出解析器提供了更可靠、更可預測的結果處理方式,極大簡化了后續的數據處理流程。

1.2 主要功能與工作原理

  • 輸出解析器通過兩個核心機制實現功能:首先通過get_format_instructions方法生成格式化指令,明確告知LLM輸出應遵循的結構;然后通過parse方法將LLM的原始響應解析為目標數據結構。這種雙重機制既保證了輸出的規范性,又提供了靈活的數據轉換能力。典型的應用場景包括將文本轉換為JSON對象、列表、枚舉值或特定領域對象等結構化數據。

1.3 常用解析器類型

  • LangChain提供了豐富的內置解析器,包括ListParser(列表解析器)、DatetimeParser(日期時間解析器)、EnumParser(枚舉解析器)和PydanticOutputParser(JSON解析器)等。其中PydanticOutputParser特別強大,它基于Pydantic模型定義數據結構,可以處理嵌套復雜的JSON格式,并自動生成對應的格式指令。此外還有StructuredOutputParser用于處理自定義類結構,Auto-FixingParser可自動修復格式錯誤。

二 主要輸出解析器類型

LangChain提供了多種輸出解析器,適用于不同場景:

2.1 Pydantic/Json輸出解析器

    • Pydantic/Json解析器允許您定義嚴格的輸出模式,確保LLM響應符合預期的數據結構,非常適合需要強類型驗證的場景。
from langchain.output_parsers import PydanticOutputParser
from pydantic import Field, BaseModelclass UserProfile(BaseModel):name: str = Field(description="用戶全名")age: int = Field(description="用戶年齡")hobbies: list[str] = Field(description="用戶愛好列表")parser = PydanticOutputParser(pydantic_object=UserProfile)
  • 完整案例:
import os
from langchain_core.output_parsers import PydanticOutputParser
# from langchain_core.output_parsers import JsonOutputParser
from langchain_core.prompts import PromptTemplate
from langchain_openai import ChatOpenAI
from pydantic import Field, BaseModel# 配置 API 易環境
os.environ["OPENAI_API_KEY"] = "hk-xxx"
os.environ["OPENAI_API_BASE"] = "https://api.openai-hk.com/v1"model=ChatOpenAI(model="gpt-4",temperature=0)# 定義期望的數據結構
class Joke(BaseModel):setup:str =Field(description="設置笑話的問題")punchline:str =Field(description="解決笑話的答案")# 用于提示語言模型填充數據結構的查詢意圖
joke_query="告訴我一個笑話"
# 設置解析器+將指令注入提示模板
# parser=JsonOutputParser(pydantic_object=Joke)
parser=PydanticOutputParser(pydantic_object=Joke)
prompt=PromptTemplate(template="回答用戶的查詢。\n{format_instructions}\n{query}\n",input_variables=["query"],partial_variables={"format_instructions":parser.get_format_instructions()}
)
print(parser.get_format_instructions())
  • 輸出結果:
"""
The output should be formatted as a JSON instance that conforms to the JSON schema below.As an example, for the schema {"properties": {"foo": {"title": "Foo", "description": "a list of strings", "type": "array", "items": {"type": "string"}}}, "required": ["foo"]}
the object {"foo": ["bar", "baz"]} is a well-formatted instance of the schema. The object {"properties": {"foo": ["bar", "baz"]}} is not well-formatted.Here is the output schema:
{"properties": {"setup": {"description": "設置笑話的問題", "title": "Setup", "type": "string"}, "punchline": {"description": "解決笑話的答案", "title": "Punchline", "type": "string"}}, "required": ["setup", "punchline"]}
"""
chain=prompt|model|parser
response=chain.invoke({"query":joke_query})
print(response)
"""
{'setup': '為什么計算機不能得感冒?', 'punchline': '因為它們有防火墻!'}
"""

2.2 結構化輸出解析器

  • 當需要靈活定義輸出結構而不想引入Pydantic依賴時,結構化輸出解析器是理想選擇。
from langchain.output_parsers import StructuredOutputParser, ResponseSchemaresponse_schemas = [ResponseSchema(name="answer", description="問題的答案"),ResponseSchema(name="source", description="答案來源")
]parser = StructuredOutputParser.from_response_schemas(response_schemas)
  • 完整代碼
import os
from langchain.output_parsers import StructuredOutputParser, ResponseSchema
from langchain_core.prompts import PromptTemplate
from langchain_openai import ChatOpenAI# 配置 API 易環境
os.environ["OPENAI_API_KEY"] = "hk-xxx"
os.environ["OPENAI_API_BASE"] = "https://api.openai-hk.com/v1"model=ChatOpenAI(model="gpt-4",temperature=0)response_schemas = [ResponseSchema(name="answer", description="問題的答案"),ResponseSchema(name="source", description="答案來源")
]# 設置解析器+將指令注入提示模板
parser = StructuredOutputParser.from_response_schemas(response_schemas)prompt=PromptTemplate(template="回答用戶的查詢。\n{format_instructions}\n{query}\n",input_variables=["query"],partial_variables={"format_instructions":parser.get_format_instructions()}
)
print(parser.get_format_instructions())
"""
The output should be a markdown code snippet formatted in the following schema, including the leading and trailing "```json" and "```":{"answer": string  // 問題的答案"source": string  // 答案來源
}"""
chain=prompt|model|parser
# 用于提示語言模型填充數據結構的查詢意圖
joke_query="告訴我一個笑話"
response=chain.invoke({"query":joke_query})print(response)
"""
{'answer': '為什么數學書總是很憂傷?因為它有太多的問題!', 'source': '常見幽默笑話'}
"""

2.3 列表解析器

  • 簡單高效地將逗號分隔的列表響應轉換為Python列表,適用于簡單的枚舉場景。
from langchain.output_parsers import CommaSeparatedListOutputParserparser = CommaSeparatedListOutputParser()

2.4 日期解析器

  • 專門處理日期時間字符串,將其轉換為Python datetime對象,省去了手動解析的麻煩。
from langchain.output_parsers import DatetimeOutputParserparser = DatetimeOutputParser()

2.5 Json輸出解析器

  • JSON作為現代API和Web應用中最常用的數據交換格式,LangChain提供了專門的JSON輸出解析器來簡化處理流程。

import osfrom langchain_core.output_parsers import JsonOutputParser
from langchain_core.prompts import PromptTemplate
from langchain_openai import ChatOpenAI
from pydantic import Field, BaseModel# 配置 API 易環境
os.environ["OPENAI_API_KEY"] = "hk-xxx"
os.environ["OPENAI_API_BASE"] = "https://api.openai-hk.com/v1"model=ChatOpenAI(model="gpt-4",temperature=0)# 定義期望的數據結構
class Joke(BaseModel):setup:str =Field(description="設置笑話的問題")punchline:str =Field(description="解決笑話的答案")# 用于提示語言模型填充數據結構的查詢意圖
joke_query="告訴我一個笑話"
# 設置解析器+將指令注入提示模板
parser=JsonOutputParser(pydantic_object=Joke)
prompt=PromptTemplate(template="回答用戶的查詢。\n{format_instructions}\n{query}\n",input_variables=["query"],partial_variables={"format_instructions":parser.get_format_instructions()}
)
print(parser.get_format_instructions())
"""
The output should be formatted as a JSON instance that conforms to the JSON schema below.As an example, for the schema {"properties": {"foo": {"title": "Foo", "description": "a list of strings", "type": "array", "items": {"type": "string"}}}, "required": ["foo"]}
the object {"foo": ["bar", "baz"]} is a well-formatted instance of the schema. The object {"properties": {"foo": ["bar", "baz"]}} is not well-formatted.Here is the output schema:{"properties": {"setup": {"description": "設置笑話的問題", "title": "Setup", "type": "string"}, "punchline": {"description": "解決笑話的答案", "title": "Punchline", "type": "string"}}, "required": ["setup", "punchline"]}"""
chain=prompt|model|parser
response=chain.invoke({"query":joke_query})
for s in chain.stream({"query":joke_query}):print(s)"""
{}
{'setup': ''}
{'setup': '為'}
{'setup': '為什'}
{'setup': '為什么'}
{'setup': '為什么電'}
{'setup': '為什么電腦'}
{'setup': '為什么電腦很'}
{'setup': '為什么電腦很好'}
{'setup': '為什么電腦很好吃'}
{'setup': '為什么電腦很好吃?'}
{'setup': '為什么電腦很好吃?', 'punchline': ''}
{'setup': '為什么電腦很好吃?', 'punchline': '因'}
{'setup': '為什么電腦很好吃?', 'punchline': '因為'}
{'setup': '為什么電腦很好吃?', 'punchline': '因為它'}
{'setup': '為什么電腦很好吃?', 'punchline': '因為它們'}
{'setup': '為什么電腦很好吃?', 'punchline': '因為它們有'}
{'setup': '為什么電腦很好吃?', 'punchline': '因為它們有很'}
{'setup': '為什么電腦很好吃?', 'punchline': '因為它們有很多'}
{'setup': '為什么電腦很好吃?', 'punchline': '因為它們有很多字'}
{'setup': '為什么電腦很好吃?', 'punchline': '因為它們有很多字節'}
{'setup': '為什么電腦很好吃?', 'punchline': '因為它們有很多字節('}
{'setup': '為什么電腦很好吃?', 'punchline': '因為它們有很多字節(bytes'}
{'setup': '為什么電腦很好吃?', 'punchline': '因為它們有很多字節(bytes)'}
{'setup': '為什么電腦很好吃?', 'punchline': '因為它們有很多字節(bytes)!'}
"""

2.6 xml輸出解析器

  • LangChain的XML輸出解析器為這些場景提供了專業支持。

import osfrom langchain_core.output_parsers import  XMLOutputParser
from langchain_core.prompts import PromptTemplate
from langchain_openai import ChatOpenAI# 配置 API 易環境
os.environ["OPENAI_API_KEY"] = "hk-xxx"
os.environ["OPENAI_API_BASE"] = "https://api.openai-hk.com/v1"model=ChatOpenAI(model="gpt-4",temperature=0)# 用于提示語言模型填充數據結構的查詢意圖
actor_query="生成周星馳的簡化電影作品列表,按照最新的時間降序"# 設置解析器+將指令注入提示模板
parser=XMLOutputParser(tags=["movies","actor","film","name","genre"])
prompt=PromptTemplate(template="回答用戶的查詢。\n{format_instructions}\n{query}\n",input_variables=["query"],partial_variables={"format_instructions":parser.get_format_instructions()}
)
print(parser.get_format_instructions())
  • 執行輸出:
"""
The output should be formatted as a XML file.
1. Output should conform to the tags below.
2. If tags are not given, make them on your own.
3. Remember to always open and close all the tags.As an example, for the tags ["foo", "bar", "baz"]:
1. String "<foo><bar><baz></baz></bar>
</foo>" is a well-formatted instance of the schema.
2. String "<foo><bar></foo>" is a badly-formatted instance.
3. String "<foo><tag></tag>
</foo>" is a badly-formatted instance.Here are the output tags:['movies', 'actor', 'film', 'name', 'genre']
"""
chain=prompt|model
response=chain.invoke({"query":actor_query})
xml_output=parser.parse(response.content)
print(response.content)
"""
```xml
<movies><actor><name>周星馳</name><film><name>美人魚</name><genre>喜劇</genre><year>2016</year></film><film><name>西游降魔篇</name><genre>喜劇</genre><year>2013</year></film><film><name>長江七號</name><genre>科幻</genre><year>2008</year></film><film><name>功夫</name><genre>動作</genre><year>2004</year></film><film><name>少林足球</name><genre>喜劇</genre><year>2001</year></film></actor>
</movies>這是一個簡化的電影作品列表,列出了周星馳的一些電影,包括電影名稱、類型和年份。這個列表是按照最新的時間降序排列的。
"""

三 高級使用技巧

3.1 自定義解析邏輯

  • 通過繼承BaseOutputParser,可以創建完全自定義的解析邏輯,處理特殊響應格式。
from langchain.output_parsers import BaseOutputParserclass BooleanParser(BaseOutputParser[bool]):def parse(self, text: str) -> bool:cleaned = text.strip().lower()if cleaned in ("yes", "true", "1"):return Trueelif cleaned in ("no", "false", "0"):return Falseraise ValueError(f"無法解析為布爾值: {text}")@propertydef _type(self) -> str:return "boolean_parser"

3.2 重試與錯誤處理

  • 當初始解析失敗時,重試解析器會自動嘗試修正錯誤,顯著提高系統魯棒性。
from langchain.output_parsers import RetryWithErrorOutputParserretry_parser = RetryWithErrorOutputParser.from_llm(parser=parser,llm=chat_llm
)

3.3 多模式解析

  • 輸出修正解析器可以檢測并嘗試自動修復格式錯誤的響應,特別適合生產環境中提高可靠性。
from langchain.output_parsers import OutputFixingParserfixing_parser = OutputFixingParser.from_llm(parser=parser, llm=chat_llm)

四 實際應用示例

4.1 構建問答系統

import osfrom langchain_core.output_parsers import JsonOutputParser
from langchain_openai import ChatOpenAI
from langchain.prompts import ChatPromptTemplate
from pydantic import BaseModel, Field# 配置 API 環境
os.environ["OPENAI_API_KEY"] = "hk-xxx"
os.environ["OPENAI_API_BASE"] = "https://api.openai-hk.com/v1"template = """根據上下文回答問題,并按照要求格式化輸出。
上下文: {context}
問題: {question}
{format_instructions}"""prompt = ChatPromptTemplate.from_template(template)
model = ChatOpenAI(model="gpt-4")# 定義輸出數據結構
class Answer(BaseModel):answer: str = Field(description="根據上下文回答問題")confidence: float = Field(description="回答的置信度")# 創建解析器
parser = JsonOutputParser(pydantic_model=Answer)chain = prompt | model | parserresult = chain.invoke({"context": "LangChain是一個LLM應用開發框架...","question": "LangChain是什么?","format_instructions": parser.get_format_instructions()
})print(result)

4.2 性能優化建議

  1. 清晰的指令:在提示中明確說明輸出格式要求。
  2. 漸進式解析:復雜結構可分步解析。
  3. 錯誤回退:實現備用解析策略。
  4. 緩存機制:對相同輸入緩存解析結果。
  5. 監控指標:跟蹤解析成功率,及時發現模式問題。

五 總結

  • LangChain的輸出解析器組件為LLM應用開發提供了關鍵的結構化數據處理能力。通過合理選擇和使用各種解析器,開發者可以:
    • 確保數據的一致性和可靠性
    • 減少膠水代碼和手動解析工作
    • 構建更健壯的生產級應用
    • 專注于業務邏輯而非數據清洗

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

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

相關文章

Spring Boot項目中JSON解析庫的深度解析與應用實踐

在現代Web開發中&#xff0c;JSON&#xff08;JavaScript Object Notation&#xff09;作為輕量級的數據交換格式&#xff0c;已成為前后端通信的核心橋梁。Spring Boot作為Java生態中最流行的微服務框架&#xff0c;提供了對多種JSON庫的無縫集成支持。本文將深入探討Spring B…

OPenCV CUDA模塊光流------高效地執行光流估計的類BroxOpticalFlow

操作系統&#xff1a;ubuntu22.04 OpenCV版本&#xff1a;OpenCV4.9 IDE:Visual Studio Code 編程語言&#xff1a;C11 算法描述 cv::cuda::BroxOpticalFlow 是 OpenCV CUDA 模塊中實現Brox光流算法的類。該類用于在 GPU 上高效地計算兩幀圖像之間的稠密光流&#xff08;Dens…

視覺分析在人員行為屬性檢測中的應用

基于視覺分析的人員行為屬性檢測方案 一、背景與需求分析 在工業生產、建筑施工、公共安全等領域&#xff0c;人員行為屬性的合規性檢測是保障安全生產的關鍵環節。例如&#xff0c;工地工人未佩戴安全帽、廚房人員未佩戴手套、作業現場人員使用手機等行為&#xff0c;均可能…

Linux--進程的程序替換

問題導入&#xff1a; 前面我們知道了&#xff0c;fork之后&#xff0c;子進程會繼承父進程的代碼和“數據”&#xff08;寫實拷貝&#xff09;。 那么如果我們需要子進程完全去完成一個自己的程序怎么辦呢&#xff1f; 進程的程序替換來完成這個功能&#xff01; 1.替換原理…

場景題-3

如何實現一個消息隊列 拆解分析主流的幾種消息隊列 1、基本架構 生產者Producer、消費者Consumer、Broker&#xff1a;生產者發送消息&#xff0c;消費者接受消息&#xff0c;Broker是服務端&#xff0c;處理消息的存儲、備份、刪除和消費關系的維護。 主題和分區&#xff…

vue2 項目中 npm run dev 運行98% after emitting CopyPlugin 卡死

今天在運行項目時&#xff0c;發現如下問題&#xff1a; 開始以為是node_modules依賴的問題&#xff0c;于是重新 npm install&#xff0c;重啟項目后還是未解決。 在網上找了一圈發現有人說是 require引入圖片地址沒有寫。在我的項目中排查沒有這個問題&#xff0c;最后發現某…

73 LV的使用(XFS文件系統)

四 LV的使用 先創建一個LV01 lvcreate -L 10G lv01 datavg Logical volume "lv01" created. 將創建出來的LV01進行格式化 mkfs.xxx LV的名稱(絕對路徑) 絕對路徑的組成:/dev/你創建VG的名字/LV的名字 mkfs.xfs /dev/datavg/lv01 掛載你的LV…

mybatis中判斷等于字符串的條件怎么寫

mybatis中判斷等于字符串的條件怎么寫_mybatis 等于字符串-CSDN博客 因為mybatis映射文件&#xff0c;是使用的ognl表達式&#xff0c;ognl是java語言&#xff08;強類型語言&#xff09;&#xff0c;會把‘X’解析成字符&#xff0c;而不是字符串。 所以比較字符串相等使用是…

C語言實現絕對值差值函數

在C語言中&#xff0c;可以編寫一個函數來計算兩個數的差值的絕對值。以下是一個簡單的實現&#xff1a; #include <stdio.h> #include <stdlib.h> // 用于abs函數&#xff08;如果需要&#xff09; // 方法1&#xff1a;使用標準庫函數 int absoluteDifference1…

Three.js中AR實現詳解并詳細介紹基于圖像標記模式AR生成的詳細步驟

文檔地址 Three.js中AR實現詳解 以下是Three.js中實現AR功能的詳細解析&#xff0c;涵蓋技術原理、實現步驟、核心組件及優化策略&#xff1a; &#x1f9e9; 一、技術基礎 AR.js框架的核心作用 AR.js是Three.js實現AR的基石&#xff0c;提供以下核心能力&#xff1a; 多模…

Vue3.5 企業級管理系統實戰(二十三):權限指令

在實際應用場景中&#xff0c;常常需要依據用戶角色對按鈕的操作權限實施控制。實現這一控制主要有兩種方式&#xff1a;一種是借助前端指令基于角色進行權限管控&#xff0c;另一種是通過后臺返回對應的權限屬性來實現精細化控制。本文聚焦于前端權限指令展開探討。 1 權限指…

軟考 系統架構設計師系列知識點之雜項集萃(81)

接前一篇文章&#xff1a;軟考 系統架構設計師系列知識點之雜項集萃&#xff08;80&#xff09; 第145題 商業智能是企業對商業數據的搜集、管理和分析的系統過程&#xff0c;主要技術包括&#xff08;&#xff09;。 A. 數據倉庫、聯機分析和數據挖掘 B. 數據采集、數據清洗…

深入淺出Java ParallelStream:高效并行利器還是隱藏的陷阱?

在Java 8帶來的眾多革新中&#xff0c;Stream API徹底改變了我們對集合操作的方式。而其中最引人注目的特性之一便是parallelStream——它承諾只需簡單調用一個方法&#xff0c;就能讓數據處理任務自動并行化&#xff0c;充分利用多核CPU的優勢。但在美好承諾的背后&#xff0c…

SQL Transactions(事務)、隔離機制

目錄 Why Transactions? Example: Bad Interaction Transactions ACID Transactions COMMIT ROLLBACK How the Transaction Log Works How Data Is Stored Example: Interacting Processes Interleaving of Statements Example: Strange Interleaving Fixing the…

第R9周:阿爾茨海默病診斷(優化特征選擇版)

文章目錄 1. 導入數據2. 數據處理2.1 患病占比2.2 相關性分析2.3 年齡與患病探究 3. 特征選擇4. 構建數據集4.1 數據集劃分與標準化4.2 構建加載 5. 構建模型6. 模型訓練6.1 構建訓練函數6.2 構建測試函數6.3 設置超參數 7. 模型訓練8. 模型評估8.1 結果圖 8.2 混淆矩陣9. 總結…

OpenLayers 分屏對比(地圖聯動)

注&#xff1a;當前使用的是 ol 5.3.0 版本&#xff0c;天地圖使用的key請到天地圖官網申請&#xff0c;并替換為自己的key 地圖分屏對比在WebGIS開發中是很常見的功能&#xff0c;和卷簾圖層不一樣的是&#xff0c;分屏對比是在各個地圖中添加相同或者不同的圖層進行對比查看。…

【大模型】大模型數據訓練格式

1. SFT&#xff08;有監督微調&#xff09; 1.1 數據格式 JSONL&#xff08;每行一個 JSON 對象&#xff09;最為流行&#xff1b;也可用 CSV&#xff0f;TSV&#xff0c;但 JSONL 更靈活。字段設計 prompt&#xff1a;用戶輸入或任務指令&#xff08;通常以“系統指令&#…

[論文閱讀] 人工智能 | 利用負信號蒸餾:用REDI框架提升LLM推理能力

【論文速讀】利用負信號蒸餾&#xff1a;用REDI框架提升LLM推理能力 論文信息 arXiv:2505.24850 cs.LG cs.AI cs.CL Harnessing Negative Signals: Reinforcement Distillation from Teacher Data for LLM Reasoning Authors: Shuyao Xu, Cheng Peng, Jiangxuan Long, Weidi…

Cursor 1.0正式推出:全面解析你的AI 編程助手

目錄 前言 一、BugBot&#xff1a;你的私人代碼審查專家 二、Background Agent&#xff1a;7x24小時在線的云端開發伙伴 三、Jupyter Notebook 深度集成&#xff1a;數據科學家的福音 四、記憶功能 (Memories)&#xff1a;讓 AI 更懂你的項目 五、MCP 與工具生態&#xf…

QILSTE 精巧電子元件H4-108FO/5M解析

型號&#xff1a;H4-108FO/5M 在電子元件的浩瀚宇宙中&#xff0c;H4-108FO/5M 仿佛一顆散發著獨特光芒的恒星&#xff0c;其參數和特性交織成一張錯綜復雜的網絡&#xff0c;既令人困惑又充滿驚喜。這款型號的產品&#xff0c;以其 1.60.80.4mm 的微小尺寸&#xff0c;卻蘊含…