LangChain简明教程(11)

《LangChain简明教程》系列文章目录

  1. LangChain简明教程(1)
  2. LangChain简明教程(2)
  3. LangChain简明教程(3)
  4. LangChain简明教程(4)
  5. LangChain简明教程(5)
  6. LangChain简明教程(6)
  7. LangChain简明教程(7)
  8. LangChain简明教程(8)
  9. LangChain简明教程(9)
  10. LangChain简明教程(10)

使用 LangServe 部署

LangServe 帮助开发者将 LangChain 的可运行对象(runnables)和链(chains)部署为 REST API。这个库与 FastAPI 集成,并使用 pydantic 进行数据验证。此外,它还提供了一个客户端,可用于调用部署在服务器上的 runnables,同时在 LangChainJS 中也提供了 JavaScript 客户端。

功能特性

  • 自动推断输入输出 Schema:从 LangChain 对象中自动推断输入和输出的格式定义,并在每次 API 调用时进行校验,提供详细的错误信息。
  • API 文档页面:提供基于 JSONSchema 和 Swagger 的 API 接口文档页面。
  • 高效的 /invoke/batch/stream 接口:支持单台服务器上处理大量并发请求。
  • /stream_log 接口:用于流式传输链(chain)或代理(agent)中的所有(或部分)中间步骤。
  • 交互式测试页面:位于 /playground,支持流式输出和查看中间步骤。
  • 内置(可选)追踪功能:集成到 LangSmith;只需添加 API 密钥即可开启追踪功能(见后续说明)。
  • 基于成熟的开源 Python 库构建:如 FastAPI、Pydantic、uvloop 和 asyncio。

限制

  • 不支持客户端回调机制:对于由服务器端触发的事件,目前还不支持客户端回调。
  • OpenAPI 文档生成限制:当使用 Pydantic V2 时,不会生成 OpenAPI 文档。FastAPI 不支持混合使用 Pydantic V1 和 V2 的命名空间。详见后续相关章节。

启动和调用 API

使用 LangChain CLI 快速启动一个 LangServe 项目。要使用 langchain CLI,请确保已经安装了最新版本的 langchain-cli。可以通过以下命令安装:

pip install -U langchain-cli

使用 LangChain 模板快速启动 LangServe 实例。

langchain app new ../path/to/directory

以下是一个服务器示例,它部署了一个 OpenAI 的聊天模型、一个 Anthropic 的聊天模型,以及一个使用 Anthropic 模型来讲某个主题相关笑话的链(chain)。

#!/usr/bin/env python
from fastapi import FastAPI
from langchain.prompts import ChatPromptTemplate
from langchain.chat_models import ChatAnthropic, ChatOpenAI
from langserve import add_routes

app = FastAPI(
  title="LangChain Server",
  version="1.0",
  description="A simple api server using Langchain's Runnable interfaces",
)

add_routes(
    app,
    ChatOpenAI(),
    path="/openai",
)

add_routes(
    app,
    ChatAnthropic(),
    path="/anthropic",
)

model = ChatAnthropic()
prompt = ChatPromptTemplate.from_template("tell me a joke about {topic}")
add_routes(
    app,
    prompt | model,
    path="/chain",
)

if __name__ == "__main__":
    import uvicorn

    uvicorn.run(app, host="localhost", port=8000)

一旦部署了上面的服务器,可以使用以下命令查看生成的 OpenAPI 文档:

curl localhost:8000/docs

注意,要有 /docs

from langchain.schema import SystemMessage, HumanMessage
from langchain.prompts import ChatPromptTemplate
from langchain.schema.runnable import RunnableMap
from langserve import RemoteRunnable

openai = RemoteRunnable("http://localhost:8000/openai/")
anthropic = RemoteRunnable("http://localhost:8000/anthropic/")
joke_chain = RemoteRunnable("http://localhost:8000/chain/")

joke_chain.invoke({"topic": "parrots"})

# or async
await joke_chain.ainvoke({"topic": "parrots"})

prompt = [
    SystemMessage(content='Act like either a cat or a parrot.'),
    HumanMessage(content='Hello!')
]

# Supports astream
async for msg in anthropic.astream(prompt):
    print(msg, end="", flush=True)

prompt = ChatPromptTemplate.from_messages(
    [("system", "Tell me a long story about {topic}")]
)

# Can define custom chains
chain = prompt | RunnableMap({
    "openai": openai,
    "anthropic": anthropic,
})

chain.batch([{ "topic": "parrots" }, { "topic": "cats" }])

在 TypeScript(需要 LangChain.js 版本 0.0.166 或更高)中:

import { RemoteRunnable } from "langchain/runnables/remote";

const chain = new RemoteRunnable({
  url: `http://localhost:8000/chain/invoke/`,
});
const result = await chain.invoke({
  topic: "cats",
});

用 Python 的 requests 调用:

import requests
response = requests.post(
    "http://localhost:8000/chain/invoke/",
    json={'input': {'topic': 'cats'}}
)
response.json()

也可以用 curl:

curl --location --request POST 'http://localhost:8000/chain/invoke/' \
    --header 'Content-Type: application/json' \
    --data-raw '{
        "input": {
            "topic": "cats"
        }
    }'

如下代码将一个 LangChain 的 Runnable 对象通过 FastAPI 应用(app)暴露为一组 REST API 接口,并指定访问路径为 /my_runnable。

...
add_routes(
  app,
  runnable,
  path="/my_runnable",
)

使用 add_routes(...) 函数(来自 langserve),自动为给定的 runnable 添加多个标准的 API 路由。
参数说明:

  • app: 一个 FastAPI 实例,表示你的 Web 服务应用。
  • runnable: 一个 LangChain 的 Runnable 对象,例如一个模型、chain 或 agent。
  • path=“/my_runnable”: 指定该 runnable 访问路径的基础 URL。

自动生成的路由包括:

路由方法功能
/my_runnable/invokePOST单个输入调用 runnable
/my_runnable/batchPOST批量输入调用 runnable
/my_runnable/streamPOST流式输出调用结果
/my_runnable/stream_logPOST流式输出结果和中间步骤
/my_runnable/input_schemaGET获取 runnable 的输入格式定义(JSON Schema)
/my_runnable/output_schemaGET获取 runnable 的输出格式定义
/my_runnable/config_schemaGET获取 runnable 的配置格式定义
/my_runnable/playgroundGET提供一个交互式 UI 页面用于测试 runnable

你可以在 /my_runnable/playground 找到一个交互式测试页面。这个页面提供了一个简单的 UI 界面,用于配置并调用你的 runnable,支持流式输出和查看中间步骤。

适用于客户端与服务器的安装 langserve 的方法:

pip install "langserve[all]"

或者使用以下命令安装依赖:

  • 用于客户端:pip install "langserve[client]"
  • 用于服务器端:pip install "langserve[server]"

如果需要为服务器添加身份验证功能,请参考 FastAPI 的安全文档中间件文档

使用以下命令部署到 GCP Cloud Run(注意,这里仅以此为例说明部署方法):

gcloud run deploy [your-service-name] --source . --port 8001 --allow-unauthenticated --region us-central1 --set-env-vars=OPENAI_API_KEY=your_key

GCP Cloud Run 是 Google Cloud Platform (GCP) 提供的一项完全托管的无服务器计算服务,它允许运行由 HTTP 请求触发的容器化应用程序。使用 Cloud Run,可以轻松地部署、管理和扩展应用,而无需担心底层基础设施的管理。这意味着开发者可以专注于编写代码和业务逻辑,而不必操心服务器配置、维护以及自动伸缩等运维问题。

GCP Cloud Run 是 Google Cloud Platform 提供的一项特定服务,它依赖于 Google 的基础架构和服务体系。不能在国内其他云服务商提供的云上部署。如果需要,可以选择该云服务商提供的类似服务。

LangServe 对 Pydantic 2 提供了有限的支持。在使用 Pydantic V2 时,不会为 invoke / batch / stream / stream_log 等接口生成 OpenAPI 文档。FastAPI 目前不支持混合使用 Pydantic V1 和 V2 的命名空间。而 LangChain 在 Pydantic V2 中使用的是 V1 兼容的命名空间。所以,要确保与 LangChain 的兼容性。

除了这些限制之外,API 接口、Playground 页面以及其他功能都能如你所愿。

处理文件

LLM 应用程序通常会处理文件。实现文件处理可以采用不同的架构方式,从高层次来看包括:

  • 文件可以通过一个专用端点(一个具体的 URL 或接口路径)上传,并通过另一个端点进行处理。
  • 文件既可以以值的形式上传(即文件的字节数据),也可以以引用形式上传(例如指向 S3 的 URL)。
  • 处理端点可以是阻塞式的,也可以是非阻塞式的。
  • 如果需要大量处理,可以将任务卸载到专门的进程池中。

应当根据应用场景选择合适的架构。假设通过值的方式将文件上传给某个 runnable,应使用 base64 编码来传输文件(当前尚不支持 multipart/form-data 格式)。

以下是一个示例,展示如何使用 base64 编码将文件发送给远程的 runnable。请注意,你也可以通过引用方式上传文件(如 S3 URL),或将文件以 multipart/form-data 形式上传到一个专用端点进行处理。

所有 runnable 都定义了输入和输出类型。可以通过 input_schemaoutput_schema 属性来访问这些类型。LangServe 使用这些类型来进行数据验证和生成文档。如果覆盖默认推断出的类型,可以使用 with_types 方法。

下面是一个简单的示例,用于说明这个概念:

from typing import Any
from fastapi import FastAPI
from langchain.schema.runnable import RunnableLambda

app = FastAPI()

def func(x: Any) -> int:
    """Mistyped function that should accept an int but accepts anything."""
    return x + 1

runnable = RunnableLambda(func).with_types(
    input_schema=int,
)

add_routes(app, runnable)

如果将数据反序列化为 Pydantic 模型,而不是等效的字典(dict)表示形式,可以继承 CustomUserType。目前,该类型仅在服务端生效,用于指定期望的解码行为。如果继承了该类型,服务器将把解码后的数据保持为 Pydantic 模型的形式,而不会将其转换为字典。

from fastapi import FastAPI
from langchain.schema.runnable import RunnableLambda
from langserve import add_routes
from langserve.schema import CustomUserType

app = FastAPI()

class Foo(CustomUserType):
    bar: int

def func(foo: Foo) -> int:
    """Sample function that expects a Foo type which is a pydantic model"""
    assert isinstance(foo, Foo)
    return foo.bar

add_routes(app, RunnableLambda(func), path="/foo")

Playground 允许从后端为 runnable 定义自定义控件(widget)。一个控件是在字段级别上指定的,并作为输入类型 JSON Schema 的一部分进行传输。一个控件必须包含一个名为 type 的键,其值必须是已知控件列表中的一个。其他控件的键将对应一些值,这些值描述了 JSON 对象中的路径。

通用 Schema:

type JsonPath = number | string | (number | string)[];
type NameSpacedPath = { title: string; path: JsonPath }; // Using title to mimic json schema, but can use namespace
type OneOfPath = { oneOf: JsonPath[] };

type Widget = {
    type: string // Some well-known type (e.g., base64file, chat, etc.)
    [key: string]: JsonPath | NameSpacedPath | OneOfPath;
};

允许在 UI Playground 中创建一个文件上传输入框,用于上传以 base64 编码字符串形式传输的文件。下面是一个完整示例。

try:
    from pydantic.v1 import Field
except ImportError:
    from pydantic import Field

from langserve import CustomUserType

# ATTENTION: Inherit from CustomUserType instead of BaseModel otherwise
# the server will decode it into a dict instead of a pydantic model.
class FileProcessingRequest(CustomUserType):
    """Request including a base64 encoded file."""

    # The extra field is used to specify a widget for the playground UI.
    file: str = Field(..., extra={"widget": {"type": "base64file"}})
    num_chars: int = 100
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

CS创新实验室

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值