No project description provided
Project description
GigaServe 🦜️🏓 = LangServe + GigaChat
🚩 We will be releasing a hosted version of LangServe for one-click deployments of LangChain applications. Sign up here to get on the waitlist.
О GigaServe
GigaServe = LangServe + GigaChain
helps developers deploy GigaChain
runnables and chains as a REST API.
С помощью библиотеки GigaServe вы можете реализовать REST API для предоставления доступа к runnable-интерфейсам и цепочкам GigaChain.
Библиотека GigaServe интегрирована с FastAPI и использует для валидации данных Pydantic.
Особенности библиотеки
- Схемы ввода и вывода автоматически определяются на основе объекта GigaChain, применяются для каждого запроса к API и обеспечивают подробные сообщения об ошибках.
- Страница API-документации с JSONSchema и Swagger.
- Эффективные эндпоинты
/invoke
,/batch
и/stream
с поддержкой множества одновременных запросов на одном сервере. - Эндпоинт
/stream_log
для потоковой передачи всех или выбранных промежуточных шагов работы цепочки/агента. - Интерактивная страница
/playground
с потоковым выводом и демонстрацией промежуточных шагов. - Использование проверенных open-source библиотек Python таких, как FastAPI, Pydantic, uvloop и asyncio.
- Use the client SDK to call a LangServe server as if it was a Runnable running locally (or call the HTTP API directly)
- Возможность обращения к серверу GigaServe с помощью клиентского SDK, как если бы это был локальный runnable-интерфейс (или возможность обратиться напрямую к HTTP API).
Ограничения
- Обратные вызовы клиента пока не поддерживаются для событий, происходящих на сервере
- При использовании Pydantic V2 документация OpenAPI не генерируется. Это связанно с тем, что Fast API не поддерживает смешивание пространств имен pydantic v1 и v2. Подробнее в разделе ниже.
Безопасность
Уязвимость в версиях 0.0.13 - 0.0.15 — Интерактивная страница, доступная по адресу /playground
, позволяет получить доступ к произвольным файлам на сервере. Устранено в версии 0.0.16.
GigaChain CLI 🛠️
Для быстрой настройки проекта GigaChain используйте актуальную версию GigaChain CLI:
- Vulnerability in Versions 0.0.13 - 0.0.15 -- playground endpoint allows accessing arbitrary files on server. Resolved in 0.0.16.
Установка
Для клиента и сервера
pip install "gigaserve[all]"
или pip install "gigaserve[client]"
для установки клиента и pip gigaserve "langserve[server]"
для установки сервера.
gigachain app new ../path/to/directory
Вы можете установить актуальную версию CLI с помощью менеджера пакетов pip:
pip install -U gigachain-cli
Примеры
Для быстрого старта GigaServe используйте шаблоны GigaChain.
Больше примеров шаблонов вы найдете в соответствующей директории.
Сервер
Пример ниже разворачивает модель чата OpenAI, модель чата Anthropic, и цепочку, которая генерирует шутку по заданной теме (topic
) с помощью модели Anthropic.
#!/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="GigaChain Server",
version="1.0",
description="Простой API-сервер, использующий runnable-интерфейсы GigaChain",
)
add_routes(
app,
ChatOpenAI(),
path="/openai",
)
add_routes(
app,
ChatAnthropic(),
path="/anthropic",
)
model = ChatAnthropic()
prompt = ChatPromptTemplate.from_template("расскажи шутку о {topic}")
add_routes(
app,
prompt | model,
path="/joke",
)
if __name__ == "__main__":
import uvicorn
uvicorn.run(app, host="localhost", port=8000)
Документация
Сгенерированная OpenAPI-документация к серверу, развернутому с помощью предыдущего примера, доступна по адресу:
⚠️ If using pydantic v2, docs will not be generated for invoke/batch/stream/stream_log. See Pydantic section below for more details.
curl localhost:8000/docs
[!NOTE] ⚠️ Обращение к адресу
localhost:8000
будет возвращать ошибку 404 by design, пока вы не определите@app.get("/")
.
Клиент
Пример клиента на основе Python SDK:
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/joke/")
# Синхронный вызов
joke_chain.invoke({"topic": "попугаи"})
# Асинхронный вызов
await joke_chain.ainvoke({"topic": "попугаии"})
prompt = [
SystemMessage(content='Веди себя как кошка или попугай.'),
HumanMessage(content='Привет!')
]
# Поддержка astream
async for msg in anthropic.astream(prompt):
print(msg, end="", flush=True)
prompt = ChatPromptTemplate.from_messages(
[("system", "Расскажи мне длинную историю о {topic}")]
)
# Определение собственных цепочек
chain = prompt | RunnableMap({
"openai": openai,
"anthropic": anthropic,
})
chain.batch([{ "topic": "попугаи" }, { "topic": "кошки" }])
Пример клиента на TypeScript (для работы клиента требуется LangChain.js версии 0.0.166 или выше):
import { RemoteRunnable } from "langchain/runnables/remote";
const chain = new RemoteRunnable({
url: `http://localhost:8000/joke/`,
});
const result = await chain.invoke({
topic: "кошки",
});
Клиент, использующий Python-библиотеку requests
:
import requests
response = requests.post(
"http://localhost:8000/joke/invoke/",
json={'input': {'topic': 'кошки'}}
)
response.json()
Использование cURL:
curl --location --request POST 'http://localhost:8000/joke/invoke/' \
--header 'Content-Type: application/json' \
--data-raw '{
"input": {
"topic": "кошки"
}
}'
Эндпоинты
С помощью примера ниже вы можете добавить на сервер заранее подготовленные эндпоинты для работы с runnable-интерфейсами:
...
add_routes(
app,
runnable,
path="/my_runnable",
)
Список эндпоинтов:
POST /my_runnable/invoke
- вызвать runnable-интерфейс для единичных входных данных;POST /my_runnable/batch
- вызвать runnable-интерфейс для набора входных данных;POST /my_runnable/stream
- вызвать для единичных входных данных с потоковым выводом;POST /my_runnable/stream_log
- вызвать для единичных входных данных с потоковым выводом, включая вывод промежуточных шагов по ходу генерации;GET /my_runnable/input_schema
- получить json-схему входных данных runnable-интерфейса;GET /my_runnable/output_schema
- получить json-схему выходных данных runnable-интерфейса;GET /my_runnable/config_schema
- получить json-схему параметров конфигурации runnable-интерфейса;
Playground
Playground доступен по адресу /my_runnable/playground
. На ней представлен простой интерфейс, который позволяет настроить параметры runnable-интерфейса и сделать запрос к нему с потоковым выводом и демонстрацией промежуточных шагов.
Эти адреса соответствуют LangChain Expression Language interface (LCEL) -- обратитесь к документации за более подробными деталями
Виджеты
Playground поддерживает виджеты и может использоваться для тестирования ваших цепочек с разными входными данными.
In addition, for configurable runnables, the playground will allow you to configure the runnable and share a link with the configuration:
В завершении, для настраиваемых цепочек, playground позволяет настроить цепочку и поделиться ссылкой на конфигурацию:
Sharing
pip install "gigaserve[client]"
Работа с классическими цепочками
GigaServe работает как с runnable-интерфейсами(написанным с помощью constructed via LangChain Expression Language), так и с классическими цепочками (посредством наследования от Chain
). Но следует учиывать, что некоторые входные схемы для устаревших цепочек могут быть некорректными или неполными и могут вызывать ошибки. Это можно предотвратить, если обновить аттрибут input_schema
таких цепочек в LangChain.
Deploy to Azure
You can deploy to Azure using Azure Container Apps (Serverless):
az containerapp up --name [container-app-name] --source . --resource-group [resource-group-name] --environment [environment-name] --ingress external --target-port 8001 --env-vars=OPENAI_API_KEY=your_key
You can find more info here
Deploy to GCP
Добавление аутентификации
О том как добавить аутентификацию на свой сервер GigaServe вы может узнать в разделах документации FastAPI, посвященных безопасности и использованию связующего ПО.
Развертывание
Развертывание на GCP
Для развертывания на GCP Cloud Run используйте команду:
gcloud run deploy [your-service-name] --source . --port 8001 --allow-unauthenticated --region us-central1 --set-env-vars=GIGACHAT_API_KEY=your_key
Работа с Pydantic
GigaServe поддерживает Pydantic 2 с некоторыми ограничениями:
- При использовании Pydantic V2 документация OpenAPI не генерируется. Это связанно с тем, что Fast API не поддерживает смешивание пространств имен pydantic v1 и v2.
- GigaChain использует пространство имен версии v1 в Pydantic v2.
За исключением указанных ограничений эндпоинты API, интерактивная страница и другие функции должны работать корректно.
Дополнительные возможности
Handling Authentication
Если вам нужна дополнительная аутентификация для вашего сервер, пожалуйста обратитесь к документации FastAPI security documentation и middleware documentation.
Работа с файлами
Обработка файлов это типичная задача для больших языковых моделей. Существуют различные архитектурные подходы для решения этой задачи:
- Файл может быть загружен на сервер с помощью выделенного эндпоинта и обработан с помощью отдельного эндпоинта
- Файл может быть представлен как в виде бинарного значения, так и в виде ссылки, например, на содержимое файла, размещенное на хранилище s3.
- Эндпоинт может блокирующим или неблокирующим.
- Сложную обработку можно выделить в отдельный пул процессов.
Выбирайте подход в соответсвии со своими задачами.
GigaServe пока не поддерживает тип multipart/form-data
.
Для загрузки бинарного значения файла в runnable-интерфейс используйте кодировку base64.
Пример загрузки файла закодированного с помощью base64.
Вы также можете загружать файлы с помощью ссылок (например, на хранилище s3) или загружать их на отдельный эндпоинт как multipart/form-data
Настраиваемые типы входных и выходных данных
Типы входных и выходных данных определяются для всех runnable-интерфейсов. Они доступны в аттрибутах input_schema
и output_schema
. GigaServe использует эти типы для валидации данных и генерации документации.
Вы можете переопределить наследованные типы с помощью метода with_types
.
Общий пример работы с типами:
from typing import Any
from fastapi import FastAPI
from langchain.schema.runnable import RunnableLambda
app = FastAPI()
def func(x: Any) -> int:
"""Ошибочно заданная функция, которая принимает любые данные, хотя должна принимать int."""
return x + 1
runnable = RunnableLambda(func).with_types(
input_schema=int,
)
add_routes(app, runnable)
Пользовательские типы
Для десериализации данных в виде pydantic-модели, а не dict
, унаследуйтесь от CustomUserType
. При наследовании от этого типа сервер будет не будет преобразовывать данные в dict
, а будет сохранять их как 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:
"""Пример функции, которая ожидает тип Foo, представленный в виде моде pydantic model"""
assert isinstance(foo, Foo)
return foo.bar
# Обратите внимание, что входные и выходные типы наследуются автоматически!
# Вам не нужно их указывать
# runnable = RunnableLambda(func).with_types( # <-- Не нужно в данном случае
# input_schema=Foo,
# output_schema=int,
#
add_routes(app, RunnableLambda(func), path="/foo")
Виджеты интерактивной страницы
На интерактивной странице вы можете создавать различные виджеты, демонстрирующие работу runnable-интерфейсов вашего бекенда.
- Виджет задается на уровне поля и поставляется как часть JSON-схемы вводного типа.
- Виджет должен содержать ключ
type
, значением которого является один из известного списка виджетов - Другие ключи виджета будут связаны со значениями, описывающими пути в JSON-объекте
Общая схема:
type JsonPath = number | string | (number | string)[];
type NameSpacedPath = { title: string; path: JsonPath }; // title используется для имитации json-схемы,но можно использовать namespace
type OneOfPath = { oneOf: JsonPath[] };
type Widget = {
type: string // Какой-то хорошо известный тип, например, base64file, chat и др.
[key: string]: JsonPath | NameSpacedPath | OneOfPath;
};
Виджет загрузки файла
Виджет позволяет загружать файлы в интерфейсе интерактивной страницы. Работает для файлов, представленных в виде строки, закодированной в base64.
Фрагмент примера:
try:
from pydantic.v1 import Field
except ImportError:
from pydantic import Field
from langserve import CustomUserType
# ВНИМАНИЕ: Наследуйтесь от CustomUserType, а не от BaseModel. В противном случае
# сервер декодирует данные в dict, а не модель pydantic.
class FileProcessingRequest(CustomUserType):
"""Request including a base64 encoded file."""
# Дополнительное поле используется, чтобы задать виджет в интерфейсе интерактивной страницы.
file: str = Field(..., extra={"widget": {"type": "base64file"}})
num_chars: int = 100
[!NOTE] Подробный пример загрузки файла.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Hashes for gigaserve-0.0.32-py3-none-any.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | e20963f165d52077d99471960068ed01e7e2d7f001fb640e0695c3e5352448ad |
|
MD5 | a3aca31b85057c9dbd24046cbbe539d8 |
|
BLAKE2b-256 | dc62373b131bff7fc803a082f30bf60e642516f357ab167050e6cfe38e576d2e |