⚠️ 重要通知: 此仓库不再维护。
⚡ 使用 Jina 和 FastAPI 在生产环境中运行 LangChain 应用 🚀
Jina 是一个开源框架,用于在生产环境中构建可扩展的多模态 AI 应用。 LangChain 是另一个用于构建由大型语言模型 (LLM) 提供支持的应用的开源框架。
langchain-serve 可以帮助你在 Jina AI 云端快速部署你的 LangChain 应用。你可以在不牺牲本地开发的便利性的情况下,享受云端的可扩展性和无服务器架构。而且,如果你愿意,你也可以将 LangChain 应用部署在你自己的基础设施上,以确保数据隐私。通过 langchain-serve,你可以在云端或本地基础设施上创建 REST/Websocket API,启动由 LLM 提供支持的 Slack 机器人,或将 LangChain 应用打包成 FastAPI 包。
给我们一个 :star: 并告诉我们你还想看到什么功能!
☁️ LLM 应用即服务
langchain-serve 目前将以下应用作为服务封装,一键部署到 Jina AI 云端。
🔮 AutoGPT 即服务
AutoGPT 是一个“AI 代理”,它在接收到自然语言目标后,会通过分解子任务、利用互联网和其他工具在自动循环中尝试达成目标。
显示用法
-
使用一条命令在 Jina AI 云端部署
autogpt
lc-serve deploy autogpt
显示命令输出
╭──────────────┬────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │ 应用 ID │ autogpt-6cbd489454 │ ├──────────────┼────────────────────────────────────────────────────────────────────────────────────────────────────────┤ │ 阶段 │ 提供服务 │ ├──────────────┼────────────────────────────────────────────────────────────────────────────────────────────────────────┤ │ 端点 │ wss://autogpt-6cbd489454.wolf.jina.ai │ ├──────────────┼────────────────────────────────────────────────────────────────────────────────────────────────────────┤ │ 应用日志 │ dashboards.wolf.jina.ai │ ├──────────────┼────────────────────────────────────────────────────────────────────────────────────────────────────────┤ │ Swagger UI │ https://autogpt-6cbd489454.wolf.jina.ai/docs │ ├──────────────┼────────────────────────────────────────────────────────────────────────────────────────────────────────┤ │ OpenAPI JSON │ https://autogpt-6cbd489454.wolf.jina.ai/openapi.json │ ╰──────────────┴────────────────────────────────────────────────────────────────────────────────────────────────────────╯
-
使用 API 将 autogpt 与外部服务集成。在你的 CLI 上体验集成的效果
lc-serve playground autogpt
显示 Playground
🧠 Babyagi 即服务
Babyagi 是一个任务驱动的自主代理,它使用 LLM 创建、优先排序并执行任务。这是一个通用 AI 代理,可用于自动化各种任务。
显示用法
-
使用一条命令在 Jina AI 云端部署
babyagi
lc-serve deploy babyagi
-
使用我们的 Websocket API 将 babyagi 与外部服务集成。在你的 CLI 上体验集成的效果
lc-serve playground babyagi
显示 Playground
:panda_face: pandas-ai 即服务
pandas-ai 将 LLM 功能集成到 Pandas 中,使数据框在 Python 代码中具有对话能力。感谢 langchain-serve,我们现在可以在几秒钟内在 Jina AI 云端公开 pandas-ai 的 API。
显示用法
-
在 Jina AI 云端部署 pandas-ai
lc-serve deploy pandas-ai
显示命令输出
╭──────────────┬─────────────────────────────────────────────────────────────────────────────────╮ │ 应用 ID │ pandasai-06879349ca │ ├──────────────┼─────────────────────────────────────────────────────────────────────────────────┤ │ 阶段 │ 提供服务 │ ├──────────────┼─────────────────────────────────────────────────────────────────────────────────┤ │ 端点 │ wss://pandasai-06879349ca.wolf.jina.ai │ ├──────────────┼─────────────────────────────────────────────────────────────────────────────────┤ │ 应用日志 │ dashboards.wolf.jina.ai │ ├──────────────┼─────────────────────────────────────────────────────────────────────────────────┤ │ Swagger UI │ https://pandasai-06879349ca.wolf.jina.ai/docs │ ├──────────────┼─────────────────────────────────────────────────────────────────────────────────┤ │ OpenAPI JSON │ https://pandasai-06879349ca.wolf.jina.ai/openapi.json │ ╰──────────────┴─────────────────────────────────────────────────────────────────────────────────╯
-
将你的 DataFrame 上传到 Jina AI 云端(可选 - 你也可以使用公开的 CSV 文件)
-
在 Python 文件中定义你的 DataFrame
# dataframe.py import pandas as pd df = pd.DataFrame(some_data)
-
使用
<module>:<variable>
语法将你的 DataFrame 上传到 Jina AI 云端lc-serve util upload-df dataframe:df
-
-
使用 pandas-ai API 对你的 DataFrame 进行对话化。使用本地 Playground 在你的 CLI 上体验集成效果
lc-serve playground pandas-ai <host>
显示 Playground
💬 基于 PDF 的问答机器人
pdfqna
是一个简单的问答机器人,使用 LLM 在 PDF 文档上回答问题,展示了如何轻松地在 Jina AI 云端集成 langchain 应用。
显示用法
-
使用一条命令在 Jina AI 云端部署
pdf_qna
lc-serve deploy pdf-qna
-
使用 Streamlit playground 在你的 CLI 上体验集成效果
lc-serve playground pdf-qna
显示 Playground
🔥 在 Jina AI Cloud 上提供安全、可扩展、无服务器的流媒体 REST/Websocket API。
- 🌎 全球可用的 REST/Websocket API,自动生成 TLS 证书。
- 🌊 使用 Websockets 实时流式处理 LLM 交互。
- 👥 为你的代理启用人工反馈环节。
- 💬 构建、部署并分发使用 Langchain 构建的 Slack 机器人。
- 🔑 使用 Bearer 令牌保护你的 API,API 授权。
- 📄 随 API 提供的 Swagger UI 和 OpenAPI 规范。
- ⚡️ 无服务器、自动扩展的应用程序,根据流量自动扩展。
- 🗝️ 安全处理密钥和环境变量。
- 📁 挂载在应用程序上的持久存储(EFS)以存储数据。
- ⏱️ 触发一次性作业异步运行,允许非阻塞执行。
- 📊 内置日志记录、监控和 API 跟踪。
- 🤖 无需更改代码即可管理 API、管理 Dockerfile 或担心基础设施!
🏠 使用 Docker Compose 或 Kubernetes 自托管 LLM 应用程序
- 🚀 一键命令将你的应用程序导出为 Kubernetes 或 Docker Compose YAML 文件。
- 👉
lc-serve export app --kind <kubernetes/docker-compose> --path .
- 📦 在你的内部基础设施上部署应用程序,遵循你的安全策略。
- 📞 如果你需要在自己的基础设施上使用 Jina AI Cloud 的全部功能,请与我们联系。
🧰 使用
首先,我们通过 pip 安装 langchain-serve
。
pip install langchain-serve
🔄 使用 @serving
装饰器的 REST API
👉 让我们通过 逐步指南 来构建、部署和使用 REST API,使用 @serving
装饰器。
🤖💬 构建、部署和分发使用 LangChain 构建的 Slack 机器人
langchain-serve 提供一个 @slackbot
装饰器,快速构建、部署和分发 LLM 驱动的 Slack 机器人,而无需担心基础设施问题。它为任何 langchain 应用程序提供了一个简单的界面,使其在用户已熟悉的平台上非常容易访问。
✨ 准备好深入了吗?
🔐 授权你的 API
为了增加一层安全性,我们可以通过在 @serving
装饰器中添加 auth
参数来集成任何自定义的 API 授权。
显示代码与注意事项
from lcserve import serving
def authorizer(token: str) -> Any:
if not token == 'mysecrettoken': # 修改此处以添加你自己的授权逻辑
raise Exception('Unauthorized') # 如果请求未被授权则抛出异常
return 'userid' # 返回任意用户 ID 或对象
@serving(auth=authorizer)
def ask(question: str, **kwargs) -> str:
auth_response = kwargs['auth_response'] # 这将是 'userid'
return ...
@serving(websocket=True, auth=authorizer)
async def talk(question: str, **kwargs) -> str:
auth_response = kwargs['auth_response'] # 这将是 'userid'
return ...
🤔 关于 auth
函数的注意事项
- 应仅接受一个参数
token
。 - 如果请求未被授权,应抛出一个异常。
- 可以返回任意对象,该对象将通过
kwargs
传递给函数中的auth_response
对象。 - 期望在请求的
Authorization
头部中有 Bearer 令牌。 - 使用
curl
发送的示例 HTTP 请求:curl -X 'POST' 'http://localhost:8080/ask' -H 'Authorization: Bearer mysecrettoken' -d '{ "question": "...", "envs": {} }'
- 使用
wscat
发送的示例 WebSocket 请求:wscat -H "Authorization: Bearer mysecrettoken" -c ws://localhost:8080/talk
🙋♂️ 使用 WebSockets 启用流式处理和人工反馈环节(HITL)
在生产环境中为 LangChain 代理启用 HITL 可能具有挑战性,因为代理通常运行在人类无法直接访问的服务器上。langchain-serve 通过启用 websocket API,弥合了代理与人工操作员之间实时交互和反馈的差距。
查看这个 示例,了解如何为你的代理启用 HITL。
📁 Jina AI Cloud 上的持久存储
在 Jina AI Cloud 上部署的每个应用程序都会获得一个本地挂载的持久存储(EFS),可以通过 @serving
函数中的 workspace
参数访问。
显示代码
from lcserve import serving
@serving
def store(text: str, **kwargs):
workspace: str = kwargs.get('workspace')
path = f'{workspace}/store.txt'
print(f'Writing to {path}')
with open(path, 'a') as f:
f.writelines(text + '\n')
return 'OK'
@serving(websocket=True)
async def stream(**kwargs):
workspace: str = kwargs.get('workspace')
websocket: WebSocket = kwargs.get('websocket')
path = f'{workspace}/store.txt'
print(f'Streaming {path}')
async with aiofiles.open(path, 'r') as f:
async for line in f:
await websocket.send_text(line)
return 'OK'
在这里,我们使用 workspace
通过 REST 端点将输入文本存储在一个文件中,并通过 WebSocket 端点流式传输该文件的内容。
🚀 使用 FastAPI 构建自己的应用程序
如果你已经有一个包含预定义端点的 FastAPI 应用程序,可以使用 lc-serve
将其部署在 Jina AI Cloud 上。
lc-serve deploy jcloud --app filename:app
显示详情
让我们以一个简单的 FastAPI 应用程序为例,其目录结构如下:
.
└── endpoints.py
# endpoints.py
from typing import Union
from fastapi import FastAPI
app = FastAPI()
@app.get("/status")
def read_root():
return {"Hello": "World"}
@app.get("/items/{item_id}")
def read_item(item_id: int, q: Union[str, None] = None):
return {"item_id": item_id, "q": q}
lc-serve deploy jcloud --app endpoints:app
🗝️ 部署时使用 Secrets
你可以在应用部署时通过 --secrets
标志传递一个 secrets 文件来使用机密信息。secrets 文件应为 .env
文件,包含机密信息。
lcserve deploy jcloud app --secrets .env
显示详情
让我们以一个使用 OPENAI_API_KEY
存储为机密的简单应用为例。
此应用程序目录包含以下文件:
.
├── main.py # 应用程序
├── jcloud.yml # JCloud 部署配置文件
├── README.md # 此 README 文件
├── requirements.txt # 应用程序的要求文件
└── secrets.env # 包含 redis 凭据的机密文件
注意 此目录中的
secret.env
是一个虚拟文件。你应该在创建 Redis 实例后,用你自己的机密信息替换它。(例如通过 Upstash 创建),例如:
OPENAI_API_KEY=sk-xxx
main.py
文件内容如下:
# main.py
from lcserve import serving
from langchain.prompts import PromptTemplate
from langchain.chains import LLMChain
from langchain.chat_models import ChatOpenAI
prompt = PromptTemplate(
input_variables=["subject"],
template="Write me a short poem about {subject}?",
)
@serving(openai_tracing=True)
def poem(subject: str, **kwargs):
tracing_handler = kwargs.get("tracing_handler")
chat = ChatOpenAI(
| 描述 | 命令 |
| --- | ---: |
| 本地部署应用 | `lc-serve deploy local app` |
| 导出应用为 Kubernetes YAML | `lc-serve export app --kind kubernetes --path .` |
| 导出应用为 Docker Compose YAML | `lc-serve export app --kind docker-compose --path .` |
| 在 JCloud 上部署应用 | `lc-serve deploy jcloud app` |
| 在 JCloud 上部署 FastAPI 应用 | `lc-serve deploy jcloud --app <app-name>:<app-object>` |
| 更新 JCloud 上的现有应用 | `lc-serve deploy jcloud app --app-id <app-id>` |
| 获取 JCloud 上应用的状态 | `lc-serve status <app-id>` |
| 列出 JCloud 上的所有应用 | `lc-serve list` |
| 删除 JCloud 上的应用 | `lc-serve remove <app-id>` |
| 暂停 JCloud 上的应用 | `lc-serve pause <app-id>` |
| 恢复 JCloud 上的应用 | `lc-serve resume <app-id>` |
# 💡 JCloud 部署
## ⚙️ 配置
对于 JCloud 部署,您可以通过使用 `--config` 选项提供一个 YAML 配置文件来配置应用程序基础设施。支持的配置项有:
- 实例类型 (`instance`),由 [Jina AI Cloud](https://docs.jina.ai/concepts/jcloud/configuration/#cpu-tiers) 定义。
- 应用程序的最小副本数量 (`autoscale_min`)。将其设置为 0 可以启用[无服务器](https://en.wikipedia.org/wiki/Serverless_computing)。
- 磁盘大小 (`disk_size`),单位为 GB。默认值为 1 GB。
例如:
instance: C4 autoscale_min: 0 disk_size: 1.5G
您还可以在应用程序目录中包含一个 `jcloud.yaml` 文件,并设置所需的配置。然而,请注意,如果在命令行中明确使用了 `--config` 选项,本地的 jcloud.yaml 文件将被忽略。命令行提供的配置文件将优先于本地文件。
如果您没有提供配置文件或未指定特定配置,将应用以下默认设置:
instance: C3 autoscale_min: 1 disk_size: 1G
## 💰 计费
JCloud 上托管的应用程序按两个类别收费:
**基本积分**
- 基本积分用于确保您的应用程序具有高可用性,至少保持一个实例持续运行,以便随时处理传入的请求。如果您希望停止服务应用程序,可以完全删除应用程序或将其暂停,后者允许您基于持久化配置恢复应用程序服务(有关详细信息,请参阅 [`lc-serve` CLI 部分](#-lc-serve-cli))。两种选项都将停止积分消耗。
- 基本积分的实际收费基于 [Jina AI Cloud 定义的实例类型](https://docs.jina.ai/concepts/jcloud/configuration/#cpu-tiers)。
- 默认情况下,使用实例类型 `C3`,至少 1 个实例,以及 1G 的 [Amazon EFS](https://aws.amazon.com/efs/) 磁盘,这意味着如果您的应用程序在 JCloud 上提供服务,每小时将收费约 10 积分。
- 您可以通过使用 `--config` 选项提供 YAML 配置文件来更改实例类型和最小实例数量。例如,如果您想使用实例类型 `C4`,最小副本数为 0,EFS 磁盘大小为 2G,可以提供以下配置文件:
```yaml
instance: C4
autoscale_min: 0
disk_size: 2G
服务积分
- 服务积分在您的应用程序主动处理传入请求时收费。
- 服务积分的实际收费基于实例类型的积分乘以应用程序服务请求的时长。
- 您将按应用程序服务请求的每秒收费。
总积分费用 = 基本积分 + 服务积分。 (Jina AI Cloud 定义每个积分为 €0.005)
示例
示例 1
考虑一个 HTTP 应用程序在上一个小时内服务了 10
分钟的请求,并使用自定义配置:
instance: C4
autoscale_min: 0
disk_size: 2G
每小时总收费积分将为 3.33
。计算如下:
C4 实例的每小时积分率为 20。
EFS 的每小时积分率为 0.104 每 GB。
基本积分 = 0 + 2 * 0.104 = 0.208(因为 `autoscale_min` 为 0)
服务积分 = 20 * 10/60 = 3.33
每小时总积分 = 0.208 + 3.33 = 3.538
示例 2
考虑一个 WebSocket 应用程序在上一个小时内有 20 分钟的活跃连接,并使用默认配置。
instance: C3
autoscale_min: 1
disk_size: 1G
每小时总收费积分将为 13.33
。计算如下:
C3 实例的每小时积分率为 10。
EFS 的每小时积分率为 0.104 每 GB。
基本积分 = 10 + 1 * 0.104 = 10.104(因为 `autoscale_min` 为 1)
服务积分 = 10 * 20/60 = 3.33
每小时总积分 = 10.104 + 3.33 = 13.434
❓ 常见问题解答
lc-serve
命令未找到- 我的客户端连接到 JCloud 托管的应用程序时超时,应该怎么办?
- 如何将环境变量传递给应用程序?
- JCloud 部署在推送镜像到 Jina Hubble 时失败,应该怎么办?
- 调试 babyagi playground 的请求/响应以进行外部集成
lc-serve
命令未找到
展开
lc-serve
命令在 langchain-serve
安装期间注册。如果您收到 command not found: lc-serve
错误,请将 lc-serve
命令替换为 python -m lcserve
并重试。
我的客户端连接到 JCloud 托管的应用程序时超时,应该怎么办?
展开
如果您发出较长的 HTTP/WebSocket 请求,默认超时时间(2 分钟)可能不适合您的使用场景。您可以在 JCloud 部署期间使用 --timeout
参数提供自定义超时时间。
此外,对于 HTTP,由于我们在 langchain-serve
中使用的开源软件的限制,您可能会遇到超时问题。我们正在努力永久解决此问题,建议您在客户端中暂时使用 HTTP/1.1 作为临时解决方案。
对于 WebSocket,请注意如果连接空闲超过 5 分钟将会被关闭。
如何将环境变量传递给应用程序?
展开
我们提供两种传递环境变量的选项:
-
在应用程序部署期间使用
--env
来加载.env
文件中的环境变量。例如,lc-serve deploy jcloud app --env some.env
将加载some.env
文件中的所有环境变量并将其传递给应用程序。这些环境变量将在应用程序中以os.environ['ENV_VAR_NAME']
的形式使用。 -
您还可以在向应用程序发送请求时传递环境变量,支持 HTTP 和 WebSocket。请求体中的
envs
字段用于传递环境变量。例如{ "question": "生命的意义是什么?", "envs": { "ENV_VAR_NAME": "ENV_VAR_VALUE" } }
JCloud 部署在推送镜像到 Jina Hubble 时失败,应该怎么办?
展开
请使用 --verbose
并重试以获取更多信息。如果您在 arm64
架构的计算机上操作,请使用 --platform linux/amd64
重试,以便镜像能够正确构建。