You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

寻求LangChain中ChatBedrock替代ChatOpenAI实现结构化输出路由的方案

替代ChatBedrock缺失with_structured_output的查询路由方案

针对AWS ChatBedrock无法使用with_structured_output实现查询路由的问题,以下是三种可落地的替代方案,均能实现从指定列表选择数据源、输出无冗余结构化结果的核心需求:

方法一:自定义Prompt + Pydantic输出解析器

这是通用型方案,适配Bedrock上所有支持文本输出的模型。核心思路是在Prompt中明确告知模型输出格式,再用LangChain的PydanticOutputParser解析结果。

from typing import List, Literal
from langchain_core.prompts import ChatPromptTemplate
from langchain_core.pydantic_v1 import BaseModel, Field
from langchain_core.output_parsers import PydanticOutputParser
from langchain_aws import ChatBedrock

# 定义路由规则模型
class RouteQuery(BaseModel):
    """路由用户查询到最相关的数据源"""
    datasources: List[Literal["python_docs", "js_docs", "golang_docs"]] = Field(
        ...,
        description="从给定列表中选择与用户问题最相关的数据源,只能选列表内选项"
    )

# 初始化Pydantic解析器
parser = PydanticOutputParser(pydantic_object=RouteQuery)

# 构造约束型Prompt,强制输出纯净JSON
system_prompt = f"""你是专业查询路由专家,根据问题涉及的编程语言匹配对应数据源。
必须严格按照以下格式输出JSON,禁止添加任何解释性文字:
{parser.get_format_instructions()}
注意:datasources只能从["python_docs", "js_docs", "golang_docs"]中选择,支持多选。"""

prompt = ChatPromptTemplate.from_messages(
    [
        ("system", system_prompt),
        ("human", "{question}"),
    ]
)

# 初始化Bedrock模型(以Claude 3 Sonnet为例)
llm = ChatBedrock(
    model_id="anthropic.claude-3-sonnet-20240229-v1:0",
    temperature=0,
    model_kwargs={"max_tokens": 200}
)

# 构建路由链
router_chain = prompt | llm | parser

# 测试调用
result = router_chain.invoke({
    "question": "Python和JS版本的OpenAI聊天模型功能是否一致?"
})
print(result)
# 输出:RouteQuery(datasources=['python_docs', 'js_docs'])

方法二:利用Bedrock模型原生结构化输出能力

部分Bedrock模型(如Anthropic Claude、Amazon Titan)支持原生工具调用/结构化输出功能,可直接生成符合要求的结果,减少解析步骤。

以Claude 3为例,利用其工具调用格式:

from typing import List, Literal
from langchain_core.messages import HumanMessage, SystemMessage
from langchain_core.pydantic_v1 import BaseModel, Field
from langchain_aws import ChatBedrock

class RouteQuery(BaseModel):
    """路由用户查询到最相关的数据源"""
    datasources: List[Literal["python_docs", "js_docs", "golang_docs"]] = Field(
        ...,
        description="选择与用户问题最相关的数据源,只能从指定列表选取"
    )

# 定义工具描述(符合Claude工具调用规范)
tool_definition = {
    "name": "route_query",
    "description": "将用户查询路由到最相关的数据源",
    "input_schema": RouteQuery.model_json_schema()
}

# 构造系统提示,强制使用指定工具返回结果
system_prompt = """你是查询路由专家,必须使用提供的route_query工具返回结果,直接输出工具调用的JSON格式,无需其他内容。"""

messages = [
    SystemMessage(content=system_prompt),
    HumanMessage(
        content="Python和JS版本的OpenAI聊天模型功能是否一致?",
        additional_kwargs={"tools": [tool_definition]}
    )
]

# 初始化Bedrock Claude模型
llm = ChatBedrock(
    model_id="anthropic.claude-3-sonnet-20240229-v1:0",
    temperature=0,
    model_kwargs={"max_tokens": 200}
)

# 调用并解析结果
response = llm.invoke(messages)
tool_call = response.additional_kwargs.get("tool_calls", [])[0]
result = RouteQuery(**tool_call["input"])
print(result)
# 输出:RouteQuery(datasources=['python_docs', 'js_docs'])

方法三:使用JSON输出解析器(简化版)

如果不需要严格的Pydantic验证,可直接用JsonOutputParser快速实现需求:

from typing import List, Literal
from langchain_core.prompts import ChatPromptTemplate
from langchain_core.output_parsers import JsonOutputParser
from langchain_aws import ChatBedrock
from langchain_core.pydantic_v1 import BaseModel, Field

class RouteQuery(BaseModel):
    datasources: List[Literal["python_docs", "js_docs", "golang_docs"]]

# 定义JSON Schema
json_schema = RouteQuery.model_json_schema()
parser = JsonOutputParser()

# 构造约束Prompt
system_prompt = f"""你是查询路由专家,根据问题选择对应的数据源,只能从["python_docs", "js_docs", "golang_docs"]中选取。
必须输出符合以下JSON Schema的纯净JSON,无任何额外内容:
{json_schema}"""

prompt = ChatPromptTemplate.from_messages(
    [("system", system_prompt), ("human", "{question}")]
)

llm = ChatBedrock(
    model_id="anthropic.claude-3-haiku-20240307-v1:0",
    temperature=0
)

# 构建链
chain = prompt | llm | parser

# 调用并转换为Pydantic对象(可选)
result = chain.invoke({"question": "Python和JS版本的OpenAI聊天模型功能是否一致?"})
route_result = RouteQuery(**result)
print(route_result)

关键注意事项

  • Prompt约束要绝对明确:必须强调只能从指定数据源列表选择,且输出只能是结构化内容,禁止添加任何解释性文字。
  • 优先选择结构化友好模型:如Claude 3系列,这类模型对格式约束的依从性更高,能降低解析失败概率。
  • 固定温度参数:将temperature设为0,确保输出稳定性,避免随机结果干扰后续逻辑。

内容的提问来源于stack exchange,提问作者Mischa

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.24 08:25:16