mirror of
https://github.com/langchain-ai/langserve.git
synced 2026-07-25 13:15:44 -04:00
Compare commits
12 Commits
v0.1.1
...
jacob/docs
| Author | SHA1 | Date | |
|---|---|---|---|
| 86eb39b863 | |||
| 1b389f0751 | |||
| 6ef3aca359 | |||
| 81a633e0f4 | |||
| bb74431183 | |||
| 4be04bda6d | |||
| bba7122986 | |||
| ee250d20f2 | |||
| 21bf92f80c | |||
| 37f41e54ce | |||
| 075bdd0cfc | |||
| 08d4bdd61a |
@@ -1,4 +1,4 @@
|
||||
{
|
||||
"contributors": ["eyurtsev", "hwchase17", "nfcampos", "efriis", "jacoblee93", "dqbd", "kreneskyp", "adarsh-jha-dev", "harris", "baskaryan", "hinthornw", "bracesproul", "jakerachleff", "craigsdennis", "anhi", "169", "LarchLiu", "PaulLockett", "RCMatthias", "jwynia", "majiayu000", "mpskex", "shivachittamuru", "sinashaloudegi", "sowsan", "akira", "lucianotonet", "JGalego", "nat-n", "dirien", "donbr", "rahilvora", "WarrenTheRabbit", "StreetLamb"],
|
||||
"contributors": ["eyurtsev", "hwchase17", "nfcampos", "efriis", "jacoblee93", "dqbd", "kreneskyp", "adarsh-jha-dev", "harris", "baskaryan", "hinthornw", "bracesproul", "jakerachleff", "craigsdennis", "anhi", "169", "LarchLiu", "PaulLockett", "RCMatthias", "jwynia", "majiayu000", "mpskex", "shivachittamuru", "sinashaloudegi", "sowsan", "akira", "lucianotonet", "JGalego", "nat-n", "dirien", "donbr", "rahilvora", "WarrenTheRabbit", "StreetLamb", "ccurme"],
|
||||
"message": "Thank you for your pull request and welcome to our community. We require contributors to sign our Contributor License Agreement, and we don't seem to have the username {{usersWithoutCLA}} on file. In order for us to review and merge your code, please complete the Individual Contributor License Agreement here https://forms.gle/AQFbtkWRoHXUgipM6 .\n\nThis process is done manually on our side, so after signing the form one of the maintainers will add you to the contributors list.\n\nFor more details about why we have a CLA and other contribution guidelines please see: https://github.com/langchain-ai/langserve/blob/main/CONTRIBUTING.md."
|
||||
}
|
||||
|
||||
@@ -6,13 +6,13 @@
|
||||
[](https://discord.com/channels/1038097195422978059/1170024642245832774)
|
||||
|
||||
🚩 We will be releasing a hosted version of LangServe for one-click deployments of
|
||||
LangChain applications. [Sign up here](https://airtable.com/apppQ9p5XuujRl3wJ/shrABpHWdxry8Bacm)
|
||||
LangChain applications. [Sign up here](https://forms.gle/KC13Nzn76UeLaghK7)
|
||||
to get on the waitlist.
|
||||
|
||||
## Overview
|
||||
|
||||
[LangServe](https://github.com/langchain-ai/langserve) helps developers
|
||||
deploy `LangChain` [runnables and chains](https://python.langchain.com/docs/expression_language/)
|
||||
deploy `LangChain` [runnables and chains](https://python.langchain.com/v0.2/docs/how_to/#langchain-expression-language-lcel)
|
||||
as a REST API.
|
||||
|
||||
This library is integrated with [FastAPI](https://fastapi.tiangolo.com/) and
|
||||
@@ -53,7 +53,7 @@ in [LangChain.js](https://js.langchain.com/docs/ecosystem/langserve).
|
||||
|
||||
We will be releasing a hosted version of LangServe for one-click deployments of
|
||||
LangChain
|
||||
applications. [Sign up here](https://airtable.com/apppQ9p5XuujRl3wJ/shrABpHWdxry8Bacm)
|
||||
applications. [Sign up here](https://forms.gle/KC13Nzn76UeLaghK7)
|
||||
to get on the waitlist.
|
||||
|
||||
## Security
|
||||
@@ -128,13 +128,13 @@ directory.
|
||||
| :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| **LLMs** Minimal example that reserves OpenAI and Anthropic chat models. Uses async, supports batching and streaming. | [server](https://github.com/langchain-ai/langserve/tree/main/examples/llm/server.py), [client](https://github.com/langchain-ai/langserve/blob/main/examples/llm/client.ipynb) |
|
||||
| **Retriever** Simple server that exposes a retriever as a runnable. | [server](https://github.com/langchain-ai/langserve/tree/main/examples/retrieval/server.py), [client](https://github.com/langchain-ai/langserve/tree/main/examples/retrieval/client.ipynb) |
|
||||
| **Conversational Retriever** A [Conversational Retriever](https://python.langchain.com/docs/expression_language/cookbook/retrieval#conversational-retrieval-chain) exposed via LangServe | [server](https://github.com/langchain-ai/langserve/tree/main/examples/conversational_retrieval_chain/server.py), [client](https://github.com/langchain-ai/langserve/tree/main/examples/conversational_retrieval_chain/client.ipynb) |
|
||||
| **Conversational Retriever** A Conversational Retriever exposed via LangServe | [server](https://github.com/langchain-ai/langserve/tree/main/examples/conversational_retrieval_chain/server.py), [client](https://github.com/langchain-ai/langserve/tree/main/examples/conversational_retrieval_chain/client.ipynb) |
|
||||
| **Agent** without **conversation history** based on [OpenAI tools](https://python.langchain.com/docs/modules/agents/agent_types/openai_functions_agent) | [server](https://github.com/langchain-ai/langserve/tree/main/examples/agent/server.py), [client](https://github.com/langchain-ai/langserve/tree/main/examples/agent/client.ipynb) |
|
||||
| **Agent** with **conversation history** based on [OpenAI tools](https://python.langchain.com/docs/modules/agents/agent_types/openai_functions_agent) | [server](https://github.com/langchain-ai/langserve/blob/main/examples/agent_with_history/server.py), [client](https://github.com/langchain-ai/langserve/blob/main/examples/agent_with_history/client.ipynb) |
|
||||
| [RunnableWithMessageHistory](https://python.langchain.com/docs/expression_language/how_to/message_history) to implement chat persisted on backend, keyed off a `session_id` supplied by client. | [server](https://github.com/langchain-ai/langserve/tree/main/examples/chat_with_persistence/server.py), [client](https://github.com/langchain-ai/langserve/tree/main/examples/chat_with_persistence/client.ipynb) |
|
||||
| [RunnableWithMessageHistory](https://python.langchain.com/docs/expression_language/how_to/message_history) to implement chat persisted on backend, keyed off a `conversation_id` supplied by client, and `user_id` (see Auth for implementing `user_id` properly). | [server](https://github.com/langchain-ai/langserve/tree/main/examples/chat_with_persistence_and_user/server.py), [client](https://github.com/langchain-ai/langserve/tree/main/examples/chat_with_persistence_and_user/client.ipynb) |
|
||||
| [Configurable Runnable](https://python.langchain.com/docs/expression_language/how_to/configure) to create a retriever that supports run time configuration of the index name. | [server](https://github.com/langchain-ai/langserve/tree/main/examples/configurable_retrieval/server.py), [client](https://github.com/langchain-ai/langserve/tree/main/examples/configurable_retrieval/client.ipynb) |
|
||||
| [Configurable Runnable](https://python.langchain.com/docs/expression_language/how_to/configure) that shows configurable fields and configurable alternatives. | [server](https://github.com/langchain-ai/langserve/tree/main/examples/configurable_chain/server.py), [client](https://github.com/langchain-ai/langserve/tree/main/examples/configurable_chain/client.ipynb) |
|
||||
| [RunnableWithMessageHistory](https://python.langchain.com/v0.2/docs/how_to/message_history/) to implement chat persisted on backend, keyed off a `session_id` supplied by client. | [server](https://github.com/langchain-ai/langserve/tree/main/examples/chat_with_persistence/server.py), [client](https://github.com/langchain-ai/langserve/tree/main/examples/chat_with_persistence/client.ipynb) |
|
||||
| [RunnableWithMessageHistory](https://python.langchain.com/v0.2/docs/how_to/message_history/) to implement chat persisted on backend, keyed off a `conversation_id` supplied by client, and `user_id` (see Auth for implementing `user_id` properly). | [server](https://github.com/langchain-ai/langserve/tree/main/examples/chat_with_persistence_and_user/server.py), [client](https://github.com/langchain-ai/langserve/tree/main/examples/chat_with_persistence_and_user/client.ipynb) |
|
||||
| [Configurable Runnable](https://python.langchain.com/v0.2/docs/how_to/configure/) to create a retriever that supports run time configuration of the index name. | [server](https://github.com/langchain-ai/langserve/tree/main/examples/configurable_retrieval/server.py), [client](https://github.com/langchain-ai/langserve/tree/main/examples/configurable_retrieval/client.ipynb) |
|
||||
| [Configurable Runnable](https://python.langchain.com/v0.2/docs/how_to/configure/) that shows configurable fields and configurable alternatives. | [server](https://github.com/langchain-ai/langserve/tree/main/examples/configurable_chain/server.py), [client](https://github.com/langchain-ai/langserve/tree/main/examples/configurable_chain/client.ipynb) |
|
||||
| **APIHandler** Shows how to use `APIHandler` instead of `add_routes`. This provides more flexibility for developers to define endpoints. Works well with all FastAPI patterns, but takes a bit more effort. | [server](https://github.com/langchain-ai/langserve/tree/main/examples/api_handler_examples/server.py) |
|
||||
| **LCEL Example** Example that uses LCEL to manipulate a dictionary input. | [server](https://github.com/langchain-ai/langserve/tree/main/examples/passthrough_dict/server.py), [client](https://github.com/langchain-ai/langserve/tree/main/examples/passthrough_dict/client.ipynb) |
|
||||
| **Auth** with `add_routes`: Simple authentication that can be applied across all endpoints associated with app. (Not useful on its own for implementing per user logic.) | [server](https://github.com/langchain-ai/langserve/tree/main/examples/auth/global_deps/server.py) |
|
||||
@@ -167,17 +167,17 @@ app = FastAPI(
|
||||
|
||||
add_routes(
|
||||
app,
|
||||
ChatOpenAI(),
|
||||
ChatOpenAI(model="gpt-3.5-turbo-0125"),
|
||||
path="/openai",
|
||||
)
|
||||
|
||||
add_routes(
|
||||
app,
|
||||
ChatAnthropic(),
|
||||
ChatAnthropic(model="claude-3-haiku-20240307"),
|
||||
path="/anthropic",
|
||||
)
|
||||
|
||||
model = ChatAnthropic()
|
||||
model = ChatAnthropic(model="claude-3-haiku-20240307")
|
||||
prompt = ChatPromptTemplate.from_template("tell me a joke about {topic}")
|
||||
add_routes(
|
||||
app,
|
||||
@@ -331,14 +331,14 @@ adds of these endpoints to the server:
|
||||
- `GET /my_runnable/config_schema` - json schema for config of the runnable
|
||||
|
||||
These endpoints match
|
||||
the [LangChain Expression Language interface](https://python.langchain.com/docs/expression_language/interface) --
|
||||
the [LangChain Expression Language interface](https://python.langchain.com/v0.2/docs/how_to/lcel_cheatsheet/) --
|
||||
please reference this documentation for more details.
|
||||
|
||||
## Playground
|
||||
|
||||
You can find a playground page for your runnable at `/my_runnable/playground/`. This
|
||||
exposes a simple UI
|
||||
to [configure](https://python.langchain.com/docs/expression_language/how_to/configure)
|
||||
to [configure](https://python.langchain.com/v0.2/docs/how_to/configure/)
|
||||
and invoke your runnable with streaming output and intermediate steps.
|
||||
|
||||
<p align="center">
|
||||
@@ -427,7 +427,7 @@ for demos or testing.
|
||||
## Legacy Chains
|
||||
|
||||
LangServe works with both Runnables (constructed
|
||||
via [LangChain Expression Language](https://python.langchain.com/docs/expression_language/))
|
||||
via [LangChain Expression Language](https://python.langchain.com/v0.2/docs/how_to/#langchain-expression-language-lcel))
|
||||
and legacy chains (inheriting from `Chain`).
|
||||
However, some of the input schemas for legacy chains may be incomplete/incorrect,
|
||||
leading to errors.
|
||||
|
||||
@@ -20,15 +20,15 @@ Relevant LangChain documentation:
|
||||
from typing import Any
|
||||
|
||||
from fastapi import FastAPI
|
||||
from langchain.agents import AgentExecutor, tool
|
||||
from langchain.agents import AgentExecutor
|
||||
from langchain.agents.format_scratchpad import format_to_openai_functions
|
||||
from langchain.agents.output_parsers import OpenAIFunctionsAgentOutputParser
|
||||
from langchain.chat_models import ChatOpenAI
|
||||
from langchain.embeddings import OpenAIEmbeddings
|
||||
from langchain.prompts import ChatPromptTemplate, MessagesPlaceholder
|
||||
from langchain.pydantic_v1 import BaseModel
|
||||
from langchain.tools.render import format_tool_to_openai_function
|
||||
from langchain.vectorstores import FAISS
|
||||
from langchain_community.vectorstores import FAISS
|
||||
from langchain_core.prompts import ChatPromptTemplate, MessagesPlaceholder
|
||||
from langchain_core.tools import tool
|
||||
from langchain_core.utils.function_calling import format_tool_to_openai_function
|
||||
from langchain_openai import ChatOpenAI, OpenAIEmbeddings
|
||||
|
||||
from langserve import add_routes
|
||||
|
||||
|
||||
@@ -47,15 +47,15 @@ Relevant LangChain documentation:
|
||||
from typing import Any, AsyncIterator, List, Literal
|
||||
|
||||
from fastapi import FastAPI
|
||||
from langchain.agents import AgentExecutor, tool
|
||||
from langchain.agents import AgentExecutor
|
||||
from langchain.agents.format_scratchpad.openai_tools import (
|
||||
format_to_openai_tool_messages,
|
||||
)
|
||||
from langchain.agents.output_parsers.openai_tools import OpenAIToolsAgentOutputParser
|
||||
from langchain.prompts import MessagesPlaceholder
|
||||
from langchain_community.tools.convert_to_openai import format_tool_to_openai_tool
|
||||
from langchain_core.prompts import ChatPromptTemplate
|
||||
from langchain_core.prompts import ChatPromptTemplate, MessagesPlaceholder
|
||||
from langchain_core.runnables import RunnableLambda
|
||||
from langchain_core.tools import tool
|
||||
from langchain_core.utils.function_calling import format_tool_to_openai_tool
|
||||
from langchain_openai import ChatOpenAI
|
||||
|
||||
from langserve import add_routes
|
||||
|
||||
@@ -26,15 +26,15 @@ Relevant LangChain documentation:
|
||||
from typing import Any, List, Union
|
||||
|
||||
from fastapi import FastAPI
|
||||
from langchain.agents import AgentExecutor, tool
|
||||
from langchain.agents import AgentExecutor
|
||||
from langchain.agents.format_scratchpad.openai_tools import (
|
||||
format_to_openai_tool_messages,
|
||||
)
|
||||
from langchain.agents.output_parsers.openai_tools import OpenAIToolsAgentOutputParser
|
||||
from langchain.prompts import MessagesPlaceholder
|
||||
from langchain_community.tools.convert_to_openai import format_tool_to_openai_tool
|
||||
from langchain_core.messages import AIMessage, FunctionMessage, HumanMessage
|
||||
from langchain_core.prompts import ChatPromptTemplate
|
||||
from langchain_core.prompts import ChatPromptTemplate, MessagesPlaceholder
|
||||
from langchain_core.tools import tool
|
||||
from langchain_core.utils.function_calling import format_tool_to_openai_tool
|
||||
from langchain_openai import ChatOpenAI
|
||||
|
||||
from langserve import add_routes
|
||||
|
||||
@@ -35,7 +35,6 @@ from typing import Any, List, Optional, Union
|
||||
|
||||
from fastapi import Depends, FastAPI, HTTPException, Request, Response, status
|
||||
from fastapi.security import OAuth2PasswordBearer, OAuth2PasswordRequestForm
|
||||
from langchain_community.embeddings.openai import OpenAIEmbeddings
|
||||
from langchain_community.vectorstores.chroma import Chroma
|
||||
from langchain_core.documents import Document
|
||||
from langchain_core.runnables import (
|
||||
@@ -44,6 +43,7 @@ from langchain_core.runnables import (
|
||||
RunnableSerializable,
|
||||
)
|
||||
from langchain_core.vectorstores import VectorStore
|
||||
from langchain_openai import OpenAIEmbeddings
|
||||
from typing_extensions import Annotated
|
||||
|
||||
from langserve import APIHandler
|
||||
|
||||
@@ -36,7 +36,6 @@ from typing import Any, Dict, List, Optional, Union
|
||||
|
||||
from fastapi import Depends, FastAPI, HTTPException, Request, status
|
||||
from fastapi.security import OAuth2PasswordBearer, OAuth2PasswordRequestForm
|
||||
from langchain_community.embeddings.openai import OpenAIEmbeddings
|
||||
from langchain_community.vectorstores.chroma import Chroma
|
||||
from langchain_core.documents import Document
|
||||
from langchain_core.runnables import (
|
||||
@@ -45,6 +44,7 @@ from langchain_core.runnables import (
|
||||
RunnableSerializable,
|
||||
)
|
||||
from langchain_core.vectorstores import VectorStore
|
||||
from langchain_openai import OpenAIEmbeddings
|
||||
from typing_extensions import Annotated
|
||||
|
||||
from langserve import add_routes
|
||||
|
||||
@@ -5,7 +5,7 @@ state back and forth between server and client.
|
||||
from typing import List, Union
|
||||
|
||||
from fastapi import FastAPI
|
||||
from langchain.chat_models import ChatAnthropic
|
||||
from langchain_anthropic import ChatAnthropic
|
||||
from langchain_core.messages import AIMessage, HumanMessage, SystemMessage
|
||||
from langchain_core.prompts import ChatPromptTemplate, MessagesPlaceholder
|
||||
|
||||
|
||||
@@ -13,8 +13,8 @@ from pathlib import Path
|
||||
from typing import Callable, Union
|
||||
|
||||
from fastapi import FastAPI, HTTPException
|
||||
from langchain.chat_models import ChatAnthropic
|
||||
from langchain.memory import FileChatMessageHistory
|
||||
from langchain_anthropic import ChatAnthropic
|
||||
from langchain_community.chat_message_histories import FileChatMessageHistory
|
||||
from langchain_core.chat_history import BaseChatMessageHistory
|
||||
from langchain_core.prompts import ChatPromptTemplate, MessagesPlaceholder
|
||||
from langchain_core.runnables.history import RunnableWithMessageHistory
|
||||
|
||||
@@ -13,13 +13,13 @@ from pathlib import Path
|
||||
from typing import Any, Callable, Dict, Union
|
||||
|
||||
from fastapi import FastAPI, HTTPException, Request
|
||||
from langchain.chat_models import ChatOpenAI
|
||||
from langchain.memory import FileChatMessageHistory
|
||||
from langchain.schema.runnable.utils import ConfigurableFieldSpec
|
||||
from langchain_community.chat_message_histories import FileChatMessageHistory
|
||||
from langchain_core import __version__
|
||||
from langchain_core.chat_history import BaseChatMessageHistory
|
||||
from langchain_core.prompts import ChatPromptTemplate, MessagesPlaceholder
|
||||
from langchain_core.runnables import ConfigurableFieldSpec
|
||||
from langchain_core.runnables.history import RunnableWithMessageHistory
|
||||
from langchain_openai import ChatOpenAI
|
||||
from typing_extensions import TypedDict
|
||||
|
||||
from langserve import add_routes
|
||||
|
||||
@@ -17,15 +17,12 @@ on the LLM and use the stream_log endpoint rather than stream endpoint.
|
||||
from typing import Any, AsyncIterator, Dict, List, Optional, cast
|
||||
|
||||
from fastapi import FastAPI
|
||||
from langchain.agents import AgentExecutor, tool
|
||||
from langchain.agents import AgentExecutor
|
||||
from langchain.agents.format_scratchpad import format_to_openai_functions
|
||||
from langchain.agents.output_parsers import OpenAIFunctionsAgentOutputParser
|
||||
from langchain.chat_models import ChatOpenAI
|
||||
from langchain.embeddings import OpenAIEmbeddings
|
||||
from langchain.prompts import ChatPromptTemplate, MessagesPlaceholder
|
||||
from langchain.pydantic_v1 import BaseModel
|
||||
from langchain.tools.render import format_tool_to_openai_function
|
||||
from langchain.vectorstores import FAISS
|
||||
from langchain_community.vectorstores import FAISS
|
||||
from langchain_core.prompts import ChatPromptTemplate, MessagesPlaceholder
|
||||
from langchain_core.runnables import (
|
||||
ConfigurableField,
|
||||
ConfigurableFieldSpec,
|
||||
@@ -33,6 +30,9 @@ from langchain_core.runnables import (
|
||||
RunnableConfig,
|
||||
)
|
||||
from langchain_core.runnables.utils import Input, Output
|
||||
from langchain_core.tools import tool
|
||||
from langchain_core.utils.function_calling import format_tool_to_openai_function
|
||||
from langchain_openai import ChatOpenAI, OpenAIEmbeddings
|
||||
|
||||
from langserve import add_routes
|
||||
|
||||
|
||||
@@ -10,10 +10,10 @@ from typing import Any, Dict
|
||||
|
||||
from fastapi import FastAPI, HTTPException, Request
|
||||
from fastapi.middleware.cors import CORSMiddleware
|
||||
from langchain.chat_models import ChatOpenAI
|
||||
from langchain.prompts import PromptTemplate
|
||||
from langchain.schema.output_parser import StrOutputParser
|
||||
from langchain.schema.runnable import ConfigurableField
|
||||
from langchain_core.output_parsers import StrOutputParser
|
||||
from langchain_core.prompts import PromptTemplate
|
||||
from langchain_core.runnables import ConfigurableField
|
||||
from langchain_openai import ChatOpenAI
|
||||
|
||||
from langserve import add_routes
|
||||
|
||||
|
||||
@@ -3,17 +3,18 @@
|
||||
from typing import Any, Iterable, List, Optional, Type
|
||||
|
||||
from fastapi import FastAPI
|
||||
from langchain.embeddings import OpenAIEmbeddings
|
||||
from langchain.schema import Document
|
||||
from langchain.schema.embeddings import Embeddings
|
||||
from langchain.schema.retriever import BaseRetriever
|
||||
from langchain.schema.runnable import (
|
||||
from langchain.schema.vectorstore import VST
|
||||
from langchain_community.vectorstores import FAISS
|
||||
from langchain_core.documents import Document
|
||||
from langchain_core.embeddings import Embeddings
|
||||
from langchain_core.retrievers import BaseRetriever
|
||||
from langchain_core.runnables import (
|
||||
ConfigurableFieldSingleOption,
|
||||
RunnableConfig,
|
||||
RunnableSerializable,
|
||||
)
|
||||
from langchain.schema.vectorstore import VST
|
||||
from langchain.vectorstores import FAISS, VectorStore
|
||||
from langchain_core.vectorstores import VectorStore
|
||||
from langchain_openai import OpenAIEmbeddings
|
||||
|
||||
from langserve import add_routes
|
||||
from langserve.pydantic_v1 import BaseModel, Field
|
||||
|
||||
@@ -13,14 +13,11 @@ from operator import itemgetter
|
||||
from typing import List, Tuple
|
||||
|
||||
from fastapi import FastAPI
|
||||
from langchain.chat_models import ChatOpenAI
|
||||
from langchain.embeddings import OpenAIEmbeddings
|
||||
from langchain.prompts import ChatPromptTemplate
|
||||
from langchain.prompts.prompt import PromptTemplate
|
||||
from langchain.schema import format_document
|
||||
from langchain.schema.output_parser import StrOutputParser
|
||||
from langchain.schema.runnable import RunnableMap, RunnablePassthrough
|
||||
from langchain.vectorstores import FAISS
|
||||
from langchain_community.vectorstores import FAISS
|
||||
from langchain_core.output_parsers import StrOutputParser
|
||||
from langchain_core.prompts import ChatPromptTemplate, PromptTemplate, format_document
|
||||
from langchain_core.runnables import RunnableMap, RunnablePassthrough
|
||||
from langchain_openai import ChatOpenAI, OpenAIEmbeddings
|
||||
|
||||
from langserve import add_routes
|
||||
from langserve.pydantic_v1 import BaseModel, Field
|
||||
|
||||
@@ -15,10 +15,10 @@ allowing one to upload a binary file using the langserve playground UI.
|
||||
import base64
|
||||
|
||||
from fastapi import FastAPI
|
||||
from langchain.document_loaders.blob_loaders import Blob
|
||||
from langchain.document_loaders.parsers.pdf import PDFMinerParser
|
||||
from langchain.pydantic_v1 import Field
|
||||
from langchain.schema.runnable import RunnableLambda
|
||||
from langchain_community.document_loaders.parsers.pdf import PDFMinerParser
|
||||
from langchain_core.document_loaders import Blob
|
||||
from langchain_core.runnables import RunnableLambda
|
||||
|
||||
from langserve import CustomUserType, add_routes
|
||||
|
||||
|
||||
@@ -2,7 +2,8 @@
|
||||
"""Example LangChain server exposes multiple runnables (LLMs in this case)."""
|
||||
|
||||
from fastapi import FastAPI
|
||||
from langchain.chat_models import ChatAnthropic, ChatOpenAI
|
||||
from langchain_anthropic import ChatAnthropic
|
||||
from langchain_openai import ChatOpenAI
|
||||
|
||||
from langserve import add_routes
|
||||
|
||||
@@ -14,12 +15,12 @@ app = FastAPI(
|
||||
|
||||
add_routes(
|
||||
app,
|
||||
ChatOpenAI(),
|
||||
ChatOpenAI(model="gpt-3.5-turbo-0125"),
|
||||
path="/openai",
|
||||
)
|
||||
add_routes(
|
||||
app,
|
||||
ChatAnthropic(),
|
||||
ChatAnthropic(model="claude-3-haiku-20240307"),
|
||||
path="/anthropic",
|
||||
)
|
||||
|
||||
|
||||
@@ -4,9 +4,9 @@
|
||||
from typing import Any, Callable, Dict, List, Optional, TypedDict
|
||||
|
||||
from fastapi import FastAPI
|
||||
from langchain.chat_models import ChatOpenAI
|
||||
from langchain.prompts import ChatPromptTemplate
|
||||
from langchain.schema.runnable import RunnableMap, RunnablePassthrough
|
||||
from langchain_core.prompts import ChatPromptTemplate
|
||||
from langchain_core.runnables import RunnableParallel, RunnablePassthrough
|
||||
from langchain_openai import ChatOpenAI
|
||||
|
||||
from langserve import add_routes
|
||||
|
||||
@@ -43,7 +43,7 @@ model = ChatOpenAI()
|
||||
|
||||
underlying_chain = prompt | model
|
||||
|
||||
wrapped_chain = RunnableMap(
|
||||
wrapped_chain = RunnableParallel(
|
||||
{
|
||||
"output": _create_projection(exclude_keys=["info"]) | underlying_chain,
|
||||
"info": _create_projection(include_keys=["info"]),
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
#!/usr/bin/env python
|
||||
"""Example LangChain server exposes a retriever."""
|
||||
from fastapi import FastAPI
|
||||
from langchain.embeddings import OpenAIEmbeddings
|
||||
from langchain.vectorstores import FAISS
|
||||
from langchain_community.vectorstores import FAISS
|
||||
from langchain_openai import OpenAIEmbeddings
|
||||
|
||||
from langserve import add_routes
|
||||
|
||||
|
||||
@@ -9,7 +9,8 @@ See more documentation at:
|
||||
https://fastapi.tiangolo.com/tutorial/bigger-applications/
|
||||
"""
|
||||
from fastapi import APIRouter, FastAPI
|
||||
from langchain.chat_models import ChatAnthropic, ChatOpenAI
|
||||
from langchain_anthropic import ChatAnthropic
|
||||
from langchain_openai import ChatOpenAI
|
||||
|
||||
from langserve import add_routes
|
||||
|
||||
@@ -20,13 +21,13 @@ router = APIRouter(prefix="/models")
|
||||
# Invocations to this router will appear in trace logs as /models/openai
|
||||
add_routes(
|
||||
router,
|
||||
ChatOpenAI(),
|
||||
ChatOpenAI(model="gpt-3.5-turbo-0125"),
|
||||
path="/openai",
|
||||
)
|
||||
# Invocations to this router will appear in trace logs as /models/anthropic
|
||||
add_routes(
|
||||
router,
|
||||
ChatAnthropic(),
|
||||
ChatAnthropic(model="claude-3-haiku-20240307"),
|
||||
path="/anthropic",
|
||||
)
|
||||
|
||||
|
||||
@@ -6,7 +6,7 @@ from typing import List, Union
|
||||
|
||||
from fastapi import FastAPI
|
||||
from fastapi.middleware.cors import CORSMiddleware
|
||||
from langchain.chat_models import ChatAnthropic
|
||||
from langchain_anthropic import ChatAnthropic
|
||||
from langchain_core.messages import AIMessage, HumanMessage, SystemMessage
|
||||
from langchain_core.output_parsers import StrOutputParser
|
||||
from langchain_core.prompts import ChatPromptTemplate, MessagesPlaceholder
|
||||
|
||||
@@ -6,18 +6,17 @@ from typing import Any, Dict, List, Tuple
|
||||
|
||||
from fastapi import FastAPI
|
||||
from fastapi.middleware.cors import CORSMiddleware
|
||||
from langchain.chat_models.openai import ChatOpenAI
|
||||
from langchain.document_loaders.blob_loaders import Blob
|
||||
from langchain.document_loaders.parsers.pdf import PDFMinerParser
|
||||
from langchain.pydantic_v1 import BaseModel, Field
|
||||
from langchain.schema.messages import (
|
||||
from langchain_community.document_loaders.parsers.pdf import PDFMinerParser
|
||||
from langchain_core.document_loaders import Blob
|
||||
from langchain_core.messages import (
|
||||
AIMessage,
|
||||
BaseMessage,
|
||||
FunctionMessage,
|
||||
HumanMessage,
|
||||
)
|
||||
from langchain.schema.runnable import RunnableLambda
|
||||
from langchain_core.runnables import RunnableParallel
|
||||
from langchain_core.runnables import RunnableLambda, RunnableParallel
|
||||
from langchain_openai import ChatOpenAI
|
||||
|
||||
from langserve import CustomUserType
|
||||
from langserve.server import add_routes
|
||||
|
||||
@@ -852,7 +852,7 @@ class APIHandler:
|
||||
feedback_tokens=[
|
||||
FeedbackToken(
|
||||
key=feedback_key,
|
||||
url=feedback_token.url,
|
||||
token_url=feedback_token.url,
|
||||
expires_at=feedback_token.expires_at.isoformat(),
|
||||
)
|
||||
]
|
||||
@@ -999,7 +999,7 @@ class APIHandler:
|
||||
feedback_tokens=[
|
||||
FeedbackToken(
|
||||
key=feedback_key,
|
||||
url=feedback_token.url,
|
||||
token_url=feedback_token.url,
|
||||
expires_at=feedback_token.expires_at.isoformat(),
|
||||
)
|
||||
],
|
||||
|
||||
Generated
+874
-577
File diff suppressed because it is too large
Load Diff
+3
-2
@@ -1,6 +1,6 @@
|
||||
[tool.poetry]
|
||||
name = "langserve"
|
||||
version = "0.1.1"
|
||||
version = "0.2.1"
|
||||
description = ""
|
||||
readme = "README.md"
|
||||
authors = ["LangChain"]
|
||||
@@ -15,8 +15,9 @@ httpx = ">=0.23.0" # May be able to decrease this version
|
||||
fastapi = {version = ">=0.90.1,<1", optional = true}
|
||||
sse-starlette = {version = "^1.3.0", optional = true}
|
||||
pydantic = ">=1"
|
||||
langchain-core = "^0.1.0"
|
||||
langchain-core = ">=0.1,<0.3"
|
||||
orjson = ">=2"
|
||||
pyproject-toml = "^0.0.10"
|
||||
|
||||
[tool.poetry.group.dev.dependencies]
|
||||
jupyterlab = "^3.6.1"
|
||||
|
||||
@@ -71,6 +71,7 @@ from langserve.callbacks import AsyncEventAggregatorCallback
|
||||
from langserve.client import RemoteRunnable
|
||||
from langserve.lzstring import LZString
|
||||
from langserve.schema import CustomUserType
|
||||
from tests.unit_tests.utils.stubs import AnyStr
|
||||
|
||||
try:
|
||||
from pydantic.v1 import BaseModel, Field
|
||||
@@ -2558,7 +2559,7 @@ async def test_astream_events_with_prompt_model_parser_chain(
|
||||
"tags": ["seq:step:2"],
|
||||
},
|
||||
{
|
||||
"data": {"chunk": AIMessageChunk(content="Hello")},
|
||||
"data": {"chunk": AIMessageChunk(content="Hello", id=AnyStr())},
|
||||
"event": "on_chat_model_stream",
|
||||
"name": "GenericFakeChatModel",
|
||||
"tags": ["seq:step:2"],
|
||||
@@ -2582,7 +2583,7 @@ async def test_astream_events_with_prompt_model_parser_chain(
|
||||
"tags": [],
|
||||
},
|
||||
{
|
||||
"data": {"chunk": AIMessageChunk(content=" ")},
|
||||
"data": {"chunk": AIMessageChunk(content=" ", id=AnyStr())},
|
||||
"event": "on_chat_model_stream",
|
||||
"name": "GenericFakeChatModel",
|
||||
"tags": ["seq:step:2"],
|
||||
@@ -2600,7 +2601,7 @@ async def test_astream_events_with_prompt_model_parser_chain(
|
||||
"tags": [],
|
||||
},
|
||||
{
|
||||
"data": {"chunk": AIMessageChunk(content="World!")},
|
||||
"data": {"chunk": AIMessageChunk(content="World!", id=AnyStr())},
|
||||
"event": "on_chat_model_stream",
|
||||
"name": "GenericFakeChatModel",
|
||||
"tags": ["seq:step:2"],
|
||||
@@ -2632,7 +2633,9 @@ async def test_astream_events_with_prompt_model_parser_chain(
|
||||
[
|
||||
ChatGenerationChunk(
|
||||
text="Hello World!",
|
||||
message=AIMessageChunk(content="Hello World!"),
|
||||
message=AIMessageChunk(
|
||||
content="Hello World!", id=AnyStr()
|
||||
),
|
||||
)
|
||||
]
|
||||
],
|
||||
@@ -2646,7 +2649,7 @@ async def test_astream_events_with_prompt_model_parser_chain(
|
||||
},
|
||||
{
|
||||
"data": {
|
||||
"input": AIMessageChunk(content="Hello World!"),
|
||||
"input": AIMessageChunk(content="Hello World!", id=AnyStr()),
|
||||
"output": "Hello World!",
|
||||
},
|
||||
"event": "on_parser_end",
|
||||
@@ -2784,10 +2787,13 @@ async def test_remote_configurable_remote_runnable() -> None:
|
||||
result = await chain_with_history.ainvoke(
|
||||
{"question": "hi"}, {"configurable": {"session_id": "1"}}
|
||||
)
|
||||
assert result == AIMessage(content="Hello World!")
|
||||
assert result == AIMessage(content="Hello World!", id=AnyStr())
|
||||
assert store == {
|
||||
"1": InMemoryHistory(
|
||||
messages=[HumanMessage(content="hi"), AIMessage(content="Hello World!")]
|
||||
messages=[
|
||||
HumanMessage(content="hi"),
|
||||
AIMessage(content="Hello World!", id=AnyStr()),
|
||||
]
|
||||
)
|
||||
}
|
||||
|
||||
@@ -2847,7 +2853,7 @@ async def test_token_feedback_included_in_responses() -> None:
|
||||
{
|
||||
"expires_at": "2023-01-01T00:00:00",
|
||||
"key": "foo",
|
||||
"token_url": None,
|
||||
"token_url": "feedback_id",
|
||||
}
|
||||
],
|
||||
"run_id": run_id,
|
||||
@@ -2877,7 +2883,7 @@ async def test_token_feedback_included_in_responses() -> None:
|
||||
{
|
||||
"expires_at": "2023-01-01T00:00:00",
|
||||
"key": "foo",
|
||||
"token_url": None,
|
||||
"token_url": "feedback_id",
|
||||
}
|
||||
]
|
||||
},
|
||||
@@ -2886,7 +2892,7 @@ async def test_token_feedback_included_in_responses() -> None:
|
||||
{
|
||||
"expires_at": "2023-01-01T00:00:00",
|
||||
"key": "foo",
|
||||
"token_url": None,
|
||||
"token_url": "feedback_id",
|
||||
}
|
||||
]
|
||||
},
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
from typing import Any
|
||||
|
||||
|
||||
class AnyStr(str):
|
||||
def __eq__(self, other: Any) -> bool:
|
||||
return isinstance(other, str)
|
||||
@@ -8,6 +8,7 @@ from langchain_core.messages import AIMessage, AIMessageChunk, BaseMessage
|
||||
from langchain_core.outputs import ChatGenerationChunk, GenerationChunk
|
||||
|
||||
from tests.unit_tests.utils.llms import GenericFakeChatModel
|
||||
from tests.unit_tests.utils.stubs import AnyStr
|
||||
|
||||
|
||||
def test_generic_fake_chat_model_invoke() -> None:
|
||||
@@ -15,11 +16,11 @@ def test_generic_fake_chat_model_invoke() -> None:
|
||||
infinite_cycle = cycle([AIMessage(content="hello"), AIMessage(content="goodbye")])
|
||||
model = GenericFakeChatModel(messages=infinite_cycle)
|
||||
response = model.invoke("meow")
|
||||
assert response == AIMessage(content="hello")
|
||||
assert response == AIMessage(content="hello", id=AnyStr())
|
||||
response = model.invoke("kitty")
|
||||
assert response == AIMessage(content="goodbye")
|
||||
assert response == AIMessage(content="goodbye", id=AnyStr())
|
||||
response = model.invoke("meow")
|
||||
assert response == AIMessage(content="hello")
|
||||
assert response == AIMessage(content="hello", id=AnyStr())
|
||||
|
||||
|
||||
async def test_generic_fake_chat_model_ainvoke() -> None:
|
||||
@@ -27,11 +28,11 @@ async def test_generic_fake_chat_model_ainvoke() -> None:
|
||||
infinite_cycle = cycle([AIMessage(content="hello"), AIMessage(content="goodbye")])
|
||||
model = GenericFakeChatModel(messages=infinite_cycle)
|
||||
response = await model.ainvoke("meow")
|
||||
assert response == AIMessage(content="hello")
|
||||
assert response == AIMessage(content="hello", id=AnyStr())
|
||||
response = await model.ainvoke("kitty")
|
||||
assert response == AIMessage(content="goodbye")
|
||||
assert response == AIMessage(content="goodbye", id=AnyStr())
|
||||
response = await model.ainvoke("meow")
|
||||
assert response == AIMessage(content="hello")
|
||||
assert response == AIMessage(content="hello", id=AnyStr())
|
||||
|
||||
|
||||
async def test_generic_fake_chat_model_stream() -> None:
|
||||
@@ -44,26 +45,28 @@ async def test_generic_fake_chat_model_stream() -> None:
|
||||
model = GenericFakeChatModel(messages=infinite_cycle)
|
||||
chunks = [chunk async for chunk in model.astream("meow")]
|
||||
assert chunks == [
|
||||
AIMessageChunk(content="hello"),
|
||||
AIMessageChunk(content=" "),
|
||||
AIMessageChunk(content="goodbye"),
|
||||
AIMessageChunk(content="hello", id=AnyStr()),
|
||||
AIMessageChunk(content=" ", id=AnyStr()),
|
||||
AIMessageChunk(content="goodbye", id=AnyStr()),
|
||||
]
|
||||
|
||||
chunks = [chunk for chunk in model.stream("meow")]
|
||||
assert chunks == [
|
||||
AIMessageChunk(content="hello"),
|
||||
AIMessageChunk(content=" "),
|
||||
AIMessageChunk(content="goodbye"),
|
||||
AIMessageChunk(content="hello", id=AnyStr()),
|
||||
AIMessageChunk(content=" ", id=AnyStr()),
|
||||
AIMessageChunk(content="goodbye", id=AnyStr()),
|
||||
]
|
||||
|
||||
# Test streaming of additional kwargs.
|
||||
# Relying on insertion order of the additional kwargs dict
|
||||
message = AIMessage(content="", additional_kwargs={"foo": 42, "bar": 24})
|
||||
message = AIMessage(
|
||||
content="", additional_kwargs={"foo": 42, "bar": 24}, id=AnyStr()
|
||||
)
|
||||
model = GenericFakeChatModel(messages=cycle([message]))
|
||||
chunks = [chunk async for chunk in model.astream("meow")]
|
||||
assert chunks == [
|
||||
AIMessageChunk(content="", additional_kwargs={"foo": 42}),
|
||||
AIMessageChunk(content="", additional_kwargs={"bar": 24}),
|
||||
AIMessageChunk(content="", additional_kwargs={"foo": 42}, id=AnyStr()),
|
||||
AIMessageChunk(content="", additional_kwargs={"bar": 24}, id=AnyStr()),
|
||||
]
|
||||
|
||||
message = AIMessage(
|
||||
@@ -81,22 +84,28 @@ async def test_generic_fake_chat_model_stream() -> None:
|
||||
|
||||
assert chunks == [
|
||||
AIMessageChunk(
|
||||
content="", additional_kwargs={"function_call": {"name": "move_file"}}
|
||||
content="",
|
||||
additional_kwargs={"function_call": {"name": "move_file"}},
|
||||
id=AnyStr(),
|
||||
),
|
||||
AIMessageChunk(
|
||||
content="",
|
||||
additional_kwargs={
|
||||
"function_call": {"arguments": '{\n "source_path": "foo"'}
|
||||
},
|
||||
id=AnyStr(),
|
||||
),
|
||||
AIMessageChunk(
|
||||
content="", additional_kwargs={"function_call": {"arguments": ","}}
|
||||
content="",
|
||||
additional_kwargs={"function_call": {"arguments": ","}},
|
||||
id=AnyStr(),
|
||||
),
|
||||
AIMessageChunk(
|
||||
content="",
|
||||
additional_kwargs={
|
||||
"function_call": {"arguments": '\n "destination_path": "bar"\n}'}
|
||||
},
|
||||
id=AnyStr(),
|
||||
),
|
||||
]
|
||||
|
||||
@@ -116,6 +125,7 @@ async def test_generic_fake_chat_model_stream() -> None:
|
||||
'destination_path": "bar"\n}',
|
||||
}
|
||||
},
|
||||
id=AnyStr(),
|
||||
)
|
||||
|
||||
|
||||
@@ -128,9 +138,9 @@ async def test_generic_fake_chat_model_astream_log() -> None:
|
||||
]
|
||||
final = log_patches[-1]
|
||||
assert final.state["streamed_output"] == [
|
||||
AIMessageChunk(content="hello"),
|
||||
AIMessageChunk(content=" "),
|
||||
AIMessageChunk(content="goodbye"),
|
||||
AIMessageChunk(content="hello", id=AnyStr()),
|
||||
AIMessageChunk(content=" ", id=AnyStr()),
|
||||
AIMessageChunk(content="goodbye", id=AnyStr()),
|
||||
]
|
||||
|
||||
|
||||
@@ -178,8 +188,8 @@ async def test_callback_handlers() -> None:
|
||||
# New model
|
||||
results = list(model.stream("meow", {"callbacks": [MyCustomAsyncHandler(tokens)]}))
|
||||
assert results == [
|
||||
AIMessageChunk(content="hello"),
|
||||
AIMessageChunk(content=" "),
|
||||
AIMessageChunk(content="goodbye"),
|
||||
AIMessageChunk(content="hello", id=AnyStr()),
|
||||
AIMessageChunk(content=" ", id=AnyStr()),
|
||||
AIMessageChunk(content="goodbye", id=AnyStr()),
|
||||
]
|
||||
assert tokens == ["hello", " ", "goodbye"]
|
||||
|
||||
Reference in New Issue
Block a user