1、什么是chain?

        在LangChain中,Chain(链)是将多个组件(Components)按特定顺序连接起来,实现复杂任务的工作流(Workflow)或管道(Pipeline)。它是LangChain框架的基石和核心抽象。

2、多种chain的类型及使用

2.1、路由Chain(RouterChain)

from langchain.chains.router import LLMRouterChain, MultiRouteChain
from langchain.chains.router.llm_router import RouterOutputParser
from langchain.prompts import PromptTemplate
from langchain_community.llms import Tongyi
from langchain.chains import LLMChain
import os

# 初始化通义千问模型
api_key = os.getenv("DASHSCOPE_API_KEY")
llm = Tongyi(
    dashscope_api_key=api_key,
    model_name="qwen-turbo"
)

# ===== 1. 准备目标处理链 =====
# 物理专家链
physics_prompt = PromptTemplate(
    template="你是一位物理学家,用专业术语回答,并且在回答问题之前把自己的身份报一下,如物理学家:{input}",
    input_variables=["input"]
)
physics_chain = LLMChain(llm=llm, prompt=physics_prompt)

# 数学专家链
math_prompt = PromptTemplate(
    template="你是一位数学家,逐步解答,并且在回答问题之前把自己的身份报一下,如数学家:{input}",
    input_variables=["input"]
)
math_chain = LLMChain(llm=llm, prompt=math_prompt)

# 默认链(兜底)
default_prompt = PromptTemplate(
    template="{input}",
    input_variables=["input"]
)
default_chain = LLMChain(llm=llm, prompt=default_prompt)

# ===== 2. 构建路由链 =====
# 修改路由模板,使其输出符合 RouterOutputParser 期望的 JSON 格式
router_template = '''
你是一个专业路由助手,根据问题类型选择处理链。可选项:
[physics] - 涉及力、热、光、电磁等物理现象
[math] - 包含公式、计算、几何、代数等数学问题
[default] - 其他类型问题

当前输入:{input}
请严格按照以下 JSON 格式输出,不要添加任何其他内容,注意一定要输出destination:
{{"destination": "选项标识符", "next_inputs": "{input}"}}
例如:{{"destination": "math", "next_inputs": "计算球体体积公式是什么?"}}

示例:
输入:计算球体体积公式是什么?
输出:{{"destination": "math", "next_inputs": "计算球体体积公式是什么?"}}

输入:解释量子纠缠现象
输出:{{"destination": "physics", "next_inputs": "解释量子纠缠现象"}}

输入:推荐一本经典科幻小说
输出:{{"destination": "default", "next_inputs": "推荐一本经典科幻小说"}}
'''

router_chain = LLMRouterChain.from_llm(
    llm=llm,
    prompt=PromptTemplate(
        template=router_template,
        input_variables=["input"],
        output_parser=RouterOutputParser()
    )
)

# ===== 3. 组装路由系统 =====
multi_chain = MultiRouteChain(
    router_chain=router_chain,
    destination_chains={
        "physics": physics_chain,
        "math": math_chain
    },
    default_chain=default_chain,
    verbose=True

)

# ===== 4. 测试路由 =====
inputs = [
    "计算球体体积公式是什么?",       # 预期路由到math
    "解释量子纠缠现象",             # 预期路由到physics
    "推荐一本经典科幻小说"          # 预期路由到default
]

# ... existing code ...
for query in inputs:
    print(f"输入:{query}")
    result = multi_chain.invoke({"input": query})
    # 打印完整结果以检查其实际结构
    print(f"完整结果: {result}")
    
    # 根据实际输出结构调整以下代码
    if isinstance(result, dict):
        # 检查是否存在 'destination' 键
        if 'destination' in result:
            print(f"路由结果:{result['destination'].upper()}链")
            # 检查是否存在 'answer' 或 'text' 键来获取回答
            answer = result.get('answer', result.get('text', 'No answer provided'))
            print(f"回答:{answer}")
        # 如果存在 'output' 键,则进一步检查其内容
        elif 'output' in result:
            output_content = result['output']
            if isinstance(output_content, dict) and 'destination' in output_content:
                print(f"路由结果:{output_content['destination'].upper()}链")
                answer = output_content.get('answer', output_content.get('text', 'No answer provided'))
                print(f"回答:{answer}")
            else:
                print(f"路由结果:未知链")
                print(f"回答:{output_content}")
        else:
            print(f"路由结果:未知链")
            print(f"回答:{result}")
    else:
        print(f"路由结果:未知链")
        print(f"回答:{result}")
    print()
# ... existing code ...

2.2、顺序链

        在 LangChain 的 SimpleSequentialChain 中,链的排列顺序会直接影响最终输出结果。这是因为该链的核心机制是严格按声明顺序执行链,前一个链的输出会作为后一个链的输入。

from langchain.chains import LLMChain, SimpleSequentialChain
from langchain.prompts import PromptTemplate
from langchain_community.llms import Tongyi
import os

# 初始化通义千问模型
api_key = os.getenv("DASHSCOPE_API_KEY")
llm = Tongyi(
    dashscope_api_key=api_key,
    model_name="qwen-turbo-latest",
    temperature=0.7
)

# 第一个链:生成一个创意概念
concept_template = """你是一个创意专家,请为以下主题生成一个独特的概念:
主题: {input}
概念:"""
concept_prompt = PromptTemplate(template=concept_template, input_variables=["input"])
concept_chain = LLMChain(llm=llm, prompt=concept_prompt)

# 第二个链:基于概念生成详细描述
description_template = """你是一个内容策划专家,请基于以下概念生成一段详细的描述:
概念: {input}
详细描述:"""
description_prompt = PromptTemplate(template=description_template, input_variables=["input"])
description_chain = LLMChain(llm=llm, prompt=description_prompt)

# 第三个链:为描述添加标题
headline_template = """你是一个标题专家,请为以下描述生成一个吸引人的标题:
描述: {input}
标题:"""
headline_prompt = PromptTemplate(template=headline_template, input_variables=["input"])
headline_chain = LLMChain(llm=llm, prompt=headline_prompt)

# 创建 SimpleSequentialChain
# verbose=True 用于显示执行过程
overall_chain = SimpleSequentialChain(
    chains=[concept_chain, description_chain, headline_chain],
    verbose=True
)

# 测试案例
if __name__ == "__main__":
    # 输入主题
    input_topic = "人工智能在医疗领域的应用"
    
    print(f"输入主题: {input_topic}")
    print("=" * 50)
    
    # 执行链式调用
    result = overall_chain.invoke(input_topic)
    
    print("=" * 50)
    print(f"最终输出: {result['output']}")

2.3 四大文档链的对比

选择建议:
        文档短 → Stuff
        文档长且需逻辑连贯 → Refine
        海量独立文档 → MapReduce
        需筛选最佳答案 → MapRerank

Logo

火山引擎开发者社区是火山引擎打造的AI技术生态平台,聚焦Agent与大模型开发,提供豆包系列模型(图像/视频/视觉)、智能分析与会话工具,并配套评测集、动手实验室及行业案例库。社区通过技术沙龙、挑战赛等活动促进开发者成长,新用户可领50万Tokens权益,助力构建智能应用。

更多推荐