( 教学 )Agent 构建 Prompt(提示词)6. 输出修正解析器 OutputFixingParser
在 LangChain 中的 OutputFixingParser 提供了一种自动化的机制,用于纠正在输出解析过程中可能出现的错误。
该解析器旨在围绕另一个解析器(例如 PydanticOutputParser)进行部署,并在底层解析器遇到格式错误或不符合预期格式的输出时介入。
它通过调用更多的语言模型(LLM)来修正错误并确保格式正确。
其核心功能是处理初始输出不符合预设模式的情况。一旦出现此类问题,该解析器会自动检测出格式错误,并向模型提交一个新的请求,其中包含纠正问题的具体说明。这些说明会指出问题所在,并提供清晰的指导,以使数据按照正确的格式进行重新组织。
此功能在严格遵循特定模式的场景中尤为有用。
例如,当使用PydanticOutputParser来生成符合特定数据模式的输出时,可能会出现诸如缺少字段或数据类型错误等问题。
输出修正解析器的操作步骤如下:
-
错误检测 :它会识别出输出不符合模式要求。
-
错误修正 :它会向语言模型发送后续请求,并明确指示其解决相关问题。
-
根据特定要求重新格式化的输出 :"输出修正解析器"确保修正指令能够准确地指出错误之处,例如缺少的字段或不正确的数据类型。这些指令引导语言模型对输出进行重新格式化,以完全符合模式要求。
实际示例:
假设您正在使用"PydanticOutputParser"来执行一个需要特定字段(如"姓名"(字符串)、"年龄"(整数)和"电子邮件"(字符串))的规范。如果语言模型生成的输出中缺少"年龄"字段或者"电子邮件"字段不是一个有效的字符串,那么"OutputFixingParser"会自动介入。
它会向语言模型发出一个新的请求,并附上详细的说明,例如:
- 输出中缺少了
年龄这一字段。请为年龄添加一个合适的整数值。 电子邮件字段的格式不正确。请将其更正为符合有效电子邮件格式的字符串。
这种迭代过程能够确保最终输出符合指定的格式,而无需人工干预。
主要优势:
- 错误恢复:能够自动处理格式错误的输出,无需用户干预。
- 准确性提升:确保输出符合预设的格式规范,降低出现不一致情况的风险。
- 流程简化:减少手动修正的需求,节省时间并提高效率。
实施步骤: 要有效地使用输出修正解析器,请按照以下步骤操作:
-
封装解析器 :使用另一个解析器(例如
PydanticOutputParser)作为基础,来实例化OutputFixingParser。 -
定义模式:明确输出必须遵循的模式或格式。
-
启用错误修正功能 :允许
输出修正解析器通过额外的大型语言模型调用自动检测并纠正错误,确保修正指令能够准确地识别并解决问题,从而实现精确的格式重排。
通过将输出修正解析器集成到您的工作流程中,您能够确保强大的错误处理能力,并在您的 LangChain 应用程序中保持一致的输出质量。
定义数据模型和设置 PydanticOutputParser
- Actor 类使用 Pydantic 模型定义,其中 name 和 film_names 字段分别表示演员的姓名和他们出演的电影列表。
PydanticOutputParser用于将输出解析为 Actor 对象。
python
from langchain_core.output_parsers import PydanticOutputParser
from pydantic import BaseModel, Field
from typing import List
# 使用 Pydantic 定义演员类
class Actor(BaseModel):
name: str = Field(description="演员的姓名")
film_names: List[str] = Field(description="出演的电影名称列表")
# 生成随机演员电影作品列表的查询
actor_query = "生成一个随机演员的电影作品列表。"
# 使用 PydanticOutputParser 将输出解析为 Actor 对象
parser = PydanticOutputParser(pydantic_object=Actor)
尝试解析格式错误的输入数据 ***
- misformatted 变量包含一个格式不正确的字符串,它与预期的结构不匹配(使用了 ' 而不是 ")。
- 调用 parser.parse() 将会因为格式不匹配而导致错误。
python
# 尝试解析格式错误的输入数据
misformatted = "{'name': 'Tom Hanks', 'film_names': ['Forrest Gump']}"
parser.parse(misformatted)
输出的错误信息:
ruby
OutputParserException: Invalid json output: {'name': 'Tom Hanks', 'film_names': ['Forrest Gump']}
For troubleshooting, visit: https://python.langchain.com/docs/troubleshooting/errors/OUTPUT_PARSING_FAILURE
- 输出修正解析器会自动检测到格式错误,并向模型发送修正指令。
- 修正后的输出将符合 Actor 类的定义,并且可以成功解析。
使用 OutputFixingParser 修正格式错误
设置 OutputFixingParser 自动修正错误 适用与 小于 版本1.0
OutputFixingParser包装现有的PydanticOutputParser,通过对 LLM 进行额外调用来自动修复错误。这个解析过程是透明的,用户无需手动干预。- from_llm() 方法将
OutputFixingParser与ChatOpenAI连接,以修正输出中的格式问题。
python
from langchain_openai import ChatOpenAI
from langchain_core.prompts import PromptTemplate
from langchain.output_parsers import OutputFixingParser
# 定义自定义提示以提供修复说明
fixing_prompt = PromptTemplate(
template=(
"以下JSON格式不正确或不完整: {completion}\n"
),
input_variables=[
"completion",
],
)
from langchain_openai import ChatOpenAI
from pydantic import BaseModel, Field
from dotenv import load_dotenv
import os
load_dotenv()
Qwen2_5_7B_Instruct_llm = ChatOpenAI(
temperature=0.1, # 控制输出的随机性和创造性,值越低输出越稳定可预测,值越高输出越有创意但可能偏离预期 (范围: 0.0 ~ 2.0)
model_name="Qwen/Qwen2.5-7B-Instruct", # 硅基流动支持的模型名称
openai_api_key=os.getenv("SILICONFLOW_API_KEY"), # 从环境变量获取API密钥
openai_api_base="https://api.siliconflow.cn/v1" # 硅基流动API的基础URL
)
# 使用OutputFixingParser自动修复错误
new_parser = OutputFixingParser.from_llm(
parser=parser, llm=Qwen2_5_7B_Instruct_llm, prompt=fixing_prompt
)
设置 最新的 自动修正错误 使用方式 适用与 大于 版本1.0的 Langchain 库
在 LangChain 最新版本中,OutputFixingParser 已被 with_structured_output() 的内置重试机制取代,不再需要单独使用。
现代模型通过 with_structured_output() 方法 + ToolStrategy 提供自动错误修复,当解析失败时会自动重试并提供具体错误反馈。
ToolStrategy 是 LangChain 的一种 结构化输出策略 ,主要用于:
ToolStrategy 是 LangChain v1.0+ 中的一个重要组件,用于处理结构化输出和自动错误修复。
- 工具调用策略 :通过工具调用实现结构化输出
- 自动错误处理 :当解析失败时自动重试并提供具体错误反馈
- 模型兼容性 :支持不支持原生结构化输出的模型
python
from pydantic import BaseModel, Field
from langchain_openai import ChatOpenAI
from langchain.agents.structured_output import ToolStrategy
Qwen2_5_7B_Instruct_llm = ChatOpenAI(
temperature=0.1, # 控制输出的随机性和创造性,值越低输出越稳定可预测,值越高输出越有创意但可能偏离预期 (范围: 0.0 ~ 2.0)
model_name="Qwen/Qwen2.5-7B-Instruct", # 硅基流动支持的模型名称
openai_api_key=os.getenv("SILICONFLOW_API_KEY"), # 从环境变量获取API密钥
openai_api_base="https://api.siliconflow.cn/v1" # 硅基流动API的基础URL
)
class Actor(BaseModel):
name: str = Field(description="演员的姓名")
film_names: List[str] = Field(description="出演的电影名称列表")
# 自动修复解析错误 (默认重试3次)
structured_model = Qwen2_5_7B_Instruct_llm.with_structured_output(
Actor,
method="json_schema" # 或 "function_calling"
)
# 测试错误输入 - 会自动修复
result = structured_model.invoke("演员 张三 出演了 电影 1, 电影 2, 电影 3")
print(result)
或者可以选择使用 create_agent 方法创建一个智能体,该智能体会自动处理结构化输出和错误修复。
python
from langchain import create_agent
from pydantic import BaseModel, Field
from langchain_openai import ChatOpenAI
from langchain.agents.structured_output import ToolStrategy
Qwen2_5_7B_Instruct_llm = ChatOpenAI(
temperature=0.1, # 控制输出的随机性和创造性,值越低输出越稳定可预测,值越高输出越有创意但可能偏离预期 (范围: 0.0 ~ 2.0)
model_name="Qwen/Qwen2.5-7B-Instruct", # 硅基流动支持的模型名称
openai_api_key=os.getenv("SILICONFLOW_API_KEY"), # 从环境变量获取API密钥
openai_api_base="https://api.siliconflow.cn/v1" # 硅基流动API的基础URL
)
class Actor(BaseModel):
name: str = Field(description="演员的姓名")
film_names: List[str] = Field(description="出演的电影名称列表")
agent = create_agent(
model=Qwen2_5_7B_Instruct_llm,
tools=[], # 无工具时使用结构化输出
response_format=ToolStrategy(Actor, handle_errors=True) # 自动重试
)
result = agent.invoke({
"messages": [{"role": "user", "content": "Parse: 演员 张三 出演了 电影 1, 电影 2, 电影 3"}]
})
print(result["structured_response"])