-
Notifications
You must be signed in to change notification settings - Fork 1.5k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat (ai/streams): add LangChainAdapter.toAIStream() (#1549)
- Loading branch information
Showing
34 changed files
with
770 additions
and
557 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
--- | ||
'ai': patch | ||
--- | ||
|
||
feat (ai/streams): add LangChainAdapter.toAIStream() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
--- | ||
title: Adapters | ||
description: Learn how to use AI SDK Adapters. | ||
--- | ||
|
||
# Adapters | ||
|
||
Adapters are lightweight integrations that enable you to use | ||
the Vercel AI SDK UI functions (`useChat` and `useCompletion`) | ||
with 3rd party libraries. | ||
|
||
The following adapters are currently available: | ||
|
||
- [LangChain](./langchain) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,66 @@ | ||
--- | ||
title: LangChain | ||
description: Learn how to use LangChain with the Vercel AI SDK. | ||
--- | ||
|
||
# LangChain | ||
|
||
[LangChain](https://js.langchain.com/docs/) is a framework for developing applications powered by language models. | ||
It provides tools and abstractions for working with AI models, agents, vector stores, and other data sources for retrieval augmented generation (RAG). | ||
However, LangChain does not provide a way to easily build UIs or a standard way to stream data to the client. | ||
|
||
## Example: Completion | ||
|
||
Here is a basic example that uses both Vercel AI SDK and LangChain together with the [Next.js](https://nextjs.org/docs) App Router. | ||
|
||
The AI SDK `LangChainAdapter` uses the result from [LangChain ExpressionLanguage streaming](https://js.langchain.com/docs/expression_language/streaming) to pipe text to the client. | ||
`LangChainAdapter.toAIStream()` is compatible with the LangChain Expression Language `.stream()` function response. | ||
|
||
```tsx filename="app/api/completion/route.ts" highlight={"17"} | ||
import { ChatOpenAI } from '@langchain/openai'; | ||
import { LangChainAdapter, StreamingTextResponse } from 'ai'; | ||
|
||
export const dynamic = 'force-dynamic'; | ||
export const maxDuration = 60; | ||
|
||
export async function POST(req: Request) { | ||
const { prompt } = await req.json(); | ||
|
||
const model = new ChatOpenAI({ | ||
model: 'gpt-3.5-turbo-0125', | ||
temperature: 0, | ||
}); | ||
|
||
const stream = await model.stream(prompt); | ||
|
||
const aiStream = LangChainAdapter.toAIStream(stream); | ||
|
||
return new StreamingTextResponse(aiStream); | ||
} | ||
``` | ||
|
||
Then, we use the Vercel AI SDK's [`useCompletion`](/docs/ai-sdk-ui/completion) method in the page component to handle the completion: | ||
|
||
```tsx filename="app/page.tsx" | ||
'use client'; | ||
|
||
import { useCompletion } from 'ai/react'; | ||
|
||
export default function Chat() { | ||
const { completion, input, handleInputChange, handleSubmit } = | ||
useCompletion(); | ||
|
||
return ( | ||
<div> | ||
{completion} | ||
<form onSubmit={handleSubmit}> | ||
<input value={input} onChange={handleInputChange} /> | ||
</form> | ||
</div> | ||
); | ||
} | ||
``` | ||
|
||
## More Examples | ||
|
||
You can find additional examples in the Vercel AI SDK [examples/next-langchain](https://github.com/vercel/ai/tree/main/examples/next-langchain) folder. |
This file was deleted.
Oops, something went wrong.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,29 +1,29 @@ | ||
import { StreamingTextResponse, LangChainStream, Message } from 'ai'; | ||
import { ChatOpenAI } from 'langchain/chat_models/openai'; | ||
import { ChatOpenAI } from '@langchain/openai'; | ||
import { LangChainAdapter, Message, StreamingTextResponse } from 'ai'; | ||
import { AIMessage, HumanMessage } from 'langchain/schema'; | ||
|
||
export const dynamic = 'force-dynamic'; | ||
export const maxDuration = 60; | ||
|
||
export async function POST(req: Request) { | ||
const { messages } = await req.json(); | ||
const { | ||
messages, | ||
}: { | ||
messages: Message[]; | ||
} = await req.json(); | ||
|
||
const { stream, handlers } = LangChainStream(); | ||
|
||
const llm = new ChatOpenAI({ | ||
streaming: true, | ||
const model = new ChatOpenAI({ | ||
model: 'gpt-3.5-turbo-0125', | ||
temperature: 0, | ||
}); | ||
|
||
llm | ||
.call( | ||
(messages as Message[]).map(m => | ||
m.role == 'user' | ||
? new HumanMessage(m.content) | ||
: new AIMessage(m.content), | ||
), | ||
{}, | ||
[handlers], | ||
) | ||
.catch(console.error); | ||
const stream = await model.stream( | ||
messages.map(message => | ||
message.role == 'user' | ||
? new HumanMessage(message.content) | ||
: new AIMessage(message.content), | ||
), | ||
); | ||
|
||
return new StreamingTextResponse(stream); | ||
return new StreamingTextResponse(LangChainAdapter.toAIStream(stream)); | ||
} |
28 changes: 28 additions & 0 deletions
28
examples/next-langchain/app/api/completion-stream-data/route.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
import { ChatOpenAI } from '@langchain/openai'; | ||
import { LangChainAdapter, StreamData, StreamingTextResponse } from 'ai'; | ||
|
||
export const dynamic = 'force-dynamic'; | ||
export const maxDuration = 60; | ||
|
||
export async function POST(req: Request) { | ||
const { prompt } = await req.json(); | ||
|
||
const model = new ChatOpenAI({ | ||
model: 'gpt-3.5-turbo-0125', | ||
temperature: 0, | ||
}); | ||
|
||
const stream = await model.stream(prompt); | ||
|
||
const data = new StreamData(); | ||
|
||
data.append({ test: 'value' }); | ||
|
||
const aiStream = LangChainAdapter.toAIStream(stream, { | ||
onFinal() { | ||
data.close(); | ||
}, | ||
}); | ||
|
||
return new StreamingTextResponse(aiStream, {}, data); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
import { ChatOpenAI } from '@langchain/openai'; | ||
import { LangChainAdapter, StreamingTextResponse } from 'ai'; | ||
|
||
export const dynamic = 'force-dynamic'; | ||
export const maxDuration = 60; | ||
|
||
export async function POST(req: Request) { | ||
const { prompt } = await req.json(); | ||
|
||
const model = new ChatOpenAI({ | ||
model: 'gpt-3.5-turbo-0125', | ||
temperature: 0, | ||
}); | ||
|
||
const stream = await model.stream(prompt); | ||
|
||
return new StreamingTextResponse(LangChainAdapter.toAIStream(stream)); | ||
} |
This file was deleted.
Oops, something went wrong.
Oops, something went wrong.