Compare commits

..

288 Commits

Author SHA1 Message Date
Erick Friis
dc7e597363 IMPROVEMENT default docs url root 2023-11-13 13:29:07 -08:00
Yasin
b46f88d364 IMPROVEMENT add license file to subproject (#8403)
<!-- Thank you for contributing to LangChain!

Replace this comment with:
  - Description: a description of the change, 
  - Issue: the issue # it fixes (if applicable),
  - Dependencies: any dependencies required for this change,
- Tag maintainer: for a quicker response, tag the relevant maintainer
(see below),
- Twitter handle: we announce bigger features on Twitter. If your PR
gets announced and you'd like a mention, we'll gladly shout you out!

Please make sure you're PR is passing linting and testing before
submitting. Run `make format`, `make lint` and `make test` to check this
locally.

If you're adding a new integration, please include:
1. a test for the integration, preferably unit tests that do not rely on
network access,
  2. an example notebook showing its use.

Maintainer responsibilities:
  - General / Misc / if you don't know who to tag: @baskaryan
  - DataLoaders / VectorStores / Retrievers: @rlancemartin, @eyurtsev
  - Models / Prompts: @hwchase17, @baskaryan
  - Memory: @hwchase17
  - Agents / Tools / Toolkits: @hinthornw
  - Tracing / Callbacks: @agola11
  - Async: @agola11

If no one reviews your PR within a few days, feel free to @-mention the
same people again.

See contribution guidelines for more information on how to write/run
tests, lint, etc:
https://github.com/hwchase17/langchain/blob/master/.github/CONTRIBUTING.md
 -->

hi!
This is pretty straight-forward: The sdist package does not contain the
license file (which is needed by e.g. conda) because the package is
built from the subdir and can't see the license.
I _copied_ the license but since I'm unfamiliar with the projects
direction, I'm not sure that's correct.
thanks!

---------

Co-authored-by: Erick Friis <erick@langchain.dev>
2023-11-13 11:48:21 -08:00
Rui Ramos
ff19a62afc Fix Pinecone cosine relevance score (#8920)
Fixes: #8207

Description:
Pinecone returns scores (not distances) with cosine similarity. The
values according to the docs are [-1, 1], although I could never
reproduce negative values.

This PR ensures that the score returned from Pinecone is preserved,
rather than inverted, so the most relevant documents can be filtered (eg
when using similarity thresholds)

I'll leave this as a draft PR as I couldn't run the tests (my pinecone
account might not be enough - some errors were being thrown around
namespaces) so hopefully someone who _can_ will pick this up.

Maintainers:
@rlancemartin, @eyurtsev

---------

Co-authored-by: Erick Friis <erick@langchain.dev>
2023-11-13 11:47:38 -08:00
Bagatur
2e42ed5de6 Self-query template (#12694)
Co-authored-by: Erick Friis <erick@langchain.dev>
2023-11-13 11:44:19 -08:00
Konstantin Spieß
1e43025bf5 Fix serialization issue in Matching Engine Vector Store (#13266)
- **Description:** Fixed a serialization issue in the add_texts method
of the Matching Engine Vector Store caused by a typo, leading to an
attempt to serialize the json module itself.
  - **Issue:** #12154 
  - **Dependencies:** ./.
  - **Tag maintainer:**
2023-11-13 11:04:11 -08:00
William FH
9169d77cf6 Update error message in evaluation runner (#13296) 2023-11-13 11:03:20 -08:00
Leonie
32c493e3df Refine Weaviate docs and add RAG example (#13057)
- **Description:** Refine Weaviate tutorial and add an example for
Retrieval-Augmented Generation (RAG)
  - **Issue:** (not applicable),
  - **Dependencies:** none
  - **Tag maintainer:** @baskaryan <!--
If no one reviews your PR within a few days, please @-mention one of
@baskaryan, @eyurtsev, @hwchase17.
 -->
  - **Twitter handle:** @helloiamleonie

Co-authored-by: Leonie <leonie@Leonies-MBP-2.fritz.box>
2023-11-13 10:59:19 -08:00
takatost
f22f273f93 FIX: 'from_texts' method in Weaviate with non-existent kwargs param (#11604)
Due to the possibility of external inputs including UUIDs, there may be
additional values in **kwargs, while Weaviate's `__init__` method does
not support passing extra **kwarg parameters.

---------

Co-authored-by: Erick Friis <erick@langchain.dev>
2023-11-13 10:32:20 -08:00
Frank995
971d2b2e34 Add missing filter to max_marginal_relevance_search inner call to max_marginal_relevance_search_by_vector (#13260)
When calling max_marginal_relevance_search from PGVector the filter
param is not carried over to max_marginal_relevance_search_by_vector

---------

Co-authored-by: Bagatur <baskaryan@gmail.com>
2023-11-13 10:31:34 -08:00
chevalmuscle
3ad78e48e2 Use endpoint_url if provided with boto3 session for dynamodb (#11622)
- **Description:** Uses `endpoint_url` if provided with a boto3 session.
When running dynamodb locally, credentials are required even if invalid.
With this change, it will be possible to pass a boto3 session with
credentials and specify an endpoint_url

---------

Co-authored-by: Bagatur <baskaryan@gmail.com>
Co-authored-by: Erick Friis <erick@langchain.dev>
2023-11-13 10:31:16 -08:00
Erick Friis
18acc22f29 Ollama pass kwargs as options instead of top (#13280)
Noticed params are really in `options` instead while reviewing #12895
2023-11-13 10:28:47 -08:00
刘 方瑞
46af56dc4f Add MyScaleWithoutJSON which allows user to wrap columns into Document's Metadata (#13164)
<!-- Thank you for contributing to LangChain!

Replace this entire comment with:
  - **Description:** a description of the change, 
  - **Issue:** the issue # it fixes (if applicable),
  - **Dependencies:** any dependencies required for this change,
- **Tag maintainer:** for a quicker response, tag the relevant
maintainer (see below),
- **Twitter handle:** we announce bigger features on Twitter. If your PR
gets announced, and you'd like a mention, we'll gladly shout you out!

Please make sure your PR is passing linting and testing before
submitting. Run `make format`, `make lint` and `make test` to check this
locally.

See contribution guidelines for more information on how to write/run
tests, lint, etc:

https://github.com/langchain-ai/langchain/blob/master/.github/CONTRIBUTING.md

If you're adding a new integration, please include:
1. a test for the integration, preferably unit tests that do not rely on
network access,
2. an example notebook showing its use. It lives in `docs/extras`
directory.

If no one reviews your PR within a few days, please @-mention one of
@baskaryan, @eyurtsev, @hwchase17.
 -->
Replace this entire comment with:
- **Description:** Add MyScaleWithoutJSON which allows user to wrap
columns into Document's Metadata
  - **Tag maintainer:** @baskaryan
2023-11-13 10:10:36 -08:00
Michael Landis
2aa13f1e10 chore: bump momento dependency version and refactor search hit usage (#13111)
**Description**

Bumps the Momento dependency to the latest version and refactors the
usage of `SearchHit` in the Momento Vector Index (MVI) vector store
integration. This change is a one liner where we use the preferred
attribute `score` to read the query-document similarity instead of
`distance`. The latest versions of Momento clients will use this
attribute going forward.

**Dependencies**

Updated the Momento dependency to latest version.

**Tests**

💚 I re-ran the existing MVI integration tests
(`tests/integration_tests/vectorstores/test_momento_vector_index.py`)
and they pass.

**Review**
cc @baskaryan @eyurtsev
2023-11-13 09:12:21 -08:00
Junlin Zhou
4da2faba41 docs: align custom_tool document headers (#13252)
On the [Defining Custom
Tools](https://python.langchain.com/docs/modules/agents/tools/custom_tools)
page, there's a 'Subclassing the BaseTool class' paragraph under the
'Completely New Tools - String Input and Output' header. Also there's
another 'Subclassing the BaseTool' paragraph under no header, which I
think may belong to the 'Custom Structured Tools' header.

Another thing is, there's a 'Using the tool decorator' and a 'Using the
decorator' paragraph, I think should belong to 'Completely New Tools -
String Input and Output' and 'Custom Structured Tools' separately.

This PR moves those paragraphs to corresponding headers.
2023-11-13 09:03:56 -08:00
Ikko Eltociear Ashimine
700293cae9 Fix typo in timescalevector.ipynb (#13239)
enviornment -> environment
2023-11-13 09:03:07 -08:00
kYLe
cc55d2fcee Add OpenAI API v1 support for ChatAnyscale and fixed a bug with openai_api_key (#13237)
1. Add OpenAI API v1 support
2. Fixed a bug to call `get_secret_value` on a str value
(values["openai_api_key"])
2023-11-13 09:01:54 -08:00
juan-calvo-datatonic
545b76b0fd Add rag google vertex ai search template (#13294)
- **Description:** This is a template demonstrating how to utilize
Google Vertex AI Search in conjunction with ChatVertexAI()
2023-11-13 08:45:36 -08:00
Govind.S.B
9024593468 added system prompt and template fields to ollama (#13022)
**Description**
the ollama api now supports passing system prompt and template directly
instead of modifying the model file , but the ollama integration in
langchain did not have this change updated . The update just adds these
two parameters to it ( there are 2 more parameters that are pending to
be updated, I was not sure about their utility wrt to langchain )
Refer :
8713ac23a8

**Issue** : None Applicable

**Dependencies** : None Changed

**Twitter handle** : https://twitter.com/violetto96

---------

Co-authored-by: Eugene Yurtsev <eyurtsev@gmail.com>
2023-11-13 08:45:11 -08:00
langchain-infra
f55f67055f Add dockerfile template (#13240) 2023-11-13 10:33:01 -05:00
Shaurya Rohatgi
f70aa82c84 Update README.md - Added notebook for extraction_openai_tools (#13205)
added Parallel Function Calling for Structured Data Extraction notebook

<!-- Thank you for contributing to LangChain!

Replace this entire comment with:
  - **Description:** a description of the change, 
  - **Issue:** the issue # it fixes (if applicable),
  - **Dependencies:** any dependencies required for this change,
- **Tag maintainer:** for a quicker response, tag the relevant
maintainer (see below),
- **Twitter handle:** we announce bigger features on Twitter. If your PR
gets announced, and you'd like a mention, we'll gladly shout you out!

Please make sure your PR is passing linting and testing before
submitting. Run `make format`, `make lint` and `make test` to check this
locally.

See contribution guidelines for more information on how to write/run
tests, lint, etc:

https://github.com/langchain-ai/langchain/blob/master/.github/CONTRIBUTING.md

If you're adding a new integration, please include:
1. a test for the integration, preferably unit tests that do not rely on
network access,
2. an example notebook showing its use. It lives in `docs/extras`
directory.

If no one reviews your PR within a few days, please @-mention one of
@baskaryan, @eyurtsev, @hwchase17.
 -->

---------

Co-authored-by: Erick Friis <erick@langchain.dev>
2023-11-13 00:12:46 -08:00
Guillem Orellana Trullols
0f31cd8b49 Remove _get_kwarg_value function (#13184)
`_get_kwarg_value` function is useless, one can rely on python builtin
functionalities to do the exact same thing.

- **Description:** Removed `_get_kwarg_value`. Helps with code
readability.
  - **Issue:** the issue # it fixes (if applicable),
  - **Twitter handle:** @Guillem_96
2023-11-13 00:09:54 -08:00
SuperDa Fu
e1c020dfe1 dalle add model parameter (#13201)
- **Description:** dalle_image_generator adding a new model parameter,
  - **Issue:** N/A,
  - **Dependencies:** 
  - **Tag maintainer: @hwchase17
  - **Twitter handle:**

---------

Co-authored-by: dafu <xiangbingze@wenru.wang>
Co-authored-by: Eugene Yurtsev <eyurtsev@gmail.com>
Co-authored-by: Erick Friis <erickfriis@gmail.com>
2023-11-13 00:09:20 -08:00
Mario Angst
96b56a4d4f Typo fix to quickstart.mdx (#13178)
- **Description:** I fixed a very small typo in the quickstart docs
(BaeMessage -> BaseMessage)
2023-11-13 00:02:18 -08:00
Dennis de Greef
64e11592bb Improve CSV reader which can't call .strip() on NoneType (#13079)
Improve CSV reader which can't call .strip() on NoneType if there are
less cells in the row compared to the header

<!-- Thank you for contributing to LangChain!

Replace this entire comment with:
  - **Description:** 
I have a CSV file as followed

```
headerA,headerB,headerC
v1A,v1B,v1C,
v2A,v2B
v3A,v3B,v3C
```
In this case, row 2 is missing a value, which results in reading a None
type. The strip() method can not be called on None, hence raising. In
this PR I am making the change to only call strip if the value if not
None.

  - **Issue:** the issue # it fixes (if applicable),
  - **Dependencies:** any dependencies required for this change,
- **Tag maintainer:** for a quicker response, tag the relevant
maintainer (see below),
- **Twitter handle:** we announce bigger features on Twitter. If your PR
gets announced, and you'd like a mention, we'll gladly shout you out!

Please make sure your PR is passing linting and testing before
submitting. Run `make format`, `make lint` and `make test` to check this
locally.

See contribution guidelines for more information on how to write/run
tests, lint, etc:

https://github.com/langchain-ai/langchain/blob/master/.github/CONTRIBUTING.md

If you're adding a new integration, please include:
1. a test for the integration, preferably unit tests that do not rely on
network access,
2. an example notebook showing its use. It lives in `docs/extras`
directory.

If no one reviews your PR within a few days, please @-mention one of
@baskaryan, @eyurtsev, @hwchase17.
 -->
2023-11-12 23:51:39 -08:00
glad4enkonm
339973db47 Update ollama.py (#12895)
duplicate option removed
**Description:**  An issue fix, http stop option duplicate removed.
**Issue:** the issue #12892 fix
**Dependencies:** no
**Tag maintainer:** @eyurtsev

---------

Co-authored-by: Erick Friis <erick@langchain.dev>
2023-11-12 23:43:59 -08:00
刘 方瑞
e89e830c55 Free knowledge base pod information update (#12813)
<!-- Thank you for contributing to LangChain!

Replace this entire comment with:
  - **Description:** a description of the change, 
  - **Issue:** the issue # it fixes (if applicable),
  - **Dependencies:** any dependencies required for this change,
- **Tag maintainer:** for a quicker response, tag the relevant
maintainer (see below),
- **Twitter handle:** we announce bigger features on Twitter. If your PR
gets announced, and you'd like a mention, we'll gladly shout you out!

Please make sure your PR is passing linting and testing before
submitting. Run `make format`, `make lint` and `make test` to check this
locally.

See contribution guidelines for more information on how to write/run
tests, lint, etc:

https://github.com/langchain-ai/langchain/blob/master/.github/CONTRIBUTING.md

If you're adding a new integration, please include:
1. a test for the integration, preferably unit tests that do not rely on
network access,
2. an example notebook showing its use. It lives in `docs/extras`
directory.

If no one reviews your PR within a few days, please @-mention one of
@baskaryan, @eyurtsev, @hwchase17.
 -->

We updated MyScale free knowledge base, where you can try your RAG with
36 million paragraphs from wikipedia and 2 million paragraphs from
ArXiv.

The pod has two tables
```sql
CREATE TABLE default.ChatArXiv (
    `abstract` String, 
    `id` String, 
    `vector` Array(Float32), 
    `metadata` Object('JSON'), 
    `pubdate` DateTime,
    `title` String,
    `categories` Array(String),
    `authors` Array(String), 
    `comment` String,
    `primary_category` String,
    VECTOR INDEX vec_idx vector TYPE MSTG('metric_type=Cosine'), 
    CONSTRAINT vec_len CHECK length(vector) = 768) 
ENGINE = ReplacingMergeTree ORDER BY id;

CREATE TABLE wiki.Wikipedia (
    `id` String, 
    `title` String, 
    `text` String,
    `url` String,
    `wiki_id` UInt64,
    `views` Float32,
    `paragraph_id` UInt64,
    `langs` UInt32, 
    `emb` Array(Float32), 
    VECTOR INDEX emb_idx emb TYPE MSTG('metric_type=Cosine'), 
    CONSTRAINT emb_len CHECK length(emb) = 768) 
ENGINE = ReplacingMergeTree ORDER BY id;
```

You can connect those two tables using credentials below (just the same
to the old one)
URL: `msc-4a9e710a.us-east-1.aws.staging.myscale.cloud`
Port: `443`
Username: `chatdata`
Password: `myscale_rocks`

It's FREE and you can also use it with 
ChatData: https://github.com/myscale/ChatData
Retrieval-QA-Benchmark:
https://github.com/myscale/Retrieval-QA-Benchmark
... and also LangChain!

Request for review @baskaryan
2023-11-12 23:22:42 -08:00
Luis Valencia
c40973814d Update README.md (#8570)
- Description: updated readme.
  - Tag maintainer: @baskaryan
  - Twitter handle: @Levalencia

---------

Co-authored-by: Bagatur <22008038+baskaryan@users.noreply.github.com>
2023-11-12 22:07:49 -08:00
Isak Nyberg
8f81703d76 Add new models to openai callback (#13244)
**Description:** Adding the new models to the openai callback function,
info taken from [model
announcement](https://platform.openai.com/docs/models) and
[pricing](https://openai.com/pricing)

A short description for a short PR :)
2023-11-12 12:01:19 -08:00
Bagatur
ea6dd3a550 bump 335 (#13261) 2023-11-12 11:30:25 -08:00
William FH
a837b03e55 Update langsmith version 0.63 (#13208) 2023-11-12 11:29:25 -08:00
Harrison Chase
7f1d26160d update tools (#13243) 2023-11-12 10:22:54 -08:00
Nuno Campos
8d6faf5665 Make it easier to subclass runnable binding with custom init args (#13189) 2023-11-11 09:01:17 +00:00
Peter Vandenabeele
7f1964b264 Fix BeautifulSoupTransformer: no more duplicates and correct order of tags + tests (#12596) 2023-11-11 08:56:37 +00:00
Bagatur
937d7c41f3 update stack diagram (#13213) 2023-11-10 16:50:20 -08:00
Erick Friis
9c7afa8adb Upgrade cohere embedding model to v3 (#13219)
Just updates API docs, doesn't change default param from 2.0 (could be
breaking change)
2023-11-10 16:25:58 -08:00
Matvey Arye
180657ca7a Add template for conversational rag with timescale vector (#13041)
**Description:** This is like the rag-conversation template in many
ways. What's different is:
- support for a timescale vector store.
- support for time-based filters.
- support for metadata filters.

<!-- Thank you for contributing to LangChain!

Replace this entire comment with:
  - **Description:** a description of the change, 
  - **Issue:** the issue # it fixes (if applicable),
  - **Dependencies:** any dependencies required for this change,
- **Tag maintainer:** for a quicker response, tag the relevant
maintainer (see below),
- **Twitter handle:** we announce bigger features on Twitter. If your PR
gets announced, and you'd like a mention, we'll gladly shout you out!

Please make sure your PR is passing linting and testing before
submitting. Run `make format`, `make lint` and `make test` to check this
locally.

See contribution guidelines for more information on how to write/run
tests, lint, etc:

https://github.com/langchain-ai/langchain/blob/master/.github/CONTRIBUTING.md

If you're adding a new integration, please include:
1. a test for the integration, preferably unit tests that do not rely on
network access,
2. an example notebook showing its use. It lives in `docs/extras`
directory.

If no one reviews your PR within a few days, please @-mention one of
@baskaryan, @eyurtsev, @hwchase17.
 -->

---------

Co-authored-by: Erick Friis <erick@langchain.dev>
2023-11-10 16:12:32 -08:00
Andrew Zhou
1a1a1a883f fleet_context docs update (#13221)
- **Description:** Changed the fleet_context documentation to use
`context.download_embeddings()` from the latest release from our
package. More details here:
https://github.com/fleet-ai/context/tree/main#api
  - **Issue:** n/a
  - **Dependencies:** n/a
  - **Tag maintainer:** @baskaryan 
  - **Twitter handle:** @andrewthezhou
2023-11-10 14:53:57 -08:00
Erick Friis
8fdf15c023 Fix Document Loader Unit Test - Docusaurus (#13228) 2023-11-10 14:52:01 -08:00
Lee
72ad448daa feat: Docusaurus Loader (#9138)
Added a Docusaurus Loader

Issue: #6353

I had to implement this for working with the Ionic documentation, and
wanted to open this up as a draft to get some guidance on building this
out further. I wasn't sure if having it be a light extension of the
SitemapLoader was in the spirit of a proper feature for the library --
but I'm grateful for the opportunities Langchain has given me and I'd
love to build this out properly for the sake of the community.

Any feedback welcome!
2023-11-10 14:21:55 -08:00
VAS
8fa960641a Update Documentation: Corrected Typos and Improved Clarity (#11725)
Docs updates

---------

Co-authored-by: Advaya <126754021+bluevayes@users.noreply.github.com>
Co-authored-by: Erick Friis <erick@langchain.dev>
2023-11-10 14:14:44 -08:00
Leonid Ganeline
e165daa0ae new course on DeepLearning.ai (#12755)
Added a new course on
[DeepLearning.ai](https://learn.deeplearning.ai/functions-tools-agents-langchain)
Added the LangChain `Wikipedia` link. Probably, it can be placed in the
"More" menu.
2023-11-10 13:55:27 -08:00
Erick Friis
93ae589f1b Add mongo parent template to index (#13222) 2023-11-10 11:56:44 -08:00
Tomaz Bratanic
0dc4ab0be1 Neo4j chat message history (#13008) 2023-11-10 11:53:34 -08:00
Bagatur
bf8cf7e042 Bagatur/langserve blurb (#13217) 2023-11-10 14:05:43 -05:00
fyasla
d266b3ea4a issue #12165 mask API key in chat_models/azureml_endpoint module (#12836)
- **Description:** `AzureMLChatOnlineEndpoint` object from
langchain/chat_models/azureml_endpoint.py safe to print
without having any secrets included in raw format in the string
representation.
  - **Issue:** #12165,
  - **Tag maintainer:** @eyurtsev

---------

Co-authored-by: Faysal Bougamale <faysal.bougamale@horiba.com>
Co-authored-by: Bagatur <baskaryan@gmail.com>
2023-11-10 14:05:19 -05:00
Anush
52f34de9b7 feat: FastEmbed embedding provider (#13109)
## Description:
This PR intends to add
[Qdrant/FastEmbed](https://qdrant.github.io/fastembed/) as a local
embeddings provider, associated tests and documentation.

**Documentation preview:**
https://langchain-git-fork-anush008-master-langchain.vercel.app/docs/integrations/text_embedding/fastembed

---------

Co-authored-by: Eugene Yurtsev <eyurtsev@gmail.com>
2023-11-10 13:51:52 -05:00
Eugene Yurtsev
b0e8cbe0b3 Add RunnableSequence documentation (#13094)
Add RunnableSequence documentation
2023-11-10 13:44:43 -05:00
Eugene Yurtsev
869df62736 Document RunnableWithFallbacks (#13088)
Add documentation to RunnableWithFallbacks
2023-11-10 13:16:21 -05:00
Eugene Yurtsev
8313c218da Add more runnable documentation (#13083)
- Adding documentation to the runnable.
- Documentation is not organized in the best way for the runnable; i.e.,
in
terms of LCEL vs. other standard methods, will follow up with more
edits.
2023-11-10 13:14:57 -05:00
Erick Friis
a26105de8e vectara rag mq (#13214)
Description: another Vectara template for MultiQuery RAG flow
Twitter handle: @ofermend

Fixes to #13106

---------

Co-authored-by: Ofer Mendelevitch <ofer@vectara.com>
Co-authored-by: Ofer Mendelevitch <ofermend@gmail.com>
2023-11-10 10:08:45 -08:00
Bagatur
24386e0860 bump 334, exp 40 (#13211) 2023-11-10 09:43:29 -08:00
Lance Martin
d2e50b3108 Add Chroma multimodal cookbook (#12952)
Pending:
* https://github.com/chroma-core/chroma/pull/1294
* https://github.com/chroma-core/chroma/pull/1293

---------

Co-authored-by: Erick Friis <erick@langchain.dev>
Co-authored-by: Bagatur <baskaryan@gmail.com>
2023-11-10 09:43:10 -08:00
The1Bill
55912868da Update toolkit.py to remove single quotes around table names (#12445)
**Description:** Removing the single quote wrapper around the table
names in the SQL agent toolkit.py file as it misleads the LLM into
querying against tables with single quotes around their names.
**Issue:** #7457 
**Dependencies:** None
**Tag maintainer:** @hwchase17 
**Twitter handle:** None
2023-11-10 06:39:15 -08:00
Nuno Campos
362a446999 Changes to root listener (#12174)
- Implement config_specs to include session_id
- Remove Runnable method and update notebook
- Add more details to notebook, eg. show input schema and config schema
before and after adding message history

---------

Co-authored-by: Harrison Chase <hw.chase.17@gmail.com>
2023-11-10 09:53:48 +00:00
Nuno Campos
b2b94424db Update return type for Runnable.__or__ (#12880)
<!-- Thank you for contributing to LangChain!

Replace this entire comment with:
  - **Description:** a description of the change, 
  - **Issue:** the issue # it fixes (if applicable),
  - **Dependencies:** any dependencies required for this change,
- **Tag maintainer:** for a quicker response, tag the relevant
maintainer (see below),
- **Twitter handle:** we announce bigger features on Twitter. If your PR
gets announced, and you'd like a mention, we'll gladly shout you out!

Please make sure your PR is passing linting and testing before
submitting. Run `make format`, `make lint` and `make test` to check this
locally.

See contribution guidelines for more information on how to write/run
tests, lint, etc:

https://github.com/langchain-ai/langchain/blob/master/.github/CONTRIBUTING.md

If you're adding a new integration, please include:
1. a test for the integration, preferably unit tests that do not rely on
network access,
2. an example notebook showing its use. It lives in `docs/extras`
directory.

If no one reviews your PR within a few days, please @-mention one of
@baskaryan, @eyurtsev, @hwchase17.
 -->
2023-11-10 09:52:38 +00:00
Bagatur
dd7959f4ac template readme's in docs (#13152) 2023-11-09 23:36:21 -08:00
Bagatur
86b93b5810 Add serve to quickstart (#13174) 2023-11-09 23:10:26 -08:00
Bagatur
fbf7047468 Bagatur/update agent docs (#13167) 2023-11-09 21:14:30 -08:00
Harrison Chase
0a2b1c7471 improve duck duck go tool (#13165) 2023-11-09 20:49:39 -08:00
Bagatur
850336bcf1 Update model i/o docs (#13160) 2023-11-09 20:35:55 -08:00
Jacob Lee
cf271784fa Add basic critique revise template (#12688)
@baskaryan @hwchase17

---------

Co-authored-by: Erick Friis <erick@langchain.dev>
2023-11-09 17:33:29 -08:00
Cweili
ee3ceb0fb8 Document: Fix "Biadu" typo (#12985)
Fix document "Baidu Cloud ElasticSearch VectorSearch" `Biadu` typo.
2023-11-09 17:32:38 -08:00
Chenyu Zhao
defd4b4f11 Clean up Fireworks provider documentation (#13157) 2023-11-09 16:35:05 -08:00
Bagatur
d9e493e96c fix module sidebar (#13158) 2023-11-09 16:31:45 -08:00
wemysschen
e76ff63125 fix baiducloud_vector_search document typo (#12976)
**Issue:**
fix baiducloud_vector_search document typo

---------

Co-authored-by: wemysschen <root@icoding-cwx.bcc-szzj.baidu.com>
2023-11-09 16:27:04 -08:00
Holt Skinner
fceae456b9 fix: Updates to formatting in Google Drive Retriever docs (#13015)
- Minor updates to formatting to make easier to read
2023-11-09 16:15:55 -08:00
Bagatur
c63eb9d797 LCEL nits (#13155) 2023-11-09 16:09:33 -08:00
Shinya Maeda
28cc60b347 Fix langchain.llms OpenAI completion doesn't work due to v1 client update (#13099)
This commit fixes the issue that langchain.llms OpenAI completion
stopped working since the V1 openai client update.

Replace this entire comment with:
- **Description:** This PR fixes the issue [AttributeError: module
'openai' has no attribute
'Completion'](https://github.com/langchain-ai/langchain/issues/12967)
similar to
8e0cb2eb84
and https://github.com/langchain-ai/langchain/pull/12969,
  - **Issue:** https://github.com/langchain-ai/langchain/issues/12967,
  - **Dependencies:** `openai` v1.x.x client,
  - **Tag maintainer:** @baskaryan,
  - **Twitter handle:** @dosuken123 

Please make sure your PR is passing linting and testing before
submitting. Run `make format`, `make lint` and `make test` to check this
locally.

See contribution guidelines for more information on how to write/run
tests, lint, etc:

https://github.com/langchain-ai/langchain/blob/master/.github/CONTRIBUTING.md

If you're adding a new integration, please include:
1. a test for the integration, preferably unit tests that do not rely on
network access,
2. an example notebook showing its use. It lives in `docs/extras`
directory.

If no one reviews your PR within a few days, please @-mention one of
@baskaryan, @eyurtsev, @hwchase17.

---------

Co-authored-by: Erick Friis <erick@langchain.dev>
Co-authored-by: Bagatur <baskaryan@gmail.com>
2023-11-09 15:12:19 -08:00
Bagatur
555ce600ef Bagatur/docs serve context (#13150) 2023-11-09 15:05:18 -08:00
Bagatur
ff43cd6701 OpenAI remove httpx typing (#13154)
Addresses #13124
2023-11-09 14:32:09 -08:00
Erick Friis
8ad3b255dc Pirate Speak Configurable Template (#13153) 2023-11-09 22:13:45 +00:00
Bagatur
eb51150557 update oai tool agent doc (#13147) 2023-11-09 12:37:30 -08:00
Bagatur
b298f550fe update modules sidebar (#13141) 2023-11-09 11:57:09 -08:00
Bagatur
84e65533e9 Docs: combine LCEL index and why (#13142) 2023-11-09 11:16:45 -08:00
Bagatur
1311450646 fix langsmith links (#13144) 2023-11-09 11:12:50 -08:00
Bagatur
8b2a82b5ce Bagatur/docs smith context (#13139) 2023-11-09 10:22:49 -08:00
Erick Friis
58da6e0d47 Multimodal rag traces (#13140) 2023-11-09 09:54:00 -08:00
Bagatur
150d58304d update oai cookbooks (#13135) 2023-11-09 08:04:51 -08:00
Bagatur
f04cc4b7e1 bump 333 (#13131) 2023-11-09 07:33:15 -08:00
billytrend-cohere
b346d4a455 Add message to documents (#12552)
This adds the response message as a document to the rag retriever so
users can choose to use this. Also drops document limit.

---------

Co-authored-by: Bagatur <baskaryan@gmail.com>
2023-11-09 07:30:48 -08:00
Harrison Chase
5f38770161 Support oai tool call (#13110)
Co-authored-by: Bagatur <baskaryan@gmail.com>
Co-authored-by: Nuno Campos <nuno@boringbits.io>
2023-11-09 07:29:29 -08:00
Stefano Lottini
c52725bdc5 (Astra DB/Cassandra) Minor clarification about dependencies in the demo notebook (#13118)
This PR helps developers trying the Astra DB / Cassandra vector store
quickstart notebook by making it clear what other dependencies are
required.
2023-11-09 09:19:15 -05:00
Holt Skinner
0fc8fd12bd feat: Vertex AI Search - Add Snippet Retrieval for Non-Advanced Website Data Stores (#13020)
https://cloud.google.com/generative-ai-app-builder/docs/snippets#snippets

---------

Co-authored-by: Eugene Yurtsev <eyurtsev@gmail.com>
2023-11-08 21:52:50 -05:00
Erick Friis
3dbaaf59b2 Tool Retrieval Template (#13104)
Adds a template like
https://python.langchain.com/docs/modules/agents/how_to/custom_agent_with_tool_retrieval

Uses OpenAI functions, LCEL, and FAISS
2023-11-08 18:33:31 -08:00
Jacob Lee
76283e9625 Adds embeddings filter option to return scores in state (#12489)
CC @baskaryan @assafelovic
2023-11-08 17:50:06 -08:00
jakerachleff
18601bd4c8 Get project from langchain sdk (#13100)
## Description
We need to centralize the API we use to get the project name for our
tracers. This PR makes it so we always get this from a shared function
in the langsmith sdk.

## Dependencies
Upgraded langsmith from 0.52 to 0.62 to include the new API
`get_tracer_project`
2023-11-08 17:10:12 -08:00
Bagatur
72e12f6bcf update more azure docs (#13093) 2023-11-08 14:11:16 -08:00
Bagatur
1703f132c6 update azure embedding docs (#13091) 2023-11-08 13:39:31 -08:00
Bagatur
9fdfac22c2 bump 332 (#13089) 2023-11-08 13:23:16 -08:00
Bagatur
1f85ec34d5 bump 331rc3 exp 39 (#13086) 2023-11-08 13:00:13 -08:00
Anton Troynikov
9f077270c8 Don't pass EF to chroma (#13085)
- **Description:** 

Recently Chroma rolled out a breaking change on the way we handle
embedding functions, in order to support multi-modal collections.

This broke the way LangChain's `Chroma` objects get created, because we
were passing the EF down into the Chroma collection:
https://docs.trychroma.com/migration#migration-to-0416---november-7-2023

However, internally, we are never actually using embeddings on the
chroma collection - LangChain's `Chroma` object calls it instead. Thus
we just don't pass an `embedding_function` to Chroma itself, which fixes
the issue.
2023-11-08 12:55:35 -08:00
Erick Friis
f15f8e01cf Azure OpenAI Embeddings (#13039)
Co-authored-by: Bagatur <baskaryan@gmail.com>
2023-11-08 12:37:17 -08:00
David Peterson
37561d8986 Add Proper Import Error (#13042)
- **Description:** The issue was not listing the proper import error for
amazon textract loader.
- **Issue:** Time wasted trying to figure out what to install...
(langchain docs don't list the dependency either)
  - **Dependencies:** N/A
  - **Tag maintainer:** @sbusso 
  - **Twitter handle:** @h9ste

---------

Co-authored-by: Harrison Chase <hw.chase.17@gmail.com>
2023-11-08 10:29:08 -08:00
Eugene Yurtsev
06c503f672 Add RunnableRetry Documentation (#13074) 2023-11-08 18:20:18 +00:00
Bagatur
55aeff6777 oai assistant multiple actions (#13068) 2023-11-08 08:25:37 -08:00
Erick Friis
a9b70baef9 cli updates, 0.0.16 (#13034)
- confirm flags, serve detection
- 0.0.16
- always gen code
- pip bool
2023-11-08 07:47:30 -08:00
Bagatur
1f27104626 Fleet context (#13038)
cc @adrwz
2023-11-07 18:57:09 -08:00
Bagatur
d26fd6f0d1 redirect langsmith walkthrough (#13040) 2023-11-07 18:24:13 -08:00
Erick Friis
6f45532620 Upgrade docs postcss (#13031) 2023-11-07 15:50:25 -08:00
Erick Friis
54ad3cc2b8 template versions again (#13030)
- scipy was locked due to py version
- same guardrails-output-parser
- rag-redis
2023-11-07 15:15:18 -08:00
Erick Friis
506f81563f Update Deps in Experimental (#13029) 2023-11-07 15:15:09 -08:00
Erick Friis
db4b97d590 Relock Templates (#13028) 2023-11-07 15:01:49 -08:00
Stefano Lottini
4f4b020582 Add "Astra DB" vector store integration (#12966)
# Astra DB Vector store integration

- **Description:** This PR adds a `VectorStore` implementation for
DataStax Astra DB using its HTTP API
  - **Issue:** (no related issue)
- **Dependencies:** A new required dependency is `astrapy` (`>=0.5.3`)
which was added to pyptoject.toml, optional, as per guidelines
- **Tag maintainer:** I recently mentioned to @baskaryan this
integration was coming
  - **Twitter handle:** `@rsprrs` if you want to mention me

This PR introduces the `AstraDB` vector store class, extensive
integration test coverage, a reworking of the documentation which
conflates Cassandra and Astra DB on a single "provider" page and a new,
completely reworked vector-store example notebook (common to the
Cassandra store, since parts of the flow is shared by the two APIs). I
also took care in ensuring docs (and redirects therein) are behaving
correctly.

All style, linting, typechecks and tests pass as far as the `AstraDB`
integration is concerned.

I could build the documentation and check it all right (but ran into
trouble with the `api_docs_build` makefile target which I could not
verify: `Error: Unable to import module
'plan_and_execute.agent_executor' with error: No module named
'langchain_experimental'` was the first of many similar errors)

Thank you for a review!
Stefano

---------

Co-authored-by: Erick Friis <erick@langchain.dev>
2023-11-07 14:45:33 -08:00
Tomaz Bratanic
13bd83bd61 Add neo4j vector memory template (#12993) 2023-11-07 13:00:49 -08:00
Bagatur
5ac2fc5bb2 update stack diagram (#13021) 2023-11-07 12:59:24 -08:00
Yang, Bo
600caff03c Add Memorize tool (#11722)
- **Description:** Add `Memorize` tool
  - **Tag maintainer:** @hwchase17

This PR added a new tool `Memorize` so that an agent can use it to
fine-tune itself. This tool requires `TrainableLLM` introduced in #11721

DEMO:
6a9003d5db

![image](https://github.com/langchain-ai/langchain/assets/601530/d6f0cb45-54df-4dcf-b143-f8aefb1e76e3)
2023-11-07 12:42:10 -08:00
Bagatur
cf481c9418 bump exp 38 (#13016) 2023-11-07 11:49:23 -08:00
Bagatur
57e19989f6 Bagatur/oai assistant (#13010) 2023-11-07 11:44:53 -08:00
Erick Friis
74134dd7e1 cli pyproject updating (#12945)
`langchain app add` and `langchain app remove` will now keep the
dependencies list updated.

---------

Co-authored-by: Nuno Campos <nuno@boringbits.io>
2023-11-07 11:06:08 -08:00
Tomaz Bratanic
d9abcf1aae Neo4j conversation cypher template (#12927)
Adding custom graph memory to Cypher chain

---------

Co-authored-by: Erick Friis <erick@langchain.dev>
2023-11-07 11:05:28 -08:00
Lance Martin
2287a311cf Multi modal RAG + QA Cookbooks (#12946)
Co-authored-by: Erick Friis <erick@langchain.dev>
Co-authored-by: Eugene Yurtsev <eyurtsev@gmail.com>
Co-authored-by: Vinzenz Klass <76391770+VinzenzKlass@users.noreply.github.com>
Co-authored-by: Praveen Venkateswaran <praveenv@uci.edu>
Co-authored-by: Praveen Venkateswaran <praveen.venkateswaran@ibm.com>
Co-authored-by: Kacper Łukawski <kacperlukawski@users.noreply.github.com>
Co-authored-by: Bagatur <22008038+baskaryan@users.noreply.github.com>
Co-authored-by: Bagatur <baskaryan@gmail.com>
Co-authored-by: Ofer Mendelevitch <ofermend@gmail.com>
Co-authored-by: Harrison Chase <hw.chase.17@gmail.com>
2023-11-07 09:10:24 -08:00
Bagatur
6175dc30aa bump 331rc2 (#13006) 2023-11-07 08:52:17 -08:00
Jasan
ff87f4b4f9 Fix for rag-supabase readme (#12869)
- **Description:** Correct naming for package in README
- **Issue:** README wasn't aligned with pyproject.toml, resulting in not
being able to install the rag-supabase package.
  - **Tag maintainer:** @gregnr
2023-11-06 19:38:22 -08:00
Harrison Chase
99ffeb239f add ingest for mongo (#12897) 2023-11-06 19:28:22 -08:00
Ofer Mendelevitch
ce21308f29 Vectara RAG template (#12975)
- **Description:** RAG template using Vectara
  - **Twitter handle:** @ofermend
2023-11-06 19:24:00 -08:00
Erick Friis
0c81cd923e oai v1 embeddings (#12969)
Initial PR to get OpenAIEmbeddings working with the new sdk

fyi @rlancemartin 

Fixes #12943

---------

Co-authored-by: Bagatur <baskaryan@gmail.com>
2023-11-06 18:52:33 -08:00
Bagatur
fdbb45d79e bump 331rc1 (#12965) 2023-11-06 15:36:43 -08:00
Bagatur
3bb8030a6e fix max_tokens (#12964) 2023-11-06 15:36:05 -08:00
Bagatur
a9002a82b8 bump 331rc0 (#12963) 2023-11-06 15:19:33 -08:00
Harrison Chase
c27400efeb Support multimodal messages (#11320)
Co-authored-by: Bagatur <baskaryan@gmail.com>
2023-11-06 15:14:18 -08:00
Bagatur
388f248391 add oai v1 cookbook (#12961) 2023-11-06 14:28:32 -08:00
Bagatur
4f7dff9d66 Record system fingerprint chat openai (#12960) 2023-11-06 14:25:53 -08:00
Bagatur
8e0cb2eb84 ChatOpenAI and AzureChatOpenAI openai>=1 compatible (#12948) 2023-11-06 13:24:18 -08:00
Kacper Łukawski
52d0055a91 Add support of Cohere Embed v3 (#12940)
Cohere released the new embedding API (Embed v3:
https://txt.cohere.com/introducing-embed-v3/) that treats document and
query embeddings differently. This PR updated the `CohereEmbeddings` to
use them appropriately. It also works with the old models.
2023-11-06 15:06:58 -05:00
Praveen Venkateswaran
8e0dcb37d2 Add SecretStr for Symbl.ai Nebula API (#12896)
Description: This PR masks API key secrets for the Nebula model from
Symbl.ai
Issue: #12165 
Maintainer: @eyurtsev

---------

Co-authored-by: Praveen Venkateswaran <praveen.venkateswaran@ibm.com>
2023-11-06 14:13:59 -05:00
Vinzenz Klass
59d0bd2150 feat: acquire advisory lock before creating extension in pgvector (#12935)
- **Description:** Acquire advisory lock before attempting to create
extension on postgres server, preventing errors in concurrent
executions.
  - **Issue:** #12933
  - **Dependencies:** None

---------

Co-authored-by: Eugene Yurtsev <eyurtsev@gmail.com>
2023-11-06 14:00:39 -05:00
Eugene Yurtsev
b376854b26 Fix for anyscale chat model api key (#12938)
* ChatAnyscale was missing coercion to SecretStr for anyscale api key
* The model inherits from ChatOpenAI so it should not force the openai
api key to be secret str until openai model has the same changes

https://github.com/langchain-ai/langchain/issues/12841
2023-11-06 13:28:02 -05:00
Bagatur
58889149c2 fix guides link (#12941) 2023-11-06 08:13:02 -08:00
matthieudelaro
52503a367f Remove useless line of code from sql.ipynb (#12906)
This PR remove a single line of code from a notebook of the
documentation. This line used to define a variable, which is never used
in the code.
For further context, for reviewers, here is the online documentation:
https://python.langchain.com/docs/use_cases/qa_structured/sql#case-3-sql-agents
2023-11-06 07:59:12 -08:00
hmasdev
622bf12c2e fix regex pattern of structured output parser (#12929)
- **Description:** fix the regex pattern of
[StructuredChatOutputParser](https://github.com/langchain-ai/langchain/blob/master/libs/langchain/langchain/agents/structured_chat/output_parser.py#L18)
and add unit tests for the code change.
- **Issue:** #12158 #12922
- **Dependencies:** None
- **Tag maintainer:** 
- **Twitter handle:** @hmdev3
- **NOTE:** This PR conflicts #7495 . After #7495 is merged, I am going
to update PR.
2023-11-06 07:53:14 -08:00
wemysschen
8c02f4fbd8 add baidu cloud vectorsearch document (#12928)
**Description:** 
Add BaiduCloud VectorSearch document with implement of BESVectorSearch
in langchain vectorstores

---------

Co-authored-by: wemysschen <root@icoding-cwx.bcc-szzj.baidu.com>
2023-11-06 07:52:50 -08:00
wemysschen
8d7144e6a6 fix baiducloud directory loader import file loader (#12924)
**Issue:** 
fix baiducloud BOS directory loader imports its file loader

---------

Co-authored-by: wemysschen <root@icoding-cwx.bcc-szzj.baidu.com>
2023-11-06 07:52:31 -08:00
Alex Howard
5bb2ea51a5 docs: clean up vestigial markdown (#12907)
- **Description:** Remove text "LangChain currently does not support"
which appears to be vestigial leftovers from a previous change.
  - **Issue:** N/A
  - **Dependencies:** N/A
  - **Tag maintainer:** @baskaryan, @eyurtsev
  - **Twitter handle:** thezanke
2023-11-06 07:51:56 -08:00
Praveen Venkateswaran
1eb7d3a862 docs: update hf pipeline docs (#12908)
- **Description:** Noticed that the Hugging Face Pipeline documentation
was a bit out of date.
Updated with information about passing in a pipeline directly
(consistent with docstring) and a recent contribution of mine on adding
support for multi-gpu specifications with Accelerate in
21eeba075c
2023-11-06 07:51:31 -08:00
Christoffer Bo Petersen
37da6e546b Fix typo in e2b_data_analysis.ipynb (#12930)
Just a small typo fix
2023-11-06 07:37:30 -08:00
Kacper Łukawski
621419f71e Fix normalizing the cosine distance in Qdrant (#12934)
Qdrant was incorrectly calculating the cosine similarity and returning
`0.0` for the best match, instead of `1.0`. Internally Qdrant returns a
cosine score from `-1.0` (worst match) to `1.0` (best match), and the
current formula reflects it.
2023-11-06 07:36:59 -08:00
Hech
8fe6bcc662 Fix return metadata when searching for DingoDB (#12937) 2023-11-06 07:35:36 -08:00
Jakub Novák
ada3d2cbd1 Add possibility to pass on_artifacts for a specific conversation (#12687)
Possibility to pass on_artifacts to a conversation. It can be then
achieved by adding this way:

```python
result = agent.run(
    input=message.text,
    metadata={
        "on_artifact": CALLBACK_FUNCTION
    },
)
```
2023-11-06 07:29:47 -08:00
Bagatur
0378662e1d fix langsmith link (#12939) 2023-11-06 07:17:05 -08:00
Harrison Chase
1a92d2245d Harrison/docs smith serve (#12898)
Co-authored-by: Bagatur <baskaryan@gmail.com>
2023-11-06 07:07:25 -08:00
Bagatur
53f453f01a bump 331 (#12932) 2023-11-06 05:58:12 -08:00
Priyadutt
a4d9e986fb Update csv.ipynb description (#12878)
The line removed is not required as there are no other alternative
solutions above than that.

<!-- Thank you for contributing to LangChain!

Replace this entire comment with:
  - **Description:** a description of the change, 
  - **Issue:** the issue # it fixes (if applicable),
  - **Dependencies:** any dependencies required for this change,
- **Tag maintainer:** for a quicker response, tag the relevant
maintainer (see below),
- **Twitter handle:** we announce bigger features on Twitter. If your PR
gets announced, and you'd like a mention, we'll gladly shout you out!

Please make sure your PR is passing linting and testing before
submitting. Run `make format`, `make lint` and `make test` to check this
locally.

See contribution guidelines for more information on how to write/run
tests, lint, etc:

https://github.com/langchain-ai/langchain/blob/master/.github/CONTRIBUTING.md

If you're adding a new integration, please include:
1. a test for the integration, preferably unit tests that do not rely on
network access,
2. an example notebook showing its use. It lives in `docs/extras`
directory.

If no one reviews your PR within a few days, please @-mention one of
@baskaryan, @eyurtsev, @hwchase17.
 -->
2023-11-06 03:32:04 -08:00
Erick Friis
5000c7308e cli template gitignores (#12914)
- ap gitignore
- package
2023-11-05 22:34:45 -08:00
Harrison Chase
aba407f774 use keys not items (#12918) 2023-11-05 22:08:29 -08:00
Harrison Chase
60d025b83b mongo parent document retrieval (#12887) 2023-11-04 10:16:02 -07:00
Michael Hunger
e43b4079c8 template: use dashes instead of underscores for neo4j-cypher package and path in readme (#12827)
Minimal readme template update

underscores didn't work, dashes do
2023-11-03 15:54:48 -07:00
wemysschen
e14aa37d59 fix bes vector store search (#12828)
**Issue:** 
fix search body in baidu cloud vectorsearch

---------

Co-authored-by: wemysschen <root@icoding-cwx.bcc-szzj.baidu.com>
2023-11-03 15:39:19 -07:00
standby24x7
f04e4df7f9 coockbook: Fix typo in wikibase_agent.ipynb (#12839)
This patch fixes a spelling typo in message
within wikibase_agent.ipynb.

Signed-off-by: Masanari Iida <standby24x7@gmail.com>

Signed-off-by: Masanari Iida <standby24x7@gmail.com>
2023-11-03 14:57:37 -07:00
Kacper Łukawski
66c41c0dbf Add template for self-query-qdrant (#12795)
This PR adds a self-querying template using Qdrant as a vector store.
The template uses an artificial dataset and was implemented in a way
that simplifies passing different components and choosing LLM and
embedding providers.

---------

Co-authored-by: Erick Friis <erick@langchain.dev>
2023-11-03 13:37:29 -07:00
Daniel Chalef
f41f4c5e37 zep/rag conversation zep template (#12762)
LangServe template for a RAG Conversation App using Zep.

 @baskaryan, @eyurtsev

---------

Co-authored-by: Erick Friis <erick@langchain.dev>
2023-11-03 13:34:44 -07:00
Lance Martin
ea1ab391d4 Open Clip multimodal embeddings (#12754) 2023-11-03 13:33:36 -07:00
Bagatur
ebee616822 bump 330 (#12853) 2023-11-03 13:26:41 -07:00
Tomaz Bratanic
0dbdb8498a Neo4j Advanced RAG template (#12794)
Todo:

- [x] Docs
2023-11-03 13:22:55 -07:00
Harrison Chase
83cee2cec4 Template Readmes and Standardization (#12819)
Co-authored-by: Erick Friis <erick@langchain.dev>
2023-11-03 13:15:29 -07:00
Erick Friis
6c237716c4 Update readmes with new cli install (#12847)
Old command still works. Just simplifying.

Merge after releasing CLI 0.0.15
2023-11-03 12:10:32 -07:00
Erick Friis
7db49d3842 Confirm sys.path includes current dir for app serve (#12851)
- Make sure sys.path is set properly for langchain app serve
- bump
2023-11-03 11:37:20 -07:00
Erick Friis
1bc35f61cb CLI 0.0.14, Uvicorn update and no more [serve] (#12845)
Calls uvicorn directly from cli:
Reload works if you define app by import string instead of object.
(was doing subprocess in order to get reloading)

Version bump to 0.0.14

Remove the need for [serve] for simplicity.

Readmes are updated in #12847 to avoid cluttering this PR
2023-11-03 11:05:52 -07:00
Brace Sproul
76bcac5bb3 Remove admin prefix/suffix from docs for anthropic (#12849) 2023-11-03 10:54:16 -07:00
Harrison Chase
523e5803bb update mongo template (#12838) 2023-11-03 10:31:53 -07:00
William FH
18005c6384 Disable trace_on_chain_group auto-tracing (#12807)
Previously we treated trace_on_chain_group as a command to always start
tracing. This is unintuitive (makes the function do 2 things), and makes
it harder to toggle tracing
2023-11-03 10:05:09 -07:00
Erick Friis
0da75b9ebd Autopopulate module name in cli init (#12814) 2023-11-02 23:45:38 -07:00
William FH
98aff29fbd Add Dataset Page to printout (#12816) 2023-11-02 20:36:56 -07:00
Joseph Martinez
f573a4d0b3 Update quickstart.mdx (#12386)
**Description**
Removed confusing sentence. 
Not clear what "both" was referring to. The two required components
mentioned previously? The two methods listed below?

---------

Co-authored-by: Erick Friis <erick@langchain.dev>
2023-11-02 18:38:21 -07:00
Leonid Ganeline
e112b2f2e6 updated integrations/providers/google (#12226)
Added missed integrations. Updated formats.

---------

Co-authored-by: Erick Friis <erick@langchain.dev>
2023-11-02 18:35:31 -07:00
Manuel Rech
2e2b9c76d9 Keep also original query - multi_query.py (#12696)
When you use a MultiQuery it might be useful to use the original query
as well as the newly generated ones to maximise the changes to retriever
the correct document. I haven't created an issue, it seems a very small
and easy thing.

---------

Co-authored-by: Bagatur <baskaryan@gmail.com>
2023-11-02 18:15:02 -07:00
Michael Landis
4fe9bf70b6 feat: add a rag template for momento vector index (#12757)
# Description
Add a RAG template showcasing Momento Vector Index as a vector store.
Includes a project directory and README.

# **Twitter handle** 

Tag the company @momentohq for a mention and @mlonml for the
contribution.
2023-11-02 17:59:15 -07:00
刘 方瑞
26c4ec1eaf myscale notebook url change (#12810)
<!-- Thank you for contributing to LangChain!

Replace this entire comment with:
  - **Description:** a description of the change, 
  - **Issue:** the issue # it fixes (if applicable),
  - **Dependencies:** any dependencies required for this change,
- **Tag maintainer:** for a quicker response, tag the relevant
maintainer (see below),
- **Twitter handle:** we announce bigger features on Twitter. If your PR
gets announced, and you'd like a mention, we'll gladly shout you out!

Please make sure your PR is passing linting and testing before
submitting. Run `make format`, `make lint` and `make test` to check this
locally.

See contribution guidelines for more information on how to write/run
tests, lint, etc:

https://github.com/langchain-ai/langchain/blob/master/.github/CONTRIBUTING.md

If you're adding a new integration, please include:
1. a test for the integration, preferably unit tests that do not rely on
network access,
2. an example notebook showing its use. It lives in `docs/extras`
directory.

If no one reviews your PR within a few days, please @-mention one of
@baskaryan, @eyurtsev, @hwchase17.
 -->
2023-11-02 17:56:26 -07:00
Lance Martin
2683c2fc53 Update template index (#12809) 2023-11-02 17:51:40 -07:00
apeng-singlestore
5c0e9ac578 Add template for rag-singlestoredb (#12805)
This change adds a new template for simple RAG using the SingleStoreDB
vectorstore.

Twitter: @alexjpeng

---------

Co-authored-by: Erick Friis <erick@langchain.dev>
2023-11-02 17:51:00 -07:00
Bagatur
658a3a8607 FEAT: Merge TileDB vecstore (#12811) 2023-11-02 17:40:32 -07:00
Akio Nishimura
c04647bb4e Correct number of elements in config list in batch() and abatch() of BaseLLM (#12713)
- **Description:** Correct number of elements in config list in
`batch()` and `abatch()` of `BaseLLM` in case `max_concurrency` is not
None.
- **Issue:** #12643
- **Twitter handle:** @akionux

---------

Co-authored-by: Bagatur <baskaryan@gmail.com>
2023-11-02 17:28:48 -07:00
James Braza
88b506b321 Adds missing urllib.parse for IDE warning of PubMedAPIWrapper (#12808)
Resolves an IDE (PyCharm 2023.2.3 PE) warning around
`urllib.parse.quote`, also enabling CTRL-click
2023-11-02 17:27:25 -07:00
Bagatur
a2bb0dd445 TileDB update import unit tests 2023-11-02 17:24:22 -07:00
Nikos Papailiou
2fdaa1e5fd Add TileDB vectorstore implementation (#12624)
- **Description:** Add [TileDB](https://tiledb.com) vectorstore
implementation. TileDB offers ANN search capabilities using the
[TileDB-Vector-Search](https://github.com/TileDB-Inc/TileDB-Vector-Search)
module. It provides serverless execution of ANN queries and storage of
vector indexes both on local disk and cloud object stores (i.e. AWS S3).
More details in:
- [Why TileDB as a Vector
Database](https://tiledb.com/blog/why-tiledb-as-a-vector-database)
- [TileDB 101: Vector
Search](https://tiledb.com/blog/tiledb-101-vector-search)
- **Twitter handle:** @tiledb
2023-11-02 17:21:03 -07:00
盐粒 Yanli
1b233798a0 feat: Supprt pgvecto.rs as a VectorStore (#12718)
Supprt [pgvecto.rs](https://github.com/tensorchord/pgvecto.rs) as a new
VectorStore type.

This introduces a new dependency
[pgvecto_rs](https://pypi.org/project/pgvecto_rs/) and upgrade
SQLAlchemy to ^2.

Relate to https://github.com/tensorchord/pgvecto.rs/issues/11

---------

Co-authored-by: Bagatur <baskaryan@gmail.com>
2023-11-02 17:16:04 -07:00
Daniel Chalef
0cbdba6a9b zep: VectorStore: Use Native MMR (#12690)
- refactor to use Zep's native MMR; update example
- 
@baskaryan @eyurtsev
2023-11-02 16:45:42 -07:00
Daniel Chalef
cc3d3920e3 Zep: Summary Search and Example (#12686)
Zep now has the ability to search over chat history summaries. This PR
adds support for doing so. More here: https://blog.getzep.com/zep-v0-17/

@baskaryan @eyurtsev
2023-11-02 16:31:11 -07:00
Bagatur
526313002c add import tests to all modules (#12806) 2023-11-02 15:32:55 -07:00
Harrison Chase
6609a6033f fix vectorstore imports (#12804)
Co-authored-by: Bagatur <baskaryan@gmail.com>
2023-11-02 15:32:31 -07:00
Nuno Campos
f66a9d2adf Automatically add configurable key to config_schema if config_specs i… (#12798)
…s present

<!-- Thank you for contributing to LangChain!

Replace this entire comment with:
  - **Description:** a description of the change, 
  - **Issue:** the issue # it fixes (if applicable),
  - **Dependencies:** any dependencies required for this change,
- **Tag maintainer:** for a quicker response, tag the relevant
maintainer (see below),
- **Twitter handle:** we announce bigger features on Twitter. If your PR
gets announced, and you'd like a mention, we'll gladly shout you out!

Please make sure your PR is passing linting and testing before
submitting. Run `make format`, `make lint` and `make test` to check this
locally.

See contribution guidelines for more information on how to write/run
tests, lint, etc:

https://github.com/langchain-ai/langchain/blob/master/.github/CONTRIBUTING.md

If you're adding a new integration, please include:
1. a test for the integration, preferably unit tests that do not rely on
network access,
2. an example notebook showing its use. It lives in `docs/extras`
directory.

If no one reviews your PR within a few days, please @-mention one of
@baskaryan, @eyurtsev, @hwchase17.
 -->
2023-11-02 21:46:15 +00:00
Praveen Venkateswaran
21eeba075c enable the device_map parameter in huggingface pipeline (#12731)
### Enabling `device_map` in HuggingFacePipeline 

For multi-gpu settings with large models, the
[accelerate](https://huggingface.co/docs/accelerate/usage_guides/big_modeling#using--accelerate)
library provides the `device_map` parameter to automatically distribute
the model across GPUs / disk.

The [Transformers
pipeline](3520e37e86/src/transformers/pipelines/__init__.py (L543))
enables users to specify `device` (or) `device_map`, and handles cases
(with warnings) when both are specified.

However, Langchain's HuggingFacePipeline only supports specifying
`device` when calling transformers which limits large models and
multi-gpu use-cases.
Additionally, the [default
value](8bd3ce59cd/libs/langchain/langchain/llms/huggingface_pipeline.py (L72))
of `device` is initialized to `-1` , which is incompatible with the
transformers pipeline when `device_map` is specified.

This PR addresses the addition of `device_map` as a parameter , and
solves the incompatibility of `device = -1` when `device_map` is also
specified.
An additional test has been added for this feature. 

Additionally, some existing tests no longer work since 
1. `max_new_tokens` has to be specified under `pipeline_kwargs` and not
`model_kwargs`
2. The GPT2 tokenizer raises a `ValueError: Pipeline with tokenizer
without pad_token cannot do batching`, since the `tokenizer.pad_token`
is `None` ([related
issue](https://github.com/huggingface/transformers/issues/19853) on the
transformers repo).

This PR handles fixing these tests as well.

Co-authored-by: Praveen Venkateswaran <praveen.venkateswaran@ibm.com>
2023-11-02 14:29:06 -07:00
Mark Bell
3276aa3e17 __getattr__ should rase AttributeError not ImportError on missing attributes (#12801)
[The python
spec](https://docs.python.org/3/reference/datamodel.html#object.__getattr__)
requires that `__getattr__` throw `AttributeError` for missing
attributes but there are several places throwing `ImportError` in the
current code base. This causes a specific problem with `hasattr` since
it calls `__getattr__` then looks only for `AttributeError` exceptions.
At present, calling `hasattr` on any of these modules will raise an
unexpected exception that most code will not handle as `hasattr`
throwing exceptions is not expected.

In our case this is triggered by an exception tracker (Airbrake) that
attempts to collect the version of all installed modules with code that
looks like: `if hasattr(mod, "__version__"):`. With `HEAD` this is
causing our exception tracker to fail on all exceptions.

I only changed instances of unknown attributes raising `ImportError` and
left instances of known attributes raising `ImportError`. It feels a
little weird but doesn't seem to break anything.
2023-11-02 17:08:54 -04:00
Daniel Chalef
d966e4d13a zep: Update Zep docs and messaging (#12764)
Update Zep documentation with messaging, more details.

 @baskaryan, @eyurtsev
2023-11-02 13:39:17 -07:00
Illia
71d1a48b66 Use data from all Google search results in SerpApi.com wrapper (#12770)
- **Description:** Use all Google search results data in SerpApi.com
wrapper instead of the first one only
  - **Tag maintainer:** @hwchase17 

_P.S. `libs/langchain/tests/integration_tests/utilities/test_serpapi.py`
are not executed during the `make test`._
2023-11-02 13:31:27 -07:00
ba230t
9214d8e6ed Fixed a typo in templates/docs/CONTRIBUTING.md (delimeters =>delimiters) (#12774)
- **Description:** Just fixed a minor typo in
templates/docs/CONTRIBUTING.md.
  - **Issue:** No linked issues.

Very small contribution!
2023-11-02 13:31:04 -07:00
Armin Stepanjan
185ddc573e Fix broken links to use cases (#12777)
This PR replaces broken links to end to end usecases
([/docs/use_cases](https://python.langchain.com/docs/use_cases)) with a
non-broken version
([/docs/use_cases/qa_structured/sql](https://python.langchain.com/docs/use_cases/qa_structured/sql)),
consistently with the "Use cases" navigation button at the top of the
page.

---------

Co-authored-by: Matvey Arye <mat@timescale.com>
Co-authored-by: Erick Friis <erick@langchain.dev>
2023-11-02 13:20:54 -07:00
니콜라스
25ee10ed4f Docs: 'memory' -> 'history' typo. (#12779)
The 'MessagesPlaceholder' expects 'history' but 'RunnablePassthrough' is
assigning 'memory'.
2023-11-02 13:09:39 -07:00
yudai yamamoto
1f7e811156 Fixed broken link in Quickstart page (#12516)
- **Description:** 
Corrected a specific link within the documentation.
  
  - **Issue:**
  #12490 

  - **Dependencies:**
  - **Tag maintainer:**
  - **Twitter handle:**

---------

Co-authored-by: Erick Friis <erick@langchain.dev>
2023-11-02 13:00:53 -07:00
Ikko Eltociear Ashimine
9b02f7d59c Update llamacpp.ipynb (#12791)
HuggingFace -> Hugging Face
2023-11-02 12:52:12 -07:00
Tomaz Bratanic
2a9f40ed28 Add input types to cypher templates (#12800) 2023-11-02 12:46:02 -07:00
Nuno Campos
c4fdf78d03 Fix AddableDict raising exception when used with non-addable values (#12785)
<!-- Thank you for contributing to LangChain!

Replace this entire comment with:
  - **Description:** a description of the change, 
  - **Issue:** the issue # it fixes (if applicable),
  - **Dependencies:** any dependencies required for this change,
- **Tag maintainer:** for a quicker response, tag the relevant
maintainer (see below),
- **Twitter handle:** we announce bigger features on Twitter. If your PR
gets announced, and you'd like a mention, we'll gladly shout you out!

Please make sure your PR is passing linting and testing before
submitting. Run `make format`, `make lint` and `make test` to check this
locally.

See contribution guidelines for more information on how to write/run
tests, lint, etc:

https://github.com/langchain-ai/langchain/blob/master/.github/CONTRIBUTING.md

If you're adding a new integration, please include:
1. a test for the integration, preferably unit tests that do not rely on
network access,
2. an example notebook showing its use. It lives in `docs/extras`
directory.

If no one reviews your PR within a few days, please @-mention one of
@baskaryan, @eyurtsev, @hwchase17.
 -->
2023-11-02 18:56:29 +00:00
Erick Friis
49e283a0cd CLI 0.0.13, Configurable Template Demo (#12796) 2023-11-02 11:42:57 -07:00
Nuno Campos
d1c6ad7769 Fix on_llm_new_token(chunk=) for some chat models (#12784)
It was passing in message instead of generation

<!-- Thank you for contributing to LangChain!

Replace this entire comment with:
  - **Description:** a description of the change, 
  - **Issue:** the issue # it fixes (if applicable),
  - **Dependencies:** any dependencies required for this change,
- **Tag maintainer:** for a quicker response, tag the relevant
maintainer (see below),
- **Twitter handle:** we announce bigger features on Twitter. If your PR
gets announced, and you'd like a mention, we'll gladly shout you out!

Please make sure your PR is passing linting and testing before
submitting. Run `make format`, `make lint` and `make test` to check this
locally.

See contribution guidelines for more information on how to write/run
tests, lint, etc:

https://github.com/langchain-ai/langchain/blob/master/.github/CONTRIBUTING.md

If you're adding a new integration, please include:
1. a test for the integration, preferably unit tests that do not rely on
network access,
2. an example notebook showing its use. It lives in `docs/extras`
directory.

If no one reviews your PR within a few days, please @-mention one of
@baskaryan, @eyurtsev, @hwchase17.
 -->
2023-11-02 16:33:44 +00:00
Erick Friis
070823f294 CLI 0.0.12 (#12787) 2023-11-02 08:29:27 -07:00
Bagatur
979501c0ca bump 329 (#12778) 2023-11-02 06:02:43 -07:00
Matvey Arye
9369d6aca0 Fixes to the docs for timescale vector template (#12756) 2023-11-01 18:48:23 -07:00
Lance Martin
33810126bd Update chat prompt structure in LLaMA SQL cookbook (#12364)
Co-authored-by: Erick Friis <erick@langchain.dev>
2023-11-01 16:37:03 -07:00
ElliotKetchup
58b90f30b0 Update llama.cpp integration (#11864)
<!-- 
- **Description:** removed redondant link, replaced it with Meta's LLaMA
repo, add resources for models' hardware requirements,
  - **Issue:** None,
  - **Dependencies:** None,
  - **Tag maintainer:** None,
  - **Twitter handle:** @ElliotAlladaye
 -->
2023-11-01 16:32:02 -07:00
Manuel Soria
a228f340f1 Semantic search within postgreSQL using pgvector (#12365)
Cookbook showing how to incoporate RAG search within a postgreSQL
database using pgvector.

---------

Co-authored-by: Lance Martin <lance@langchain.dev>
Co-authored-by: Bagatur <baskaryan@gmail.com>
Co-authored-by: Erick Friis <erick@langchain.dev>
2023-11-01 16:21:34 -07:00
Erick Friis
da821320d3 Fixes 'Nonetype' not iterable for ObsidianLoader (#12751)
Implements #12726 from @Di3mex
2023-11-01 16:07:09 -07:00
Juan Bustos
67b6f4dc71 Update google_vertex_ai_palm.ipynb (#12715)
Fixed a typo

<!-- Thank you for contributing to LangChain!

Replace this entire comment with:
  - **Description:** Fixed a typo on the code
  - **Issue:** the issue # it fixes (if applicable),


Please make sure your PR is passing linting and testing before
submitting. Run `make format`, `make lint` and `make test` to check this
locally.

See contribution guidelines for more information on how to write/run
tests, lint, etc:

https://github.com/langchain-ai/langchain/blob/master/.github/CONTRIBUTING.md

If you're adding a new integration, please include:
1. a test for the integration, preferably unit tests that do not rely on
network access,
2. an example notebook showing its use. It lives in `docs/extras`
directory.

If no one reviews your PR within a few days, please @-mention one of
@baskaryan, @eyurtsev, @hwchase17.
 -->
2023-11-01 16:05:44 -07:00
Eugene Yurtsev
b1caae62fd APIChain add restrictions to domains (CVE-2023-32786) (#12747)
* Restrict the chain to specific domains by default
* This is a breaking change, but it will fail loudly upon object
instantiation -- so there should be no silent errors for users
* Resolves CVE-2023-32786
2023-11-01 18:50:34 -04:00
Erick Friis
4421ba46d7 Demo Server, Fix Timescale (#12746)
- improve demo server
- missing deps
2023-11-01 15:29:34 -07:00
Eugene Yurtsev
0e1aedb9f4 Use jinja2 sandboxing by default (#12733)
* This is an opt-in feature, so users should be aware of risks if using
jinja2.
* Regardless we'll add sandboxing by default to jinja2 templates -- this
  sandboxing is a best effort basis.
* Best strategy is still to make sure that jinja2 templates are only
loaded from trusted sources.
2023-11-01 14:54:01 -07:00
Erick Friis
ab5309f6f2 template updates (#12736)
- langchain license
- add timescale vector dep to that template
2023-11-01 13:53:26 -07:00
Lance Martin
6406c53089 Update template index w/ Timescale (#12729) 2023-11-01 12:04:54 -07:00
Erick Friis
14340ee7cd use http.client instead of urllib3 (#12660)
dep problems with requests

cloudflare debugging not worth it with urllib
2023-11-01 11:15:05 -07:00
Bagatur
eee5181b7a bump 328, exp 37 (#12722) 2023-11-01 10:27:39 -07:00
Erick Friis
3405dbbc64 dash not underscore (#12716)
template names are auto-populating with the wrong convention (with
underscores)
2023-11-01 09:48:37 -07:00
123-fake-st
8bd3ce59cd PyPDFLoader use url in metadata source if file is a web path (#12092)
**Description:** Update `langchain.document_loaders.pdf.PyPDFLoader` to
store url in metadata (instead of a temporary file path) if user
provides a web path to a pdf

- **Issue:** Related to #7034; the reporter on that issue submitted a PR
updating `PyMuPDFParser` for this behavior, but it has unresolved merge
issues as of 20 Oct 2023 #7077
- In addition to `PyPDFLoader` and `PyMuPDFParser`, these other classes
in `langchain.document_loaders.pdf` exhibit similar behavior and could
benefit from an update: `PyPDFium2Loader`, `PDFMinerLoader`,
`PDFMinerPDFasHTMLLoader`, `PDFPlumberLoader` (I'm happy to contribute
to some/all of that, including assisting with `PyMuPDFParser`, if my
work is agreeable)
- The root cause is that the underlying pdf parser classes, e.g.
`langchain.document_loaders.parsers.pdf.PyPDFParser`, never receive
information about the url; the parsers receive a
`langchain.document_loaders.blob_loaders.blob`, which contains the pdf
contents and local file path, but not the url
- This update passes the web path directly to the parser since it's
minimally invasive and doesn't require further changes to maintain
existing behavior for local files... bigger picture, I'd consider
extending `blob` so that extra information like this can be
communicated, but that has much bigger implications on the codebase
which I think warrants maintainer input

  - **Dependencies:** None

```python
# old behavior
>>> from langchain.document_loaders import PyPDFLoader
>>> loader = PyPDFLoader('https://arxiv.org/pdf/1706.03762.pdf')
>>> docs = loader.load()
>>> docs[0].metadata
{'source': '/var/folders/w2/zx77z1cs01s1thx5dhshkd58h3jtrv/T/tmpfgrorsi5/tmp.pdf', 'page': 0}

# new behavior
>>> from langchain.document_loaders import PyPDFLoader
>>> loader = PyPDFLoader('https://arxiv.org/pdf/1706.03762.pdf')
>>> docs = loader.load()
>>> docs[0].metadata
{'source': 'https://arxiv.org/pdf/1706.03762.pdf', 'page': 0}
```
2023-11-01 11:27:00 -04:00
Dave Kwon
b1954aab13 feat: Add page metadata on PDFMinerLoader (#12277)
- **Description:** #12273 's suggestion PR
Like other PDFLoader, loading pdf per each page and giving page
metadata.
  - **Issue:** #12273 
  - **Twitter handle:** @blue0_0hope

---------

Co-authored-by: Eugene Yurtsev <eyurtsev@gmail.com>
2023-11-01 11:25:37 -04:00
Duda Nogueira
7148f3e1fe Weaviate - Fix schema existence check (#12711)
This will allow you create the schema beforehand. The check was failing
and preventing importing into existing classes.

<!-- Thank you for contributing to LangChain!

Replace this entire comment with:
  - **Description:** a description of the change, 
  - **Issue:** the issue # it fixes (if applicable),
  - **Dependencies:** any dependencies required for this change,
- **Tag maintainer:** for a quicker response, tag the relevant
maintainer (see below),
- **Twitter handle:** we announce bigger features on Twitter. If your PR
gets announced, and you'd like a mention, we'll gladly shout you out!

Please make sure your PR is passing linting and testing before
submitting. Run `make format`, `make lint` and `make test` to check this
locally.

See contribution guidelines for more information on how to write/run
tests, lint, etc:

https://github.com/langchain-ai/langchain/blob/master/.github/CONTRIBUTING.md

If you're adding a new integration, please include:
1. a test for the integration, preferably unit tests that do not rely on
network access,
2. an example notebook showing its use. It lives in `docs/extras`
directory.

If no one reviews your PR within a few days, please @-mention one of
@baskaryan, @eyurtsev, @hwchase17.
 -->
2023-11-01 08:22:15 -07:00
Sayandip
8dbbcf0b6c Adding a template for Solo Performance Prompting Agent (#12627)
**Description:** This template creates an agent that transforms a single
LLM into a cognitive synergist by engaging in multi-turn
self-collaboration with multiple personas.
**Tag maintainer:** @hwchase17

---------

Co-authored-by: Sayandip Sarkar <sayandip.sarkar@skypointcloud.com>
Co-authored-by: Erick Friis <erick@langchain.dev>
2023-11-01 08:10:07 -07:00
Aidos Kanapyanov
ae63c186af Mask API key for Anyscale LLM (#12406)
Description: Add masking of API Key for Anyscale LLM when printed.
Issue: #12165 
Dependencies: None
Tag maintainer: @eyurtsev

---------

Co-authored-by: Bagatur <baskaryan@gmail.com>
Co-authored-by: Eugene Yurtsev <eyurtsev@gmail.com>
2023-11-01 10:22:26 -04:00
Predrag Gruevski
5ae51a8a85 Fix typo highlighted by ruff autoformatter. (#12691)
H/t @MichaReiser for spotting it:
https://github.com/langchain-ai/langchain/pull/12585/files#r1378253045
2023-10-31 22:16:06 -04:00
Predrag Gruevski
724b92231d Remove black caching config from CI lint workflow. (#12594)
To merge after #12585 is merged.
2023-10-31 21:39:05 -04:00
Predrag Gruevski
0ea837404a Only publish to test PyPI from the _test_release.yml workflow. (#12668)
PyPI trusted publishing wants to know which workflow is expected to do
the publish. We always want to publish from the same workflow, so we're
making `_test_release.yml` the only workflow that publishes to Test
PyPI.
2023-10-31 21:36:38 -04:00
Predrag Gruevski
321cd44f13 Use separate jobs for building and publishing test releases. (#12671)
This follows the principle of least privilege. Our `poetry build` step
doesn't need, and shouldn't get, access to our GitHub OIDC capability.

This is the same structure as I used in the already-merged PR for
refactoring the regular PyPI release workflow: #12578.
2023-10-31 21:36:26 -04:00
Erick Friis
44c8b159b9 properly increment version in cli (#12685)
Went from 0.0.9 -> 0.0.11 without releasing. Back to 10, then release.
2023-10-31 17:27:43 -07:00
Erick Friis
b825dddf95 fix elastic rag template in playground (#12682)
- a few instructions in the readme (load_documents -> ingest.py)
- added docker run command for local elastic
- adds input type definition to render playground properly
2023-10-31 17:18:35 -07:00
Lance Martin
f0eba1ac63 Add RAG input types (#12684)
Co-authored-by: Erick Friis <erick@langchain.dev>
2023-10-31 17:13:44 -07:00
Erick Friis
392cfbee24 link to templates (#12680) 2023-10-31 16:19:22 -07:00
Leonid Ganeline
ddcec005bc fix for YahooFinanceNewsTool (#12665)
Added YahooFinanceNewsTool to the __init__.py 
It was missed here.
2023-10-31 14:58:09 -07:00
Predrag Gruevski
09711ad5a1 Both lint and format templates with ruff v0.1.3. (#12676)
- Both lint and format code in `templates`.
- Upgrade to ruff v0.1.3.
2023-10-31 14:52:00 -07:00
Predrag Gruevski
01a3c9b94e Use an in-project virtualenv in the CLI package. (#12678)
Keeping it in sync with how our other packages are configured.
2023-10-31 14:51:24 -07:00
Predrag Gruevski
f7f35a9102 Use black to lint notebooks and docs for now. (#12679)
Due to #12677 having lots of errors for the time being.
2023-10-31 14:51:05 -07:00
Jacob Lee
bd668fcea1 Adds version CLI command (#12619)
Will be automatically bumped with `poetry version patch`.

@efriis @hwchase17

---------

Co-authored-by: Erick Friis <erick@langchain.dev>
2023-10-31 14:50:04 -07:00
Frank
bf5805bb32 Add quip loader (#12259)
- **Description:** implement [quip](https://quip.com) loader
  - **Issue:** https://github.com/langchain-ai/langchain/issues/10352
  - **Dependencies:** No
  -  pass make format, make lint, make test

---------

Co-authored-by: Hao Fan <h_fan@apple.com>
Co-authored-by: Bagatur <baskaryan@gmail.com>
2023-10-31 14:11:24 -07:00
Roman Vasilyev
c9a6940d58 PGVector fix (#12592)
latest release broken, this fixes it

---------

Co-authored-by: Roman Vasilyev <rvasilyev@mozilla.com>
Co-authored-by: Eugene Yurtsev <eyurtsev@gmail.com>
2023-10-31 17:01:15 -04:00
Lance Martin
9e17d1a225 Update Vertex template (#12644)
Co-authored-by: Erick Friis <erick@langchain.dev>
2023-10-31 14:00:22 -07:00
Predrag Gruevski
aa3f4a9bc8 Remove the CLI package's pydantic compatibility tests. (#12675)
They aren't necessary, since the CLI package doesn't have a direct
dependency on pydantic.
2023-10-31 16:57:38 -04:00
Predrag Gruevski
e8b99364b3 Use ruff for both linting and formatting in langchain-cli. (#12672)
Prior to this PR, `ruff` was used only for linting and not for
formatting, despite the names of the commands. This PR makes it be used
for both linting code and autoformatting it.
2023-10-31 13:52:25 -07:00
Harrison Chase
9a10b2b047 fix plate chain (#12673) 2023-10-31 13:45:09 -07:00
Margaret Qian
acfc485808 Update MosaicML Embedding Input Key (#12657)
This input key was missed in the last update PR:
https://github.com/langchain-ai/langchain/pull/7391

The input/output formats are intended to be like this:

```
{"inputs": [<prompt>]} 

{"outputs": [<output_text>]}
```
2023-10-31 14:43:30 -04:00
Erika Cardenas
d26ac5f999 Update README for Hybrid Search Weaviate (#12661)
- **Description:** Updated the README for Hybrid Search Weaviate
2023-10-31 11:02:34 -07:00
Predrag Gruevski
c871cc5055 Remove print() statements which seemed leftover from debugging. (#12648)
Added in #12159 presumably during debugging. Right now they cause a bit of visual noise.
2023-10-31 13:45:48 -04:00
Erick Friis
2a7e0a27cb update lc version (#12655)
also updated py version in `csv-agent` and `rag-codellama-fireworks`
because they have stricter python requirements
2023-10-31 10:19:15 -07:00
Predrag Gruevski
360cff81a3 Overwrite existing distributions when uploading to test PyPI. (#12658) 2023-10-31 10:02:50 -07:00
Lance Martin
da94c750c5 Add RAG template for Timescale Vector (#12651)
<!-- Thank you for contributing to LangChain!

Replace this entire comment with:
  - **Description:** a description of the change, 
  - **Issue:** the issue # it fixes (if applicable),
  - **Dependencies:** any dependencies required for this change,
- **Tag maintainer:** for a quicker response, tag the relevant
maintainer (see below),
- **Twitter handle:** we announce bigger features on Twitter. If your PR
gets announced, and you'd like a mention, we'll gladly shout you out!

Please make sure your PR is passing linting and testing before
submitting. Run `make format`, `make lint` and `make test` to check this
locally.

See contribution guidelines for more information on how to write/run
tests, lint, etc:

https://github.com/langchain-ai/langchain/blob/master/.github/CONTRIBUTING.md

If you're adding a new integration, please include:
1. a test for the integration, preferably unit tests that do not rely on
network access,
2. an example notebook showing its use. It lives in `docs/extras`
directory.

If no one reviews your PR within a few days, please @-mention one of
@baskaryan, @eyurtsev, @hwchase17.
 -->

---------

Co-authored-by: Matvey Arye <mat@timescale.com>
2023-10-31 09:56:29 -07:00
Noam Gat
14e8c74736 LM Format Enforcer Integration + Sample Notebook (#12625)
## Description

This PR adds support for
[lm-format-enforcer](https://github.com/noamgat/lm-format-enforcer) to
LangChain.

![image](https://raw.githubusercontent.com/noamgat/lm-format-enforcer/main/docs/Intro.webp)

The library is similar to jsonformer / RELLM which are supported in
Langchain, but has several advantages such as
- Batching and Beam search support
- More complete JSON Schema support
- LLM has control over whitespace, improving quality
- Better runtime performance due to only calling the LLM's generate()
function once per generate() call.

The integration is loosely based on the jsonformer integration in terms
of project structure.

## Dependencies

No compile-time dependency was added, but if `lm-format-enforcer` is not
installed, a runtime error will occur if it is trying to be used.

## Tests

Due to the integration modifying the internal parameters of the
underlying huggingface transformer LLM, it is not possible to test
without building a real LM, which requires internet access. So, similar
to the jsonformer and RELLM integrations, the testing is via the
notebook.

## Twitter Handle

[@noamgat](https://twitter.com/noamgat)


Looking forward to hearing feedback!

---------

Co-authored-by: Bagatur <baskaryan@gmail.com>
2023-10-31 09:49:01 -07:00
Stefano Lottini
a4e4b5a86f Relax python version and remove need for explicit setup step (#12637)
This PR addresses what seems like a unnecessary Python version
restriction in the pyroject.toml specs within both Cassandra (/Astra DB)
templates. With "^3.11" I got some version incompatibilities with the
latest "langchain add [...]" commands, so these are now relaxed in line
with the other templates I could inspect.

Incidentally, in the "entomology" template, the need for an explicit
"setup" step for the user to carry on has been removed, replaced by a
check-and-execute-if-necessary instruction on app startup.

Thank you for your attention!
2023-10-31 09:42:27 -07:00
Predrag Gruevski
5308b836c7 Upgrade to actions/checkout@v4 in the docs lint job. (#12581) 2023-10-31 12:41:18 -04:00
Predrag Gruevski
94f018f1ba Support release-testing packages with dashes in their names. (#12654) 2023-10-31 12:40:34 -04:00
Erick Friis
912ace18e9 fix template py verisons (#12650) 2023-10-31 09:20:29 -07:00
Brian McBrayer
b74468f399 Fix small typo on Founcational -> Router notebook (#12634)
- **Description:** Fix small typo on Founcational -> Router notebook
2023-10-31 09:16:29 -07:00
Predrag Gruevski
72fa5a463d Show ruff output inline in GitHub PRs. (#12647) 2023-10-31 12:16:01 -04:00
William FH
17c2e3b87e Rename Template (#12649)
To chatbot feedback. Update import
2023-10-31 09:15:30 -07:00
Erick Friis
7f6e751a3d template updates (#12646) 2023-10-31 09:13:58 -07:00
Leonid Kuligin
a53cac4508 added template to use Vertex Vector Search for q&a (#12622)
added template to use Vertex Vector Search for q&a
2023-10-31 08:49:24 -07:00
Lance Martin
944cb552bb Minor updates to READMEs (#12642) 2023-10-31 08:34:46 -07:00
William FH
88f0f1e73b Conversational Feedback (#12590)
Context in the README.

Show how score chat responses based on a followup from the user and then
log that as feedback in LangSmith
2023-10-31 08:34:17 -07:00
Predrag Gruevski
f94e24dfd7 Install and use ruff format instead of black for code formatting. (#12585)
Best to review one commit at a time, since two of the commits are 100%
autogenerated changes from running `ruff format`:
- Install and use `ruff format` instead of black for code formatting.
- Output of `ruff format .` in the `langchain` package.
- Use `ruff format` in experimental package.
- Format changes in experimental package by `ruff format`.
- Manual formatting fixes to make `ruff .` pass.
2023-10-31 10:53:12 -04:00
William FH
bfd719f9d8 bind_functions convenience method (#12518)
I always take 20-30 seconds to re-discover where the
`convert_to_openai_function` wrapper lives in our codebase. Chat
langchain [has no
clue](https://smith.langchain.com/public/3989d687-18c7-4108-958e-96e88803da86/r)
what to do either. There's the older `create_openai_fn_chain` , but we
haven't been recommending it in LCEL. The example we show in the
[cookbook](https://python.langchain.com/docs/expression_language/how_to/binding#attaching-openai-functions)
is really verbose.


General function calling should be as simple as possible to do, so this
seems a bit more ergonomic to me (feel free to disagree). Another option
would be to directly coerce directly in the class's init (or when
calling invoke), if provided. I'm not 100% set against that. That
approach may be too easy but not simple. This PR feels like a decent
compromise between simple and easy.

```
from enum import Enum
from typing import Optional

from pydantic import BaseModel, Field


class Category(str, Enum):
    """The category of the issue."""

    bug = "bug"
    nit = "nit"
    improvement = "improvement"
    other = "other"


class IssueClassification(BaseModel):
    """Classify an issue."""

    category: Category
    other_description: Optional[str] = Field(
        description="If classified as 'other', the suggested other category"
    )
    

from langchain.chat_models import ChatOpenAI

llm = ChatOpenAI().bind_functions([IssueClassification])
llm.invoke("This PR adds a convenience wrapper to the bind argument")

# AIMessage(content='', additional_kwargs={'function_call': {'name': 'IssueClassification', 'arguments': '{\n  "category": "improvement"\n}'}})
```
2023-10-31 07:15:37 -07:00
Nuno Campos
3143324984 Improve Runnable type inference for input_schemas (#12630)
- Prefer lambda type annotations over inferred dict schema
- For sequences that start with RunnableAssign infer seq input type as
"input type of 2nd item in sequence - output type of runnable assign"
2023-10-31 13:22:54 +00:00
Nuno Campos
2f563cee20 Add Runnable.with_listeners() (#12549)
- This binds start/end/error listeners to a runnable, which will be
called with the Run object
2023-10-31 11:04:51 +00:00
Bagatur
bcc62d63be bump 327 (#12623) 2023-10-31 02:18:08 -07:00
Erick Friis
a1fae1fddd Readme rewrite (#12615)
Co-authored-by: Lance Martin <lance@langchain.dev>
Co-authored-by: Harrison Chase <hw.chase.17@gmail.com>
2023-10-31 00:06:02 -07:00
Ankur Singh
00766c9f31 Improves the description of the installation command (#12354)
- **Description:**

 Before: 
`
To install modules needed for the common LLM providers, run:
`

After:
`
To install modules needed for the common LLM providers, run the
following command. Please bear in mind that this command is exclusively
compatible with the `bash` shell:
`


> This is required for the user so that the user will know if this
command is compatible with `zsh` or not.

---------

Co-authored-by: Bagatur <baskaryan@gmail.com>
2023-10-30 18:56:48 -07:00
Yujie Qian
1dbb77d7db VoyageEmbeddings (#12608)
- **Description:** Integrate VoyageEmbeddings into LangChain, with tests
and docs
  - **Issue:** N/A
  - **Dependencies:** N/A
  - **Tag maintainer:** N/A
  - **Twitter handle:** @Voyage_AI_

---------

Co-authored-by: Bagatur <baskaryan@gmail.com>
2023-10-30 18:37:43 -07:00
chocolate4
92bf40a921 Add a new vector store hippo for langchain #11763 (#12412)
#11763

---------

Co-authored-by: TranswarpHippo <hippo.0.assistant@gmail.com>
Co-authored-by: Bagatur <baskaryan@gmail.com>
2023-10-30 18:35:23 -07:00
Karthik Raja A
342d6c7ab6 Multi on client toolkit (#12392)
Replace this entire comment with:
-Add MultiOn close function and update key value and add async
functionality
- solved the key value TabId not found.. (updated to use latest key
value)
  
@hwchase17
2023-10-30 18:34:56 -07:00
Prabin Nepal
b109cb031b SecretStr for fireworks api (#12475)
- **Description:** This pull request removes secrets present in raw
format,
- **Issue:** Fireworks api key was exposed when printing out the
langchain object
[#12165](https://github.com/langchain-ai/langchain/issues/12165)
 - **Maintainer:** @eyurtsev

---------

Co-authored-by: Bagatur <baskaryan@gmail.com>
2023-10-30 18:17:53 -07:00
Harrison Chase
f35a65124a improve agent templates (#12528)
Co-authored-by: Eugene Yurtsev <eyurtsev@gmail.com>
2023-10-30 18:15:13 -07:00
Harrison Chase
75bb28afd8 Harrison/pii chatbot (#12523)
the pii detection in the template is pretty basic, will need to be
customized per use case

the chain it "protects" can be swapped out for any chain
2023-10-30 18:13:12 -07:00
Harrison Chase
a32c236c64 bump cli to 009 (#12611) 2023-10-30 18:12:08 -07:00
Erika Cardenas
b97b9eda21 Hybrid Search Weaviate Template (#12606)
- **Description:** This template covers hybrid search in Weaviate
  - **Dependencies:** No
  - **Twitter handle:** @ecardenas300

---------

Co-authored-by: Harrison Chase <hw.chase.17@gmail.com>
2023-10-30 18:10:48 -07:00
Martin Schade
0c7f1d8b21 Textract linearizer (#12446)
**Description:** Textract PDF Loader generating linearized output,
meaning it will replicate the structure of the source document as close
as possible based on the features passed into the call (e. g. LAYOUT,
FORMS, TABLES). With LAYOUT reading order for multi-column documents or
identification of lists and figures is supported and with TABLES it will
generate the table structure as well. FORMS will indicate "key: value"
with columms.
  - **Issue:** the issue fixes #12068 
- **Dependencies:** amazon-textract-textractor is added, which provides
the linearization
  - **Tag maintainer:** @3coins 

---------

Co-authored-by: Bagatur <baskaryan@gmail.com>
2023-10-30 18:02:10 -07:00
Harrison Chase
a7d5e0ce8a add guardrails profanity (#12609) 2023-10-30 17:01:23 -07:00
Erick Friis
e933212a3d run poetry build in working dir (#12610)
Was failing because was trying to build from root:
https://github.com/langchain-ai/langchain/actions/runs/6700033981/job/18205251365
2023-10-30 16:58:34 -07:00
Erick Friis
f39246bd7e cli should pull instead of delete+clone (#12607)
Co-authored-by: Harrison Chase <hw.chase.17@gmail.com>
2023-10-30 16:44:09 -07:00
Harrison Chase
8b5e879171 add a template for the package readme (#12499)
Co-authored-by: Erick Friis <erick@langchain.dev>
2023-10-30 16:39:39 -07:00
Bagatur
9bedda50f2 Bagatur/lakefs loader2 (#12524)
Co-authored-by: Jonathan Rosenberg <96974219+Jonathan-Rosenberg@users.noreply.github.com>
2023-10-30 16:30:27 -07:00
Brian McBrayer
3243dcc83e Fix very small typo (#12603)
- **Description:** this is the world's smallest typo change of a typo I
saw while reading the docs
2023-10-30 16:30:18 -07:00
Ackermann Yuriy
99b69fe607 Fixed missing optional tags. Added default key value for Ollama (#12599)
Added missing Optional typings. Added default values for Ollama optional
keys.

---------

Co-authored-by: Bagatur <baskaryan@gmail.com>
2023-10-30 16:30:10 -07:00
Lance Martin
f6f3ca12e7 Codebase RAG fireworks (#12597) 2023-10-30 16:21:56 -07:00
Harrison Chase
481bf6fae6 hosting note (#12589) 2023-10-30 15:31:31 -07:00
David Duong
b5c17ff188 Force List[Tuple[str,str]] to chat history widget (#12530)
Co-authored-by: Bagatur <baskaryan@gmail.com>
2023-10-30 15:19:32 -07:00
David Duong
d39b4b61b6 Batch apply poetry lock --no-update for all templates (#12531)
Ran the following bash script for all templates

```bash
#!/bin/bash

set -e
current_dir="$(pwd)"
for directory in */; do
    if [ -d "$directory" ]; then
        (cd "$directory" && poetry lock --no-update)
    fi
done

cd "$current_dir"
```

Co-authored-by: Bagatur <baskaryan@gmail.com>
2023-10-30 15:18:53 -07:00
Kenzie Mihardja
e914283cf9 add docs to min_chunk_size (#12537)
Minor addition to documentation to elaborate on min_chunk_size.

Co-authored-by: Kenzie Mihardja <kenzie@docugami.com>
2023-10-30 15:13:52 -07:00
Bagatur
016813d189 factor out to_secret (#12593) 2023-10-30 15:10:25 -07:00
hsuyuming
630ae24b28 implement get_num_tokens to use google's count_tokens function (#10565)
can get the correct token count instead of using gpt-2 model

**Description:** 
Implement get_num_tokens within VertexLLM to use google's count_tokens
function.
(https://cloud.google.com/vertex-ai/docs/generative-ai/get-token-count).
So we don't need to download gpt-2 model from huggingface, also when we
do the mapreduce chain we can get correct token count.

**Tag maintainer:** 
@lkuligin 
**Twitter handle:** 
My twitter: @abehsu1992626

---------

Co-authored-by: Bagatur <baskaryan@gmail.com>
2023-10-30 15:10:05 -07:00
Pham Vu Thai Minh
33e77a1007 Async support for FAISS (#11333)
Following this tutoral about using OpenAI Embeddings with FAISS

https://python.langchain.com/docs/integrations/vectorstores/faiss

```python
from langchain.embeddings.openai import OpenAIEmbeddings
from langchain.text_splitter import CharacterTextSplitter
from langchain.vectorstores import FAISS
from langchain.document_loaders import TextLoader
from langchain.document_loaders import TextLoader

loader = TextLoader("../../../extras/modules/state_of_the_union.txt")
documents = loader.load()
text_splitter = CharacterTextSplitter(chunk_size=1000, chunk_overlap=0)
docs = text_splitter.split_documents(documents)

embeddings = OpenAIEmbeddings()
```

This works fine

```python
db = FAISS.from_documents(docs, embeddings)
query = "What did the president say about Ketanji Brown Jackson"
docs = db.similarity_search(query)
```

But the async version is not

```python
db = await FAISS.afrom_documents(docs, embeddings)  # NotImplementedError
query = "What did the president say about Ketanji Brown Jackson"

docs = await db.asimilarity_search(query) # this will use await asyncio.get_event_loop().run_in_executor under the hood and will not call OpenAIEmbeddings.aembed_query but call OpenAIEmbeddings.embed_query
```

So this PR add async/await supports for FAISS

---------

Co-authored-by: Eugene Yurtsev <eyurtsev@gmail.com>
2023-10-30 15:08:53 -07:00
Lance Martin
26f0ca222d RAG template for MongoDB Atlas Vector Search (#12526) 2023-10-30 14:31:34 -07:00
Jeff Zhuo
13b89815a3 Issue: fix the issue #11648 init minimax llm (#12554)
e https://github.com/langchain-ai/langchain/issues/11648 Minimax
llm failed to initialize

The idea of this fix is
https://github.com/langchain-ai/langchain/issues/10917#issuecomment-1765606725

do not use  underscore in python model class

---------

Co-authored-by: zhuojianming@cmcm.com <zhuojianming@cmcm.com>
Co-authored-by: Bagatur <baskaryan@gmail.com>
2023-10-30 14:30:17 -07:00
Florian Valeye
bfb27324cb [Matching Engine] Update the Matching Engine to include the distance and filters (#12555)
Hello 👋,

This Pull Request adds more capability to the
[MatchingEngine](https://api.python.langchain.com/en/latest/vectorstores/langchain.vectorstores.matching_engine.MatchingEngine.html)
vectorstore of GCP. It includes the
`similarity_search_by_vector_with_relevance_scores` function and also
[filters](https://cloud.google.com/vertex-ai/docs/vector-search/filtering)
to `filter` the namespaces when retrieving the results.

- **Description:** Add
[filter](https://cloud.google.com/python/docs/reference/aiplatform/latest/google.cloud.aiplatform.MatchingEngineIndexEndpoint#google_cloud_aiplatform_MatchingEngineIndexEndpoint_find_neighbors)
in `similarity_search` and add
`similarity_search_by_vector_with_relevance_scores` method
  - **Dependencies:** None
  - **Tag maintainer:** Unknown

Thank you!

---------

Co-authored-by: Bagatur <baskaryan@gmail.com>
2023-10-30 14:12:59 -07:00
Predrag Gruevski
3c5c384f1a Test-publish to test PyPI and separate jobs to limit permissions. (#12578)
Before making a new `langchain` release, we want to test that everything
works as expected. This PR lets us publish `langchain` to test PyPI,
then install it from there and run checks to ensure everything works
normally before publishing it "for real".

It also takes the opportunity to refactor the build process, splitting
up the build, release-creation, and PyPI upload steps into separate jobs
that do not share their elevated permissions with each other.
2023-10-30 17:10:14 -04:00
Harrison Chase
1d51363e49 change project template (#12493) 2023-10-30 14:06:30 -07:00
Holt Skinner
e53b9ccd70 feat: Add Google Cloud Text-to-Speech Tool (#12572)
- Add Tool for [Google Cloud
Text-to-Speech](https://cloud.google.com/text-to-speech)
- Follows similar structure to [Eleven Labs
Text2Speech](https://python.langchain.com/docs/integrations/tools/eleven_labs_tts)

---------

Co-authored-by: Bagatur <baskaryan@gmail.com>
2023-10-30 14:05:39 -07:00
834 changed files with 110973 additions and 25031 deletions

View File

@@ -17,13 +17,16 @@ For more info, check out the [GitHub documentation](https://docs.github.com/en/f
## VS Code Dev Containers
[![Open in Dev Containers](https://img.shields.io/static/v1?label=Dev%20Containers&message=Open&color=blue&logo=visualstudiocode)](https://vscode.dev/redirect?url=vscode://ms-vscode-remote.remote-containers/cloneInVolume?url=https://github.com/langchain-ai/langchain)
Note: If you click this link you will open the main repo and not your local cloned repo, you can use this link and replace with your username and cloned repo name:
Note: If you click the link above you will open the main repo (langchain-ai/langchain) and not your local cloned repo. This is fine if you only want to run and test the library, but if you want to contribute you can use the link below and replace with your username and cloned repo name:
```
https://vscode.dev/redirect?url=vscode://ms-vscode-remote.remote-containers/cloneInVolume?url=https://github.com/<yourusername>/<yourclonedreponame>
```
Then you will have a local cloned repo where you can contribute and then create pull requests.
If you already have VS Code and Docker installed, you can use the button above to get started. This will cause VS Code to automatically install the Dev Containers extension if needed, clone the source code into a container volume, and spin up a dev container for use.
You can also follow these steps to open this repo in a container using the VS Code Dev Containers extension:
Alternatively you can also follow these steps to open this repo in a container using the VS Code Dev Containers extension:
1. If this is your first time using a development container, please ensure your system meets the pre-reqs (i.e. have Docker installed) in the [getting started steps](https://aka.ms/vscode-remote/containers/getting-started).

View File

@@ -134,7 +134,7 @@ Run these locally before submitting a PR; the CI system will check also.
#### Code Formatting
Formatting for this project is done via a combination of [Black](https://black.readthedocs.io/en/stable/) and [ruff](https://docs.astral.sh/ruff/rules/).
Formatting for this project is done via [ruff](https://docs.astral.sh/ruff/rules/).
To run formatting for docs, cookbook and templates:
@@ -159,7 +159,7 @@ This is especially useful when you have made changes to a subset of the project
#### Linting
Linting for this project is done via a combination of [Black](https://black.readthedocs.io/en/stable/), [ruff](https://docs.astral.sh/ruff/rules/), and [mypy](http://mypy-lang.org/).
Linting for this project is done via a combination of [ruff](https://docs.astral.sh/ruff/rules/) and [mypy](http://mypy-lang.org/).
To run linting for docs, cookbook and templates:
@@ -302,8 +302,8 @@ make api_docs_linkcheck
### Verify Documentation changes
After pushing documentation changes to the repository, you can preview and verify that the changes are
what you wanted by clicking the `View deployment` or `Visit Preview` buttons on the pull request `Conversation` page.
After pushing documentation changes to the repository, you can preview and verify that the changes are
what you wanted by clicking the `View deployment` or `Visit Preview` buttons on the pull request `Conversation` page.
This will take you to a preview of the documentation changes.
This preview is created by [Vercel](https://vercel.com/docs/getting-started-with-vercel).

View File

@@ -16,15 +16,12 @@ env:
POETRY_VERSION: "1.6.1"
WORKDIR: ${{ inputs.working-directory == '' && '.' || inputs.working-directory }}
# This env var allows us to get inline annotations when ruff has complaints.
RUFF_OUTPUT_FORMAT: github
jobs:
build:
runs-on: ubuntu-latest
env:
# This number is set "by eye": we want it to be big enough
# so that it's bigger than the number of commits in any reasonable PR,
# and also as small as possible since increasing the number makes
# the initial `git fetch` slower.
FETCH_DEPTH: 50
strategy:
matrix:
# Only lint on the min and max supported Python versions.
@@ -39,51 +36,6 @@ jobs:
- "3.11"
steps:
- uses: actions/checkout@v4
with:
# Fetch the last FETCH_DEPTH commits, so the mtime-changing script
# can accurately set the mtimes of files modified in the last FETCH_DEPTH commits.
fetch-depth: ${{ env.FETCH_DEPTH }}
- name: Restore workdir file mtimes to last-edited commit date
id: restore-mtimes
# This is needed to make black caching work.
# Black's cache uses file (mtime, size) to check whether a lookup is a cache hit.
# Without this command, files in the repo would have the current time as the modified time,
# since the previous action step just created them.
# This command resets the mtime to the last time the files were modified in git instead,
# which is a high-quality and stable representation of the last modification date.
run: |
# Important considerations:
# - These commands run at base of the repo, since we never `cd` to the `WORKDIR`.
# - We only want to alter mtimes for Python files, since that's all black checks.
# - We don't need to alter mtimes for directories, since black doesn't look at those.
# - We also only alter mtimes inside the `WORKDIR` since that's all we'll lint.
# - This should run before `poetry install`, because poetry's venv also contains
# Python files, and we don't want to alter their mtimes since they aren't linted.
# Ensure we fail on non-zero exits and on undefined variables.
# Also print executed commands, for easier debugging.
set -eux
# Restore the mtimes of Python files in the workdir based on git history.
.github/tools/git-restore-mtime --no-directories "$WORKDIR/**/*.py"
# Since CI only does a partial fetch (to `FETCH_DEPTH`) for efficiency,
# the local git repo doesn't have full history. There are probably files
# that were last modified in a commit *older than* the oldest fetched commit.
# After `git-restore-mtime`, such files have a mtime set to the oldest fetched commit.
#
# As new commits get added, that timestamp will keep moving forward.
# If left unchanged, this will make `black` think that the files were edited
# more recently than its cache suggests. Instead, we can set their mtime
# to a fixed date in the far past that won't change and won't cause cache misses in black.
#
# For all workdir Python files modified in or before the oldest few fetched commits,
# make their mtime be 2000-01-01 00:00:00.
OLDEST_COMMIT="$(git log --reverse '--pretty=format:%H' | head -1)"
OLDEST_COMMIT_TIME="$(git show -s '--format=%ai' "$OLDEST_COMMIT")"
find "$WORKDIR" -name '*.py' -type f -not -newermt "$OLDEST_COMMIT_TIME" -exec touch -c -m -t '200001010000' '{}' '+'
echo "oldest-commit=$OLDEST_COMMIT" >> "$GITHUB_OUTPUT"
- name: Set up Python ${{ matrix.python-version }} + Poetry ${{ env.POETRY_VERSION }}
uses: "./.github/actions/poetry_setup"
@@ -126,19 +78,6 @@ jobs:
run: |
pip install -e "$LANGCHAIN_LOCATION"
- name: Restore black cache
uses: actions/cache@v3
env:
CACHE_BASE: black-${{ runner.os }}-${{ runner.arch }}-py${{ matrix.python-version }}-${{ inputs.working-directory }}-${{ hashFiles(format('{0}/poetry.lock', env.WORKDIR)) }}
SEGMENT_DOWNLOAD_TIMEOUT_MIN: "1"
with:
path: |
${{ env.WORKDIR }}/.black_cache
key: ${{ env.CACHE_BASE }}-${{ steps.restore-mtimes.outputs.oldest-commit }}
restore-keys:
# If we can't find an exact match for our cache key, accept any with this prefix.
${{ env.CACHE_BASE }}-
- name: Get .mypy_cache to speed up mypy
uses: actions/cache@v3
env:
@@ -150,7 +89,5 @@ jobs:
- name: Analysing the code with our lint
working-directory: ${{ inputs.working-directory }}
env:
BLACK_CACHE_DIR: .black_cache
run: |
make lint

View File

@@ -9,13 +9,121 @@ on:
description: "From which folder this pipeline executes"
env:
PYTHON_VERSION: "3.10"
POETRY_VERSION: "1.6.1"
jobs:
if_release:
# Disallow publishing from branches that aren't `master`.
build:
if: github.ref == 'refs/heads/master'
runs-on: ubuntu-latest
outputs:
pkg-name: ${{ steps.check-version.outputs.pkg-name }}
version: ${{ steps.check-version.outputs.version }}
steps:
- uses: actions/checkout@v4
- name: Set up Python + Poetry ${{ env.POETRY_VERSION }}
uses: "./.github/actions/poetry_setup"
with:
python-version: ${{ env.PYTHON_VERSION }}
poetry-version: ${{ env.POETRY_VERSION }}
working-directory: ${{ inputs.working-directory }}
cache-key: release
# We want to keep this build stage *separate* from the release stage,
# so that there's no sharing of permissions between them.
# The release stage has trusted publishing and GitHub repo contents write access,
# and we want to keep the scope of that access limited just to the release job.
# Otherwise, a malicious `build` step (e.g. via a compromised dependency)
# could get access to our GitHub or PyPI credentials.
#
# Per the trusted publishing GitHub Action:
# > It is strongly advised to separate jobs for building [...]
# > from the publish job.
# https://github.com/pypa/gh-action-pypi-publish#non-goals
- name: Build project for distribution
run: poetry build
working-directory: ${{ inputs.working-directory }}
- name: Upload build
uses: actions/upload-artifact@v3
with:
name: dist
path: ${{ inputs.working-directory }}/dist/
- name: Check Version
id: check-version
shell: bash
working-directory: ${{ inputs.working-directory }}
run: |
echo pkg-name="$(poetry version | cut -d ' ' -f 1)" >> $GITHUB_OUTPUT
echo version="$(poetry version --short)" >> $GITHUB_OUTPUT
test-pypi-publish:
needs:
- build
uses:
./.github/workflows/_test_release.yml
with:
working-directory: ${{ inputs.working-directory }}
secrets: inherit
pre-release-checks:
needs:
- build
- test-pypi-publish
runs-on: ubuntu-latest
steps:
# We explicitly *don't* set up caching here. This ensures our tests are
# maximally sensitive to catching breakage.
#
# For example, here's a way that caching can cause a falsely-passing test:
# - Make the langchain package manifest no longer list a dependency package
# as a requirement. This means it won't be installed by `pip install`,
# and attempting to use it would cause a crash.
# - That dependency used to be required, so it may have been cached.
# When restoring the venv packages from cache, that dependency gets included.
# - Tests pass, because the dependency is present even though it wasn't specified.
# - The package is published, and it breaks on the missing dependency when
# used in the real world.
- uses: actions/setup-python@v4
with:
python-version: ${{ env.PYTHON_VERSION }}
- name: Test published package
shell: bash
env:
PKG_NAME: ${{ needs.build.outputs.pkg-name }}
VERSION: ${{ needs.build.outputs.version }}
# Here we specify:
# - The test PyPI index as the *primary* index, meaning that it takes priority.
# - The regular PyPI index as an extra index, so that any dependencies that
# are not found on test PyPI can be resolved and installed anyway.
#
# Without the former, we might install the wrong langchain release.
# Without the latter, we might not be able to install langchain's dependencies.
#
# TODO: add more in-depth pre-publish tests after testing that importing works
run: |
pip install \
--index-url https://test.pypi.org/simple/ \
--extra-index-url https://pypi.org/simple/ \
"$PKG_NAME==$VERSION"
# Replace all dashes in the package name with underscores,
# since that's how Python imports packages with dashes in the name.
IMPORT_NAME="$(echo "$PKG_NAME" | sed s/-/_/g)"
python -c "import $IMPORT_NAME; print(dir($IMPORT_NAME))"
publish:
needs:
- build
- test-pypi-publish
- pre-release-checks
runs-on: ubuntu-latest
permissions:
# This permission is used for trusted publishing:
# https://blog.pypi.org/posts/2023-04-20-introducing-trusted-publishers/
@@ -24,28 +132,65 @@ jobs:
# https://docs.pypi.org/trusted-publishers/adding-a-publisher/
id-token: write
# This permission is needed by `ncipollo/release-action` to create the GitHub release.
contents: write
defaults:
run:
working-directory: ${{ inputs.working-directory }}
steps:
- uses: actions/checkout@v4
- name: Set up Python + Poetry ${{ env.POETRY_VERSION }}
uses: "./.github/actions/poetry_setup"
with:
python-version: "3.10"
python-version: ${{ env.PYTHON_VERSION }}
poetry-version: ${{ env.POETRY_VERSION }}
working-directory: ${{ inputs.working-directory }}
cache-key: release
- name: Build project for distribution
run: poetry build
- name: Check Version
id: check-version
run: |
echo version=$(poetry version --short) >> $GITHUB_OUTPUT
- uses: actions/download-artifact@v3
with:
name: dist
path: ${{ inputs.working-directory }}/dist/
- name: Publish package distributions to PyPI
uses: pypa/gh-action-pypi-publish@release/v1
with:
packages-dir: ${{ inputs.working-directory }}/dist/
verbose: true
print-hash: true
mark-release:
needs:
- build
- test-pypi-publish
- pre-release-checks
- publish
runs-on: ubuntu-latest
permissions:
# This permission is needed by `ncipollo/release-action` to
# create the GitHub release.
contents: write
defaults:
run:
working-directory: ${{ inputs.working-directory }}
steps:
- uses: actions/checkout@v4
- name: Set up Python + Poetry ${{ env.POETRY_VERSION }}
uses: "./.github/actions/poetry_setup"
with:
python-version: ${{ env.PYTHON_VERSION }}
poetry-version: ${{ env.POETRY_VERSION }}
working-directory: ${{ inputs.working-directory }}
cache-key: release
- uses: actions/download-artifact@v3
with:
name: dist
path: ${{ inputs.working-directory }}/dist/
- name: Create Release
uses: ncipollo/release-action@v1
if: ${{ inputs.working-directory == 'libs/langchain' }}
@@ -54,11 +199,5 @@ jobs:
token: ${{ secrets.GITHUB_TOKEN }}
draft: false
generateReleaseNotes: true
tag: v${{ steps.check-version.outputs.version }}
tag: v${{ needs.build.outputs.version }}
commit: master
- name: Publish package distributions to PyPI
uses: pypa/gh-action-pypi-publish@release/v1
with:
packages-dir: ${{ inputs.working-directory }}/dist/
verbose: true
print-hash: true

View File

@@ -10,9 +10,60 @@ on:
env:
POETRY_VERSION: "1.6.1"
PYTHON_VERSION: "3.10"
jobs:
publish_to_test_pypi:
build:
if: github.ref == 'refs/heads/master'
runs-on: ubuntu-latest
outputs:
pkg-name: ${{ steps.check-version.outputs.pkg-name }}
version: ${{ steps.check-version.outputs.version }}
steps:
- uses: actions/checkout@v4
- name: Set up Python + Poetry ${{ env.POETRY_VERSION }}
uses: "./.github/actions/poetry_setup"
with:
python-version: ${{ env.PYTHON_VERSION }}
poetry-version: ${{ env.POETRY_VERSION }}
working-directory: ${{ inputs.working-directory }}
cache-key: release
# We want to keep this build stage *separate* from the release stage,
# so that there's no sharing of permissions between them.
# The release stage has trusted publishing and GitHub repo contents write access,
# and we want to keep the scope of that access limited just to the release job.
# Otherwise, a malicious `build` step (e.g. via a compromised dependency)
# could get access to our GitHub or PyPI credentials.
#
# Per the trusted publishing GitHub Action:
# > It is strongly advised to separate jobs for building [...]
# > from the publish job.
# https://github.com/pypa/gh-action-pypi-publish#non-goals
- name: Build project for distribution
run: poetry build
working-directory: ${{ inputs.working-directory }}
- name: Upload build
uses: actions/upload-artifact@v3
with:
name: test-dist
path: ${{ inputs.working-directory }}/dist/
- name: Check Version
id: check-version
shell: bash
working-directory: ${{ inputs.working-directory }}
run: |
echo pkg-name="$(poetry version | cut -d ' ' -f 1)" >> $GITHUB_OUTPUT
echo version="$(poetry version --short)" >> $GITHUB_OUTPUT
publish:
needs:
- build
runs-on: ubuntu-latest
permissions:
# This permission is used for trusted publishing:
@@ -21,30 +72,24 @@ jobs:
# Trusted publishing has to also be configured on PyPI for each package:
# https://docs.pypi.org/trusted-publishers/adding-a-publisher/
id-token: write
defaults:
run:
working-directory: ${{ inputs.working-directory }}
steps:
- uses: actions/checkout@v4
- name: Set up Python + Poetry ${{ env.POETRY_VERSION }}
uses: "./.github/actions/poetry_setup"
- uses: actions/download-artifact@v3
with:
python-version: "3.10"
poetry-version: ${{ env.POETRY_VERSION }}
working-directory: ${{ inputs.working-directory }}
cache-key: release
name: test-dist
path: ${{ inputs.working-directory }}/dist/
- name: Build project for distribution
run: poetry build
- name: Check Version
id: check-version
run: |
echo version=$(poetry version --short) >> $GITHUB_OUTPUT
- name: Publish package to TestPyPI
- name: Publish to test PyPI
uses: pypa/gh-action-pypi-publish@release/v1
with:
repository-url: https://test.pypi.org/legacy/
packages-dir: ${{ inputs.working-directory }}/dist/
verbose: true
print-hash: true
repository-url: https://test.pypi.org/legacy/
# We overwrite any existing distributions with the same name and version.
# This is *only for CI use* and is *extremely dangerous* otherwise!
# https://github.com/pypa/gh-action-pypi-publish#tolerating-release-package-file-duplicates
skip-existing: true

View File

@@ -19,7 +19,7 @@ jobs:
steps:
- name: Checkout repository
uses: actions/checkout@v2
uses: actions/checkout@v4
- name: Run import check
run: |

View File

@@ -45,10 +45,3 @@ jobs:
with:
working-directory: libs/cli
secrets: inherit
pydantic-compatibility:
uses:
./.github/workflows/_pydantic_compatibility.yml
with:
working-directory: libs/cli
secrets: inherit

1
.gitignore vendored
View File

@@ -178,3 +178,4 @@ docs/docs/build
docs/docs/node_modules
docs/docs/yarn.lock
_dist
docs/docs/templates

View File

@@ -43,7 +43,7 @@ spell_fix:
lint:
poetry run ruff docs templates cookbook
poetry run black docs templates cookbook --check
poetry run black docs templates cookbook --diff
format format_diff:
poetry run black docs templates cookbook

View File

@@ -47,7 +47,7 @@
},
{
"cell_type": "code",
"execution_count": 8,
"execution_count": 1,
"id": "6a75a5c6-34ee-4ab9-a664-d9b432d812ee",
"metadata": {},
"outputs": [
@@ -80,7 +80,7 @@
},
{
"cell_type": "code",
"execution_count": 12,
"execution_count": 2,
"id": "ce96f7ea-b3d5-44e1-9fa5-a79e04a9e1fb",
"metadata": {},
"outputs": [],
@@ -103,7 +103,7 @@
},
{
"cell_type": "code",
"execution_count": 13,
"execution_count": 3,
"id": "025bdd82-3bb1-4948-bc7c-c3ccd94fd05c",
"metadata": {},
"outputs": [],
@@ -133,7 +133,7 @@
},
{
"cell_type": "code",
"execution_count": 14,
"execution_count": 4,
"id": "5a4933ea-d9c0-4b0a-8177-ba4490c6532b",
"metadata": {},
"outputs": [
@@ -143,7 +143,7 @@
"' SELECT \"Team\" FROM nba_roster WHERE \"NAME\" = \\'Klay Thompson\\';'"
]
},
"execution_count": 14,
"execution_count": 4,
"metadata": {},
"output_type": "execute_result"
}
@@ -260,8 +260,8 @@
},
{
"cell_type": "code",
"execution_count": 19,
"id": "1985aa1c-eb8f-4fb1-a54f-c8aa10744687",
"execution_count": 7,
"id": "022868f2-128e-42f5-8d90-d3bb2f11d994",
"metadata": {},
"outputs": [
{
@@ -270,7 +270,7 @@
"' SELECT \"Team\" FROM nba_roster WHERE \"NAME\" = \\'Klay Thompson\\';'"
]
},
"execution_count": 19,
"execution_count": 7,
"metadata": {},
"output_type": "execute_result"
}
@@ -280,16 +280,14 @@
"from langchain.memory import ConversationBufferMemory\n",
"from langchain.prompts import ChatPromptTemplate, MessagesPlaceholder\n",
"\n",
"template = \"\"\"Based on the table schema below, write a SQL query that would answer the user's question:\n",
"template = \"\"\"Given an input question, convert it to a SQL query. No pre-amble. Based on the table schema below, write a SQL query that would answer the user's question:\n",
"{schema}\n",
"\n",
"Question: {question}\n",
"SQL Query:\"\"\"\n",
"\"\"\"\n",
"prompt = ChatPromptTemplate.from_messages(\n",
" [\n",
" (\"system\", \"Given an input question, convert it to a SQL query. No pre-amble.\"),\n",
" (\"system\", template),\n",
" MessagesPlaceholder(variable_name=\"history\"),\n",
" (\"human\", template),\n",
" (\"human\", \"{question}\"),\n",
" ]\n",
")\n",
"\n",
@@ -319,27 +317,6 @@
"sql_response_memory.invoke({\"question\": \"What team is Klay Thompson on?\"})"
]
},
{
"cell_type": "code",
"execution_count": 20,
"id": "0b45818a-1498-441d-b82d-23c29428c2bb",
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"' SELECT \"SALARY\" FROM nba_roster WHERE \"NAME\" = \\'Klay Thompson\\';'"
]
},
"execution_count": 20,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"sql_response_memory.invoke({\"question\": \"What is his salary?\"})"
]
},
{
"cell_type": "code",
"execution_count": 21,

File diff suppressed because one or more lines are too long

View File

@@ -20,6 +20,7 @@ Notebook | Description
[databricks_sql_db.ipynb](https://github.com/langchain-ai/langchain/tree/master/cookbook/databricks_sql_db.ipynb) | Connect to databricks runtimes and databricks sql.
[deeplake_semantic_search_over_...](https://github.com/langchain-ai/langchain/tree/master/cookbook/deeplake_semantic_search_over_chat.ipynb) | Perform semantic search and question-answering over a group chat using activeloop's deep lake with gpt4.
[elasticsearch_db_qa.ipynb](https://github.com/langchain-ai/langchain/tree/master/cookbook/elasticsearch_db_qa.ipynb) | Interact with elasticsearch analytics databases in natural language and build search queries via the elasticsearch dsl API.
[extraction_openai_tools.ipynb](https://github.com/langchain-ai/langchain/tree/master/cookbook/extraction_openai_tools.ipynb) | Structured Data Extraction with OpenAI Tools
[forward_looking_retrieval_augm...](https://github.com/langchain-ai/langchain/tree/master/cookbook/forward_looking_retrieval_augmented_generation.ipynb) | Implement the forward-looking active retrieval augmented generation (flare) method, which generates answers to questions, identifies uncertain tokens, generates hypothetical questions based on these tokens, and retrieves relevant documents to continue generating the answer.
[generative_agents_interactive_...](https://github.com/langchain-ai/langchain/tree/master/cookbook/generative_agents_interactive_simulacra_of_human_behavior.ipynb) | Implement a generative agent that simulates human behavior, based on a research paper, using a time-weighted memory object backed by a langchain retriever.
[gymnasium_agent_simulation.ipynb](https://github.com/langchain-ai/langchain/tree/master/cookbook/gymnasium_agent_simulation.ipynb) | Create a simple agent-environment interaction loop in simulated environments like text-based games with gymnasium.
@@ -38,10 +39,12 @@ Notebook | Description
[multiagent_bidding.ipynb](https://github.com/langchain-ai/langchain/tree/master/cookbook/multiagent_bidding.ipynb) | Implement a multi-agent simulation where agents bid to speak, with the highest bidder speaking next, demonstrated through a fictitious presidential debate example.
[myscale_vector_sql.ipynb](https://github.com/langchain-ai/langchain/tree/master/cookbook/myscale_vector_sql.ipynb) | Access and interact with the myscale integrated vector database, which can enhance the performance of language model (llm) applications.
[openai_functions_retrieval_qa....](https://github.com/langchain-ai/langchain/tree/master/cookbook/openai_functions_retrieval_qa.ipynb) | Structure response output in a question-answering system by incorporating openai functions into a retrieval pipeline.
[openai_v1_cookbook.ipynb](https://github.com/langchain-ai/langchain/tree/master/cookbook/openai_v1_cookbook.ipynb) | Explore new functionality released alongside the V1 release of the OpenAI Python library.
[petting_zoo.ipynb](https://github.com/langchain-ai/langchain/tree/master/cookbook/petting_zoo.ipynb) | Create multi-agent simulations with simulated environments using the petting zoo library.
[plan_and_execute_agent.ipynb](https://github.com/langchain-ai/langchain/tree/master/cookbook/plan_and_execute_agent.ipynb) | Create plan-and-execute agents that accomplish objectives by planning tasks with a language model (llm) and executing them with a separate agent.
[press_releases.ipynb](https://github.com/langchain-ai/langchain/tree/master/cookbook/press_releases.ipynb) | Retrieve and query company press release data powered by [Kay.ai](https://kay.ai).
[program_aided_language_model.i...](https://github.com/langchain-ai/langchain/tree/master/cookbook/program_aided_language_model.ipynb) | Implement program-aided language models as described in the provided research paper.
[retrieval_in_sql.ipynb](https://github.com/langchain-ai/langchain/tree/master/cookbook/retrieval_in_sql.ipynb) | Perform retrieval-augmented-generation (rag) on a PostgreSQL database using pgvector.
[sales_agent_with_context.ipynb](https://github.com/langchain-ai/langchain/tree/master/cookbook/sales_agent_with_context.ipynb) | Implement a context-aware ai sales agent, salesgpt, that can have natural sales conversations, interact with other systems, and use a product knowledge base to discuss a company's offerings.
[self_query_hotel_search.ipynb](https://github.com/langchain-ai/langchain/tree/master/cookbook/self_query_hotel_search.ipynb) | Build a hotel room search feature with self-querying retrieval, using a specific hotel recommendation dataset.
[smart_llm.ipynb](https://github.com/langchain-ai/langchain/tree/master/cookbook/smart_llm.ipynb) | Implement a smartllmchain, a self-critique chain that generates multiple output proposals, critiques them to find the best one, and then improves upon it to produce a final output.

View File

@@ -0,0 +1,213 @@
{
"cells": [
{
"cell_type": "markdown",
"id": "2def22ea",
"metadata": {},
"source": [
"# Extraction with OpenAI Tools\n",
"\n",
"Performing extraction has never been easier! OpenAI's tool calling ability is the perfect thing to use as it allows for extracting multiple different elements from text that are different types. \n",
"\n",
"Models after 1106 use tools and support \"parallel function calling\" which makes this super easy."
]
},
{
"cell_type": "code",
"execution_count": 8,
"id": "5c628496",
"metadata": {},
"outputs": [],
"source": [
"from langchain.chat_models import ChatOpenAI\n",
"from langchain.pydantic_v1 import BaseModel\n",
"from typing import Optional, List\n",
"from langchain.chains.openai_tools import create_extraction_chain_pydantic"
]
},
{
"cell_type": "code",
"execution_count": 2,
"id": "afe9657b",
"metadata": {},
"outputs": [],
"source": [
"# Make sure to use a recent model that supports tools\n",
"model = ChatOpenAI(model=\"gpt-3.5-turbo-1106\")"
]
},
{
"cell_type": "code",
"execution_count": 3,
"id": "bc0ca3b6",
"metadata": {},
"outputs": [],
"source": [
"# Pydantic is an easy way to define a schema\n",
"class Person(BaseModel):\n",
" \"\"\"Information about people to extract.\"\"\"\n",
"\n",
" name: str\n",
" age: Optional[int] = None"
]
},
{
"cell_type": "code",
"execution_count": 10,
"id": "2036af68",
"metadata": {},
"outputs": [],
"source": [
"chain = create_extraction_chain_pydantic(Person, model)"
]
},
{
"cell_type": "code",
"execution_count": 11,
"id": "1748ad21",
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"[Person(name='jane', age=2), Person(name='bob', age=3)]"
]
},
"execution_count": 11,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"chain.invoke({\"input\": \"jane is 2 and bob is 3\"})"
]
},
{
"cell_type": "code",
"execution_count": 12,
"id": "c8262ce5",
"metadata": {},
"outputs": [],
"source": [
"# Let's define another element\n",
"class Class(BaseModel):\n",
" \"\"\"Information about classes to extract.\"\"\"\n",
"\n",
" teacher: str\n",
" students: List[str]"
]
},
{
"cell_type": "code",
"execution_count": 13,
"id": "4973c104",
"metadata": {},
"outputs": [],
"source": [
"chain = create_extraction_chain_pydantic([Person, Class], model)"
]
},
{
"cell_type": "code",
"execution_count": 14,
"id": "e976a15e",
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"[Person(name='jane', age=2),\n",
" Person(name='bob', age=3),\n",
" Class(teacher='Mrs Sampson', students=['jane', 'bob'])]"
]
},
"execution_count": 14,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"chain.invoke({\"input\": \"jane is 2 and bob is 3 and they are in Mrs Sampson's class\"})"
]
},
{
"cell_type": "markdown",
"id": "6575a7d6",
"metadata": {},
"source": [
"## Under the hood\n",
"\n",
"Under the hood, this is a simple chain:"
]
},
{
"cell_type": "markdown",
"id": "b8ba83e5",
"metadata": {},
"source": [
"```python\n",
"from typing import Union, List, Type, Optional\n",
"\n",
"from langchain.output_parsers.openai_tools import PydanticToolsParser\n",
"from langchain.utils.openai_functions import convert_pydantic_to_openai_tool\n",
"from langchain.schema.runnable import Runnable\n",
"from langchain.pydantic_v1 import BaseModel\n",
"from langchain.prompts import ChatPromptTemplate\n",
"from langchain.schema.messages import SystemMessage\n",
"from langchain.schema.language_model import BaseLanguageModel\n",
"\n",
"_EXTRACTION_TEMPLATE = \"\"\"Extract and save the relevant entities mentioned \\\n",
"in the following passage together with their properties.\n",
"\n",
"If a property is not present and is not required in the function parameters, do not include it in the output.\"\"\" # noqa: E501\n",
"\n",
"\n",
"def create_extraction_chain_pydantic(\n",
" pydantic_schemas: Union[List[Type[BaseModel]], Type[BaseModel]],\n",
" llm: BaseLanguageModel,\n",
" system_message: str = _EXTRACTION_TEMPLATE,\n",
") -> Runnable:\n",
" if not isinstance(pydantic_schemas, list):\n",
" pydantic_schemas = [pydantic_schemas]\n",
" prompt = ChatPromptTemplate.from_messages([\n",
" (\"system\", system_message),\n",
" (\"user\", \"{input}\")\n",
" ])\n",
" tools = [convert_pydantic_to_openai_tool(p) for p in pydantic_schemas]\n",
" model = llm.bind(tools=tools)\n",
" chain = prompt | model | PydanticToolsParser(tools=pydantic_schemas)\n",
" return chain\n",
"```"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "2eac6b68",
"metadata": {},
"outputs": [],
"source": []
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3 (ipykernel)",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.9.1"
}
},
"nbformat": 4,
"nbformat_minor": 5
}

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -40,7 +40,7 @@
"\n",
"from sqlalchemy import create_engine\n",
"\n",
"MYSCALE_HOST = \"msc-1decbcc9.us-east-1.aws.staging.myscale.cloud\"\n",
"MYSCALE_HOST = \"msc-4a9e710a.us-east-1.aws.staging.myscale.cloud\"\n",
"MYSCALE_PORT = 443\n",
"MYSCALE_USER = \"chatdata\"\n",
"MYSCALE_PASSWORD = \"myscale_rocks\"\n",

View File

@@ -0,0 +1,506 @@
{
"cells": [
{
"cell_type": "markdown",
"id": "f970f757-ec76-4bf0-90cd-a2fb68b945e3",
"metadata": {},
"source": [
"# Exploring OpenAI V1 functionality\n",
"\n",
"On 11.06.23 OpenAI released a number of new features, and along with it bumped their Python SDK to 1.0.0. This notebook shows off the new features and how to use them with LangChain."
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "ee897729-263a-4073-898f-bb4cf01ed829",
"metadata": {},
"outputs": [],
"source": [
"# need openai>=1.1.0, langchain>=0.0.333, langchain-experimental>=0.0.39\n",
"!pip install -U openai langchain langchain-experimental"
]
},
{
"cell_type": "code",
"execution_count": 1,
"id": "c3e067ce-7a43-47a7-bc89-41f1de4cf136",
"metadata": {},
"outputs": [],
"source": [
"from langchain.chat_models import ChatOpenAI\n",
"from langchain.schema.messages import HumanMessage, SystemMessage"
]
},
{
"cell_type": "markdown",
"id": "fa7e7e95-90a1-4f73-98fe-10c4b4e0951b",
"metadata": {},
"source": [
"## [Vision](https://platform.openai.com/docs/guides/vision)\n",
"\n",
"OpenAI released multi-modal models, which can take a sequence of text and images as input."
]
},
{
"cell_type": "code",
"execution_count": 2,
"id": "1c8c3965-d3c9-4186-b5f3-5e67855ef916",
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"AIMessage(content='The image appears to be a diagram representing the architecture or components of a software system or framework related to language processing, possibly named LangChain or associated with a project or product called LangChain, based on the prominent appearance of that term. The diagram is organized into several layers or aspects, each containing various elements or modules:\\n\\n1. **Protocol**: This may be the foundational layer, which includes \"LCEL\" and terms like parallelization, fallbacks, tracing, batching, streaming, async, and composition. These seem related to communication and execution protocols for the system.\\n\\n2. **Integrations Components**: This layer includes \"Model I/O\" with elements such as the model, output parser, prompt, and example selector. It also has a \"Retrieval\" section with a document loader, retriever, embedding model, vector store, and text splitter. Lastly, there\\'s an \"Agent Tooling\" section. These components likely deal with the interaction with external data, models, and tools.\\n\\n3. **Application**: The application layer features \"LangChain\" with chains, agents, agent executors, and common application logic. This suggests that the system uses a modular approach with chains and agents to process language tasks.\\n\\n4. **Deployment**: This contains \"Lang')"
]
},
"execution_count": 2,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"chat = ChatOpenAI(model=\"gpt-4-vision-preview\", max_tokens=256)\n",
"chat.invoke(\n",
" [\n",
" HumanMessage(\n",
" content=[\n",
" {\"type\": \"text\", \"text\": \"What is this image showing\"},\n",
" {\n",
" \"type\": \"image_url\",\n",
" \"image_url\": {\n",
" \"url\": \"https://raw.githubusercontent.com/langchain-ai/langchain/master/docs/static/img/langchain_stack.png\",\n",
" \"detail\": \"auto\",\n",
" },\n",
" },\n",
" ]\n",
" )\n",
" ]\n",
")"
]
},
{
"cell_type": "markdown",
"id": "210f8248-fcf3-4052-a4a3-0684e08f8785",
"metadata": {},
"source": [
"## [OpenAI assistants](https://platform.openai.com/docs/assistants/overview)\n",
"\n",
"> The Assistants API allows you to build AI assistants within your own applications. An Assistant has instructions and can leverage models, tools, and knowledge to respond to user queries. The Assistants API currently supports three types of tools: Code Interpreter, Retrieval, and Function calling\n",
"\n",
"\n",
"You can interact with OpenAI Assistants using OpenAI tools or custom tools. When using exclusively OpenAI tools, you can just invoke the assistant directly and get final answers. When using custom tools, you can run the assistant and tool execution loop using the built-in AgentExecutor or easily write your own executor.\n",
"\n",
"Below we show the different ways to interact with Assistants. As a simple example, let's build a math tutor that can write and run code."
]
},
{
"cell_type": "markdown",
"id": "318da28d-4cec-42ab-ae3e-76d95bb34fa5",
"metadata": {},
"source": [
"### Using only OpenAI tools"
]
},
{
"cell_type": "code",
"execution_count": 1,
"id": "a9064bbe-d9f7-4a29-a7b3-73933b3197e7",
"metadata": {},
"outputs": [],
"source": [
"from langchain_experimental.openai_assistant import OpenAIAssistantRunnable"
]
},
{
"cell_type": "code",
"execution_count": 2,
"id": "7a20a008-49ac-46d2-aa26-b270118af5ea",
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"[ThreadMessage(id='msg_g9OJv0rpPgnc3mHmocFv7OVd', assistant_id='asst_hTwZeNMMphxzSOqJ01uBMsJI', content=[MessageContentText(text=Text(annotations=[], value='The result of \\\\(10 - 4^{2.7}\\\\) is approximately \\\\(-32.224\\\\).'), type='text')], created_at=1699460600, file_ids=[], metadata={}, object='thread.message', role='assistant', run_id='run_nBIT7SiAwtUfSCTrQNSPLOfe', thread_id='thread_14n4GgXwxgNL0s30WJW5F6p0')]"
]
},
"execution_count": 2,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"interpreter_assistant = OpenAIAssistantRunnable.create_assistant(\n",
" name=\"langchain assistant\",\n",
" instructions=\"You are a personal math tutor. Write and run code to answer math questions.\",\n",
" tools=[{\"type\": \"code_interpreter\"}],\n",
" model=\"gpt-4-1106-preview\",\n",
")\n",
"output = interpreter_assistant.invoke({\"content\": \"What's 10 - 4 raised to the 2.7\"})\n",
"output"
]
},
{
"cell_type": "markdown",
"id": "a8ddd181-ac63-4ab6-a40d-a236120379c1",
"metadata": {},
"source": [
"### As a LangChain agent with arbitrary tools\n",
"\n",
"Now let's recreate this functionality using our own tools. For this example we'll use the [E2B sandbox runtime tool](https://e2b.dev/docs?ref=landing-page-get-started)."
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "ee4cc355-f2d6-4c51-bcf7-f502868357d3",
"metadata": {},
"outputs": [],
"source": [
"!pip install e2b duckduckgo-search"
]
},
{
"cell_type": "code",
"execution_count": 3,
"id": "48681ac7-b267-48d4-972c-8a7df8393a21",
"metadata": {},
"outputs": [],
"source": [
"from langchain.tools import E2BDataAnalysisTool, DuckDuckGoSearchRun\n",
"\n",
"tools = [E2BDataAnalysisTool(api_key=\"...\"), DuckDuckGoSearchRun()]"
]
},
{
"cell_type": "code",
"execution_count": 4,
"id": "1c01dd79-dd3e-4509-a2e2-009a7f99f16a",
"metadata": {},
"outputs": [],
"source": [
"agent = OpenAIAssistantRunnable.create_assistant(\n",
" name=\"langchain assistant e2b tool\",\n",
" instructions=\"You are a personal math tutor. Write and run code to answer math questions. You can also search the internet.\",\n",
" tools=tools,\n",
" model=\"gpt-4-1106-preview\",\n",
" as_agent=True,\n",
")"
]
},
{
"cell_type": "markdown",
"id": "1ac71d8b-4b4b-4f98-b826-6b3c57a34166",
"metadata": {},
"source": [
"#### Using AgentExecutor"
]
},
{
"cell_type": "code",
"execution_count": 5,
"id": "1f137f94-801f-4766-9ff5-2de9df5e8079",
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"{'content': \"What's the weather in SF today divided by 2.7\",\n",
" 'output': \"The weather in San Francisco today is reported to have temperatures as high as 66 °F. To get the temperature divided by 2.7, we will calculate that:\\n\\n66 °F / 2.7 = 24.44 °F\\n\\nSo, when the high temperature of 66 °F is divided by 2.7, the result is approximately 24.44 °F. Please note that this doesn't have a meteorological meaning; it's purely a mathematical operation based on the given temperature.\"}"
]
},
"execution_count": 5,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"from langchain.agents import AgentExecutor\n",
"\n",
"agent_executor = AgentExecutor(agent=agent, tools=tools)\n",
"agent_executor.invoke({\"content\": \"What's the weather in SF today divided by 2.7\"})"
]
},
{
"cell_type": "markdown",
"id": "2d0a0b1d-c1b3-4b50-9dce-1189b51a6206",
"metadata": {},
"source": [
"#### Custom execution"
]
},
{
"cell_type": "code",
"execution_count": 6,
"id": "c0475fa7-b6c1-4331-b8e2-55407466c724",
"metadata": {},
"outputs": [],
"source": [
"agent = OpenAIAssistantRunnable.create_assistant(\n",
" name=\"langchain assistant e2b tool\",\n",
" instructions=\"You are a personal math tutor. Write and run code to answer math questions.\",\n",
" tools=tools,\n",
" model=\"gpt-4-1106-preview\",\n",
" as_agent=True,\n",
")"
]
},
{
"cell_type": "code",
"execution_count": 7,
"id": "b76cb669-6aba-4827-868f-00aa960026f2",
"metadata": {},
"outputs": [],
"source": [
"from langchain.schema.agent import AgentFinish\n",
"\n",
"\n",
"def execute_agent(agent, tools, input):\n",
" tool_map = {tool.name: tool for tool in tools}\n",
" response = agent.invoke(input)\n",
" while not isinstance(response, AgentFinish):\n",
" tool_outputs = []\n",
" for action in response:\n",
" tool_output = tool_map[action.tool].invoke(action.tool_input)\n",
" print(action.tool, action.tool_input, tool_output, end=\"\\n\\n\")\n",
" tool_outputs.append(\n",
" {\"output\": tool_output, \"tool_call_id\": action.tool_call_id}\n",
" )\n",
" response = agent.invoke(\n",
" {\n",
" \"tool_outputs\": tool_outputs,\n",
" \"run_id\": action.run_id,\n",
" \"thread_id\": action.thread_id,\n",
" }\n",
" )\n",
"\n",
" return response"
]
},
{
"cell_type": "code",
"execution_count": 8,
"id": "7946116a-b82f-492e-835e-ca958a8949a5",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"e2b_data_analysis {'python_code': 'print(10 - 4 ** 2.7)'} {\"stdout\": \"-32.22425314473263\", \"stderr\": \"\", \"artifacts\": []}\n",
"\n",
"\\( 10 - 4^{2.7} \\) is approximately \\(-32.22425314473263\\).\n"
]
}
],
"source": [
"response = execute_agent(agent, tools, {\"content\": \"What's 10 - 4 raised to the 2.7\"})\n",
"print(response.return_values[\"output\"])"
]
},
{
"cell_type": "code",
"execution_count": 9,
"id": "f2744a56-9f4f-4899-827a-fa55821c318c",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"e2b_data_analysis {'python_code': 'result = 10 - 4 ** 2.7\\nprint(result + 17.241)'} {\"stdout\": \"-14.983253144732629\", \"stderr\": \"\", \"artifacts\": []}\n",
"\n",
"When you add \\( 17.241 \\) to \\( 10 - 4^{2.7} \\), the result is approximately \\( -14.98325314473263 \\).\n"
]
}
],
"source": [
"next_response = execute_agent(\n",
" agent, tools, {\"content\": \"now add 17.241\", \"thread_id\": response.thread_id}\n",
")\n",
"print(next_response.return_values[\"output\"])"
]
},
{
"cell_type": "markdown",
"id": "71c34763-d1e7-4b9a-a9d7-3e4cc0dfc2c4",
"metadata": {},
"source": [
"## [JSON mode](https://platform.openai.com/docs/guides/text-generation/json-mode)\n",
"\n",
"Constrain the model to only generate valid JSON. Note that you must include a system message with instructions to use JSON for this mode to work.\n",
"\n",
"Only works with certain models. "
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "db6072c4-f3f3-415d-872b-71ea9f3c02bb",
"metadata": {},
"outputs": [],
"source": [
"chat = ChatOpenAI(model=\"gpt-3.5-turbo-1106\").bind(\n",
" response_format={\"type\": \"json_object\"}\n",
")\n",
"\n",
"output = chat.invoke(\n",
" [\n",
" SystemMessage(\n",
" content=\"Extract the 'name' and 'origin' of any companies mentioned in the following statement. Return a JSON list.\"\n",
" ),\n",
" HumanMessage(\n",
" content=\"Google was founded in the USA, while Deepmind was founded in the UK\"\n",
" ),\n",
" ]\n",
")\n",
"print(output.content)"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "08e00ccf-b991-4249-846b-9500a0ccbfa0",
"metadata": {},
"outputs": [],
"source": [
"import json\n",
"\n",
"json.loads(output.content)"
]
},
{
"cell_type": "markdown",
"id": "aa9a94d9-4319-4ab7-a979-c475ce6b5f50",
"metadata": {},
"source": [
"## [System fingerprint](https://platform.openai.com/docs/guides/text-generation/reproducible-outputs)\n",
"\n",
"OpenAI sometimes changes model configurations in a way that impacts outputs. Whenever this happens, the system_fingerprint associated with a generation will change."
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "1281883c-bf8f-4665-89cd-4f33ccde69ab",
"metadata": {},
"outputs": [],
"source": [
"chat = ChatOpenAI(model=\"gpt-3.5-turbo-1106\")\n",
"output = chat.generate(\n",
" [\n",
" [\n",
" SystemMessage(\n",
" content=\"Extract the 'name' and 'origin' of any companies mentioned in the following statement. Return a JSON list.\"\n",
" ),\n",
" HumanMessage(\n",
" content=\"Google was founded in the USA, while Deepmind was founded in the UK\"\n",
" ),\n",
" ]\n",
" ]\n",
")\n",
"print(output.llm_output)"
]
},
{
"cell_type": "markdown",
"id": "aa6565be-985d-4127-848e-c3bca9d7b434",
"metadata": {},
"source": [
"## Breaking changes to Azure classes\n",
"\n",
"OpenAI V1 rewrote their clients and separated Azure and OpenAI clients. This has led to some changes in LangChain interfaces when using OpenAI V1.\n",
"\n",
"BREAKING CHANGES:\n",
"- To use Azure embeddings with OpenAI V1, you'll need to use the new `AzureOpenAIEmbeddings` instead of the existing `OpenAIEmbeddings`. `OpenAIEmbeddings` continue to work when using Azure with `openai<1`.\n",
"```python\n",
"from langchain.embeddings import AzureOpenAIEmbeddings\n",
"```\n",
"\n",
"\n",
"RECOMMENDED CHANGES:\n",
"- When using AzureChatOpenAI, if passing in an Azure endpoint (eg https://example-resource.azure.openai.com/) this should be specified via the `azure_endpoint` parameter or the `AZURE_OPENAI_ENDPOINT`. We're maintaining backwards compatibility for now with specifying this via `openai_api_base`/`base_url` or env var `OPENAI_API_BASE` but this shouldn't be relied upon.\n",
"- When using Azure chat or embedding models, pass in API keys either via `openai_api_key` parameter or `AZURE_OPENAI_API_KEY` parameter. We're maintaining backwards compatibility for now with specifying this via `OPENAI_API_KEY` but this shouldn't be relied upon."
]
},
{
"cell_type": "markdown",
"id": "49944887-3972-497e-8da2-6d32d44345a9",
"metadata": {},
"source": [
"## Tools\n",
"\n",
"Use tools for parallel function calling."
]
},
{
"cell_type": "code",
"execution_count": 3,
"id": "916292d8-0f89-40a6-af1c-5a1122327de8",
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"[GetCurrentWeather(location='New York, NY', unit='fahrenheit'),\n",
" GetCurrentWeather(location='Los Angeles, CA', unit='fahrenheit'),\n",
" GetCurrentWeather(location='San Francisco, CA', unit='fahrenheit')]"
]
},
"execution_count": 3,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"from typing import Literal\n",
"\n",
"from langchain.output_parsers.openai_tools import PydanticToolsParser\n",
"from langchain.utils.openai_functions import convert_pydantic_to_openai_tool\n",
"from langchain.prompts import ChatPromptTemplate\n",
"from langchain.pydantic_v1 import BaseModel, Field\n",
"\n",
"\n",
"class GetCurrentWeather(BaseModel):\n",
" \"\"\"Get the current weather in a location.\"\"\"\n",
"\n",
" location: str = Field(description=\"The city and state, e.g. San Francisco, CA\")\n",
" unit: Literal[\"celsius\", \"fahrenheit\"] = Field(\n",
" default=\"fahrenheit\", description=\"The temperature unit, default to fahrenheit\"\n",
" )\n",
"\n",
"\n",
"prompt = ChatPromptTemplate.from_messages(\n",
" [(\"system\", \"You are a helpful assistant\"), (\"user\", \"{input}\")]\n",
")\n",
"model = ChatOpenAI(model=\"gpt-3.5-turbo-1106\").bind(\n",
" tools=[convert_pydantic_to_openai_tool(GetCurrentWeather)]\n",
")\n",
"chain = prompt | model | PydanticToolsParser(tools=[GetCurrentWeather])\n",
"\n",
"chain.invoke({\"input\": \"what's the weather in NYC, LA, and SF\"})"
]
}
],
"metadata": {
"kernelspec": {
"display_name": "poetry-venv",
"language": "python",
"name": "poetry-venv"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.9.1"
}
},
"nbformat": 4,
"nbformat_minor": 5
}

View File

@@ -0,0 +1,688 @@
{
"cells": [
{
"attachments": {},
"cell_type": "markdown",
"metadata": {},
"source": [
"# Incoporating semantic similarity in tabular databases\n",
"\n",
"In this notebook we will cover how to run semantic search over a specific table column within a single SQL query, combining tabular query with RAG.\n",
"\n",
"\n",
"### Overall workflow\n",
"\n",
"1. Generating embeddings for a specific column\n",
"2. Storing the embeddings in a new column (if column has low cardinality, it's better to use another table containing unique values and their embeddings)\n",
"3. Querying using standard SQL queries with [PGVector](https://github.com/pgvector/pgvector) extension which allows using L2 distance (`<->`), Cosine distance (`<=>` or cosine similarity using `1 - <=>`) and Inner product (`<#>`)\n",
"4. Running standard SQL query\n",
"\n",
"### Requirements\n",
"\n",
"We will need a PostgreSQL database with [pgvector](https://github.com/pgvector/pgvector) extension enabled. For this example, we will use a `Chinook` database using a local PostgreSQL server."
]
},
{
"cell_type": "code",
"execution_count": 1,
"metadata": {},
"outputs": [],
"source": [
"import os\n",
"import getpass\n",
"\n",
"os.environ[\"OPENAI_API_KEY\"] = os.environ.get(\"OPENAI_API_KEY\") or getpass.getpass(\n",
" \"OpenAI API Key:\"\n",
")"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"from langchain.sql_database import SQLDatabase\n",
"from langchain.chat_models import ChatOpenAI\n",
"\n",
"CONNECTION_STRING = \"postgresql+psycopg2://postgres:test@localhost:5432/vectordb\" # Replace with your own\n",
"db = SQLDatabase.from_uri(CONNECTION_STRING)"
]
},
{
"attachments": {},
"cell_type": "markdown",
"metadata": {},
"source": [
"### Embedding the song titles"
]
},
{
"attachments": {},
"cell_type": "markdown",
"metadata": {},
"source": [
"For this example, we will run queries based on semantic meaning of song titles. In order to do this, let's start by adding a new column in the table for storing the embeddings:"
]
},
{
"cell_type": "code",
"execution_count": 3,
"metadata": {},
"outputs": [],
"source": [
"# db.run('ALTER TABLE \"Track\" ADD COLUMN \"embeddings\" vector;')"
]
},
{
"attachments": {},
"cell_type": "markdown",
"metadata": {},
"source": [
"Let's generate the embedding for each *track title* and store it as a new column in our \"Track\" table"
]
},
{
"cell_type": "code",
"execution_count": 4,
"metadata": {},
"outputs": [],
"source": [
"from langchain.embeddings import OpenAIEmbeddings\n",
"\n",
"embeddings_model = OpenAIEmbeddings()"
]
},
{
"cell_type": "code",
"execution_count": 5,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"3503"
]
},
"execution_count": 5,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"tracks = db.run('SELECT \"Name\" FROM \"Track\"')\n",
"song_titles = [s[0] for s in eval(tracks)]\n",
"title_embeddings = embeddings_model.embed_documents(song_titles)\n",
"len(title_embeddings)"
]
},
{
"attachments": {},
"cell_type": "markdown",
"metadata": {},
"source": [
"Now let's insert the embeddings in the into the new column from our table"
]
},
{
"cell_type": "code",
"execution_count": 6,
"metadata": {},
"outputs": [],
"source": [
"from tqdm import tqdm\n",
"\n",
"for i in tqdm(range(len(title_embeddings))):\n",
" title = titles[i].replace(\"'\", \"''\")\n",
" embedding = title_embeddings[i]\n",
" sql_command = (\n",
" f'UPDATE \"Track\" SET \"embeddings\" = ARRAY{embedding} WHERE \"Name\" ='\n",
" + f\"'{title}'\"\n",
" )\n",
" db.run(sql_command)"
]
},
{
"attachments": {},
"cell_type": "markdown",
"metadata": {},
"source": [
"We can test the semantic search running the following query:"
]
},
{
"cell_type": "code",
"execution_count": 7,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"'[(\"Tomorrow\\'s Dream\",), (\\'Remember Tomorrow\\',), (\\'Remember Tomorrow\\',), (\\'The Best Is Yet To Come\\',), (\"Thinking \\'Bout Tomorrow\",)]'"
]
},
"execution_count": 7,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"embeded_title = embeddings_model.embed_query(\"hope about the future\")\n",
"query = (\n",
" 'SELECT \"Track\".\"Name\" FROM \"Track\" WHERE \"Track\".\"embeddings\" IS NOT NULL ORDER BY \"embeddings\" <-> '\n",
" + f\"'{embeded_title}' LIMIT 5\"\n",
")\n",
"db.run(query)"
]
},
{
"attachments": {},
"cell_type": "markdown",
"metadata": {},
"source": [
"### Creating the SQL Chain"
]
},
{
"attachments": {},
"cell_type": "markdown",
"metadata": {},
"source": [
"Let's start by defining useful functions to get info from database and running the query:"
]
},
{
"cell_type": "code",
"execution_count": 8,
"metadata": {},
"outputs": [],
"source": [
"def get_schema(_):\n",
" return db.get_table_info()\n",
"\n",
"\n",
"def run_query(query):\n",
" return db.run(query)"
]
},
{
"attachments": {},
"cell_type": "markdown",
"metadata": {},
"source": [
"Now let's build the **prompt** we will use. This prompt is an extension from [text-to-postgres-sql](https://smith.langchain.com/hub/jacob/text-to-postgres-sql?organizationId=f9b614b8-5c3a-4e7c-afbc-6d7ad4fd8892) prompt"
]
},
{
"cell_type": "code",
"execution_count": 9,
"metadata": {},
"outputs": [],
"source": [
"from langchain.prompts import ChatPromptTemplate\n",
"\n",
"template = \"\"\"You are a Postgres expert. Given an input question, first create a syntactically correct Postgres query to run, then look at the results of the query and return the answer to the input question.\n",
"Unless the user specifies in the question a specific number of examples to obtain, query for at most 5 results using the LIMIT clause as per Postgres. You can order the results to return the most informative data in the database.\n",
"Never query for all columns from a table. You must query only the columns that are needed to answer the question. Wrap each column name in double quotes (\") to denote them as delimited identifiers.\n",
"Pay attention to use only the column names you can see in the tables below. Be careful to not query for columns that do not exist. Also, pay attention to which column is in which table.\n",
"Pay attention to use date('now') function to get the current date, if the question involves \"today\".\n",
"\n",
"You can use an extra extension which allows you to run semantic similarity using <-> operator on tables containing columns named \"embeddings\".\n",
"<-> operator can ONLY be used on embeddings columns.\n",
"The embeddings value for a given row typically represents the semantic meaning of that row.\n",
"The vector represents an embedding representation of the question, given below. \n",
"Do NOT fill in the vector values directly, but rather specify a `[search_word]` placeholder, which should contain the word that would be embedded for filtering.\n",
"For example, if the user asks for songs about 'the feeling of loneliness' the query could be:\n",
"'SELECT \"[whatever_table_name]\".\"SongName\" FROM \"[whatever_table_name]\" ORDER BY \"embeddings\" <-> '[loneliness]' LIMIT 5'\n",
"\n",
"Use the following format:\n",
"\n",
"Question: <Question here>\n",
"SQLQuery: <SQL Query to run>\n",
"SQLResult: <Result of the SQLQuery>\n",
"Answer: <Final answer here>\n",
"\n",
"Only use the following tables:\n",
"\n",
"{schema}\n",
"\"\"\"\n",
"\n",
"\n",
"prompt = ChatPromptTemplate.from_messages(\n",
" [(\"system\", template), (\"human\", \"{question}\")]\n",
")"
]
},
{
"attachments": {},
"cell_type": "markdown",
"metadata": {},
"source": [
"And we can create the chain using **[LangChain Expression Language](https://python.langchain.com/docs/expression_language/)**:"
]
},
{
"cell_type": "code",
"execution_count": 10,
"metadata": {},
"outputs": [],
"source": [
"from langchain.chat_models import ChatOpenAI\n",
"from langchain.schema.output_parser import StrOutputParser\n",
"from langchain.schema.runnable import RunnablePassthrough\n",
"\n",
"db = SQLDatabase.from_uri(\n",
" CONNECTION_STRING\n",
") # We reconnect to db so the new columns are loaded as well.\n",
"llm = ChatOpenAI(model_name=\"gpt-4\", temperature=0)\n",
"\n",
"sql_query_chain = (\n",
" RunnablePassthrough.assign(schema=get_schema)\n",
" | prompt\n",
" | llm.bind(stop=[\"\\nSQLResult:\"])\n",
" | StrOutputParser()\n",
")"
]
},
{
"cell_type": "code",
"execution_count": 11,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"'SQLQuery: SELECT \"Track\".\"Name\" FROM \"Track\" JOIN \"Genre\" ON \"Track\".\"GenreId\" = \"Genre\".\"GenreId\" WHERE \"Genre\".\"Name\" = \\'Rock\\' ORDER BY \"Track\".\"embeddings\" <-> \\'[dispair]\\' LIMIT 5'"
]
},
"execution_count": 11,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"sql_query_chain.invoke(\n",
" {\n",
" \"question\": \"Which are the 5 rock songs with titles about deep feeling of dispair?\"\n",
" }\n",
")"
]
},
{
"attachments": {},
"cell_type": "markdown",
"metadata": {},
"source": [
"This chain simply generates the query. Now we will create the full chain that also handles the execution and the final result for the user:"
]
},
{
"cell_type": "code",
"execution_count": 12,
"metadata": {},
"outputs": [],
"source": [
"import re\n",
"from langchain.schema.runnable import RunnableLambda\n",
"\n",
"\n",
"def replace_brackets(match):\n",
" words_inside_brackets = match.group(1).split(\", \")\n",
" embedded_words = [\n",
" str(embeddings_model.embed_query(word)) for word in words_inside_brackets\n",
" ]\n",
" return \"', '\".join(embedded_words)\n",
"\n",
"\n",
"def get_query(query):\n",
" sql_query = re.sub(r\"\\[([\\w\\s,]+)\\]\", replace_brackets, query)\n",
" return sql_query\n",
"\n",
"\n",
"template = \"\"\"Based on the table schema below, question, sql query, and sql response, write a natural language response:\n",
"{schema}\n",
"\n",
"Question: {question}\n",
"SQL Query: {query}\n",
"SQL Response: {response}\"\"\"\n",
"\n",
"prompt = ChatPromptTemplate.from_messages(\n",
" [(\"system\", template), (\"human\", \"{question}\")]\n",
")\n",
"\n",
"full_chain = (\n",
" RunnablePassthrough.assign(query=sql_query_chain)\n",
" | RunnablePassthrough.assign(\n",
" schema=get_schema,\n",
" response=RunnableLambda(lambda x: db.run(get_query(x[\"query\"]))),\n",
" )\n",
" | prompt\n",
" | llm\n",
")"
]
},
{
"attachments": {},
"cell_type": "markdown",
"metadata": {},
"source": [
"## Using the Chain"
]
},
{
"attachments": {},
"cell_type": "markdown",
"metadata": {},
"source": [
"### Example 1: Filtering a column based on semantic meaning"
]
},
{
"attachments": {},
"cell_type": "markdown",
"metadata": {},
"source": [
"Let's say we want to retrieve songs that express `deep feeling of dispair`, but filtering based on genre:"
]
},
{
"cell_type": "code",
"execution_count": 11,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"AIMessage(content=\"The 5 rock songs with titles that convey a deep feeling of despair are 'Sea Of Sorrow', 'Surrender', 'Indifference', 'Hard Luck Woman', and 'Desire'.\")"
]
},
"execution_count": 11,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"full_chain.invoke(\n",
" {\n",
" \"question\": \"Which are the 5 rock songs with titles about deep feeling of dispair?\"\n",
" }\n",
")"
]
},
{
"attachments": {},
"cell_type": "markdown",
"metadata": {},
"source": [
"What is substantially different in implementing this method is that we have combined:\n",
"- Semantic search (songs that have titles with some semantic meaning)\n",
"- Traditional tabular querying (running JOIN statements to filter track based on genre)\n",
"\n",
"This is something we _could_ potentially achieve using metadata filtering, but it's more complex to do so (we would need to use a vector database containing the embeddings, and use metadata filtering based on genre).\n",
"\n",
"However, for other use cases metadata filtering **wouldn't be enough**."
]
},
{
"attachments": {},
"cell_type": "markdown",
"metadata": {},
"source": [
"### Example 2: Combining filters"
]
},
{
"cell_type": "code",
"execution_count": 29,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"AIMessage(content=\"The three albums which have the most amount of songs in the top 150 saddest songs are 'International Superhits' with 5 songs, 'Ten' with 4 songs, and 'Album Of The Year' with 3 songs.\")"
]
},
"execution_count": 29,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"full_chain.invoke(\n",
" {\n",
" \"question\": \"I want to know the 3 albums which have the most amount of songs in the top 150 saddest songs\"\n",
" }\n",
")"
]
},
{
"attachments": {},
"cell_type": "markdown",
"metadata": {},
"source": [
"So we have result for 3 albums with most amount of songs in top 150 saddest ones. This **wouldn't** be possible using only standard metadata filtering. Without this _hybdrid query_, we would need some postprocessing to get the result.\n",
"\n",
"Another similar exmaple:"
]
},
{
"cell_type": "code",
"execution_count": 30,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"AIMessage(content=\"The 6 albums with the shortest titles that contain songs which are in the 20 saddest song list are 'Ten', 'Core', 'Big Ones', 'One By One', 'Black Album', and 'Miles Ahead'.\")"
]
},
"execution_count": 30,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"full_chain.invoke(\n",
" {\n",
" \"question\": \"I need the 6 albums with shortest title, as long as they contain songs which are in the 20 saddest song list.\"\n",
" }\n",
")"
]
},
{
"attachments": {},
"cell_type": "markdown",
"metadata": {},
"source": [
"Let's see what the query looks like to double check:"
]
},
{
"cell_type": "code",
"execution_count": 32,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"WITH \"SadSongs\" AS (\n",
" SELECT \"TrackId\" FROM \"Track\" \n",
" ORDER BY \"embeddings\" <-> '[sad]' LIMIT 20\n",
"),\n",
"\"SadAlbums\" AS (\n",
" SELECT DISTINCT \"AlbumId\" FROM \"Track\" \n",
" WHERE \"TrackId\" IN (SELECT \"TrackId\" FROM \"SadSongs\")\n",
")\n",
"SELECT \"Album\".\"Title\" FROM \"Album\" \n",
"WHERE \"AlbumId\" IN (SELECT \"AlbumId\" FROM \"SadAlbums\") \n",
"ORDER BY \"title_len\" ASC \n",
"LIMIT 6\n"
]
}
],
"source": [
"print(\n",
" sql_query_chain.invoke(\n",
" {\n",
" \"question\": \"I need the 6 albums with shortest title, as long as they contain songs which are in the 20 saddest song list.\"\n",
" }\n",
" )\n",
")"
]
},
{
"attachments": {},
"cell_type": "markdown",
"metadata": {},
"source": [
"### Example 3: Combining two separate semantic searches\n",
"\n",
"One interesting aspect of this approach which is **substantially different from using standar RAG** is that we can even **combine** two semantic search filters:\n",
"- _Get 5 saddest songs..._\n",
"- _**...obtained from albums with \"lovely\" titles**_\n",
"\n",
"This could generalize to **any kind of combined RAG** (paragraphs discussing _X_ topic belonging from books about _Y_, replies to a tweet about _ABC_ topic that express _XYZ_ feeling)\n",
"\n",
"We will combine semantic search on songs and album titles, so we need to do the same for `Album` table:\n",
"1. Generate the embeddings\n",
"2. Add them to the table as a new column (which we need to add in the table)"
]
},
{
"cell_type": "code",
"execution_count": 60,
"metadata": {},
"outputs": [],
"source": [
"# db.run('ALTER TABLE \"Album\" ADD COLUMN \"embeddings\" vector;')"
]
},
{
"cell_type": "code",
"execution_count": 43,
"metadata": {},
"outputs": [
{
"name": "stderr",
"output_type": "stream",
"text": [
"100%|██████████| 347/347 [00:01<00:00, 179.64it/s]\n"
]
}
],
"source": [
"albums = db.run('SELECT \"Title\" FROM \"Album\"')\n",
"album_titles = [title[0] for title in eval(albums)]\n",
"album_title_embeddings = embeddings_model.embed_documents(album_titles)\n",
"for i in tqdm(range(len(album_title_embeddings))):\n",
" album_title = album_titles[i].replace(\"'\", \"''\")\n",
" album_embedding = album_title_embeddings[i]\n",
" sql_command = (\n",
" f'UPDATE \"Album\" SET \"embeddings\" = ARRAY{album_embedding} WHERE \"Title\" ='\n",
" + f\"'{album_title}'\"\n",
" )\n",
" db.run(sql_command)"
]
},
{
"cell_type": "code",
"execution_count": 45,
"metadata": {
"scrolled": true
},
"outputs": [
{
"data": {
"text/plain": [
"\"[('Realize',), ('Morning Dance',), ('Into The Light',), ('New Adventures In Hi-Fi',), ('Miles Ahead',)]\""
]
},
"execution_count": 45,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"embeded_title = embeddings_model.embed_query(\"hope about the future\")\n",
"query = (\n",
" 'SELECT \"Album\".\"Title\" FROM \"Album\" WHERE \"Album\".\"embeddings\" IS NOT NULL ORDER BY \"embeddings\" <-> '\n",
" + f\"'{embeded_title}' LIMIT 5\"\n",
")\n",
"db.run(query)"
]
},
{
"attachments": {},
"cell_type": "markdown",
"metadata": {},
"source": [
"Now we can combine both filters:"
]
},
{
"cell_type": "code",
"execution_count": 54,
"metadata": {},
"outputs": [],
"source": [
"db = SQLDatabase.from_uri(\n",
" CONNECTION_STRING\n",
") # We reconnect to dbso the new columns are loaded as well."
]
},
{
"cell_type": "code",
"execution_count": 49,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"AIMessage(content='The songs about breakouts obtained from the top 5 albums about love are \\'Royal Orleans\\', \"Nobody\\'s Fault But Mine\", \\'Achilles Last Stand\\', \\'For Your Life\\', and \\'Hots On For Nowhere\\'.')"
]
},
"execution_count": 49,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"full_chain.invoke(\n",
" {\n",
" \"question\": \"I want to know songs about breakouts obtained from top 5 albums about love\"\n",
" }\n",
")"
]
},
{
"attachments": {},
"cell_type": "markdown",
"metadata": {},
"source": [
"This is something **different** that **couldn't be achieved** using standard metadata filtering over a vectordb."
]
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3 (ipykernel)",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.8.18"
}
},
"nbformat": 4,
"nbformat_minor": 2
}

View File

@@ -35,7 +35,7 @@
"tags": []
},
"source": [
"### API keys and other secrats\n",
"### API keys and other secrets\n",
"\n",
"We use an `.ini` file, like this: \n",
"```\n",

View File

@@ -15,7 +15,7 @@ poetry run python scripts/model_feat_table.py
poetry run nbdoc_build --srcdir docs
cp ../cookbook/README.md src/pages/cookbook.mdx
cp ../.github/CONTRIBUTING.md docs/contributing.md
wget https://raw.githubusercontent.com/langchain-ai/langserve/main/README.md -O docs/guides/deployments/langserve.md
wget https://raw.githubusercontent.com/langchain-ai/langserve/main/README.md -O docs/langserve.md
poetry run python scripts/generate_api_reference_links.py
yarn install
yarn start

File diff suppressed because one or more lines are too long

View File

@@ -6,10 +6,13 @@ Below are links to tutorials and courses on LangChain. For written guides on com
---------------------
### [LangChain on Wikipedia](https://en.wikipedia.org/wiki/LangChain)
### DeepLearning.AI courses
by [Harrison Chase](https://github.com/hwchase17) and [Andrew Ng](https://en.wikipedia.org/wiki/Andrew_Ng)
by [Harrison Chase](https://en.wikipedia.org/wiki/LangChain) and [Andrew Ng](https://en.wikipedia.org/wiki/Andrew_Ng)
- [LangChain for LLM Application Development](https://learn.deeplearning.ai/langchain)
- [LangChain Chat with Your Data](https://learn.deeplearning.ai/langchain-chat-with-your-data)
- ⛓ [Functions, Tools and Agents with LangChain](https://learn.deeplearning.ai/functions-tools-agents-langchain)
### Handbook
[LangChain AI Handbook](https://www.pinecone.io/learn/langchain/) By **James Briggs** and **Francisco Ingham**

View File

@@ -73,7 +73,7 @@
"source": [
"chain = (\n",
" RunnablePassthrough.assign(\n",
" memory=RunnableLambda(memory.load_memory_variables) | itemgetter(\"history\")\n",
" history=RunnableLambda(memory.load_memory_variables) | itemgetter(\"history\")\n",
" )\n",
" | prompt\n",
" | model\n",

View File

@@ -30,7 +30,7 @@
"source": [
"## PromptTemplate + LLM\n",
"\n",
"The simplest composition is just combing a prompt and model to create a chain that takes user input, adds it to a prompt, passes it to a model, and returns the raw model output.\n",
"The simplest composition is just combining a prompt and model to create a chain that takes user input, adds it to a prompt, passes it to a model, and returns the raw model output.\n",
"\n",
"Note, you can mix and match PromptTemplate/ChatPromptTemplates and LLMs/ChatModels as you like here."
]

View File

@@ -12,6 +12,19 @@
"Suppose we have a simple prompt + model sequence:"
]
},
{
"cell_type": "code",
"execution_count": 1,
"id": "950297ed-2d67-4091-8ea7-1d412d259d04",
"metadata": {},
"outputs": [],
"source": [
"from langchain.chat_models import ChatOpenAI\n",
"from langchain.prompts import ChatPromptTemplate\n",
"from langchain.schema import StrOutputParser\n",
"from langchain.schema.runnable import RunnablePassthrough"
]
},
{
"cell_type": "code",
"execution_count": 11,
@@ -37,11 +50,6 @@
}
],
"source": [
"from langchain.chat_models import ChatOpenAI\n",
"from langchain.prompts import ChatPromptTemplate\n",
"from langchain.schema import StrOutputParser\n",
"from langchain.schema.runnable import RunnablePassthrough\n",
"\n",
"prompt = ChatPromptTemplate.from_messages(\n",
" [\n",
" (\n",
@@ -105,31 +113,29 @@
},
{
"cell_type": "code",
"execution_count": 14,
"execution_count": 3,
"id": "f66a0fe4-fde0-4706-8863-d60253f211c7",
"metadata": {},
"outputs": [],
"source": [
"functions = [\n",
" {\n",
" \"name\": \"solver\",\n",
" \"description\": \"Formulates and solves an equation\",\n",
" \"parameters\": {\n",
" \"type\": \"object\",\n",
" \"properties\": {\n",
" \"equation\": {\n",
" \"type\": \"string\",\n",
" \"description\": \"The algebraic expression of the equation\",\n",
" },\n",
" \"solution\": {\n",
" \"type\": \"string\",\n",
" \"description\": \"The solution to the equation\",\n",
" },\n",
"function = {\n",
" \"name\": \"solver\",\n",
" \"description\": \"Formulates and solves an equation\",\n",
" \"parameters\": {\n",
" \"type\": \"object\",\n",
" \"properties\": {\n",
" \"equation\": {\n",
" \"type\": \"string\",\n",
" \"description\": \"The algebraic expression of the equation\",\n",
" },\n",
" \"solution\": {\n",
" \"type\": \"string\",\n",
" \"description\": \"The solution to the equation\",\n",
" },\n",
" \"required\": [\"equation\", \"solution\"],\n",
" },\n",
" }\n",
"]"
" \"required\": [\"equation\", \"solution\"],\n",
" },\n",
"}"
]
},
{
@@ -161,19 +167,70 @@
" ]\n",
")\n",
"model = ChatOpenAI(model=\"gpt-4\", temperature=0).bind(\n",
" function_call={\"name\": \"solver\"}, functions=functions\n",
" function_call={\"name\": \"solver\"}, functions=[function]\n",
")\n",
"runnable = {\"equation_statement\": RunnablePassthrough()} | prompt | model\n",
"runnable.invoke(\"x raised to the third plus seven equals 12\")"
]
},
{
"cell_type": "markdown",
"id": "f07d7528-9269-4d6f-b12e-3669592a9e03",
"metadata": {},
"source": [
"## Attaching OpenAI tools"
]
},
{
"cell_type": "code",
"execution_count": null,
"execution_count": 5,
"id": "2cdeeb4c-0c1f-43da-bd58-4f591d9e0671",
"metadata": {},
"outputs": [],
"source": []
"source": [
"tools = [\n",
" {\n",
" \"type\": \"function\",\n",
" \"function\": {\n",
" \"name\": \"get_current_weather\",\n",
" \"description\": \"Get the current weather in a given location\",\n",
" \"parameters\": {\n",
" \"type\": \"object\",\n",
" \"properties\": {\n",
" \"location\": {\n",
" \"type\": \"string\",\n",
" \"description\": \"The city and state, e.g. San Francisco, CA\",\n",
" },\n",
" \"unit\": {\"type\": \"string\", \"enum\": [\"celsius\", \"fahrenheit\"]},\n",
" },\n",
" \"required\": [\"location\"],\n",
" },\n",
" },\n",
" }\n",
"]"
]
},
{
"cell_type": "code",
"execution_count": 9,
"id": "2b65beab-48bb-46ff-a5a4-ef8ac95a513c",
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"AIMessage(content='', additional_kwargs={'tool_calls': [{'id': 'call_zHN0ZHwrxM7nZDdqTp6dkPko', 'function': {'arguments': '{\"location\": \"San Francisco, CA\", \"unit\": \"celsius\"}', 'name': 'get_current_weather'}, 'type': 'function'}, {'id': 'call_aqdMm9HBSlFW9c9rqxTa7eQv', 'function': {'arguments': '{\"location\": \"New York, NY\", \"unit\": \"celsius\"}', 'name': 'get_current_weather'}, 'type': 'function'}, {'id': 'call_cx8E567zcLzYV2WSWVgO63f1', 'function': {'arguments': '{\"location\": \"Los Angeles, CA\", \"unit\": \"celsius\"}', 'name': 'get_current_weather'}, 'type': 'function'}]})"
]
},
"execution_count": 9,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"model = ChatOpenAI(model=\"gpt-3.5-turbo-1106\").bind(tools=tools)\n",
"model.invoke(\"What's the weather in SF, NYC and LA?\")"
]
}
],
"metadata": {

View File

@@ -5,7 +5,7 @@
"id": "39eaf61b",
"metadata": {},
"source": [
"# Configuration\n",
"# Configure chain internals at runtime\n",
"\n",
"Oftentimes you may want to experiment with, or even expose to the end user, multiple different ways of doing things.\n",
"In order to make this experience as easy as possible, we have defined two methods.\n",
@@ -594,7 +594,7 @@
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.10.1"
"version": "3.9.1"
}
},
"nbformat": 4,

View File

@@ -5,7 +5,7 @@
"id": "fbc4bf6e",
"metadata": {},
"source": [
"# Run arbitrary functions\n",
"# Run custom functions\n",
"\n",
"You can use arbitrary functions in the pipeline\n",
"\n",
@@ -175,7 +175,7 @@
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.10.1"
"version": "3.9.1"
}
},
"nbformat": 4,

View File

@@ -4,7 +4,7 @@
"cell_type": "markdown",
"metadata": {},
"source": [
"# Custom generator functions\n",
"# Stream custom generator functions\n",
"\n",
"You can use generator functions (ie. functions that use the `yield` keyword, and behave like iterators) in a LCEL pipeline.\n",
"\n",
@@ -21,15 +21,7 @@
"cell_type": "code",
"execution_count": 1,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"lion, tiger, wolf, gorilla, panda\n"
]
}
],
"outputs": [],
"source": [
"from typing import Iterator, List\n",
"\n",
@@ -43,16 +35,51 @@
")\n",
"model = ChatOpenAI(temperature=0.0)\n",
"\n",
"\n",
"str_chain = prompt | model | StrOutputParser()\n",
"\n",
"print(str_chain.invoke({\"animal\": \"bear\"}))"
"str_chain = prompt | model | StrOutputParser()"
]
},
{
"cell_type": "code",
"execution_count": 2,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"lion, tiger, wolf, gorilla, panda"
]
}
],
"source": [
"for chunk in str_chain.stream({\"animal\": \"bear\"}):\n",
" print(chunk, end=\"\", flush=True)"
]
},
{
"cell_type": "code",
"execution_count": 8,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"'lion, tiger, wolf, gorilla, panda'"
]
},
"execution_count": 8,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"str_chain.invoke({\"animal\": \"bear\"})"
]
},
{
"cell_type": "code",
"execution_count": 4,
"metadata": {},
"outputs": [],
"source": [
"# This is a custom parser that splits an iterator of llm tokens\n",
@@ -77,22 +104,61 @@
},
{
"cell_type": "code",
"execution_count": 3,
"execution_count": 5,
"metadata": {},
"outputs": [],
"source": [
"list_chain = str_chain | split_into_list"
]
},
{
"cell_type": "code",
"execution_count": 6,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"['lion', 'tiger', 'wolf', 'gorilla', 'panda']\n"
"['lion']\n",
"['tiger']\n",
"['wolf']\n",
"['gorilla']\n",
"['panda']\n"
]
}
],
"source": [
"list_chain = str_chain | split_into_list\n",
"\n",
"print(list_chain.invoke({\"animal\": \"bear\"}))"
"for chunk in list_chain.stream({\"animal\": \"bear\"}):\n",
" print(chunk, flush=True)"
]
},
{
"cell_type": "code",
"execution_count": 7,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"['lion', 'tiger', 'wolf', 'gorilla', 'panda']"
]
},
"execution_count": 7,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"list_chain.invoke({\"animal\": \"bear\"})"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": []
}
],
"metadata": {
@@ -111,9 +177,9 @@
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.11.5"
"version": "3.9.1"
}
},
"nbformat": 4,
"nbformat_minor": 2
"nbformat_minor": 4
}

View File

@@ -5,7 +5,7 @@
"id": "b022ab74-794d-4c54-ad47-ff9549ddb9d2",
"metadata": {},
"source": [
"# Use RunnableParallel/RunnableMap\n",
"# Parallelize steps\n",
"\n",
"RunnableParallel (aka. RunnableMap) makes it easy to execute multiple Runnables in parallel, and to return the output of these Runnables as a map."
]
@@ -195,7 +195,7 @@
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.10.1"
"version": "3.9.1"
}
},
"nbformat": 4,

View File

@@ -5,7 +5,7 @@
"id": "4b47436a",
"metadata": {},
"source": [
"# Route between multiple Runnables\n",
"# Dynamically route logic based on input\n",
"\n",
"This notebook covers how to do routing in the LangChain Expression Language.\n",
"\n",

View File

@@ -4,33 +4,30 @@ sidebar_class_name: hidden
# LangChain Expression Language (LCEL)
LangChain Expression Language or LCEL is a declarative way to easily compose chains together.
There are several benefits to writing chains in this manner (as opposed to writing normal code):
LangChain Expression Language, or LCEL, is a declarative way to easily compose chains together.
LCEL was designed from day 1 to **support putting prototypes in production, with no code changes**, from the simplest “prompt + LLM” chain to the most complex chains (weve seen folks successfully run LCEL chains with 100s of steps in production). To highlight a few of the reasons you might want to use LCEL:
**Async, Batch, and Streaming Support**
Any chain constructed this way will automatically have full sync, async, batch, and streaming support.
This makes it easy to prototype a chain in a Jupyter notebook using the sync interface, and then expose it as an async streaming interface.
**Streaming support**
When you build your chains with LCEL you get the best possible time-to-first-token (time elapsed until the first chunk of output comes out). For some chains this means eg. we stream tokens straight from an LLM to a streaming output parser, and you get back parsed, incremental chunks of output at the same rate as the LLM provider outputs the raw tokens.
**Fallbacks**
The non-determinism of LLMs makes it important to be able to handle errors gracefully.
With LCEL you can easily attach fallbacks to any chain.
**Async support**
Any chain built with LCEL can be called both with the synchronous API (eg. in your Jupyter notebook while prototyping) as well as with the asynchronous API (eg. in a [LangServe](/docs/langsmith) server). This enables using the same code for prototypes and in production, with great performance, and the ability to handle many concurrent requests in the same server.
**Parallelism**
Since LLM applications involve (sometimes long) API calls, it often becomes important to run things in parallel.
With LCEL syntax, any components that can be run in parallel automatically are.
**Optimized parallel execution**
Whenever your LCEL chains have steps that can be executed in parallel (eg if you fetch documents from multiple retrievers) we automatically do it, both in the sync and the async interfaces, for the smallest possible latency.
**Seamless LangSmith Tracing Integration**
**Retries and fallbacks**
Configure retries and fallbacks for any part of your LCEL chain. This is a great way to make your chains more reliable at scale. Were currently working on adding streaming support for retries/fallbacks, so you can get the added reliability without any latency cost.
**Access intermediate results**
For more complex chains its often very useful to access the results of intermediate steps even before the final output is produced. This can be used let end-users know something is happening, or even just to debug your chain. You can stream intermediate results, and its available on every [LangServe](/docs/langserve) server.
**Input and output schemas**
Input and output schemas give every LCEL chain Pydantic and JSONSchema schemas inferred from the structure of your chain. This can be used for validation of inputs and outputs, and is an integral part of LangServe.
**Seamless LangSmith tracing integration**
As your chains get more and more complex, it becomes increasingly important to understand what exactly is happening at every step.
With LCEL, **all** steps are automatically logged to [LangSmith](https://smith.langchain.com) for maximal observability and debuggability.
With LCEL, **all** steps are automatically logged to [LangSmith](/docs/langsmith/) for maximum observability and debuggability.
#### [Interface](/docs/expression_language/interface)
The base interface shared by all LCEL objects
#### [How to](/docs/expression_language/how_to)
How to use core features of LCEL
#### [Cookbook](/docs/expression_language/cookbook)
Examples of common LCEL usage patterns
#### [Why use LCEL](/docs/expression_language/why)
A deeper dive into the benefits of LCEL
**Seamless LangServe deployment integration**
Any chain created with LCEL can be easily deployed using LangServe.

View File

@@ -8,7 +8,7 @@
"---\n",
"sidebar_position: 0\n",
"title: Interface\n",
"---\n"
"---"
]
},
{
@@ -31,26 +31,17 @@
"- [`abatch`](#async-batch): call the chain on a list of inputs async\n",
"- [`astream_log`](#async-stream-intermediate-steps): stream back intermediate steps as they happen, in addition to the final response\n",
"\n",
"The **input type** varies by component:\n",
"The **input type** and **output type** varies by component:\n",
"\n",
"| Component | Input Type |\n",
"| --- | --- |\n",
"|Prompt|Dictionary|\n",
"|Retriever|Single string|\n",
"|LLM, ChatModel| Single string, list of chat messages or a PromptValue|\n",
"|Tool|Single string, or dictionary, depending on the tool|\n",
"|OutputParser|The output of an LLM or ChatModel|\n",
"| Component | Input Type | Output Type |\n",
"| --- | --- | --- |\n",
"| Prompt | Dictionary | PromptValue |\n",
"| ChatModel | Single string, list of chat messages or a PromptValue | ChatMessage |\n",
"| LLM | Single string, list of chat messages or a PromptValue | String |\n",
"| OutputParser | The output of an LLM or ChatModel | Depends on the parser |\n",
"| Retriever | Single string | List of Documents |\n",
"| Tool | Single string or dictionary, depending on the tool | Depends on the tool |\n",
"\n",
"The **output type** also varies by component:\n",
"\n",
"| Component | Output Type |\n",
"| --- | --- |\n",
"| LLM | String |\n",
"| ChatModel | ChatMessage |\n",
"| Prompt | PromptValue |\n",
"| Retriever | List of documents |\n",
"| Tool | Depends on the tool |\n",
"| OutputParser | Depends on the parser |\n",
"\n",
"All runnables expose input and output **schemas** to inspect the inputs and outputs:\n",
"- [`input_schema`](#input-schema): an input Pydantic model auto-generated from the structure of the Runnable\n",
@@ -1161,7 +1152,7 @@
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.10.12"
"version": "3.9.1"
}
},
"nbformat": 4,

View File

@@ -1,11 +0,0 @@
# Why use LCEL?
The LangChain Expression Language was designed from day 1 to **support putting prototypes in production, with no code changes**, from the simplest “prompt + LLM” chain to the most complex chains (weve seen folks successfully running in production LCEL chains with 100s of steps). To highlight a few of the reasons you might want to use LCEL:
- first-class support for streaming: when you build your chains with LCEL you get the best possible time-to-first-token (time elapsed until the first chunk of output comes out). For some chains this means eg. we stream tokens straight from an LLM to a streaming output parser, and you get back parsed, incremental chunks of output at the same rate as the LLM provider outputs the raw tokens. Were constantly improving streaming support, recently we added a [streaming JSON parser](https://twitter.com/LangChainAI/status/1709690468030914584), and more is in the works.
- first-class async support: any chain built with LCEL can be called both with the synchronous API (eg. in your Jupyter notebook while prototyping) as well as with the asynchronous API (eg. in a [LangServe](https://github.com/langchain-ai/langserve) server). This enables using the same code for prototypes and in production, with great performance, and the ability to handle many concurrent requests in the same server.
- optimised parallel execution: whenever your LCEL chains have steps that can be executed in parallel (eg if you fetch documents from multiple retrievers) we automatically do it, both in the sync and the async interfaces, for the smallest possible latency.
- support for retries and fallbacks: more recently weve added support for configuring retries and fallbacks for any part of your LCEL chain. This is a great way to make your chains more reliable at scale. Were currently working on adding streaming support for retries/fallbacks, so you can get the added reliability without any latency cost.
- accessing intermediate results: for more complex chains its often very useful to access the results of intermediate steps even before the final output is produced. This can be used let end-users know something is happening, or even just to debug your chain. Weve added support for [streaming intermediate results](https://x.com/LangChainAI/status/1711806009097044193?s=20), and its available on every LangServe server.
- [input and output schemas](https://x.com/LangChainAI/status/1711805322195861934?s=20): input and output schemas give every LCEL chain Pydantic and JSONSchema schemas inferred from the structure of your chain. This can be used for validation of inputs and outputs, and is an integral part of LangServe.
- tracing with LangSmith: all chains built with LCEL have first-class tracing support, which can be used to debug your chains, or to understand whats happening in production. To enable this all you have to do is add your [LangSmith](https://www.langchain.com/langsmith) API key as an environment variable.

View File

@@ -19,26 +19,7 @@ import CodeBlock from "@theme/CodeBlock";
This will install the bare minimum requirements of LangChain.
A lot of the value of LangChain comes when integrating it with various model providers, datastores, etc.
By default, the dependencies needed to do that are NOT installed.
However, there are two other ways to install LangChain that do bring in those dependencies.
To install modules needed for the common LLM providers, run:
```bash
pip install langchain[llms]
```
To install all modules needed for all integrations, run:
```bash
pip install langchain[all]
```
Note that if you are using `zsh`, you'll need to quote square brackets when passing them as an argument to a command, for example:
```bash
pip install 'langchain[all]'
```
By default, the dependencies needed to do that are NOT installed. You will need to install the dependencies for specific integrations separately.
## From source
@@ -47,3 +28,37 @@ If you want to install from source, you can do so by cloning the repo and be sur
```bash
pip install -e .
```
## Langchain experimental
The `langchain-experimental` package holds experimental LangChain code, intended for research and experimental uses.
Install with:
```bash
pip install langchain-experimental
```
## LangChain CLI
The LangChain CLI is useful for working with LangChain templates and other LangServe projects.
Install with:
```bash
pip install langchain-cli
```
## LangServe
LangServe helps developers deploy LangChain runnables and chains as a REST API.
LangServe is automatically installed by LangChain CLI.
If not using LangChain CLI, install with:
```bash
pip install "langserve[all]"
```
for both client and server dependencies. Or `pip install "langserve[client]"` for client code, and `pip install "langserve[server]"` for server code.
## LangSmith SDK
The LangSmith SDK is automatically installed by LangChain.
If not using LangChain, install with:
```bash
pip install langsmith
```

View File

@@ -8,11 +8,26 @@ sidebar_position: 0
- **Are context-aware**: connect a language model to sources of context (prompt instructions, few shot examples, content to ground its response in, etc.)
- **Reason**: rely on a language model to reason (about how to answer based on provided context, what actions to take, etc.)
The main value props of LangChain are:
1. **Components**: abstractions for working with language models, along with a collection of implementations for each abstraction. Components are modular and easy-to-use, whether you are using the rest of the LangChain framework or not
2. **Off-the-shelf chains**: a structured assembly of components for accomplishing specific higher-level tasks
This framework consists of several parts.
- **LangChain Libraries**: The Python and JavaScript libraries. Contains interfaces and integrations for a myriad of components, a basic run time for combining these components into chains and agents, and off-the-shelf implementations of chains and agents.
- **[LangChain Templates](/docs/templates)**: A collection of easily deployable reference architectures for a wide variety of tasks.
- **[LangServe](/docs/langserve)**: A library for deploying LangChain chains as a REST API.
- **[LangSmith](/docs/langsmith)**: A developer platform that lets you debug, test, evaluate, and monitor chains built on any LLM framework and seamlessly integrates with LangChain.
Off-the-shelf chains make it easy to get started. For complex applications, components make it easy to customize existing chains and build new ones.
![LangChain Diagram](/img/langchain_stack.png)
Together, these products simplify the entire application lifecycle:
- **Develop**: Write your applications in LangChain/LangChain.js. Hit the ground running using Templates for reference.
- **Productionize**: Use LangSmith to inspect, test and monitor your chains, so that you can constantly improve and deploy with confidence.
- **Deploy**: Turn any chain into an API with LangServe.
## LangChain Libraries
The main value props of the LangChain packages are:
1. **Components**: composable tools and integrations for working with language models. Components are modular and easy-to-use, whether you are using the rest of the LangChain framework or not
2. **Off-the-shelf chains**: built-in assemblages of components for accomplishing higher-level tasks
Off-the-shelf chains make it easy to get started. Components make it easy to customize existing chains and build new ones.
## Get started
@@ -20,45 +35,59 @@ Off-the-shelf chains make it easy to get started. For complex applications, comp
We recommend following our [Quickstart](/docs/get_started/quickstart) guide to familiarize yourself with the framework by building your first LangChain application.
_**Note**: These docs are for the LangChain [Python package](https://github.com/langchain-ai/langchain). For documentation on [LangChain.js](https://github.com/langchain-ai/langchainjs), the JS/TS version, [head here](https://js.langchain.com/docs)._
Read up on our [Security](/docs/security) best practices to make sure you're developing safely with LangChain.
:::note
These docs focus on the Python LangChain library. [Head here](https://js.langchain.com) for docs on the JavaScript LangChain library.
:::
## LangChain Expression Language (LCEL)
LCEL is a declarative way to compose chains. LCEL was designed from day 1 to support putting prototypes in production, with no code changes, from the simplest “prompt + LLM” chain to the most complex chains.
- **[Overview](/docs/expression_language/)**: LCEL and its benefits
- **[Interface](/docs/expression_language/interface)**: The standard interface for LCEL objects
- **[How-to](/docs/expression_language/interface)**: Key features of LCEL
- **[Cookbook](/docs/expression_language/cookbook)**: Example code for accomplishing common tasks
## Modules
LangChain provides standard, extendable interfaces and external integrations for the following modules, listed from least to most complex:
LangChain provides standard, extendable interfaces and integrations for the following modules:
#### [Model I/O](/docs/modules/model_io/)
Interface with language models
#### [Retrieval](/docs/modules/data_connection/)
Interface with application-specific data
#### [Chains](/docs/modules/chains/)
Construct sequences of calls
#### [Agents](/docs/modules/agents/)
Let chains choose which tools to use given high-level directives
#### [Memory](/docs/modules/memory/)
Persist application state between runs of a chain
#### [Callbacks](/docs/modules/callbacks/)
Log and stream intermediate steps of any chain
Let models choose which tools to use given high-level directives
## Examples, ecosystem, and resources
### [Use cases](/docs/use_cases/question_answering/)
Walkthroughs and best-practices for common end-to-end use cases, like:
Walkthroughs and techniques for common end-to-end use cases, like:
- [Document question answering](/docs/use_cases/question_answering/)
- [Chatbots](/docs/use_cases/chatbots/)
- [Analyzing structured data](/docs/use_cases/qa_structured/sql/)
- and much more...
### [Guides](/docs/guides/)
Learn best practices for developing with LangChain.
### [Integrations](/docs/integrations/providers/)
LangChain is part of a rich ecosystem of tools that integrate with our framework and build on top of it. Check out our growing list of [integrations](/docs/integrations/providers/).
### [Ecosystem](/docs/integrations/providers/)
LangChain is part of a rich ecosystem of tools that integrate with our framework and build on top of it. Check out our growing list of [integrations](/docs/integrations/providers/) and [dependent repos](/docs/additional_resources/dependents).
### [Guides](/docs/guides/adapters/openai)
Best practices for developing with LangChain.
### [Additional resources](/docs/additional_resources/)
Our community is full of prolific developers, creative builders, and fantastic teachers. Check out [YouTube tutorials](/docs/additional_resources/youtube) for great tutorials from folks in the community, and [Gallery](https://github.com/kyrolabs/awesome-langchain) for a list of awesome LangChain projects, compiled by the folks at [KyroLabs](https://kyrolabs.com).
### [API reference](https://api.python.langchain.com)
Head to the reference section for full documentation of all classes and methods in the LangChain and LangChain Experimental Python packages.
### [Developer's guide](/docs/contributing)
Check out the developer's guide for guidelines on contributing and help getting your dev environment set up.
### [Community](/docs/community)
Head to the [Community navigator](/docs/community) to find places to ask questions, share feedback, meet other developers, and dream about the future of LLMs.
## API reference
Head to the [reference](https://api.python.langchain.com) section for full documentation of all classes and methods in the LangChain Python package.

View File

@@ -1,6 +1,17 @@
# Quickstart
## Installation
In this quickstart we'll show you how to:
- Get setup with LangChain, LangSmith and LangServe
- Use the most basic and common components of LangChain: prompt templates, models, and output parsers
- Use LangChain Expression Language, the protocol that LangChain is built on and which facilitates component chaining
- Build simple application with LangChain
- Trace your application with LangSmith
- Serve your application with LangServe
That's a fair amount to cover! Let's dive in.
## Setup
### Installation
To install LangChain run:
@@ -20,7 +31,7 @@ import CodeBlock from "@theme/CodeBlock";
For more details, see our [Installation guide](/docs/get_started/installation).
## Environment setup
### Environment
Using LangChain will usually require integrations with one or more model providers, data stores, APIs, etc. For this example, we'll use OpenAI's model APIs.
@@ -39,54 +50,79 @@ export OPENAI_API_KEY="..."
If you'd prefer not to set an environment variable you can pass the key in directly via the `openai_api_key` named parameter when initiating the OpenAI LLM class:
```python
from langchain.llms import OpenAI
from langchain.chat_models import ChatOpenAI
llm = OpenAI(openai_api_key="...")
llm = ChatOpenAI(openai_api_key="...")
```
### LangSmith
## Building an application
Many of the applications you build with LangChain will contain multiple steps with multiple invocations of LLM calls.
As these applications get more and more complex, it becomes crucial to be able to inspect what exactly is going on inside your chain or agent.
The best way to do this is with [LangSmith](https://smith.langchain.com).
Now we can start building our language model application. LangChain provides many modules that can be used to build language model applications.
Modules can be used as stand-alones in simple applications and they can be combined for more complex use cases.
Note that LangSmith is not needed, but it is helpful.
If you do want to use LangSmith, after you sign up at the link above, make sure to set your environment variables to start logging traces:
The most common and most important chain that LangChain helps create contains three things:
- LLM: The language model is the core reasoning engine here. In order to work with LangChain, you need to understand the different types of language models and how to work with them.
- Prompt Templates: This provides instructions to the language model. This controls what the language model outputs, so understanding how to construct prompts and different prompting strategies is crucial.
- Output Parsers: These translate the raw response from the LLM to a more workable format, making it easy to use the output downstream.
```shell
export LANGCHAIN_TRACING_V2="true"
export LANGCHAIN_API_KEY=...
```
In this getting started guide we will cover those three components by themselves, and then go over how to combine all of them.
### LangServe
LangServe helps developers deploy LangChain chains as a REST API. You do not need to use LangServe to use LangChain, but in this guide we'll show how you can deploy your app with LangServe.
Install with:
```bash
pip install "langserve[all]"
```
## Building with LangChain
LangChain provides many modules that can be used to build language model applications.
Modules can be used as standalones in simple applications and they can be composed for more complex use cases.
Composition is powered by **LangChain Expression Language** (LCEL), which defines a unified `Runnable` interface that many modules implement, making it possible to seamlessly chain components.
The simplest and most common chain contains three things:
- LLM/Chat Model: The language model is the core reasoning engine here. In order to work with LangChain, you need to understand the different types of language models and how to work with them.
- Prompt Template: This provides instructions to the language model. This controls what the language model outputs, so understanding how to construct prompts and different prompting strategies is crucial.
- Output Parser: These translate the raw response from the language model to a more workable format, making it easy to use the output downstream.
In this guide we'll cover those three components individually, and then go over how to combine them.
Understanding these concepts will set you up well for being able to use and customize LangChain applications.
Most LangChain applications allow you to configure the LLM and/or the prompt used, so knowing how to take advantage of this will be a big enabler.
Most LangChain applications allow you to configure the model and/or the prompt, so knowing how to take advantage of this will be a big enabler.
## LLMs
### LLM / Chat Model
There are two types of language models, which in LangChain are called:
There are two types of language models:
- LLMs: this is a language model which takes a string as input and returns a string
- ChatModels: this is a language model which takes a list of messages as input and returns a message
- `LLM`: underlying model takes a string as input and returns a string
- `ChatModel`: underlying model takes a list of messages as input and returns a message
The input/output for LLMs is simple and easy to understand - a string.
But what about ChatModels? The input there is a list of `ChatMessages`, and the output is a single `ChatMessage`.
A `ChatMessage` has two required components:
Strings are simple, but what exactly are messages? The base message interface is defined by `BaseMessage`, which has two required attributes:
- `content`: This is the content of the message.
- `role`: This is the role of the entity from which the `ChatMessage` is coming from.
- `content`: The content of the message. Usually a string.
- `role`: The entity from which the `BaseMessage` is coming.
LangChain provides several objects to easily distinguish between different roles:
- `HumanMessage`: A `ChatMessage` coming from a human/user.
- `AIMessage`: A `ChatMessage` coming from an AI/assistant.
- `SystemMessage`: A `ChatMessage` coming from the system.
- `FunctionMessage`: A `ChatMessage` coming from a function call.
- `HumanMessage`: A `BaseMessage` coming from a human/user.
- `AIMessage`: A `BaseMessage` coming from an AI/assistant.
- `SystemMessage`: A `BaseMessage` coming from the system.
- `FunctionMessage` / `ToolMessage`: A `BaseMessage` containing the output of a function or tool call.
If none of those roles sound right, there is also a `ChatMessage` class where you can specify the role manually.
For more information on how to use these different messages most effectively, see our prompting guide.
LangChain provides a standard interface for both, but it's useful to understand this difference in order to construct prompts for a given language model.
The standard interface that LangChain provides has two methods:
- `predict`: Takes in a string, returns a string
- `predict_messages`: Takes in a list of messages, returns a message.
LangChain provides a common interface that's shared by both `LLM`s and `ChatModel`s.
However it's useful to understand the difference in order to most effectively construct prompts for a given language model.
The simplest way to call an `LLM` or `ChatModel` is using `.invoke()`, the universal synchronous call method for all LangChain Expression Language (LCEL) objects:
- `LLM.invoke`: Takes in a string, returns a string.
- `ChatModel.invoke`: Takes in a list of `BaseMessage`, returns a `BaseMessage`.
The input types for these methods are actually more general than this, but for simplicity here we can assume LLMs only take strings and Chat models only takes lists of messages.
Check out the "Go deeper" section below to learn more about model invocation.
Let's see how to work with these different types of models and these different types of inputs.
First, let's import an LLM and a ChatModel.
@@ -97,50 +133,36 @@ from langchain.chat_models import ChatOpenAI
llm = OpenAI()
chat_model = ChatOpenAI()
llm.predict("hi!")
>>> "Hi"
chat_model.predict("hi!")
>>> "Hi"
```
The `OpenAI` and `ChatOpenAI` objects are basically just configuration objects.
`LLM` and `ChatModel` objects are effectively configuration objects.
You can initialize them with parameters like `temperature` and others, and pass them around.
Next, let's use the `predict` method to run over a string input.
```python
text = "What would be a good company name for a company that makes colorful socks?"
llm.predict(text)
# >> Feetful of Fun
chat_model.predict(text)
# >> Socks O'Color
```
Finally, let's use the `predict_messages` method to run over a list of messages.
```python
from langchain.schema import HumanMessage
text = "What would be a good company name for a company that makes colorful socks?"
messages = [HumanMessage(content=text)]
llm.predict_messages(messages)
llm.invoke(text)
# >> Feetful of Fun
chat_model.predict_messages(messages)
# >> Socks O'Color
chat_model.invoke(messages)
# >> AIMessage(content="Socks O'Color")
```
For both these methods, you can also pass in parameters as keyword arguments.
For example, you could pass in `temperature=0` to adjust the temperature that is used from what the object was configured with.
Whatever values are passed in during run time will always override what the object was configured with.
<details> <summary>Go deeper</summary>
`LLM.invoke` and `ChatModel.invoke` actually both support as input any of `Union[str, List[BaseMessage], PromptValue]`.
`PromptValue` is an object that defines it's own custom logic for returning it's inputs either as a string or as messages.
`LLM`s have logic for coercing any of these into a string, and `ChatModel`s have logic for coercing any of these to messages.
The fact that `LLM` and `ChatModel` accept the same inputs means that you can directly swap them for one another in most chains without breaking anything,
though it's of course important to think about how inputs are being coerced and how that may affect model performance.
To dive deeper on models head to the [Language models](/docs/modules/model_io/models) section.
## Prompt templates
</details>
### Prompt templates
Most LLM applications do not pass user input directly into an LLM. Usually they will add the user input to a larger piece of text, called a prompt template, that provides additional context on the specific task at hand.
@@ -157,7 +179,7 @@ prompt = PromptTemplate.from_template("What is a good name for a company that ma
prompt.format(product="colorful socks")
```
```pycon
```python
What is a good name for a company that makes colorful socks?
```
@@ -166,10 +188,10 @@ You can "partial" out variables - e.g. you can format only some of the variables
You can compose them together, easily combining different templates into a single prompt.
For explanations of these functionalities, see the [section on prompts](/docs/modules/model_io/prompts) for more detail.
PromptTemplates can also be used to produce a list of messages.
`PromptTemplate`s can also be used to produce a list of messages.
In this case, the prompt not only contains information about the content, but also each message (its role, its position in the list, etc.).
Here, what happens most often is a ChatPromptTemplate is a list of ChatMessageTemplates.
Each ChatMessageTemplate contains instructions for how to format that ChatMessage - its role, and then also its content.
Here, what happens most often is a `ChatPromptTemplate` is a list of `ChatMessageTemplates`.
Each `ChatMessageTemplate` contains instructions for how to format that `ChatMessage` - its role, and then also its content.
Let's take a look at this below:
```python
@@ -196,13 +218,13 @@ chat_prompt.format_messages(input_language="English", output_language="French",
ChatPromptTemplates can also be constructed in other ways - see the [section on prompts](/docs/modules/model_io/prompts) for more detail.
## Output parsers
### Output parsers
OutputParsers convert the raw output of an LLM into a format that can be used downstream.
There are few main types of OutputParsers, including:
`OutputParsers` convert the raw output of a language model into a format that can be used downstream.
There are few main types of `OutputParser`s, including:
- Convert text from LLM into structured information (e.g. JSON)
- Convert a ChatMessage into just a string
- Convert text from `LLM` into structured information (e.g. JSON)
- Convert a `ChatMessage` into just a string
- Convert the extra information returned from a call besides the message (like OpenAI function invocation) into a string.
For full information on this, see the [section on output parsers](/docs/modules/model_io/output_parsers).
@@ -224,7 +246,7 @@ CommaSeparatedListOutputParser().parse("hi, bye")
# >> ['hi', 'bye']
```
## PromptTemplate + LLM + OutputParser
### Composing with LCEL
We can now combine all these into one chain.
This chain will take input variables, pass those to a prompt template to create a prompt, pass the prompt to a language model, and then pass the output through an (optional) output parser.
@@ -232,15 +254,17 @@ This is a convenient way to bundle up a modular piece of logic.
Let's see it in action!
```python
from typing import List
from langchain.chat_models import ChatOpenAI
from langchain.prompts.chat import ChatPromptTemplate
from langchain.prompts import ChatPromptTemplate
from langchain.schema import BaseOutputParser
class CommaSeparatedListOutputParser(BaseOutputParser):
class CommaSeparatedListOutputParser(BaseOutputParser[List[str]]):
"""Parse the output of an LLM call to a comma-separated list."""
def parse(self, text: str):
def parse(self, text: str) -> List[str]:
"""Parse the output of an LLM call."""
return text.strip().split(", ")
@@ -258,20 +282,118 @@ chain.invoke({"text": "colors"})
# >> ['red', 'blue', 'green', 'yellow', 'orange']
```
Note that we are using the `|` syntax to join these components together.
This `|` syntax is called the LangChain Expression Language.
To learn more about this syntax, read the documentation [here](/docs/expression_language).
This `|` syntax is powered by the LangChain Expression Language (LCEL) and relies on the universal `Runnable` interface that all of these objects implement.
To learn more about LCEL, read the documentation [here](/docs/expression_language).
## Tracing with LangSmith
Assuming we've set our environment variables as shown in the beginning, all of the model and chain calls we've been making will have been automatically logged to LangSmith.
Once there, we can use LangSmith to debug and annotate our application traces, then turn them into datasets for evaluating future iterations of the application.
Check out what the trace for the above chain would look like:
https://smith.langchain.com/public/09370280-4330-4eb4-a7e8-c91817f6aa13/r
For more on LangSmith [head here](/docs/langsmith/).
## Serving with LangServe
Now that we've built an application, we need to serve it. That's where LangServe comes in.
LangServe helps developers deploy LCEL chains as a REST API.
The library is integrated with FastAPI and uses pydantic for data validation.
### Server
To create a server for our application we'll make a `serve.py` file with three things:
1. The definition of our chain (same as above)
2. Our FastAPI app
3. A definition of a route from which to serve the chain, which is done with `langserve.add_routes`
```python
#!/usr/bin/env python
from typing import List
from fastapi import FastAPI
from langchain.prompts import ChatPromptTemplate
from langchain.chat_models import ChatOpenAI
from langchain.schema import BaseOutputParser
from langserve import add_routes
# 1. Chain definition
class CommaSeparatedListOutputParser(BaseOutputParser[List[str]]):
"""Parse the output of an LLM call to a comma-separated list."""
def parse(self, text: str) -> List[str]:
"""Parse the output of an LLM call."""
return text.strip().split(", ")
template = """You are a helpful assistant who generates comma separated lists.
A user will pass in a category, and you should generate 5 objects in that category in a comma separated list.
ONLY return a comma separated list, and nothing more."""
human_template = "{text}"
chat_prompt = ChatPromptTemplate.from_messages([
("system", template),
("human", human_template),
])
category_chain = chat_prompt | ChatOpenAI() | CommaSeparatedListOutputParser()
# 2. App definition
app = FastAPI(
title="LangChain Server",
version="1.0",
description="A simple api server using Langchain's Runnable interfaces",
)
# 3. Adding chain route
add_routes(
app,
category_chain,
path="/category_chain",
)
if __name__ == "__main__":
import uvicorn
uvicorn.run(app, host="localhost", port=8000)
```
And that's it! If we execute this file:
```bash
python serve.py
```
we should see our chain being served at localhost:8000.
### Playground
Every LangServe service comes with a simple built-in UI for configuring and invoking the application with streaming output and visibility into intermediate steps.
Head to http://localhost:8000/category_chain/playground/ to try it out!
### Client
Now let's set up a client for programmatically interacting with our service. We can easily do this with the `langserve.RemoteRunnable`.
Using this, we can interact with the served chain as if it were running client-side.
```python
from langserve import RemoteRunnable
remote_chain = RemoteRunnable("http://localhost:8000/category_chain/")
remote_chain.invoke({"text": "colors"})
# >> ['red', 'blue', 'green', 'yellow', 'orange']
```
To learn more about the many other features of LangServe [head here](/docs/langserve).
## Next steps
This is it!
We've now gone over how to create the core building block of LangChain applications.
There is a lot more nuance in all these components (LLMs, prompts, output parsers) and a lot more different components to learn about as well.
We've touched on how to build an application with LangChain, how to trace it with LangSmith, and how to serve it with LangServe.
There are a lot more features in all three of these than we can cover here.
To continue on your journey:
- [Dive deeper](/docs/modules/model_io) into LLMs, prompts, and output parsers
- Learn the other [key components](/docs/modules)
- Read up on [LangChain Expression Language](/docs/expression_language) to learn how to chain these components together
- Check out our [helpful guides](/docs/guides) for detailed walkthroughs on particular topics
- Explore [end-to-end use cases](/docs/use_cases)
- Read up on [LangChain Expression Language (LCEL)](/docs/expression_language) to learn how to chain these components together
- [Dive deeper](/docs/modules/model_io) into LLMs, prompts, and output parsers and learn the other [key components](/docs/modules)
- Explore common [end-to-end use cases](/docs/use_cases/qa_structured/sql) and [template applications](/docs/templates)
- [Read up on LangSmith](/docs/langsmith/), the platform for debugging, testing, monitoring and more
- Learn more about serving your applications with [LangServe](/docs/langserve)

View File

@@ -8,7 +8,7 @@ Here are a few different tools and functionalities to aid in debugging.
## Tracing
Platforms with tracing capabilities like [LangSmith](/docs/guides/langsmith/) and [WandB](/docs/integrations/providers/wandb_tracing) are the most comprehensive solutions for debugging. These platforms make it easy to not only log and visualize LLM apps, but also to actively debug, test and refine them.
Platforms with tracing capabilities like [LangSmith](/docs/langsmith/) and [WandB](/docs/integrations/providers/wandb_tracing) are the most comprehensive solutions for debugging. These platforms make it easy to not only log and visualize LLM apps, but also to actively debug, test and refine them.
For anyone building production-grade LLM applications, we highly recommend using a platform like this.

View File

@@ -1,85 +1,7 @@
# Template repos
# LangChain Templates
So, you've created a really cool chain - now what? How do you deploy it and make it easily shareable with the world?
For more information on LangChain Templates, visit
This section covers several options for that. Note that these options are meant for quick deployment of prototypes and demos, not for production systems. If you need help with the deployment of a production system, please contact us directly.
What follows is a list of template GitHub repositories designed to be easily forked and modified to use your chain. This list is far from exhaustive, and we are EXTREMELY open to contributions here.
## [Streamlit](https://github.com/hwchase17/langchain-streamlit-template)
This repo serves as a template for how to deploy a LangChain with Streamlit.
It implements a chatbot interface.
It also contains instructions for how to deploy this app on the Streamlit platform.
## [Gradio (on Hugging Face)](https://github.com/hwchase17/langchain-gradio-template)
This repo serves as a template for how to deploy a LangChain with Gradio.
It implements a chatbot interface, with a "Bring-Your-Own-Token" approach (nice for not wracking up big bills).
It also contains instructions for how to deploy this app on the Hugging Face platform.
This is heavily influenced by James Weaver's [excellent examples](https://huggingface.co/JavaFXpert).
## [Chainlit](https://github.com/Chainlit/cookbook)
This repo is a cookbook explaining how to visualize and deploy LangChain agents with Chainlit.
You create ChatGPT-like UIs with Chainlit. Some of the key features include intermediary steps visualisation, element management & display (images, text, carousel, etc.) as well as cloud deployment.
Chainlit [doc](https://docs.chainlit.io/langchain) on the integration with LangChain
## [Beam](https://github.com/slai-labs/get-beam/tree/main/examples/langchain-question-answering)
This repo serves as a template for how to deploy a LangChain with [Beam](https://beam.cloud).
It implements a Question Answering app and contains instructions for deploying the app as a serverless REST API.
## [Vercel](https://github.com/homanp/vercel-langchain)
A minimal example on how to run LangChain on Vercel using Flask.
## [FastAPI + Vercel](https://github.com/msoedov/langcorn)
A minimal example on how to run LangChain on Vercel using FastAPI and LangCorn/Uvicorn.
## [Kinsta](https://github.com/kinsta/hello-world-langchain)
A minimal example on how to deploy LangChain to [Kinsta](https://kinsta.com) using Flask.
## [Fly.io](https://github.com/fly-apps/hello-fly-langchain)
A minimal example of how to deploy LangChain to [Fly.io](https://fly.io/) using Flask.
## [DigitalOcean App Platform](https://github.com/homanp/digitalocean-langchain)
A minimal example of how to deploy LangChain to DigitalOcean App Platform.
## [CI/CD Google Cloud Build + Dockerfile + Serverless Google Cloud Run](https://github.com/g-emarco/github-assistant)
Boilerplate LangChain project on how to deploy to Google Cloud Run using Docker with Cloud Build CI/CD pipeline.
## [Google Cloud Run](https://github.com/homanp/gcp-langchain)
A minimal example of how to deploy LangChain to Google Cloud Run.
## [SteamShip](https://github.com/steamship-core/steamship-langchain/)
This repository contains LangChain adapters for Steamship, enabling LangChain developers to rapidly deploy their apps on Steamship. This includes: production-ready endpoints, horizontal scaling across dependencies, persistent storage of app state, multi-tenancy support, etc.
## [Langchain-serve](https://github.com/jina-ai/langchain-serve)
This repository allows users to deploy any LangChain app as REST/WebSocket APIs or, as Slack Bots with ease. Benefit from the scalability and serverless architecture of Jina AI Cloud, or deploy on-premise with Kubernetes.
## [BentoML](https://github.com/ssheng/BentoChain)
This repository provides an example of how to deploy a LangChain application with [BentoML](https://github.com/bentoml/BentoML). BentoML is a framework that enables the containerization of machine learning applications as standard OCI images. BentoML also allows for the automatic generation of OpenAPI and gRPC endpoints. With BentoML, you can integrate models from all popular ML frameworks and deploy them as microservices running on the most optimal hardware and scaling independently.
## [OpenLLM](https://github.com/bentoml/OpenLLM)
OpenLLM is a platform for operating large language models (LLMs) in production. With OpenLLM, you can run inference with any open-source LLM, deploy to the cloud or on-premises, and build powerful AI apps. It supports a wide range of open-source LLMs, offers flexible APIs, and first-class support for LangChain and BentoML.
See OpenLLM's [integration doc](https://github.com/bentoml/OpenLLM#%EF%B8%8F-integrations) for usage with LangChain.
## [Databutton](https://databutton.com/home?new-data-app=true)
These templates serve as examples of how to build, deploy, and share LangChain applications using Databutton. You can create user interfaces with Streamlit, automate tasks by scheduling Python code, and store files and data in the built-in store. Examples include a Chatbot interface with conversational memory, a Personal search engine, and a starter template for LangChain apps. Deploying and sharing is just one click away.
## [AzureML Online Endpoint](https://github.com/Azure/azureml-examples/blob/main/sdk/python/endpoints/online/llm/langchain/1_langchain_basic_deploy.ipynb)
A minimal example of how to deploy LangChain to an Azure Machine Learning Online Endpoint.
- [LangChain Templates Quickstart](https://github.com/langchain-ai/langchain/blob/master/templates/README.md)
- [LangChain Templates Index](https://github.com/langchain-ai/langchain/blob/master/templates/docs/INDEX.md)
- [Full List of Templates](https://github.com/langchain-ai/langchain/blob/master/templates/)

View File

@@ -113,7 +113,7 @@
"tags": []
},
"source": [
"Here are two examples of how to use the `TrubricsCallbackHandler` with Langchain [LLMs](https://python.langchain.com/docs/modules/model_io/models/llms/) or [Chat Models](https://python.langchain.com/docs/modules/model_io/models/chat/). We will use OpenAI models, so set your `OPENAI_API_KEY` key here:"
"Here are two examples of how to use the `TrubricsCallbackHandler` with Langchain [LLMs](https://python.langchain.com/docs/modules/model_io/llms/) or [Chat Models](https://python.langchain.com/docs/modules/model_io/chat/). We will use OpenAI models, so set your `OPENAI_API_KEY` key here:"
]
},
{

View File

@@ -5,18 +5,20 @@
"id": "38f26d7a",
"metadata": {},
"source": [
"# Azure\n",
"# Azure OpenAI\n",
"\n",
"This notebook goes over how to connect to an Azure hosted OpenAI endpoint"
"This notebook goes over how to connect to an Azure hosted OpenAI endpoint. We recommend having version `openai>=1` installed."
]
},
{
"cell_type": "code",
"execution_count": 2,
"execution_count": 3,
"id": "96164b42",
"metadata": {},
"outputs": [],
"source": [
"import os\n",
"\n",
"from langchain.chat_models import AzureChatOpenAI\n",
"from langchain.schema import HumanMessage"
]
@@ -24,57 +26,51 @@
{
"cell_type": "code",
"execution_count": 4,
"id": "cbe4bb58-ba13-4355-8af9-cd990dc47a64",
"metadata": {},
"outputs": [],
"source": [
"os.environ[\"AZURE_OPENAI_API_KEY\"] = \"...\"\n",
"os.environ[\"AZURE_OPENAI_ENDPOINT\"] = \"https://<your-endpoint>.openai.azure.com/\""
]
},
{
"cell_type": "code",
"execution_count": 14,
"id": "8161278f",
"metadata": {},
"outputs": [],
"source": [
"BASE_URL = \"https://${TODO}.openai.azure.com\"\n",
"API_KEY = \"...\"\n",
"DEPLOYMENT_NAME = \"chat\"\n",
"model = AzureChatOpenAI(\n",
" openai_api_base=BASE_URL,\n",
" openai_api_version=\"2023-05-15\",\n",
" deployment_name=DEPLOYMENT_NAME,\n",
" openai_api_key=API_KEY,\n",
" openai_api_type=\"azure\",\n",
" azure_deployment=\"your-deployment-name\",\n",
")"
]
},
{
"cell_type": "code",
"execution_count": 5,
"execution_count": 15,
"id": "99509140",
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"AIMessage(content=\"\\n\\nJ'aime programmer.\", additional_kwargs={})"
"AIMessage(content=\"J'adore la programmation.\")"
]
},
"execution_count": 5,
"execution_count": 15,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"model(\n",
" [\n",
" HumanMessage(\n",
" content=\"Translate this sentence from English to French. I love programming.\"\n",
" )\n",
" ]\n",
")"
"message = HumanMessage(\n",
" content=\"Translate this sentence from English to French. I love programming.\"\n",
")\n",
"model([message])"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "3b6e9376",
"metadata": {},
"outputs": [],
"source": []
},
{
"cell_type": "markdown",
"id": "f27fa24d",
@@ -88,7 +84,7 @@
},
{
"cell_type": "code",
"execution_count": null,
"execution_count": 8,
"id": "0531798a",
"metadata": {},
"outputs": [],
@@ -98,48 +94,19 @@
},
{
"cell_type": "code",
"execution_count": 14,
"id": "3fd97dfc",
"metadata": {},
"outputs": [],
"source": [
"BASE_URL = \"https://{endpoint}.openai.azure.com\"\n",
"API_KEY = \"...\"\n",
"DEPLOYMENT_NAME = \"gpt-35-turbo\" # in Azure, this deployment has version 0613 - input and output tokens are counted separately"
]
},
{
"cell_type": "code",
"execution_count": 15,
"execution_count": null,
"id": "aceddb72",
"metadata": {
"scrolled": true
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Total Cost (USD): $0.000054\n"
]
}
],
"outputs": [],
"source": [
"model = AzureChatOpenAI(\n",
" openai_api_base=BASE_URL,\n",
" openai_api_version=\"2023-05-15\",\n",
" deployment_name=DEPLOYMENT_NAME,\n",
" openai_api_key=API_KEY,\n",
" openai_api_type=\"azure\",\n",
" azure_deployment=\"gpt-35-turbo\", # in Azure, this deployment has version 0613 - input and output tokens are counted separately\n",
")\n",
"with get_openai_callback() as cb:\n",
" model(\n",
" [\n",
" HumanMessage(\n",
" content=\"Translate this sentence from English to French. I love programming.\"\n",
" )\n",
" ]\n",
" )\n",
" model([message])\n",
" print(\n",
" f\"Total Cost (USD): ${format(cb.total_cost, '.6f')}\"\n",
" ) # without specifying the model version, flat-rate 0.002 USD per 1k input and output tokens is used"
@@ -169,21 +136,12 @@
],
"source": [
"model0613 = AzureChatOpenAI(\n",
" openai_api_base=BASE_URL,\n",
" openai_api_version=\"2023-05-15\",\n",
" deployment_name=DEPLOYMENT_NAME,\n",
" openai_api_key=API_KEY,\n",
" openai_api_type=\"azure\",\n",
" deployment_name=\"gpt-35-turbo,\n",
" model_version=\"0613\",\n",
")\n",
"with get_openai_callback() as cb:\n",
" model0613(\n",
" [\n",
" HumanMessage(\n",
" content=\"Translate this sentence from English to French. I love programming.\"\n",
" )\n",
" ]\n",
" )\n",
" model0613([message])\n",
" print(f\"Total Cost (USD): ${format(cb.total_cost, '.6f')}\")"
]
},
@@ -212,7 +170,7 @@
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.8.10"
"version": "3.9.1"
}
},
"nbformat": 4,

View File

@@ -9,9 +9,9 @@
"\n",
"Note: This is separate from the Google PaLM integration. Google has chosen to offer an enterprise version of PaLM through GCP, and this supports the models made available through there. \n",
"\n",
"By default, Google Cloud [does not use](https://cloud.google.com/vertex-ai/docs/generative-ai/data-governance#foundation_model_development) Customer Data to train its foundation models as part of Google Cloud`s AI/ML Privacy Commitment. More details about how Google processes data can also be found in [Google's Customer Data Processing Addendum (CDPA)](https://cloud.google.com/terms/data-processing-addendum).\n",
"By default, Google Cloud [does not use](https://cloud.google.com/vertex-ai/docs/generative-ai/data-governance#foundation_model_development) customer data to train its foundation models as part of Google Cloud`s AI/ML Privacy Commitment. More details about how Google processes data can also be found in [Google's Customer Data Processing Addendum (CDPA)](https://cloud.google.com/terms/data-processing-addendum).\n",
"\n",
"To use Vertex AI PaLM you must have the `google-cloud-aiplatform` Python package installed and either:\n",
"To use `Google Cloud Vertex AI` PaLM you must have the `google-cloud-aiplatform` Python package installed and either:\n",
"- Have credentials configured for your environment (gcloud, workload identity, etc...)\n",
"- Store the path to a service account JSON file as the GOOGLE_APPLICATION_CREDENTIALS environment variable\n",
"\n",

View File

@@ -65,9 +65,7 @@
"id": "359565a7-dad3-403c-a73c-6414b1295127",
"metadata": {},
"source": [
"## 2. Define chat loader\n",
"\n",
"LangChain currently does not support "
"## 2. Define chat loader"
]
},
{

View File

@@ -64,7 +64,9 @@
"source": [
"## Load Documents\n",
"\n",
"If the DOCUGAMI_API_KEY environment variable is set, there is no need to pass it in to the loader explicitly otherwise you can pass it in as the `access_token` parameter."
"If the DOCUGAMI_API_KEY environment variable is set, there is no need to pass it in to the loader explicitly otherwise you can pass it in as the `access_token` parameter.\n",
"\n",
"The DocugamiLoader has a default minimum chunk size of 32. Chunks smaller than that are appended to subsequent chunks. Set min_chunk_size to 0 to get all structural chunks regardless of size."
]
},
{

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,103 @@
{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# lakeFS\n",
"\n",
">[lakeFS](https://docs.lakefs.io/) provides scalable version control over the data lake, and uses Git-like semantics to create and access those versions.\n",
"\n",
"This notebooks covers how to load document objects from a `lakeFS` path (whether it's an object or a prefix).\n"
]
},
{
"cell_type": "markdown",
"source": [
"## Initializing the lakeFS loader\n",
"\n",
"Replace `ENDPOINT`, `LAKEFS_ACCESS_KEY`, and `LAKEFS_SECRET_KEY` values with your own."
],
"metadata": {
"collapsed": false
}
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"from langchain.document_loaders import LakeFSLoader"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"ENDPOINT = \"\"\n",
"LAKEFS_ACCESS_KEY = \"\"\n",
"LAKEFS_SECRET_KEY = \"\"\n",
"\n",
"lakefs_loader = LakeFSLoader(\n",
" lakefs_access_key=LAKEFS_ACCESS_KEY,\n",
" lakefs_secret_key=LAKEFS_SECRET_KEY,\n",
" lakefs_endpoint=ENDPOINT,\n",
")"
]
},
{
"cell_type": "markdown",
"source": [
"## Specifying a path\n",
"You can specify a prefix or a complete object path to control which files to load.\n",
"\n",
"Specify the repository, reference (branch, commit id, or tag), and path in the corresponding `REPO`, `REF`, and `PATH` to load the documents from:"
],
"metadata": {
"collapsed": false
}
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"REPO = \"\"\n",
"REF = \"\"\n",
"PATH = \"\"\n",
"\n",
"lakefs_loader.set_repo(REPO)\n",
"lakefs_loader.set_ref(REF)\n",
"lakefs_loader.set_path(PATH)\n",
"\n",
"docs = lakefs_loader.load()\n",
"docs"
]
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3 (ipykernel)",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.9.1"
}
},
"nbformat": 4,
"nbformat_minor": 2
}

View File

@@ -18,7 +18,7 @@
},
{
"cell_type": "code",
"execution_count": 1,
"execution_count": 2,
"id": "c049beaf-f904-4ce6-91ca-805da62084c2",
"metadata": {
"tags": []
@@ -28,14 +28,135 @@
"name": "stdout",
"output_type": "stream",
"text": [
"\u001b[33mDEPRECATION: amazon-textract-pipeline-pagedimensions 0.0.8 has a non-standard dependency specifier Pillow>=9.4.*. pip 23.3 will enforce this behaviour change. A possible replacement is to upgrade to a newer version of amazon-textract-pipeline-pagedimensions or contact the author to suggest that they release a version with a conforming dependency specifiers. Discussion can be found at https://github.com/pypa/pip/issues/12063\u001b[0m\u001b[33m\n",
"\u001b[0m\u001b[33mDEPRECATION: amazon-textract-pipeline-pagedimensions 0.0.8 has a non-standard dependency specifier pypdf>=2.5.*. pip 23.3 will enforce this behaviour change. A possible replacement is to upgrade to a newer version of amazon-textract-pipeline-pagedimensions or contact the author to suggest that they release a version with a conforming dependency specifiers. Discussion can be found at https://github.com/pypa/pip/issues/12063\u001b[0m\u001b[33m\n",
"\u001b[0m\n",
"\u001b[1m[\u001b[0m\u001b[34;49mnotice\u001b[0m\u001b[1;39;49m]\u001b[0m\u001b[39;49m A new release of pip is available: \u001b[0m\u001b[31;49m23.2\u001b[0m\u001b[39;49m -> \u001b[0m\u001b[32;49m23.3\u001b[0m\n",
"\u001b[1m[\u001b[0m\u001b[34;49mnotice\u001b[0m\u001b[1;39;49m]\u001b[0m\u001b[39;49m To update, run: \u001b[0m\u001b[32;49mpython -m pip install --upgrade pip\u001b[0m\n",
"Obtaining file:///Users/schadem/code/github/schadem/langchain/libs/langchain\n",
" Installing build dependencies ... \u001b[?25ldone\n",
"\u001b[?25h Checking if build backend supports build_editable ... \u001b[?25ldone\n",
"\u001b[?25h Getting requirements to build editable ... \u001b[?25ldone\n",
"\u001b[?25h Preparing editable metadata (pyproject.toml) ... \u001b[?25ldone\n",
"\u001b[?25hRequirement already satisfied: PyYAML>=5.3 in /Users/schadem/.pyenv/versions/3.11.1/envs/langchain/lib/python3.11/site-packages (from langchain==0.0.267) (6.0.1)\n",
"Requirement already satisfied: SQLAlchemy<3,>=1.4 in /Users/schadem/.pyenv/versions/3.11.1/envs/langchain/lib/python3.11/site-packages (from langchain==0.0.267) (2.0.22)\n",
"Requirement already satisfied: aiohttp<4.0.0,>=3.8.3 in /Users/schadem/.pyenv/versions/3.11.1/envs/langchain/lib/python3.11/site-packages (from langchain==0.0.267) (3.8.6)\n",
"Requirement already satisfied: amazon-textract-textractor<2 in /Users/schadem/.pyenv/versions/3.11.1/envs/langchain/lib/python3.11/site-packages (from langchain==0.0.267) (1.4.1)\n",
"Collecting dataclasses-json<0.6.0,>=0.5.7 (from langchain==0.0.267)\n",
" Obtaining dependency information for dataclasses-json<0.6.0,>=0.5.7 from https://files.pythonhosted.org/packages/97/5f/e7cc90f36152810cab08b6c9c1125e8bcb9d76f8b3018d101b5f877b386c/dataclasses_json-0.5.14-py3-none-any.whl.metadata\n",
" Downloading dataclasses_json-0.5.14-py3-none-any.whl.metadata (22 kB)\n",
"Requirement already satisfied: langsmith<0.1.0,>=0.0.21 in /Users/schadem/.pyenv/versions/3.11.1/envs/langchain/lib/python3.11/site-packages (from langchain==0.0.267) (0.0.44)\n",
"Requirement already satisfied: numexpr<3.0.0,>=2.8.4 in /Users/schadem/.pyenv/versions/3.11.1/envs/langchain/lib/python3.11/site-packages (from langchain==0.0.267) (2.8.7)\n",
"Requirement already satisfied: numpy<2,>=1 in /Users/schadem/.pyenv/versions/3.11.1/envs/langchain/lib/python3.11/site-packages (from langchain==0.0.267) (1.24.4)\n",
"Requirement already satisfied: pydantic<3,>=1 in /Users/schadem/.pyenv/versions/3.11.1/envs/langchain/lib/python3.11/site-packages (from langchain==0.0.267) (1.10.13)\n",
"Requirement already satisfied: requests<3,>=2 in /Users/schadem/.pyenv/versions/3.11.1/envs/langchain/lib/python3.11/site-packages (from langchain==0.0.267) (2.31.0)\n",
"Requirement already satisfied: tenacity<9.0.0,>=8.1.0 in /Users/schadem/.pyenv/versions/3.11.1/envs/langchain/lib/python3.11/site-packages (from langchain==0.0.267) (8.2.3)\n",
"Requirement already satisfied: attrs>=17.3.0 in /Users/schadem/.pyenv/versions/3.11.1/envs/langchain/lib/python3.11/site-packages (from aiohttp<4.0.0,>=3.8.3->langchain==0.0.267) (23.1.0)\n",
"Requirement already satisfied: charset-normalizer<4.0,>=2.0 in /Users/schadem/.pyenv/versions/3.11.1/envs/langchain/lib/python3.11/site-packages (from aiohttp<4.0.0,>=3.8.3->langchain==0.0.267) (3.3.0)\n",
"Requirement already satisfied: multidict<7.0,>=4.5 in /Users/schadem/.pyenv/versions/3.11.1/envs/langchain/lib/python3.11/site-packages (from aiohttp<4.0.0,>=3.8.3->langchain==0.0.267) (6.0.4)\n",
"Requirement already satisfied: async-timeout<5.0,>=4.0.0a3 in /Users/schadem/.pyenv/versions/3.11.1/envs/langchain/lib/python3.11/site-packages (from aiohttp<4.0.0,>=3.8.3->langchain==0.0.267) (4.0.3)\n",
"Requirement already satisfied: yarl<2.0,>=1.0 in /Users/schadem/.pyenv/versions/3.11.1/envs/langchain/lib/python3.11/site-packages (from aiohttp<4.0.0,>=3.8.3->langchain==0.0.267) (1.9.2)\n",
"Requirement already satisfied: frozenlist>=1.1.1 in /Users/schadem/.pyenv/versions/3.11.1/envs/langchain/lib/python3.11/site-packages (from aiohttp<4.0.0,>=3.8.3->langchain==0.0.267) (1.4.0)\n",
"Requirement already satisfied: aiosignal>=1.1.2 in /Users/schadem/.pyenv/versions/3.11.1/envs/langchain/lib/python3.11/site-packages (from aiohttp<4.0.0,>=3.8.3->langchain==0.0.267) (1.3.1)\n",
"Requirement already satisfied: Pillow in /Users/schadem/.pyenv/versions/3.11.1/envs/langchain/lib/python3.11/site-packages (from amazon-textract-textractor<2->langchain==0.0.267) (10.1.0)\n",
"Requirement already satisfied: XlsxWriter<3.1,>=3.0 in /Users/schadem/.pyenv/versions/3.11.1/envs/langchain/lib/python3.11/site-packages (from amazon-textract-textractor<2->langchain==0.0.267) (3.0.9)\n",
"Collecting amazon-textract-caller<0.1.0,>=0.0.27 (from amazon-textract-textractor<2->langchain==0.0.267)\n",
" Using cached amazon_textract_caller-0.0.29-py2.py3-none-any.whl (13 kB)\n",
"Requirement already satisfied: amazon-textract-pipeline-pagedimensions in /Users/schadem/.pyenv/versions/3.11.1/envs/langchain/lib/python3.11/site-packages (from amazon-textract-textractor<2->langchain==0.0.267) (0.0.8)\n",
"Requirement already satisfied: amazon-textract-response-parser<0.2.0,>=0.1.45 in /Users/schadem/.pyenv/versions/3.11.1/envs/langchain/lib/python3.11/site-packages (from amazon-textract-textractor<2->langchain==0.0.267) (0.1.48)\n",
"Requirement already satisfied: editdistance==0.6.2 in /Users/schadem/.pyenv/versions/3.11.1/envs/langchain/lib/python3.11/site-packages (from amazon-textract-textractor<2->langchain==0.0.267) (0.6.2)\n",
"Requirement already satisfied: tabulate<0.10,>=0.9 in /Users/schadem/.pyenv/versions/3.11.1/envs/langchain/lib/python3.11/site-packages (from amazon-textract-textractor<2->langchain==0.0.267) (0.9.0)\n",
"Requirement already satisfied: marshmallow<4.0.0,>=3.18.0 in /Users/schadem/.pyenv/versions/3.11.1/envs/langchain/lib/python3.11/site-packages (from dataclasses-json<0.6.0,>=0.5.7->langchain==0.0.267) (3.20.1)\n",
"Requirement already satisfied: typing-inspect<1,>=0.4.0 in /Users/schadem/.pyenv/versions/3.11.1/envs/langchain/lib/python3.11/site-packages (from dataclasses-json<0.6.0,>=0.5.7->langchain==0.0.267) (0.9.0)\n",
"Requirement already satisfied: typing-extensions>=4.2.0 in /Users/schadem/.pyenv/versions/3.11.1/envs/langchain/lib/python3.11/site-packages (from pydantic<3,>=1->langchain==0.0.267) (4.8.0)\n",
"Requirement already satisfied: idna<4,>=2.5 in /Users/schadem/.pyenv/versions/3.11.1/envs/langchain/lib/python3.11/site-packages (from requests<3,>=2->langchain==0.0.267) (3.4)\n",
"Requirement already satisfied: urllib3<3,>=1.21.1 in /Users/schadem/.pyenv/versions/3.11.1/envs/langchain/lib/python3.11/site-packages (from requests<3,>=2->langchain==0.0.267) (1.26.18)\n",
"Requirement already satisfied: certifi>=2017.4.17 in /Users/schadem/.pyenv/versions/3.11.1/envs/langchain/lib/python3.11/site-packages (from requests<3,>=2->langchain==0.0.267) (2023.7.22)\n",
"Requirement already satisfied: boto3>=1.26.35 in /Users/schadem/.pyenv/versions/3.11.1/envs/langchain/lib/python3.11/site-packages (from amazon-textract-caller<0.1.0,>=0.0.27->amazon-textract-textractor<2->langchain==0.0.267) (1.28.67)\n",
"Requirement already satisfied: botocore in /Users/schadem/.pyenv/versions/3.11.1/envs/langchain/lib/python3.11/site-packages (from amazon-textract-caller<0.1.0,>=0.0.27->amazon-textract-textractor<2->langchain==0.0.267) (1.31.67)\n",
"Requirement already satisfied: packaging>=17.0 in /Users/schadem/.pyenv/versions/3.11.1/envs/langchain/lib/python3.11/site-packages (from marshmallow<4.0.0,>=3.18.0->dataclasses-json<0.6.0,>=0.5.7->langchain==0.0.267) (23.2)\n",
"Requirement already satisfied: mypy-extensions>=0.3.0 in /Users/schadem/.pyenv/versions/3.11.1/envs/langchain/lib/python3.11/site-packages (from typing-inspect<1,>=0.4.0->dataclasses-json<0.6.0,>=0.5.7->langchain==0.0.267) (1.0.0)\n",
"Requirement already satisfied: pypdf>=2.5.* in /Users/schadem/.pyenv/versions/3.11.1/envs/langchain/lib/python3.11/site-packages (from amazon-textract-pipeline-pagedimensions->amazon-textract-textractor<2->langchain==0.0.267) (3.16.4)\n",
"Requirement already satisfied: jmespath<2.0.0,>=0.7.1 in /Users/schadem/.pyenv/versions/3.11.1/envs/langchain/lib/python3.11/site-packages (from boto3>=1.26.35->amazon-textract-caller<0.1.0,>=0.0.27->amazon-textract-textractor<2->langchain==0.0.267) (1.0.1)\n",
"Requirement already satisfied: s3transfer<0.8.0,>=0.7.0 in /Users/schadem/.pyenv/versions/3.11.1/envs/langchain/lib/python3.11/site-packages (from boto3>=1.26.35->amazon-textract-caller<0.1.0,>=0.0.27->amazon-textract-textractor<2->langchain==0.0.267) (0.7.0)\n",
"Requirement already satisfied: python-dateutil<3.0.0,>=2.1 in /Users/schadem/.pyenv/versions/3.11.1/envs/langchain/lib/python3.11/site-packages (from botocore->amazon-textract-caller<0.1.0,>=0.0.27->amazon-textract-textractor<2->langchain==0.0.267) (2.8.2)\n",
"Requirement already satisfied: six>=1.5 in /Users/schadem/.pyenv/versions/3.11.1/envs/langchain/lib/python3.11/site-packages (from python-dateutil<3.0.0,>=2.1->botocore->amazon-textract-caller<0.1.0,>=0.0.27->amazon-textract-textractor<2->langchain==0.0.267) (1.16.0)\n",
"Downloading dataclasses_json-0.5.14-py3-none-any.whl (26 kB)\n",
"Building wheels for collected packages: langchain\n",
" Building editable for langchain (pyproject.toml) ... \u001b[?25ldone\n",
"\u001b[?25h Created wheel for langchain: filename=langchain-0.0.267-py3-none-any.whl size=5553 sha256=daaf68d6658b27d69a4a092aa0a39e31f32b96868ef195102d2a17cf119f9d86\n",
" Stored in directory: /private/var/folders/s4/y_t_mj094c95t80n023c9wym0000gr/T/pip-ephem-wheel-cache-v1ynlirx/wheels/9f/73/28/b1d250633de6bd5759f959e16889c6c841dd0e0ffb6474185a\n",
"Successfully built langchain\n",
"\u001b[33mDEPRECATION: amazon-textract-pipeline-pagedimensions 0.0.8 has a non-standard dependency specifier Pillow>=9.4.*. pip 23.3 will enforce this behaviour change. A possible replacement is to upgrade to a newer version of amazon-textract-pipeline-pagedimensions or contact the author to suggest that they release a version with a conforming dependency specifiers. Discussion can be found at https://github.com/pypa/pip/issues/12063\u001b[0m\u001b[33m\n",
"\u001b[0m\u001b[33mDEPRECATION: amazon-textract-pipeline-pagedimensions 0.0.8 has a non-standard dependency specifier pypdf>=2.5.*. pip 23.3 will enforce this behaviour change. A possible replacement is to upgrade to a newer version of amazon-textract-pipeline-pagedimensions or contact the author to suggest that they release a version with a conforming dependency specifiers. Discussion can be found at https://github.com/pypa/pip/issues/12063\u001b[0m\u001b[33m\n",
"\u001b[0mInstalling collected packages: dataclasses-json, amazon-textract-caller, langchain\n",
" Attempting uninstall: dataclasses-json\n",
" Found existing installation: dataclasses-json 0.6.1\n",
" Uninstalling dataclasses-json-0.6.1:\n",
" Successfully uninstalled dataclasses-json-0.6.1\n",
" Attempting uninstall: amazon-textract-caller\n",
" Found existing installation: amazon-textract-caller 0.2.0\n",
" Uninstalling amazon-textract-caller-0.2.0:\n",
" Successfully uninstalled amazon-textract-caller-0.2.0\n",
" Attempting uninstall: langchain\n",
" Found existing installation: langchain 0.0.319\n",
" Uninstalling langchain-0.0.319:\n",
" Successfully uninstalled langchain-0.0.319\n",
"Successfully installed amazon-textract-caller-0.0.29 dataclasses-json-0.5.14 langchain-0.0.267\n",
"\n",
"\u001b[1m[\u001b[0m\u001b[34;49mnotice\u001b[0m\u001b[1;39;49m]\u001b[0m\u001b[39;49m A new release of pip is available: \u001b[0m\u001b[31;49m23.2\u001b[0m\u001b[39;49m -> \u001b[0m\u001b[32;49m23.2.1\u001b[0m\n",
"\u001b[1m[\u001b[0m\u001b[34;49mnotice\u001b[0m\u001b[1;39;49m]\u001b[0m\u001b[39;49m A new release of pip is available: \u001b[0m\u001b[31;49m23.2\u001b[0m\u001b[39;49m -> \u001b[0m\u001b[32;49m23.3\u001b[0m\n",
"\u001b[1m[\u001b[0m\u001b[34;49mnotice\u001b[0m\u001b[1;39;49m]\u001b[0m\u001b[39;49m To update, run: \u001b[0m\u001b[32;49mpython -m pip install --upgrade pip\u001b[0m\n"
]
}
],
"source": [
"!pip install langchain boto3 openai tiktoken python-dotenv -q"
"# !pip install langchain boto3 openai tiktoken python-dotenv -q\n",
"!pip install boto3 openai tiktoken python-dotenv -q\n",
"!pip install -e /Users/schadem/code/github/schadem/langchain/libs/langchain"
]
},
{
"cell_type": "code",
"execution_count": 5,
"id": "e4305a0d-37da-41f9-a52c-7d166d7dbabf",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Collecting amazon-textract-caller>=0.2.0\n",
" Obtaining dependency information for amazon-textract-caller>=0.2.0 from https://files.pythonhosted.org/packages/35/42/17daacf400060ee1f768553980b7bd6bb77d5b80bcb8a82d8a9665e5bb9b/amazon_textract_caller-0.2.0-py2.py3-none-any.whl.metadata\n",
" Using cached amazon_textract_caller-0.2.0-py2.py3-none-any.whl.metadata (7.1 kB)\n",
"Requirement already satisfied: boto3>=1.26.35 in /Users/schadem/.pyenv/versions/3.11.1/envs/langchain/lib/python3.11/site-packages (from amazon-textract-caller>=0.2.0) (1.28.67)\n",
"Requirement already satisfied: botocore in /Users/schadem/.pyenv/versions/3.11.1/envs/langchain/lib/python3.11/site-packages (from amazon-textract-caller>=0.2.0) (1.31.67)\n",
"Requirement already satisfied: amazon-textract-response-parser>=0.1.39 in /Users/schadem/.pyenv/versions/3.11.1/envs/langchain/lib/python3.11/site-packages (from amazon-textract-caller>=0.2.0) (0.1.48)\n",
"Requirement already satisfied: marshmallow<4,>=3.14 in /Users/schadem/.pyenv/versions/3.11.1/envs/langchain/lib/python3.11/site-packages (from amazon-textract-response-parser>=0.1.39->amazon-textract-caller>=0.2.0) (3.20.1)\n",
"Requirement already satisfied: jmespath<2.0.0,>=0.7.1 in /Users/schadem/.pyenv/versions/3.11.1/envs/langchain/lib/python3.11/site-packages (from boto3>=1.26.35->amazon-textract-caller>=0.2.0) (1.0.1)\n",
"Requirement already satisfied: s3transfer<0.8.0,>=0.7.0 in /Users/schadem/.pyenv/versions/3.11.1/envs/langchain/lib/python3.11/site-packages (from boto3>=1.26.35->amazon-textract-caller>=0.2.0) (0.7.0)\n",
"Requirement already satisfied: python-dateutil<3.0.0,>=2.1 in /Users/schadem/.pyenv/versions/3.11.1/envs/langchain/lib/python3.11/site-packages (from botocore->amazon-textract-caller>=0.2.0) (2.8.2)\n",
"Requirement already satisfied: urllib3<2.1,>=1.25.4 in /Users/schadem/.pyenv/versions/3.11.1/envs/langchain/lib/python3.11/site-packages (from botocore->amazon-textract-caller>=0.2.0) (1.26.18)\n",
"Requirement already satisfied: packaging>=17.0 in /Users/schadem/.pyenv/versions/3.11.1/envs/langchain/lib/python3.11/site-packages (from marshmallow<4,>=3.14->amazon-textract-response-parser>=0.1.39->amazon-textract-caller>=0.2.0) (23.2)\n",
"Requirement already satisfied: six>=1.5 in /Users/schadem/.pyenv/versions/3.11.1/envs/langchain/lib/python3.11/site-packages (from python-dateutil<3.0.0,>=2.1->botocore->amazon-textract-caller>=0.2.0) (1.16.0)\n",
"Using cached amazon_textract_caller-0.2.0-py2.py3-none-any.whl (13 kB)\n",
"\u001b[33mDEPRECATION: amazon-textract-pipeline-pagedimensions 0.0.8 has a non-standard dependency specifier Pillow>=9.4.*. pip 23.3 will enforce this behaviour change. A possible replacement is to upgrade to a newer version of amazon-textract-pipeline-pagedimensions or contact the author to suggest that they release a version with a conforming dependency specifiers. Discussion can be found at https://github.com/pypa/pip/issues/12063\u001b[0m\u001b[33m\n",
"\u001b[0m\u001b[33mDEPRECATION: amazon-textract-pipeline-pagedimensions 0.0.8 has a non-standard dependency specifier pypdf>=2.5.*. pip 23.3 will enforce this behaviour change. A possible replacement is to upgrade to a newer version of amazon-textract-pipeline-pagedimensions or contact the author to suggest that they release a version with a conforming dependency specifiers. Discussion can be found at https://github.com/pypa/pip/issues/12063\u001b[0m\u001b[33m\n",
"\u001b[0mInstalling collected packages: amazon-textract-caller\n",
" Attempting uninstall: amazon-textract-caller\n",
" Found existing installation: amazon-textract-caller 0.0.29\n",
" Uninstalling amazon-textract-caller-0.0.29:\n",
" Successfully uninstalled amazon-textract-caller-0.0.29\n",
"\u001b[31mERROR: pip's dependency resolver does not currently take into account all the packages that are installed. This behaviour is the source of the following dependency conflicts.\n",
"amazon-textract-textractor 1.4.1 requires amazon-textract-caller<0.1.0,>=0.0.27, but you have amazon-textract-caller 0.2.0 which is incompatible.\u001b[0m\u001b[31m\n",
"\u001b[0mSuccessfully installed amazon-textract-caller-0.2.0\n",
"\n",
"\u001b[1m[\u001b[0m\u001b[34;49mnotice\u001b[0m\u001b[1;39;49m]\u001b[0m\u001b[39;49m A new release of pip is available: \u001b[0m\u001b[31;49m23.2\u001b[0m\u001b[39;49m -> \u001b[0m\u001b[32;49m23.3\u001b[0m\n",
"\u001b[1m[\u001b[0m\u001b[34;49mnotice\u001b[0m\u001b[1;39;49m]\u001b[0m\u001b[39;49m To update, run: \u001b[0m\u001b[32;49mpython -m pip install --upgrade pip\u001b[0m\n"
]
}
],
"source": [
"!pip install \"amazon-textract-caller>=0.2.0\""
]
},
{
@@ -53,12 +174,27 @@
},
{
"cell_type": "code",
"execution_count": 9,
"execution_count": 6,
"id": "1becee92-e82f-42d4-9b4e-b23d77cbe88d",
"metadata": {
"tags": []
},
"outputs": [],
"outputs": [
{
"ename": "ImportError",
"evalue": "cannot import name 'DocumentIntelligenceParser' from 'langchain.document_loaders.parsers.pdf' (/Users/schadem/code/github/schadem/langchain/libs/langchain/langchain/document_loaders/parsers/pdf.py)",
"output_type": "error",
"traceback": [
"\u001b[0;31m---------------------------------------------------------------------------\u001b[0m",
"\u001b[0;31mImportError\u001b[0m Traceback (most recent call last)",
"Cell \u001b[0;32mIn[6], line 1\u001b[0m\n\u001b[0;32m----> 1\u001b[0m \u001b[38;5;28;01mfrom\u001b[39;00m \u001b[38;5;21;01mlangchain\u001b[39;00m\u001b[38;5;21;01m.\u001b[39;00m\u001b[38;5;21;01mdocument_loaders\u001b[39;00m \u001b[38;5;28;01mimport\u001b[39;00m AmazonTextractPDFLoader\n\u001b[1;32m 2\u001b[0m loader \u001b[38;5;241m=\u001b[39m AmazonTextractPDFLoader(\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mexample_data/alejandro_rosalez_sample-small.jpeg\u001b[39m\u001b[38;5;124m\"\u001b[39m)\n\u001b[1;32m 3\u001b[0m documents \u001b[38;5;241m=\u001b[39m loader\u001b[38;5;241m.\u001b[39mload()\n",
"File \u001b[0;32m~/code/github/schadem/langchain/libs/langchain/langchain/document_loaders/__init__.py:46\u001b[0m\n\u001b[1;32m 44\u001b[0m \u001b[38;5;28;01mfrom\u001b[39;00m \u001b[38;5;21;01mlangchain\u001b[39;00m\u001b[38;5;21;01m.\u001b[39;00m\u001b[38;5;21;01mdocument_loaders\u001b[39;00m\u001b[38;5;21;01m.\u001b[39;00m\u001b[38;5;21;01mbigquery\u001b[39;00m \u001b[38;5;28;01mimport\u001b[39;00m BigQueryLoader\n\u001b[1;32m 45\u001b[0m \u001b[38;5;28;01mfrom\u001b[39;00m \u001b[38;5;21;01mlangchain\u001b[39;00m\u001b[38;5;21;01m.\u001b[39;00m\u001b[38;5;21;01mdocument_loaders\u001b[39;00m\u001b[38;5;21;01m.\u001b[39;00m\u001b[38;5;21;01mbilibili\u001b[39;00m \u001b[38;5;28;01mimport\u001b[39;00m BiliBiliLoader\n\u001b[0;32m---> 46\u001b[0m \u001b[38;5;28;01mfrom\u001b[39;00m \u001b[38;5;21;01mlangchain\u001b[39;00m\u001b[38;5;21;01m.\u001b[39;00m\u001b[38;5;21;01mdocument_loaders\u001b[39;00m\u001b[38;5;21;01m.\u001b[39;00m\u001b[38;5;21;01mblackboard\u001b[39;00m \u001b[38;5;28;01mimport\u001b[39;00m BlackboardLoader\n\u001b[1;32m 47\u001b[0m \u001b[38;5;28;01mfrom\u001b[39;00m \u001b[38;5;21;01mlangchain\u001b[39;00m\u001b[38;5;21;01m.\u001b[39;00m\u001b[38;5;21;01mdocument_loaders\u001b[39;00m\u001b[38;5;21;01m.\u001b[39;00m\u001b[38;5;21;01mblob_loaders\u001b[39;00m \u001b[38;5;28;01mimport\u001b[39;00m (\n\u001b[1;32m 48\u001b[0m Blob,\n\u001b[1;32m 49\u001b[0m BlobLoader,\n\u001b[1;32m 50\u001b[0m FileSystemBlobLoader,\n\u001b[1;32m 51\u001b[0m YoutubeAudioLoader,\n\u001b[1;32m 52\u001b[0m )\n\u001b[1;32m 53\u001b[0m \u001b[38;5;28;01mfrom\u001b[39;00m \u001b[38;5;21;01mlangchain\u001b[39;00m\u001b[38;5;21;01m.\u001b[39;00m\u001b[38;5;21;01mdocument_loaders\u001b[39;00m\u001b[38;5;21;01m.\u001b[39;00m\u001b[38;5;21;01mblockchain\u001b[39;00m \u001b[38;5;28;01mimport\u001b[39;00m BlockchainDocumentLoader\n",
"File \u001b[0;32m~/code/github/schadem/langchain/libs/langchain/langchain/document_loaders/blackboard.py:9\u001b[0m\n\u001b[1;32m 7\u001b[0m \u001b[38;5;28;01mfrom\u001b[39;00m \u001b[38;5;21;01mlangchain\u001b[39;00m\u001b[38;5;21;01m.\u001b[39;00m\u001b[38;5;21;01mdocstore\u001b[39;00m\u001b[38;5;21;01m.\u001b[39;00m\u001b[38;5;21;01mdocument\u001b[39;00m \u001b[38;5;28;01mimport\u001b[39;00m Document\n\u001b[1;32m 8\u001b[0m \u001b[38;5;28;01mfrom\u001b[39;00m \u001b[38;5;21;01mlangchain\u001b[39;00m\u001b[38;5;21;01m.\u001b[39;00m\u001b[38;5;21;01mdocument_loaders\u001b[39;00m\u001b[38;5;21;01m.\u001b[39;00m\u001b[38;5;21;01mdirectory\u001b[39;00m \u001b[38;5;28;01mimport\u001b[39;00m DirectoryLoader\n\u001b[0;32m----> 9\u001b[0m \u001b[38;5;28;01mfrom\u001b[39;00m \u001b[38;5;21;01mlangchain\u001b[39;00m\u001b[38;5;21;01m.\u001b[39;00m\u001b[38;5;21;01mdocument_loaders\u001b[39;00m\u001b[38;5;21;01m.\u001b[39;00m\u001b[38;5;21;01mpdf\u001b[39;00m \u001b[38;5;28;01mimport\u001b[39;00m PyPDFLoader\n\u001b[1;32m 10\u001b[0m \u001b[38;5;28;01mfrom\u001b[39;00m \u001b[38;5;21;01mlangchain\u001b[39;00m\u001b[38;5;21;01m.\u001b[39;00m\u001b[38;5;21;01mdocument_loaders\u001b[39;00m\u001b[38;5;21;01m.\u001b[39;00m\u001b[38;5;21;01mweb_base\u001b[39;00m \u001b[38;5;28;01mimport\u001b[39;00m WebBaseLoader\n\u001b[1;32m 13\u001b[0m \u001b[38;5;28;01mclass\u001b[39;00m \u001b[38;5;21;01mBlackboardLoader\u001b[39;00m(WebBaseLoader):\n",
"File \u001b[0;32m~/code/github/schadem/langchain/libs/langchain/langchain/document_loaders/pdf.py:17\u001b[0m\n\u001b[1;32m 15\u001b[0m \u001b[38;5;28;01mfrom\u001b[39;00m \u001b[38;5;21;01mlangchain\u001b[39;00m\u001b[38;5;21;01m.\u001b[39;00m\u001b[38;5;21;01mdocument_loaders\u001b[39;00m\u001b[38;5;21;01m.\u001b[39;00m\u001b[38;5;21;01mbase\u001b[39;00m \u001b[38;5;28;01mimport\u001b[39;00m BaseLoader\n\u001b[1;32m 16\u001b[0m \u001b[38;5;28;01mfrom\u001b[39;00m \u001b[38;5;21;01mlangchain\u001b[39;00m\u001b[38;5;21;01m.\u001b[39;00m\u001b[38;5;21;01mdocument_loaders\u001b[39;00m\u001b[38;5;21;01m.\u001b[39;00m\u001b[38;5;21;01mblob_loaders\u001b[39;00m \u001b[38;5;28;01mimport\u001b[39;00m Blob\n\u001b[0;32m---> 17\u001b[0m \u001b[38;5;28;01mfrom\u001b[39;00m \u001b[38;5;21;01mlangchain\u001b[39;00m\u001b[38;5;21;01m.\u001b[39;00m\u001b[38;5;21;01mdocument_loaders\u001b[39;00m\u001b[38;5;21;01m.\u001b[39;00m\u001b[38;5;21;01mparsers\u001b[39;00m\u001b[38;5;21;01m.\u001b[39;00m\u001b[38;5;21;01mpdf\u001b[39;00m \u001b[38;5;28;01mimport\u001b[39;00m (\n\u001b[1;32m 18\u001b[0m AmazonTextractPDFParser,\n\u001b[1;32m 19\u001b[0m DocumentIntelligenceParser,\n\u001b[1;32m 20\u001b[0m PDFMinerParser,\n\u001b[1;32m 21\u001b[0m PDFPlumberParser,\n\u001b[1;32m 22\u001b[0m PyMuPDFParser,\n\u001b[1;32m 23\u001b[0m PyPDFium2Parser,\n\u001b[1;32m 24\u001b[0m PyPDFParser,\n\u001b[1;32m 25\u001b[0m )\n\u001b[1;32m 26\u001b[0m \u001b[38;5;28;01mfrom\u001b[39;00m \u001b[38;5;21;01mlangchain\u001b[39;00m\u001b[38;5;21;01m.\u001b[39;00m\u001b[38;5;21;01mdocument_loaders\u001b[39;00m\u001b[38;5;21;01m.\u001b[39;00m\u001b[38;5;21;01munstructured\u001b[39;00m \u001b[38;5;28;01mimport\u001b[39;00m UnstructuredFileLoader\n\u001b[1;32m 27\u001b[0m \u001b[38;5;28;01mfrom\u001b[39;00m \u001b[38;5;21;01mlangchain\u001b[39;00m\u001b[38;5;21;01m.\u001b[39;00m\u001b[38;5;21;01mutils\u001b[39;00m \u001b[38;5;28;01mimport\u001b[39;00m get_from_dict_or_env\n",
"\u001b[0;31mImportError\u001b[0m: cannot import name 'DocumentIntelligenceParser' from 'langchain.document_loaders.parsers.pdf' (/Users/schadem/code/github/schadem/langchain/libs/langchain/langchain/document_loaders/parsers/pdf.py)"
]
}
],
"source": [
"from langchain.document_loaders import AmazonTextractPDFLoader\n",
"\n",
@@ -876,7 +1012,7 @@
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.11.1"
"version": "3.11.6"
}
},
"nbformat": 4,

View File

@@ -404,16 +404,16 @@
"metadata": {},
"outputs": [],
"source": [
"chian = prompt | llm\n",
"chain = prompt | llm\n",
"print(chain.invoke({\"thing\": \"life\"}))"
]
}
],
"metadata": {
"kernelspec": {
"display_name": "poetry-venv",
"display_name": "Python 3 (ipykernel)",
"language": "python",
"name": "poetry-venv"
"name": "python3"
},
"language_info": {
"codemirror_mode": {
@@ -425,7 +425,7 @@
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.9.1"
"version": "3.10.12"
},
"vscode": {
"interpreter": {

View File

@@ -1,155 +1,218 @@
{
"cells": [
{
"cell_type": "markdown",
"id": "959300d4",
"metadata": {},
"source": [
"# Hugging Face Local Pipelines\n",
"\n",
"Hugging Face models can be run locally through the `HuggingFacePipeline` class.\n",
"\n",
"The [Hugging Face Model Hub](https://huggingface.co/models) hosts over 120k models, 20k datasets, and 50k demo apps (Spaces), all open source and publicly available, in an online platform where people can easily collaborate and build ML together.\n",
"\n",
"These can be called from LangChain either through this local pipeline wrapper or by calling their hosted inference endpoints through the HuggingFaceHub class. For more information on the hosted pipelines, see the [HuggingFaceHub](huggingface_hub.html) notebook."
]
"cells": [
{
"cell_type": "markdown",
"id": "959300d4",
"metadata": {},
"source": [
"# Hugging Face Local Pipelines\n",
"\n",
"Hugging Face models can be run locally through the `HuggingFacePipeline` class.\n",
"\n",
"The [Hugging Face Model Hub](https://huggingface.co/models) hosts over 120k models, 20k datasets, and 50k demo apps (Spaces), all open source and publicly available, in an online platform where people can easily collaborate and build ML together.\n",
"\n",
"These can be called from LangChain either through this local pipeline wrapper or by calling their hosted inference endpoints through the HuggingFaceHub class. For more information on the hosted pipelines, see the [HuggingFaceHub](huggingface_hub.html) notebook."
]
},
{
"cell_type": "markdown",
"id": "4c1b8450-5eaf-4d34-8341-2d785448a1ff",
"metadata": {
"tags": []
},
"source": [
"To use, you should have the ``transformers`` python [package installed](https://pypi.org/project/transformers/), as well as [pytorch](https://pytorch.org/get-started/locally/). You can also install `xformer` for a more memory-efficient attention implementation."
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "d772b637-de00-4663-bd77-9bc96d798db2",
"metadata": {
"tags": []
},
"outputs": [],
"source": [
"%pip install transformers --quiet"
]
},
{
"cell_type": "markdown",
"id": "91ad075f-71d5-4bc8-ab91-cc0ad5ef16bb",
"metadata": {},
"source": [
"### Model Loading\n",
"\n",
"Models can be loaded by specifying the model parameters using the `from_model_id` method."
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "165ae236-962a-4763-8052-c4836d78a5d2",
"metadata": {
"tags": []
},
"outputs": [],
"source": [
"from langchain.llms.huggingface_pipeline import HuggingFacePipeline\n",
"\n",
"hf = HuggingFacePipeline.from_model_id(\n",
" model_id=\"gpt2\",\n",
" task=\"text-generation\",\n",
" pipeline_kwargs={\"max_new_tokens\": 10},\n",
")"
]
},
{
"cell_type": "markdown",
"id": "00104b27-0c15-4a97-b198-4512337ee211",
"metadata": {},
"source": [
"They can also be loaded by passing in an existing `transformers` pipeline directly"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"from langchain.llms.huggingface_pipeline import HuggingFacePipeline\n",
"from transformers import AutoModelForCausalLM, AutoTokenizer, pipeline\n",
"\n",
"model_id = \"gpt2\"\n",
"tokenizer = AutoTokenizer.from_pretrained(model_id)\n",
"model = AutoModelForCausalLM.from_pretrained(model_id)\n",
"pipe = pipeline(\"text-generation\", model=model, tokenizer=tokenizer, max_new_tokens=10)\n",
"hf = HuggingFacePipeline(pipeline=pipe)"
],
"id": "7f426a4f"
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Create Chain\n",
"\n",
"With the model loaded into memory, you can compose it with a prompt to\n",
"form a chain."
],
"id": "60e7ba8d"
},
{
"cell_type": "code",
"execution_count": null,
"id": "3acf0069",
"metadata": {},
"outputs": [],
"source": [
"from langchain.prompts import PromptTemplate\n",
"\n",
"template = \"\"\"Question: {question}\n",
"\n",
"Answer: Let's think step by step.\"\"\"\n",
"prompt = PromptTemplate.from_template(template)\n",
"\n",
"chain = prompt | hf\n",
"\n",
"question = \"What is electroencephalography?\"\n",
"\n",
"print(chain.invoke({\"question\": question}))"
]
},
{
"cell_type": "markdown",
"id": "dbbc3a37",
"metadata": {},
"source": [
"### GPU Inference\n",
"\n",
"When running on a machine with GPU, you can specify the `device=n` parameter to put the model on the specified device.\n",
"Defaults to `-1` for CPU inference.\n",
"\n",
"If you have multiple-GPUs and/or the model is too large for a single GPU, you can specify `device_map=\"auto\"`, which requires and uses the [Accelerate](https://huggingface.co/docs/accelerate/index) library to automatically determine how to load the model weights. \n",
"\n",
"*Note*: both `device` and `device_map` should not be specified together and can lead to unexpected behavior."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"gpu_llm = HuggingFacePipeline.from_model_id(\n",
" model_id=\"gpt2\",\n",
" task=\"text-generation\",\n",
" device=0, # replace with device_map=\"auto\" to use the accelerate library.\n",
" pipeline_kwargs={\"max_new_tokens\": 10},\n",
")\n",
"\n",
"gpu_chain = prompt | gpu_llm\n",
"\n",
"question = \"What is electroencephalography?\"\n",
"\n",
"print(gpu_chain.invoke({\"question\": question}))"
],
"id": "703c91c8"
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Batch GPU Inference\n",
"\n",
"If running on a device with GPU, you can also run inference on the GPU in batch mode."
],
"id": "59276016"
},
{
"cell_type": "code",
"execution_count": null,
"id": "097ba62f",
"metadata": {},
"outputs": [],
"source": [
"gpu_llm = HuggingFacePipeline.from_model_id(\n",
" model_id=\"bigscience/bloom-1b7\",\n",
" task=\"text-generation\",\n",
" device=0, # -1 for CPU\n",
" batch_size=2, # adjust as needed based on GPU map and model size.\n",
" model_kwargs={\"temperature\": 0, \"max_length\": 64},\n",
")\n",
"\n",
"gpu_chain = prompt | gpu_llm.bind(stop=[\"\\n\\n\"])\n",
"\n",
"questions = []\n",
"for i in range(4):\n",
" questions.append({\"question\": f\"What is the number {i} in french?\"})\n",
"\n",
"answers = gpu_chain.batch(questions)\n",
"for answer in answers:\n",
" print(answer)"
]
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3 (ipykernel)",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.10.5"
}
},
{
"cell_type": "markdown",
"id": "4c1b8450-5eaf-4d34-8341-2d785448a1ff",
"metadata": {
"tags": []
},
"source": [
"To use, you should have the ``transformers`` python [package installed](https://pypi.org/project/transformers/), as well as [pytorch](https://pytorch.org/get-started/locally/). You can also install `xformer` for a more memory-efficient attention implementation."
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "d772b637-de00-4663-bd77-9bc96d798db2",
"metadata": {
"tags": []
},
"outputs": [],
"source": [
"%pip install transformers --quiet"
]
},
{
"cell_type": "markdown",
"id": "91ad075f-71d5-4bc8-ab91-cc0ad5ef16bb",
"metadata": {},
"source": [
"### Load the model"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "165ae236-962a-4763-8052-c4836d78a5d2",
"metadata": {
"tags": []
},
"outputs": [],
"source": [
"from langchain.llms import HuggingFacePipeline\n",
"\n",
"llm = HuggingFacePipeline.from_model_id(\n",
" model_id=\"bigscience/bloom-1b7\",\n",
" task=\"text-generation\",\n",
" model_kwargs={\"temperature\": 0, \"max_length\": 64},\n",
")"
]
},
{
"cell_type": "markdown",
"id": "00104b27-0c15-4a97-b198-4512337ee211",
"metadata": {},
"source": [
"### Create Chain\n",
"\n",
"With the model loaded into memory, you can compose it with a prompt to\n",
"form a chain."
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "3acf0069",
"metadata": {},
"outputs": [],
"source": [
"from langchain.prompts import PromptTemplate\n",
"\n",
"template = \"\"\"Question: {question}\n",
"\n",
"Answer: Let's think step by step.\"\"\"\n",
"prompt = PromptTemplate.from_template(template)\n",
"\n",
"chain = prompt | llm\n",
"\n",
"question = \"What is electroencephalography?\"\n",
"\n",
"print(chain.invoke({\"question\": question}))"
]
},
{
"cell_type": "markdown",
"id": "dbbc3a37",
"metadata": {},
"source": [
"### Batch GPU Inference\n",
"\n",
"If running on a device with GPU, you can also run inference on the GPU in batch mode."
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "097ba62f",
"metadata": {},
"outputs": [],
"source": [
"gpu_llm = HuggingFacePipeline.from_model_id(\n",
" model_id=\"bigscience/bloom-1b7\",\n",
" task=\"text-generation\",\n",
" device=0, # -1 for CPU\n",
" batch_size=2, # adjust as needed based on GPU map and model size.\n",
" model_kwargs={\"temperature\": 0, \"max_length\": 64},\n",
")\n",
"\n",
"gpu_chain = prompt | gpu_llm.bind(stop=[\"\\n\\n\"])\n",
"\n",
"questions = []\n",
"for i in range(4):\n",
" questions.append({\"question\": f\"What is the number {i} in french?\"})\n",
"\n",
"answers = gpu_chain.batch(questions)\n",
"for answer in answers:\n",
" print(answer)"
]
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3 (ipykernel)",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.8.10"
}
},
"nbformat": 4,
"nbformat_minor": 5
}
"nbformat": 4,
"nbformat_minor": 5
}

View File

@@ -6,9 +6,9 @@
"source": [
"# Llama.cpp\n",
"\n",
"[llama-cpp-python](https://github.com/abetlen/llama-cpp-python) is a Python binding for [llama.cpp](https://github.com/ggerganov/llama.cpp). \n",
"[llama-cpp-python](https://github.com/abetlen/llama-cpp-python) is a Python binding for [llama.cpp](https://github.com/ggerganov/llama.cpp).\n",
"\n",
"It supports inference for [many LLMs](https://github.com/ggerganov/llama.cpp), which can be accessed on [HuggingFace](https://huggingface.co/TheBloke).\n",
"It supports inference for [many LLMs](https://github.com/ggerganov/llama.cpp#description) models, which can be accessed on [Hugging Face](https://huggingface.co/TheBloke).\n",
"\n",
"This notebook goes over how to run `llama-cpp-python` within LangChain.\n",
"\n",
@@ -54,7 +54,7 @@
"source": [
"### Installation with OpenBLAS / cuBLAS / CLBlast\n",
"\n",
"`lama.cpp` supports multiple BLAS backends for faster processing. Use the `FORCE_CMAKE=1` environment variable to force the use of cmake and install the pip package for the desired BLAS backend ([source](https://github.com/abetlen/llama-cpp-python#installation-with-openblas--cublas--clblast)).\n",
"`llama.cpp` supports multiple BLAS backends for faster processing. Use the `FORCE_CMAKE=1` environment variable to force the use of cmake and install the pip package for the desired BLAS backend ([source](https://github.com/abetlen/llama-cpp-python#installation-with-openblas--cublas--clblast)).\n",
"\n",
"Example installation with cuBLAS backend:"
]
@@ -177,7 +177,11 @@
"\n",
"You don't need an `API_TOKEN` as you will run the LLM locally.\n",
"\n",
"It is worth understanding which models are suitable to be used on the desired machine."
"It is worth understanding which models are suitable to be used on the desired machine.\n",
"\n",
"[TheBloke's](https://huggingface.co/TheBloke) Hugging Face models have a `Provided files` section that exposes the RAM required to run models of different quantisation sizes and methods (eg: [Llama2-7B-Chat-GGUF](https://huggingface.co/TheBloke/Llama-2-7b-Chat-GGUF#provided-files)).\n",
"\n",
"This [github issue](https://github.com/facebookresearch/llama/issues/425) is also relevant to find the right model for your machine."
]
},
{
@@ -199,7 +203,7 @@
"cell_type": "markdown",
"metadata": {},
"source": [
"**Consider using a template that suits your model! Check the models page on HuggingFace etc. to get a correct prompting template.**"
"**Consider using a template that suits your model! Check the models page on Hugging Face etc. to get a correct prompting template.**"
]
},
{

View File

@@ -0,0 +1,367 @@
{
"cells": [
{
"cell_type": "markdown",
"id": "fdd7864c-93e6-4eb4-a923-b80d2ae4377d",
"metadata": {},
"source": [
"# LM Format Enforcer\n",
"\n",
"[LM Format Enforcer](https://github.com/noamgat/lm-format-enforcer) is a library that enforces the output format of language models by filtering tokens.\n",
"\n",
"It works by combining a character level parser with a tokenizer prefix tree to allow only the tokens which contains sequences of characters that lead to a potentially valid format.\n",
"\n",
"It supports batched generation.\n",
"\n",
"**Warning - this module is still experimental**"
]
},
{
"cell_type": "code",
"execution_count": 1,
"id": "1617e327-d9a2-4ab6-aa9f-30a3167a3393",
"metadata": {
"tags": []
},
"outputs": [],
"source": [
"!pip install --upgrade lm-format-enforcer > /dev/null"
]
},
{
"cell_type": "markdown",
"id": "a3c3331d",
"metadata": {},
"source": [
"### Setting up the model\n",
"\n",
"We will start by setting up a LLama2 model and initializing our desired output format.\n",
"Note that Llama2 [requires approval for access to the models](https://huggingface.co/meta-llama/Llama-2-7b-chat-hf).\n"
]
},
{
"cell_type": "code",
"execution_count": 2,
"id": "d4d616ae-4d11-425f-b06c-c706d0386c68",
"metadata": {
"tags": []
},
"outputs": [],
"source": [
"import logging\n",
"from langchain_experimental.pydantic_v1 import BaseModel\n",
"\n",
"logging.basicConfig(level=logging.ERROR)\n",
"\n",
"\n",
"class PlayerInformation(BaseModel):\n",
" first_name: str\n",
" last_name: str\n",
" num_seasons_in_nba: int\n",
" year_of_birth: int"
]
},
{
"cell_type": "code",
"execution_count": 3,
"id": "93fe95cd",
"metadata": {},
"outputs": [
{
"name": "stderr",
"output_type": "stream",
"text": [
"/home/noamgat/envs/langchain_experimental/lib/python3.10/site-packages/tqdm/auto.py:21: TqdmWarning: IProgress not found. Please update jupyter and ipywidgets. See https://ipywidgets.readthedocs.io/en/stable/user_install.html\n",
" from .autonotebook import tqdm as notebook_tqdm\n",
"Downloading shards: 100%|██████████| 2/2 [00:00<00:00, 3.58it/s]\n",
"Loading checkpoint shards: 100%|██████████| 2/2 [05:32<00:00, 166.35s/it]\n",
"Downloading (…)okenizer_config.json: 100%|██████████| 1.62k/1.62k [00:00<00:00, 4.87MB/s]\n"
]
}
],
"source": [
"import torch\n",
"from transformers import AutoTokenizer, AutoModelForCausalLM, AutoConfig\n",
"\n",
"model_id = \"meta-llama/Llama-2-7b-chat-hf\"\n",
"\n",
"device = \"cuda\"\n",
"\n",
"if torch.cuda.is_available():\n",
" config = AutoConfig.from_pretrained(model_id)\n",
" config.pretraining_tp = 1\n",
" model = AutoModelForCausalLM.from_pretrained(\n",
" model_id,\n",
" config=config,\n",
" torch_dtype=torch.float16,\n",
" load_in_8bit=True,\n",
" device_map=\"auto\",\n",
" )\n",
"else:\n",
" raise Exception(\"GPU not available\")\n",
"tokenizer = AutoTokenizer.from_pretrained(model_id)\n",
"if tokenizer.pad_token_id is None:\n",
" # Required for batching example\n",
" tokenizer.pad_token_id = tokenizer.eos_token_id"
]
},
{
"cell_type": "markdown",
"id": "66bd89f1-8daa-433d-bb8f-5b0b3ae34b00",
"metadata": {},
"source": [
"### HuggingFace Baseline\n",
"\n",
"First, let's establish a qualitative baseline by checking the output of the model without structured decoding."
]
},
{
"cell_type": "code",
"execution_count": 9,
"id": "d5522977-51e8-40eb-9403-8ab70b14908e",
"metadata": {
"tags": []
},
"outputs": [],
"source": [
"DEFAULT_SYSTEM_PROMPT = \"\"\"\\\n",
"You are a helpful, respectful and honest assistant. Always answer as helpfully as possible, while being safe. Your answers should not include any harmful, unethical, racist, sexist, toxic, dangerous, or illegal content. Please ensure that your responses are socially unbiased and positive in nature.\\n\\nIf a question does not make any sense, or is not factually coherent, explain why instead of answering something not correct. If you don't know the answer to a question, please don't share false information.\\\n",
"\"\"\"\n",
"\n",
"prompt = \"\"\"Please give me information about {player_name}. You must respond using JSON format, according to the following schema:\n",
"\n",
"{arg_schema}\n",
"\n",
"\"\"\"\n",
"\n",
"\n",
"def make_instruction_prompt(message):\n",
" return f\"[INST] <<SYS>>\\n{DEFAULT_SYSTEM_PROMPT}\\n<</SYS>> {message} [/INST]\"\n",
"\n",
"\n",
"def get_prompt(player_name):\n",
" return make_instruction_prompt(\n",
" prompt.format(\n",
" player_name=player_name, arg_schema=PlayerInformation.schema_json()\n",
" )\n",
" )"
]
},
{
"cell_type": "code",
"execution_count": 5,
"id": "9148e4b8-d370-4c05-a873-c121b65057b5",
"metadata": {
"tags": []
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
" {\n",
"\"title\": \"PlayerInformation\",\n",
"\"type\": \"object\",\n",
"\"properties\": {\n",
"\"first_name\": {\n",
"\"title\": \"First Name\",\n",
"\"type\": \"string\"\n",
"},\n",
"\"last_name\": {\n",
"\"title\": \"Last Name\",\n",
"\"type\": \"string\"\n",
"},\n",
"\"num_seasons_in_nba\": {\n",
"\"title\": \"Num Seasons In Nba\",\n",
"\"type\": \"integer\"\n",
"},\n",
"\"year_of_birth\": {\n",
"\"title\": \"Year Of Birth\",\n",
"\"type\": \"integer\"\n",
"\n",
"}\n",
"\n",
"\"required\": [\n",
"\"first_name\",\n",
"\"last_name\",\n",
"\"num_seasons_in_nba\",\n",
"\"year_of_birth\"\n",
"]\n",
"}\n",
"\n",
"}\n"
]
}
],
"source": [
"from transformers import pipeline\n",
"from langchain.llms import HuggingFacePipeline\n",
"\n",
"hf_model = pipeline(\n",
" \"text-generation\", model=model, tokenizer=tokenizer, max_new_tokens=200\n",
")\n",
"\n",
"original_model = HuggingFacePipeline(pipeline=hf_model)\n",
"\n",
"generated = original_model.predict(get_prompt(\"Michael Jordan\"))\n",
"print(generated)"
]
},
{
"cell_type": "markdown",
"id": "b6e7b9cf-8ce5-4f87-b4bf-100321ad2dd1",
"metadata": {},
"source": [
"***The result is usually closer to the JSON object of the schema definition, rather than a json object conforming to the schema. Lets try to enforce proper output.***"
]
},
{
"cell_type": "markdown",
"id": "96115154-a90a-46cb-9759-573860fc9b79",
"metadata": {},
"source": [
"## JSONFormer LLM Wrapper\n",
"\n",
"Let's try that again, now providing a the Action input's JSON Schema to the model."
]
},
{
"cell_type": "code",
"execution_count": 6,
"id": "0f7447fe-22a9-47db-85b9-7adf0f19307d",
"metadata": {
"tags": []
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
" { \"first_name\": \"Michael\", \"last_name\": \"Jordan\", \"num_seasons_in_nba\": 15, \"year_of_birth\": 1963 }\n"
]
}
],
"source": [
"from langchain_experimental.llms import LMFormatEnforcer\n",
"\n",
"lm_format_enforcer = LMFormatEnforcer(\n",
" json_schema=PlayerInformation.schema(), pipeline=hf_model\n",
")\n",
"results = lm_format_enforcer.predict(get_prompt(\"Michael Jordan\"))\n",
"print(results)"
]
},
{
"cell_type": "markdown",
"id": "32077d74-0605-4138-9a10-0ce36637040d",
"metadata": {
"tags": []
},
"source": [
"**The output conforms to the exact specification! Free of parsing errors.**\n",
"\n",
"This means that if you need to format a JSON for an API call or similar, if you can generate the schema (from a pydantic model or general) you can use this library to make sure that the JSON output is correct, with minimal risk of hallucinations.\n",
"\n",
"### Batch processing\n",
"\n",
"LMFormatEnforcer also works in batch mode:"
]
},
{
"cell_type": "code",
"execution_count": 7,
"id": "9817095b",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
" { \"first_name\": \"Michael\", \"last_name\": \"Jordan\", \"num_seasons_in_nba\": 15, \"year_of_birth\": 1963 }\n",
" { \"first_name\": \"Kareem\", \"last_name\": \"Abdul-Jabbar\", \"num_seasons_in_nba\": 20, \"year_of_birth\": 1947 }\n",
" { \"first_name\": \"Timothy\", \"last_name\": \"Duncan\", \"num_seasons_in_nba\": 19, \"year_of_birth\": 1976 }\n"
]
}
],
"source": [
"prompts = [\n",
" get_prompt(name) for name in [\"Michael Jordan\", \"Kareem Abdul Jabbar\", \"Tim Duncan\"]\n",
"]\n",
"results = lm_format_enforcer.generate(prompts)\n",
"for generation in results.generations:\n",
" print(generation[0].text)"
]
},
{
"cell_type": "markdown",
"id": "59bea0d8",
"metadata": {},
"source": [
"## Regular Expressions\n",
"\n",
"LMFormatEnforcer has an additional mode, which uses regular expressions to filter the output. Note that it uses [interegular](https://pypi.org/project/interegular/) under the hood, therefore it does not support 100% of the regex capabilities."
]
},
{
"cell_type": "code",
"execution_count": 8,
"id": "da63ce31-de79-4462-a1a9-b726b698c5ba",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Unenforced output:\n",
" I apologize, but the question you have asked is not factually coherent. Michael Jordan was born on February 17, 1963, in Fort Greene, Brooklyn, New York, USA. Therefore, I cannot provide an answer in the mm/dd/yyyy format as it is not a valid date.\n",
"I understand that you may have asked this question in good faith, but I must ensure that my responses are always accurate and reliable. I'm just an AI, my primary goal is to provide helpful and informative answers while adhering to ethical and moral standards. If you have any other questions, please feel free to ask, and I will do my best to assist you.\n",
"Enforced Output:\n",
" In mm/dd/yyyy format, Michael Jordan was born in 02/17/1963\n"
]
}
],
"source": [
"question_prompt = \"When was Michael Jordan Born? Please answer in mm/dd/yyyy format.\"\n",
"date_regex = r\"(0?[1-9]|1[0-2])\\/(0?[1-9]|1\\d|2\\d|3[01])\\/(19|20)\\d{2}\"\n",
"answer_regex = \" In mm/dd/yyyy format, Michael Jordan was born in \" + date_regex\n",
"\n",
"lm_format_enforcer = LMFormatEnforcer(regex=answer_regex, pipeline=hf_model)\n",
"\n",
"full_prompt = make_instruction_prompt(question_prompt)\n",
"print(\"Unenforced output:\")\n",
"print(original_model.predict(full_prompt))\n",
"print(\"Enforced Output:\")\n",
"print(lm_format_enforcer.predict(full_prompt))"
]
},
{
"cell_type": "markdown",
"id": "0b1839c5",
"metadata": {},
"source": [
"As in the previous example, the output conforms to the regular expression and contains the correct information."
]
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3 (ipykernel)",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.10.13"
}
},
"nbformat": 4,
"nbformat_minor": 5
}

View File

@@ -288,7 +288,7 @@
"metadata": {},
"source": [
"## Streaming Response\n",
"You can optionally stream the response as it is produced, which is helpful to show interactivity to users for time-consuming generations. See detailed docs on [Streaming](https://python.langchain.com/docs/modules/model_io/models/llms/how_to/streaming_llm) for more information."
"You can optionally stream the response as it is produced, which is helpful to show interactivity to users for time-consuming generations. See detailed docs on [Streaming](https://python.langchain.com/docs/modules/model_io/llms/how_to/streaming_llm) for more information."
]
},
{

View File

@@ -0,0 +1,76 @@
{
"cells": [
{
"cell_type": "markdown",
"id": "91c6a7ef",
"metadata": {},
"source": [
"# Neo4j\n",
"\n",
"[Neo4j](https://en.wikipedia.org/wiki/Neo4j) is an open-source graph database management system, renowned for its efficient management of highly connected data. Unlike traditional databases that store data in tables, Neo4j uses a graph structure with nodes, edges, and properties to represent and store data. This design allows for high-performance queries on complex data relationships.\n",
"\n",
"This notebook goes over how to use `Neo4j` to store chat message history."
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "d15e3302",
"metadata": {},
"outputs": [],
"source": [
"from langchain.memory import Neo4jChatMessageHistory\n",
"\n",
"history = Neo4jChatMessageHistory(\n",
" url=\"bolt://localhost:7687\",\n",
" username=\"neo4j\",\n",
" password=\"password\",\n",
" session_id=\"session_id_1\"\n",
")\n",
"\n",
"history.add_user_message(\"hi!\")\n",
"\n",
"history.add_ai_message(\"whats up?\")"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "64fc465e",
"metadata": {},
"outputs": [],
"source": [
"history.messages"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "8af285f8",
"metadata": {},
"outputs": [],
"source": []
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3 (ipykernel)",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.8.8"
}
},
"nbformat": 4,
"nbformat_minor": 5
}

View File

@@ -6,32 +6,31 @@
"source": [
"# Zep\n",
"\n",
">[Zep](https://docs.getzep.com/) is a long-term memory store for LLM applications.\n",
">\n",
">`Zep` stores, summarizes, embeds, indexes, and enriches conversational AI chat histories, and exposes them via simple, low-latency APIs.\n",
"## Fast, Scalable Building Blocks for LLM Apps\n",
"Zep is an open source platform for productionizing LLM apps. Go from a prototype\n",
"built in LangChain or LlamaIndex, or a custom app, to production in minutes without\n",
"rewriting code.\n",
"\n",
"Key Features:\n",
"\n",
"- **Fast!** Zeps async extractors operate independently of your chat loop, ensuring a snappy user experience.\n",
"- **Long-term memory persistence**, with access to historical messages irrespective of your summarization strategy.\n",
"- **Auto-summarization** of memory messages based on a configurable message window. A series of summaries are stored, providing flexibility for future summarization strategies.\n",
"- **Hybrid search** over memories and metadata, with messages automatically embedded upon creation.\n",
"- **Entity Extractor** that automatically extracts named entities from messages and stores them in the message metadata.\n",
"- **Auto-token counting** of memories and summaries, allowing finer-grained control over prompt assembly.\n",
"- Python and JavaScript SDKs.\n",
"- **Fast!** Zep operates independently of the your chat loop, ensuring a snappy user experience.\n",
"- **Chat History Memory, Archival, and Enrichment**, populate your prompts with relevant chat history, sumamries, named entities, intent data, and more.\n",
"- **Vector Search over Chat History and Documents** Automatic embedding of documents, chat histories, and summaries. Use Zep's similarity or native MMR Re-ranked search to find the most relevant.\n",
"- **Manage Users and their Chat Sessions** Users and their Chat Sessions are first-class citizens in Zep, allowing you to manage user interactions with your bots or agents easily.\n",
"- **Records Retention and Privacy Compliance** Comply with corporate and regulatory mandates for records retention while ensuring compliance with privacy regulations such as CCPA and GDPR. Fulfill *Right To Be Forgotten* requests with a single API call\n",
"\n",
"`Zep` project: [https://github.com/getzep/zep](https://github.com/getzep/zep)\n",
"Zep project: [https://github.com/getzep/zep](https://github.com/getzep/zep)\n",
"Docs: [https://docs.getzep.com/](https://docs.getzep.com/)\n",
"\n",
"\n",
"## Example\n",
"\n",
"This notebook demonstrates how to use the [Zep Long-term Memory Store](https://docs.getzep.com/) as memory for your chatbot.\n",
"This notebook demonstrates how to use [Zep](https://www.getzep.com/) as memory for your chatbot.\n",
"REACT Agent Chat Message History with Zep - A long-term memory store for LLM applications.\n",
"\n",
"We'll demonstrate:\n",
"\n",
"1. Adding conversation history to the Zep memory store.\n",
"1. Adding conversation history to Zep.\n",
"2. Running an agent and having message automatically added to the store.\n",
"3. Viewing the enriched messages.\n",
"4. Vector search over the conversation history."
@@ -39,7 +38,7 @@
},
{
"cell_type": "code",
"execution_count": 1,
"execution_count": null,
"metadata": {
"ExecuteTime": {
"end_time": "2023-07-09T19:20:49.003167Z",
@@ -65,7 +64,7 @@
},
{
"cell_type": "code",
"execution_count": 2,
"execution_count": 1,
"metadata": {
"ExecuteTime": {
"end_time": "2023-07-09T19:23:14.378234Z",
@@ -119,7 +118,10 @@
" Tool(\n",
" name=\"Search\",\n",
" func=search.run,\n",
" description=\"useful for when you need to search online for answers. You should ask targeted questions\",\n",
" description=(\n",
" \"useful for when you need to search online for answers. You should ask\"\n",
" \" targeted questions\"\n",
" ),\n",
" ),\n",
"]\n",
"\n",
@@ -223,9 +225,11 @@
"\n",
"for msg in test_history:\n",
" memory.chat_memory.add_message(\n",
" HumanMessage(content=msg[\"content\"])\n",
" if msg[\"role\"] == \"human\"\n",
" else AIMessage(content=msg[\"content\"]),\n",
" (\n",
" HumanMessage(content=msg[\"content\"])\n",
" if msg[\"role\"] == \"human\"\n",
" else AIMessage(content=msg[\"content\"])\n",
" ),\n",
" metadata=msg.get(\"metadata\", {}),\n",
" )"
]
@@ -415,7 +419,7 @@
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.10.12"
"version": "3.11.6"
}
},
"nbformat": 4,

View File

@@ -85,11 +85,11 @@ model.convert_prompt(prompt_value)
This produces the following formatted string:
```
'\n\nHuman: <admin>You are a helpful chatbot</admin>\n\nHuman: Tell me a joke about bears\n\nAssistant:'
'\n\nYou are a helpful chatbot\n\nHuman: Tell me a joke about bears\n\nAssistant:'
```
We can see that under the hood LangChain is representing `SystemMessage`s with `Human: <admin>...</admin>`,
and is appending an assistant message to the end IF the last message is NOT already an assistant message.
We can see that under the hood LangChain is not appending any prefix/suffix to `SystemMessage`'s. This is because Anthropic has no concept of `SystemMessage`.
Anthropic requires all prompts to end with assistant messages. This means if the last message is not an assistant message, the suffix `Assistant:` will automatically be inserted.
If you decide instead to use a normal PromptTemplate (one that just works on a single string) let's take a look at
what happens:

View File

@@ -1,12 +1,20 @@
# Google
All functionality related to [Google Cloud Platform](https://cloud.google.com/)
All functionality related to [Google Cloud Platform](https://cloud.google.com/) and other `Google` products.
## LLMs
### Vertex AI
Access PaLM LLMs like `text-bison` and `code-bison` via Google Cloud.
Access `PaLM` LLMs like `text-bison` and `code-bison` via `Google Vertex AI`.
We need to install `google-cloud-aiplatform` python package.
```bash
pip install google-cloud-aiplatform
```
See a [usage example](/docs/integrations/llms/google_vertex_ai_palm).
```python
from langchain.llms import VertexAI
@@ -14,7 +22,15 @@ from langchain.llms import VertexAI
### Model Garden
Access PaLM and hundreds of OSS models via Vertex AI Model Garden.
Access PaLM and hundreds of OSS models via `Vertex AI Model Garden`.
We need to install `google-cloud-aiplatform` python package.
```bash
pip install google-cloud-aiplatform
```
See a [usage example](/docs/integrations/llms/google_vertex_ai_palm#vertex-model-garden).
```python
from langchain.llms import VertexAIModelGarden
@@ -26,17 +42,26 @@ from langchain.llms import VertexAIModelGarden
Access PaLM chat models like `chat-bison` and `codechat-bison` via Google Cloud.
We need to install `google-cloud-aiplatform` python package.
```bash
pip install google-cloud-aiplatform
```
See a [usage example](/docs/integrations/chat/google_vertex_ai_palm).
```python
from langchain.chat_models import ChatVertexAI
```
## Document Loader
## Document Loaders
### Google BigQuery
> [Google BigQuery](https://cloud.google.com/bigquery) is a serverless and cost-effective enterprise data warehouse that works across clouds and scales with your data.
`BigQuery` is a part of the `Google Cloud Platform`.
First, we need to install `google-cloud-bigquery` python package.
We need to install `google-cloud-bigquery` python package.
```bash
pip install google-cloud-bigquery
@@ -50,9 +75,9 @@ from langchain.document_loaders import BigQueryLoader
### Google Cloud Storage
> [Google Cloud Storage](https://en.wikipedia.org/wiki/Google_Cloud_Storage) is a managed service for storing unstructured data.
>[Google Cloud Storage](https://en.wikipedia.org/wiki/Google_Cloud_Storage) is a managed service for storing unstructured data.
First, we need to install `google-cloud-storage` python package.
We need to install `google-cloud-storage` python package.
```bash
pip install google-cloud-storage
@@ -73,11 +98,11 @@ from langchain.document_loaders import GCSFileLoader
### Google Drive
> [Google Drive](https://en.wikipedia.org/wiki/Google_Drive) is a file storage and synchronization service developed by Google.
>[Google Drive](https://en.wikipedia.org/wiki/Google_Drive) is a file storage and synchronization service developed by Google.
Currently, only `Google Docs` are supported.
First, we need to install several python packages.
We need to install several python packages.
```bash
pip install google-api-python-client google-auth-httplib2 google-auth-oauthlib
@@ -107,11 +132,14 @@ See a [usage example and authorization instructions](/docs/integrations/document
from langchain.document_loaders import GoogleSpeechToTextLoader
```
## Vector Store
### Vertex AI Vector Search
> [Vertex AI Vector Search](https://cloud.google.com/vertex-ai/docs/matching-engine/overview),
> formerly known as Vertex AI Matching Engine, provides the industry's leading high-scale
## Vector Stores
### Google Vertex AI Vector Search
> [Google Vertex AI Vector Search](https://cloud.google.com/vertex-ai/docs/matching-engine/overview),
> formerly known as `Vertex AI Matching Engine`, provides the industry's leading high-scale
> low latency vector database. These vector databases are commonly
> referred to as vector similarity-matching or an approximate nearest neighbor (ANN) service.
@@ -153,12 +181,28 @@ from langchain.vectorstores import ScaNN
```
## Retrievers
### Google Drive
We need to install several python packages.
```bash
pip install google-api-python-client google-auth-httplib2 google-auth-oauthlib
```
See a [usage example and authorization instructions](/docs/integrations/retrievers/google_drive).
```python
from langchain_googledrive.retrievers import GoogleDriveRetriever
```
### Vertex AI Search
> [Google Cloud Vertex AI Search](https://cloud.google.com/generative-ai-app-builder/docs/introduction)
> allows developers to quickly build generative AI powered search engines for customers and employees.
First, you need to install the `google-cloud-discoveryengine` Python package.
We need to install the `google-cloud-discoveryengine` python package.
```bash
pip install google-cloud-discoveryengine
@@ -173,7 +217,7 @@ from langchain.retrievers import GoogleVertexAISearchRetriever
### Document AI Warehouse
> [Google Cloud Document AI Warehouse](https://cloud.google.com/document-ai-warehouse)
> allows enterprises to search, store, govern, and manage documents and their AI-extracted
> data and metadata in a single platform. Documents should be uploaded outside of Langchain,
> data and metadata in a single platform.
>
```python
@@ -188,14 +232,47 @@ documents = docai_wh_retriever.get_relevant_documents(
```
## Tools
### Google Drive
We need to install several python packages.
```bash
pip install google-api-python-client google-auth-httplib2 google-auth-oauthlib
```
See a [usage example and authorization instructions](/docs/integrations/tools/google_drive).
```python
from langchain.utilities.google_drive import GoogleDriveAPIWrapper
from langchain.tools.google_drive.tool import GoogleDriveSearchTool
```
### Google Places
We need to install a python package.
```bash
pip install googlemaps
```
See a [usage example and authorization instructions](/docs/integrations/tools/google_places).
```python
from langchain.tools import GooglePlacesTool
```
### Google Search
- Install requirements with `pip install google-api-python-client`
We need to install a python package.
```bash
pip install google-api-python-client
```
- Set up a Custom Search Engine, following [these instructions](https://stackoverflow.com/questions/37083058/programmatically-searching-google-in-python-using-custom-search)
- Get an API Key and Custom Search Engine ID from the previous step, and set them as environment variables `GOOGLE_API_KEY` and `GOOGLE_CSE_ID` respectively
There exists a `GoogleSearchAPIWrapper` utility which wraps this API. To import this utility:
```python
from langchain.utilities import GoogleSearchAPIWrapper
```
@@ -209,25 +286,14 @@ from langchain.agents import load_tools
tools = load_tools(["google-search"])
```
### Google Places
See a [usage example](/docs/integrations/tools/google_places).
```
pip install googlemaps
```
```python
from langchain.tools import GooglePlacesTool
```
## Document Transformers
### Google Document AI
>[Document AI](https://cloud.google.com/document-ai/docs/overview) is a `Google Cloud Platform`
> service to transform unstructured data from documents into structured data, making it easier
> to understand, analyze, and consume.
> service that transforms unstructured data from documents into structured data, making it easier
> to understand, analyze, and consume.
We need to set up a [`GCS` bucket and create your own OCR processor](https://cloud.google.com/document-ai/docs/create-processor)
The `GCS_OUTPUT_PATH` should be a path to a folder on GCS (starting with `gs://`)
@@ -269,15 +335,54 @@ See a [usage example and authorization instructions](/docs/integrations/document
from langchain.document_transformers import GoogleTranslateTransformer
```
## Chat loaders
### Gmail
## Toolkits
### GMail
> [Gmail](https://en.wikipedia.org/wiki/Gmail) is a free email service provided by Google.
This toolkit works with emails through the `Gmail API`.
First, we need to install several python packages.
We need to install several python packages.
```bash
pip install --upgrade google-auth google-auth-oauthlib google-auth-httplib2 google-api-python-client
pip install google-api-python-client google-auth-oauthlib google-auth-httplib2
```
See a [usage example and authorization instructions](/docs/integrations/toolkits/gmail).
```python
from langchain.agents.agent_toolkits import GmailToolkit
```
### Google Drive
This toolkit uses the `Google Drive API`.
We need to install several python packages.
```bash
pip install google-api-python-client google-auth-httplib2 google-auth-oauthlib
```
See a [usage example and authorization instructions](/docs/integrations/toolkits/google_drive).
```python
from langchain_googledrive.utilities.google_drive import GoogleDriveAPIWrapper
from langchain_googledrive.tools.google_drive.tool import GoogleDriveSearchTool
```
## Chat Loaders
### GMail
> [Gmail](https://en.wikipedia.org/wiki/Gmail) is a free email service provided by Google.
This loader works with emails through the `Gmail API`.
We need to install several python packages.
```bash
pip install google-api-python-client google-auth-oauthlib google-auth-httplib2
```
See a [usage example and authorization instructions](/docs/integrations/chat_loaders/gmail).
@@ -286,22 +391,69 @@ See a [usage example and authorization instructions](/docs/integrations/chat_loa
from langchain.chat_loaders.gmail import GMailLoader
```
## Agents and Toolkits
### Gmail
## 3rd Party Integrations
See a [usage example and authorization instructions](/docs/integrations/toolkits/gmail).
### SerpAPI
>[SerpApi](https://serpapi.com/) provides a 3rd-party API to access Google search results.
See a [usage example and authorization instructions](/docs/integrations/tools/google_serper).
```python
from langchain.agents.agent_toolkits import GmailToolkit
toolkit = GmailToolkit()
from langchain.utilities import GoogleSerperAPIWrapper
```
### Google Drive
### YouTube
See a [usage example and authorization instructions](/docs/integrations/toolkits/google_drive).
>[YouTube Search](https://github.com/joetats/youtube_search) package searches `YouTube` videos avoiding using their heavily rate-limited API.
>
>It uses the form on the YouTube homepage and scrapes the resulting page.
We need to install a python package.
```bash
pip install youtube_search
```
See a [usage example](/docs/integrations/tools/youtube).
```python
from langchain_googledrive.utilities.google_drive import GoogleDriveAPIWrapper
from langchain_googledrive.tools.google_drive.tool import GoogleDriveSearchTool
from langchain.tools import YouTubeSearchTool
```
### YouTube audio
>[YouTube](https://www.youtube.com/) is an online video sharing and social media platform created by `Google`.
Use `YoutubeAudioLoader` to fetch / download the audio files.
Then, use `OpenAIWhisperParser` to transcribe them to text.
We need to install several python packages.
```bash
pip install yt_dlp pydub librosa
```
See a [usage example and authorization instructions](/docs/integrations/document_loaders/youtube_audio).
```python
from langchain.document_loaders.blob_loaders.youtube_audio import YoutubeAudioLoader
from langchain.document_loaders.parsers import OpenAIWhisperParser, OpenAIWhisperParserLocal
```
### YouTube transcripts
>[YouTube](https://www.youtube.com/) is an online video sharing and social media platform created by `Google`.
We need to install `youtube-transcript-api` python package.
```bash
pip install youtube-transcript-api
```
See a [usage example](/docs/integrations/document_loaders/youtube_transcript).
```python
from langchain.document_loaders import YoutubeLoader
```

View File

@@ -2,7 +2,7 @@
All functionality related to `Microsoft Azure` and other `Microsoft` products.
## LLM
## Chat Models
### Azure OpenAI
>[Microsoft Azure](https://en.wikipedia.org/wiki/Microsoft_Azure), often referred to as `Azure` is a cloud computing platform run by `Microsoft`, which offers access, management, and development of applications and services through global data centers. It provides a range of capabilities, including software as a service (SaaS), platform as a service (PaaS), and infrastructure as a service (IaaS). `Microsoft Azure` supports many programming languages, tools, and frameworks, including Microsoft-specific and third-party software and systems.
@@ -18,16 +18,15 @@ Set the environment variables to get access to the `Azure OpenAI` service.
```python
import os
os.environ["OPENAI_API_TYPE"] = "azure"
os.environ["OPENAI_API_BASE"] = "https://<your-endpoint.openai.azure.com/"
os.environ["OPENAI_API_KEY"] = "your AzureOpenAI key"
os.environ["OPENAI_API_VERSION"] = "2023-05-15"
os.environ["AZURE_OPENAI_ENDPOINT"] = "https://<your-endpoint.openai.azure.com/"
os.environ["AZURE_OPENAI_API_KEY"] = "your AzureOpenAI key"
```
See a [usage example](/docs/integrations/llms/azure_openai_example).
See a [usage example](/docs/integrations/chat/azure_chat_openai)
```python
from langchain.llms import AzureOpenAI
from langchain.chat_models import AzureChatOpenAI
```
## Text Embedding Models
@@ -36,16 +35,16 @@ from langchain.llms import AzureOpenAI
See a [usage example](/docs/integrations/text_embedding/azureopenai)
```python
from langchain.embeddings import OpenAIEmbeddings
from langchain.embeddings import AzureOpenAIEmbeddings
```
## Chat Models
## LLMs
### Azure OpenAI
See a [usage example](/docs/integrations/chat/azure_chat_openai)
See a [usage example](/docs/integrations/llms/azure_openai_example).
```python
from langchain.chat_models import AzureChatOpenAI
from langchain.llms import AzureOpenAI
```
## Document loaders

View File

@@ -0,0 +1,85 @@
# Astra DB
This page lists the integrations available with [Astra DB](https://docs.datastax.com/en/astra/home/astra.html) and [Apache Cassandra®](https://cassandra.apache.org/).
### Setup
Install the following Python package:
```bash
pip install "astrapy>=0.5.3"
```
## Astra DB
> DataStax [Astra DB](https://docs.datastax.com/en/astra/home/astra.html) is a serverless vector-capable database built on Cassandra and made conveniently available
> through an easy-to-use JSON API.
### Vector Store
```python
from langchain.vectorstores import AstraDB
vector_store = AstraDB(
embedding=my_embedding,
collection_name="my_store",
api_endpoint="...",
token="...",
)
```
Learn more in the [example notebook](/docs/integrations/vectorstores/astradb).
## Apache Cassandra and Astra DB through CQL
> [Cassandra](https://cassandra.apache.org/) is a NoSQL, row-oriented, highly scalable and highly available database.
> Starting with version 5.0, the database ships with [vector search capabilities](https://cassandra.apache.org/doc/trunk/cassandra/vector-search/overview.html).
> DataStax [Astra DB through CQL](https://docs.datastax.com/en/astra-serverless/docs/vector-search/quickstart.html) is a managed serverless database built on Cassandra, offering the same interface and strengths.
These databases use the CQL protocol (Cassandra Query Language).
Hence, a different set of connectors, outlined below, shall be used.
### Vector Store
```python
from langchain.vectorstores import Cassandra
vector_store = Cassandra(
embedding=my_embedding,
table_name="my_store",
)
```
Learn more in the [example notebook](/docs/integrations/vectorstores/astradb) (scroll down to the CQL-specific section).
### Memory
```python
from langchain.memory import CassandraChatMessageHistory
message_history = CassandraChatMessageHistory(session_id="my-session")
```
Learn more in the [example notebook](/docs/integrations/memory/cassandra_chat_message_history).
### LLM Cache
```python
from langchain.cache import CassandraCache
langchain.llm_cache = CassandraCache()
```
Learn more in the [example notebook](/docs/integrations/llms/llm_caching) (scroll to the Cassandra section).
### Semantic LLM Cache
```python
from langchain.cache import CassandraSemanticCache
cassSemanticCache = CassandraSemanticCache(
embedding=my_embedding,
table_name="my_store",
)
```
Learn more in the [example notebook](/docs/integrations/llms/llm_caching) (scroll to the appropriate section).

View File

@@ -1,35 +0,0 @@
# Cassandra
>[Apache Cassandra®](https://cassandra.apache.org/) is a free and open-source, distributed, wide-column
> store, NoSQL database management system designed to handle large amounts of data across many commodity servers,
> providing high availability with no single point of failure. Cassandra offers support for clusters spanning
> multiple datacenters, with asynchronous masterless replication allowing low latency operations for all clients.
> Cassandra was designed to implement a combination of _Amazon's Dynamo_ distributed storage and replication
> techniques combined with _Google's Bigtable_ data and storage engine model.
## Installation and Setup
```bash
pip install cassandra-driver
pip install cassio
```
## Vector Store
See a [usage example](/docs/integrations/vectorstores/cassandra).
```python
from langchain.vectorstores import Cassandra
```
## Memory
See a [usage example](/docs/integrations/memory/cassandra_chat_message_history).
```python
from langchain.memory import CassandraChatMessageHistory
```

View File

@@ -1,22 +1,47 @@
# Fireworks
This page covers how to use the Fireworks models within Langchain.
This page covers how to use [Fireworks](https://app.fireworks.ai/) models within
Langchain.
## Installation and Setup
## Installation and setup
- To use the Fireworks model, you need to have a Fireworks API key. To generate one, sign up at [app.fireworks.ai](https://app.fireworks.ai).
- Install the Fireworks client library.
```
pip install fireworks-ai
```
- Get a Fireworks API key by signing up at [app.fireworks.ai](https://app.fireworks.ai).
- Authenticate by setting the FIREWORKS_API_KEY environment variable.
## LLM
## Authentication
Fireworks integrates with Langchain through the LLM module, which allows for standardized usage of any models deployed on the Fireworks models.
There are two ways to authenticate using your Fireworks API key:
In this example, we'll work the llama-v2-13b-chat model.
1. Setting the `FIREWORKS_API_KEY` environment variable.
```python
os.environ["FIREWORKS_API_KEY"] = "<KEY>"
```
2. Setting `fireworks_api_key` field in the Fireworks LLM module.
```python
llm = Fireworks(fireworks_api_key="<KEY>")
```
## Using the Fireworks LLM module
Fireworks integrates with Langchain through the LLM module. In this example, we
will work the llama-v2-13b-chat model.
```python
from langchain.llms.fireworks import Fireworks
llm = Fireworks(model="fireworks-llama-v2-13b-chat", max_tokens=256, temperature=0.4)
llm = Fireworks(
fireworks_api_key="<KEY>",
model="accounts/fireworks/models/llama-v2-13b-chat",
max_tokens=256)
llm("Name 3 sports.")
```

View File

@@ -11,7 +11,7 @@ Get a [Minimax group id](https://api.minimax.chat/user-center/basic-information)
## LLM
There exists a Minimax LLM wrapper, which you can access with
See a [usage example](/docs/modules/model_io/models/llms/integrations/minimax).
See a [usage example](/docs/modules/model_io/llms/integrations/minimax).
```python
from langchain.llms import Minimax
@@ -19,7 +19,7 @@ from langchain.llms import Minimax
## Chat Models
See a [usage example](/docs/modules/model_io/models/chat/integrations/minimax)
See a [usage example](/docs/modules/model_io/chat/integrations/minimax)
```python
from langchain.chat_models import MiniMaxChat

View File

@@ -46,6 +46,6 @@ eng = sqlalchemy.create_engine(conn_str)
set_llm_cache(SQLAlchemyCache(engine=eng))
```
From here, see the [LLM Caching](/docs/modules/model_io/models/llms/how_to/llm_caching) documentation on how to use.
From here, see the [LLM Caching](/docs/modules/model_io/llms/how_to/llm_caching) documentation on how to use.

View File

@@ -1,28 +1,72 @@
# Zep
>[Zep](https://docs.getzep.com/) - A long-term memory store for LLM applications.
## [Fast, Scalable Building Blocks for LLM Apps](http://www.getzep.com)
Zep is an open source platform for productionizing LLM apps. Go from a prototype
built in LangChain or LlamaIndex, or a custom app, to production in minutes without
rewriting code.
>`Zep` stores, summarizes, embeds, indexes, and enriches conversational AI chat histories, and exposes them via simple, low-latency APIs.
>- Long-term memory persistence, with access to historical messages irrespective of your summarization strategy.
>- Auto-summarization of memory messages based on a configurable message window. A series of summaries are stored, providing flexibility for future summarization strategies.
>- Vector search over memories, with messages automatically embedded on creation.
>- Auto-token counting of memories and summaries, allowing finer-grained control over prompt assembly.
>- Python and JavaScript SDKs.
Key Features:
- **Fast!** Zep operates independently of the your chat loop, ensuring a snappy user experience.
- **Chat History Memory, Archival, and Enrichment**, populate your prompts with relevant chat history, sumamries, named entities, intent data, and more.
- **Vector Search over Chat History and Documents** Automatic embedding of documents, chat histories, and summaries. Use Zep's similarity or native MMR Re-ranked search to find the most relevant.
- **Manage Users and their Chat Sessions** Users and their Chat Sessions are first-class citizens in Zep, allowing you to manage user interactions with your bots or agents easily.
- **Records Retention and Privacy Compliance** Comply with corporate and regulatory mandates for records retention while ensuring compliance with privacy regulations such as CCPA and GDPR. Fulfill *Right To Be Forgotten* requests with a single API call
`Zep` [project](https://github.com/getzep/zep)
Zep project: [https://github.com/getzep/zep](https://github.com/getzep/zep)
Docs: [https://docs.getzep.com/](https://docs.getzep.com/)
## Installation and Setup
1. Install the Zep service. See the [Zep Quick Start Guide](https://docs.getzep.com/deployment/quickstart/).
2. Install the Zep Python SDK:
```bash
pip install zep_python
```
## Zep Memory
## Retriever
Zep's [Memory API](https://docs.getzep.com/sdk/chat_history/) persists your app's chat history and metadata to a Session, enriches the memory, automatically generates summaries, and enables vector similarity search over historical chat messages and summaries.
There are two approaches to populating your prompt with chat history:
1. Retrieve the most recent N messages (and potentionally a summary) from a Session and use them to construct your prompt.
2. Search over the Session's chat history for messages that are relevant and use them to construct your prompt.
Both of these approaches may be useful, with the first providing the LLM with context as to the most recent interactions with a human. The second approach enables you to look back further in the chat history and retrieve messages that are relevant to the current conversation in a token-efficient manner.
```python
from langchain.memory import ZepMemory
```
See a [RAG App Example here](/docs/docs/integrations/memory/zep_memory).
## Memory Retriever
Zep's Memory Retriever is a LangChain Retriever that enables you to retrieve messages from a Zep Session and use them to construct your prompt.
The Retriever supports searching over both individual messages and summaries of conversations. The latter is useful for providing rich, but succinct context to the LLM as to relevant past conversations.
Zep's Memory Retriever supports both similarity search and [Maximum Marginal Relevance (MMR) reranking](https://docs.getzep.com/sdk/search_query/). MMR search is useful for ensuring that the retrieved messages are diverse and not too similar to each other
See a [usage example](/docs/integrations/retrievers/zep_memorystore).
```python
from langchain.retrievers import ZepRetriever
```
## Zep VectorStore
Zep's [Document VectorStore API](https://docs.getzep.com/sdk/documents/) enables you to store and retrieve documents using vector similarity search. Zep doesn't require you to understand
distance functions, types of embeddings, or indexing best practices. You just pass in your chunked documents, and Zep handles the rest.
Zep supports both similarity search and [Maximum Marginal Relevance (MMR) reranking](https://docs.getzep.com/sdk/search_query/).
MMR search is useful for ensuring that the retrieved documents are diverse and not too similar to each other.
```python
from langchain.vectorstores.zep import ZepVectorStore
```
See a [usage example](/docs/integrations/vectorstores/zep).

File diff suppressed because one or more lines are too long

View File

@@ -66,25 +66,26 @@
"id": "fa339ca0-f478-440c-ba80-0e5f41a19ce1",
"metadata": {},
"source": [
"By default, all files with these mime-type can be converted to `Document`.\n",
"- text/text\n",
"- text/plain\n",
"- text/html\n",
"- text/csv\n",
"- text/markdown\n",
"- image/png\n",
"- image/jpeg\n",
"- application/epub+zip\n",
"- application/pdf\n",
"- application/rtf\n",
"- application/vnd.google-apps.document (GDoc)\n",
"- application/vnd.google-apps.presentation (GSlide)\n",
"- application/vnd.google-apps.spreadsheet (GSheet)\n",
"- application/vnd.google.colaboratory (Notebook colab)\n",
"- application/vnd.openxmlformats-officedocument.presentationml.presentation (PPTX)\n",
"- application/vnd.openxmlformats-officedocument.wordprocessingml.document (DOCX)\n",
"By default, all files with these MIME types can be converted to `Document`.\n",
"\n",
"It's possible to update or customize this. See the documentation of `GDriveRetriever`.\n",
"- `text/text`\n",
"- `text/plain`\n",
"- `text/html`\n",
"- `text/csv`\n",
"- `text/markdown`\n",
"- `image/png`\n",
"- `image/jpeg`\n",
"- `application/epub+zip`\n",
"- `application/pdf`\n",
"- `application/rtf`\n",
"- `application/vnd.google-apps.document` (GDoc)\n",
"- `application/vnd.google-apps.presentation` (GSlide)\n",
"- `application/vnd.google-apps.spreadsheet` (GSheet)\n",
"- `application/vnd.google.colaboratory` (Notebook colab)\n",
"- `application/vnd.openxmlformats-officedocument.presentationml.presentation` (PPTX)\n",
"- `application/vnd.openxmlformats-officedocument.wordprocessingml.document` (DOCX)\n",
"\n",
"It's possible to update or customize this. See the documentation of `GoogleDriveRetriever`.\n",
"\n",
"But, the corresponding packages must be installed."
]
@@ -121,16 +122,17 @@
"metadata": {},
"source": [
"You can customize the criteria to select the files. A set of predefined filter are proposed:\n",
"| template | description |\n",
"| -------------------------------------- | --------------------------------------------------------------------- |\n",
"| gdrive-all-in-folder | Return all compatible files from a `folder_id` |\n",
"| gdrive-query | Search `query` in all drives |\n",
"| gdrive-by-name | Search file with name `query`) |\n",
"| gdrive-query-in-folder | Search `query` in `folder_id` (and sub-folders in `_recursive=true`) |\n",
"| gdrive-mime-type | Search a specific `mime_type` |\n",
"| gdrive-mime-type-in-folder | Search a specific `mime_type` in `folder_id` |\n",
"| gdrive-query-with-mime-type | Search `query` with a specific `mime_type` |\n",
"| gdrive-query-with-mime-type-and-folder | Search `query` with a specific `mime_type` and in `folder_id` |"
"\n",
"| Template | Description |\n",
"| -------------------------------------- | --------------------------------------------------------------------- |\n",
"| `gdrive-all-in-folder` | Return all compatible files from a `folder_id` |\n",
"| `gdrive-query` | Search `query` in all drives |\n",
"| `gdrive-by-name` | Search file with name `query` |\n",
"| `gdrive-query-in-folder` | Search `query` in `folder_id` (and sub-folders in `_recursive=true`) |\n",
"| `gdrive-mime-type` | Search a specific `mime_type` |\n",
"| `gdrive-mime-type-in-folder` | Search a specific `mime_type` in `folder_id` |\n",
"| `gdrive-query-with-mime-type` | Search `query` with a specific `mime_type` |\n",
"| `gdrive-query-with-mime-type-and-folder` | Search `query` with a specific `mime_type` and in `folder_id` |"
]
},
{

View File

@@ -6,23 +6,20 @@
"metadata": {},
"source": [
"# Zep\n",
"## Retriever Example for [Zep](https://docs.getzep.com/) - Fast, scalable building blocks for LLM Apps\n",
"\n",
"### More on Zep:\n",
"## Retriever Example for [Zep](https://docs.getzep.com/)\n",
"\n",
"### Fast, Scalable Building Blocks for LLM Apps\n",
"Zep is an open source platform for productionizing LLM apps. Go from a prototype\n",
"built in LangChain or LlamaIndex, or a custom app, to production in minutes without\n",
"rewriting code.\n",
"\n",
"Key Features:\n",
"\n",
"- **Fast!** Zeps async extractors operate independently of the your chat loop, ensuring a snappy user experience.\n",
"- **Long-term memory persistence**, with access to historical messages irrespective of your summarization strategy.\n",
"- **Auto-summarization** of memory messages based on a configurable message window. A series of summaries are stored, providing flexibility for future summarization strategies.\n",
"- **Hybrid search** over memories and metadata, with messages automatically embedded on creation.\n",
"- **Entity Extractor** that automatically extracts named entities from messages and stores them in the message metadata.\n",
"- **Auto-token counting** of memories and summaries, allowing finer-grained control over prompt assembly.\n",
"- Python and JavaScript SDKs.\n",
"- **Fast!** Zep operates independently of the your chat loop, ensuring a snappy user experience.\n",
"- **Chat History Memory, Archival, and Enrichment**, populate your prompts with relevant chat history, sumamries, named entities, intent data, and more.\n",
"- **Vector Search over Chat History and Documents** Automatic embedding of documents, chat histories, and summaries. Use Zep's similarity or native MMR Re-ranked search to find the most relevant.\n",
"- **Manage Users and their Chat Sessions** Users and their Chat Sessions are first-class citizens in Zep, allowing you to manage user interactions with your bots or agents easily.\n",
"- **Records Retention and Privacy Compliance** Comply with corporate and regulatory mandates for records retention while ensuring compliance with privacy regulations such as CCPA and GDPR. Fulfill *Right To Be Forgotten* requests with a single API call\n",
"\n",
"Zep project: [https://github.com/getzep/zep](https://github.com/getzep/zep)\n",
"Docs: [https://docs.getzep.com/](https://docs.getzep.com/)\n"
@@ -40,7 +37,12 @@
"We'll demonstrate:\n",
"\n",
"1. Adding conversation history to the Zep memory store.\n",
"2. Vector search over the conversation history.\n",
"2. Vector search over the conversation history: \n",
" 1. With a similarity search over chat messages\n",
" 2. Using maximal marginal relevance re-ranking of a chat message search\n",
" 3. Filtering a search using metadata filters\n",
" 4. A similarity search over summaries of the chat messages\n",
" 5. Using maximal marginal relevance re-ranking of a summary search\n",
"\n"
]
},
@@ -106,16 +108,7 @@
},
"collapsed": false
},
"outputs": [
{
"name": "stderr",
"output_type": "stream",
"text": [
"/Users/danielchalef/dev/langchain/.venv/lib/python3.11/site-packages/zep_python/zep_client.py:86: Warning: You are using an incompatible Zep server version. Please upgrade to {MINIMUM_SERVER_VERSION} or later.\n",
" self._healthcheck(base_url)\n"
]
}
],
"outputs": [],
"source": [
"session_id = str(uuid4()) # This is a unique identifier for the user/session\n",
"\n",
@@ -193,6 +186,60 @@
" \" environmental disasters, poverty, and violence.\"\n",
" ),\n",
" },\n",
" {\"role\": \"human\", \"content\": \"What is the setting of the book?\"},\n",
" {\n",
" \"role\": \"ai\",\n",
" \"content\": (\n",
" \"The book is set in a dystopian future in the 2020s, where society has\"\n",
" \" collapsed due to climate change and economic crises.\"\n",
" ),\n",
" },\n",
" {\"role\": \"human\", \"content\": \"Who is the protagonist?\"},\n",
" {\n",
" \"role\": \"ai\",\n",
" \"content\": (\n",
" \"The protagonist of the book is Lauren Olamina, a young woman who possesses\"\n",
" \" 'hyperempathy', the ability to feel pain and other sensations she\"\n",
" \" witnesses.\"\n",
" ),\n",
" },\n",
" {\"role\": \"human\", \"content\": \"What is the main theme of the book?\"},\n",
" {\n",
" \"role\": \"ai\",\n",
" \"content\": (\n",
" \"The main theme of the book is survival in the face of drastic societal\"\n",
" \" change and collapse. It also explores themes of adaptability, community,\"\n",
" \" and the human capacity for change.\"\n",
" ),\n",
" },\n",
" {\"role\": \"human\", \"content\": \"What is the 'Parable of the Sower'?\"},\n",
" {\n",
" \"role\": \"ai\",\n",
" \"content\": (\n",
" \"The 'Parable of the Sower' is a biblical parable that Butler uses as a\"\n",
" \" metaphor in the book. In the parable, a sower scatters seeds, some of\"\n",
" \" which fall on fertile ground and grow, while others fall on rocky ground\"\n",
" \" or among thorns and fail to grow. The parable is used to illustrate the\"\n",
" \" importance of receptivity and preparedness in the face of change.\"\n",
" ),\n",
" },\n",
" {\"role\": \"human\", \"content\": \"What is Butler's writing style like?\"},\n",
" {\n",
" \"role\": \"ai\",\n",
" \"content\": (\n",
" \"Butler's writing style is known for its clarity, directness, and\"\n",
" \" psychological insight. Her narratives often involve complex, diverse\"\n",
" \" characters and explore themes of race, gender, and power.\"\n",
" ),\n",
" },\n",
" {\"role\": \"human\", \"content\": \"What other books has she written?\"},\n",
" {\n",
" \"role\": \"ai\",\n",
" \"content\": (\n",
" \"In addition to 'Parable of the Sower', Butler has written several other\"\n",
" \" notable works, including 'Kindred', 'Dawn', and 'Parable of the Talents'.\"\n",
" ),\n",
" },\n",
"]\n",
"\n",
"for msg in test_history:\n",
@@ -202,7 +249,9 @@
" else AIMessage(content=msg[\"content\"])\n",
" )\n",
"\n",
"time.sleep(2) # Wait for the messages to be embedded"
"time.sleep(\n",
" 10\n",
") # Wait for the messages to be embedded and summarized. Speed depends on OpenAI API latency and your rate limits."
]
},
{
@@ -231,11 +280,11 @@
{
"data": {
"text/plain": [
"[Document(page_content='Parable of the Sower is a science fiction novel by Octavia Butler, published in 1993. It follows the story of Lauren Olamina, a young woman living in a dystopian future where society has collapsed due to environmental disasters, poverty, and violence.', metadata={'score': 0.8897589445114136, 'uuid': 'f99ecec3-f778-4bfd-8bb7-c3c00ae919c0', 'created_at': '2023-10-17T22:53:08.664849Z', 'updated_at': '0001-01-01T00:00:00Z', 'role': 'ai', 'metadata': {'system': {'entities': [{'Label': 'GPE', 'Matches': [{'End': 20, 'Start': 15, 'Text': 'Sower'}], 'Name': 'Sower'}, {'Label': 'PERSON', 'Matches': [{'End': 65, 'Start': 51, 'Text': 'Octavia Butler'}], 'Name': 'Octavia Butler'}, {'Label': 'DATE', 'Matches': [{'End': 84, 'Start': 80, 'Text': '1993'}], 'Name': '1993'}, {'Label': 'PERSON', 'Matches': [{'End': 124, 'Start': 110, 'Text': 'Lauren Olamina'}], 'Name': 'Lauren Olamina'}]}}, 'token_count': 56}),\n",
" Document(page_content=\"Write a short synopsis of Butler's book, Parable of the Sower. What is it about?\", metadata={'score': 0.8856973648071289, 'uuid': 'f6aba470-f15f-4b22-84ef-1c0d315a31de', 'created_at': '2023-10-17T22:53:08.642659Z', 'updated_at': '0001-01-01T00:00:00Z', 'role': 'human', 'metadata': {'system': {'entities': [{'Label': 'ORG', 'Matches': [{'End': 32, 'Start': 26, 'Text': 'Butler'}], 'Name': 'Butler'}, {'Label': 'WORK_OF_ART', 'Matches': [{'End': 61, 'Start': 41, 'Text': 'Parable of the Sower'}], 'Name': 'Parable of the Sower'}]}}, 'token_count': 23}),\n",
" Document(page_content='Who was Octavia Butler?', metadata={'score': 0.7759557962417603, 'uuid': '26aab7b5-34b1-4aff-9be0-7834a7702be4', 'created_at': '2023-10-17T22:53:08.585297Z', 'updated_at': '0001-01-01T00:00:00Z', 'role': 'human', 'metadata': {'system': {'entities': [{'Label': 'PERSON', 'Matches': [{'End': 22, 'Start': 8, 'Text': 'Octavia Butler'}], 'Name': 'Octavia Butler'}], 'intent': 'The subject is asking for information about Octavia Butler, a specific person.'}}, 'token_count': 8}),\n",
" Document(page_content=\"Octavia Butler's contemporaries included Ursula K. Le Guin, Samuel R. Delany, and Joanna Russ.\", metadata={'score': 0.760245680809021, 'uuid': 'ee4aa8e9-9913-4e69-a2a5-77a85294d24e', 'created_at': '2023-10-17T22:53:08.611466Z', 'updated_at': '0001-01-01T00:00:00Z', 'role': 'ai', 'metadata': {'system': {'entities': [{'Label': 'PERSON', 'Matches': [{'End': 16, 'Start': 0, 'Text': \"Octavia Butler's\"}], 'Name': \"Octavia Butler's\"}, {'Label': 'ORG', 'Matches': [{'End': 58, 'Start': 41, 'Text': 'Ursula K. Le Guin'}], 'Name': 'Ursula K. Le Guin'}, {'Label': 'PERSON', 'Matches': [{'End': 76, 'Start': 60, 'Text': 'Samuel R. Delany'}], 'Name': 'Samuel R. Delany'}, {'Label': 'PERSON', 'Matches': [{'End': 93, 'Start': 82, 'Text': 'Joanna Russ'}], 'Name': 'Joanna Russ'}]}}, 'token_count': 27}),\n",
" Document(page_content='You might want to read Ursula K. Le Guin or Joanna Russ.', metadata={'score': 0.7596070170402527, 'uuid': '9fa630e6-0b17-4d77-80b0-ba99249850c0', 'created_at': '2023-10-17T22:53:08.630731Z', 'updated_at': '0001-01-01T00:00:00Z', 'role': 'ai', 'metadata': {'system': {'entities': [{'Label': 'ORG', 'Matches': [{'End': 40, 'Start': 23, 'Text': 'Ursula K. Le Guin'}], 'Name': 'Ursula K. Le Guin'}, {'Label': 'PERSON', 'Matches': [{'End': 55, 'Start': 44, 'Text': 'Joanna Russ'}], 'Name': 'Joanna Russ'}]}}, 'token_count': 18})]"
"[Document(page_content=\"What is the 'Parable of the Sower'?\", metadata={'score': 0.9250216484069824, 'uuid': '4cbfb1c0-6027-4678-af43-1e18acb224bb', 'created_at': '2023-11-01T00:32:40.224256Z', 'updated_at': '0001-01-01T00:00:00Z', 'role': 'human', 'metadata': {'system': {'entities': [{'Label': 'WORK_OF_ART', 'Matches': [{'End': 34, 'Start': 13, 'Text': \"Parable of the Sower'\"}], 'Name': \"Parable of the Sower'\"}]}}, 'token_count': 13}),\n",
" Document(page_content='Parable of the Sower is a science fiction novel by Octavia Butler, published in 1993. It follows the story of Lauren Olamina, a young woman living in a dystopian future where society has collapsed due to environmental disasters, poverty, and violence.', metadata={'score': 0.8897348046302795, 'uuid': '3dd9f5ed-9dc9-4427-9da6-aba1b8278a5c', 'created_at': '2023-11-01T00:32:40.192527Z', 'updated_at': '0001-01-01T00:00:00Z', 'role': 'ai', 'metadata': {'system': {'entities': [{'Label': 'GPE', 'Matches': [{'End': 20, 'Start': 15, 'Text': 'Sower'}], 'Name': 'Sower'}, {'Label': 'PERSON', 'Matches': [{'End': 65, 'Start': 51, 'Text': 'Octavia Butler'}], 'Name': 'Octavia Butler'}, {'Label': 'DATE', 'Matches': [{'End': 84, 'Start': 80, 'Text': '1993'}], 'Name': '1993'}, {'Label': 'PERSON', 'Matches': [{'End': 124, 'Start': 110, 'Text': 'Lauren Olamina'}], 'Name': 'Lauren Olamina'}], 'intent': 'Providing information'}}, 'token_count': 56}),\n",
" Document(page_content=\"Write a short synopsis of Butler's book, Parable of the Sower. What is it about?\", metadata={'score': 0.8856019973754883, 'uuid': '81761dcb-38f3-4686-a4f5-6cb1007eaf29', 'created_at': '2023-11-01T00:32:40.187543Z', 'updated_at': '0001-01-01T00:00:00Z', 'role': 'human', 'metadata': {'system': {'entities': [{'Label': 'ORG', 'Matches': [{'End': 32, 'Start': 26, 'Text': 'Butler'}], 'Name': 'Butler'}, {'Label': 'WORK_OF_ART', 'Matches': [{'End': 61, 'Start': 41, 'Text': 'Parable of the Sower'}], 'Name': 'Parable of the Sower'}], 'intent': \"The subject is asking for a brief summary of Butler's book, Parable of the Sower, and what it is about.\"}}, 'token_count': 23}),\n",
" Document(page_content=\"The 'Parable of the Sower' is a biblical parable that Butler uses as a metaphor in the book. In the parable, a sower scatters seeds, some of which fall on fertile ground and grow, while others fall on rocky ground or among thorns and fail to grow. The parable is used to illustrate the importance of receptivity and preparedness in the face of change.\", metadata={'score': 0.8781436681747437, 'uuid': '1a8c5f99-2fec-425d-bc37-176ab91e7080', 'created_at': '2023-11-01T00:32:40.22836Z', 'updated_at': '0001-01-01T00:00:00Z', 'role': 'ai', 'metadata': {'system': {'entities': [{'Label': 'WORK_OF_ART', 'Matches': [{'End': 26, 'Start': 5, 'Text': \"Parable of the Sower'\"}], 'Name': \"Parable of the Sower'\"}, {'Label': 'ORG', 'Matches': [{'End': 60, 'Start': 54, 'Text': 'Butler'}], 'Name': 'Butler'}]}}, 'token_count': 84}),\n",
" Document(page_content=\"In addition to 'Parable of the Sower', Butler has written several other notable works, including 'Kindred', 'Dawn', and 'Parable of the Talents'.\", metadata={'score': 0.8745182752609253, 'uuid': '45d8aa08-85ab-432f-8902-81712fe363b9', 'created_at': '2023-11-01T00:32:40.245081Z', 'updated_at': '0001-01-01T00:00:00Z', 'role': 'ai', 'metadata': {'system': {'entities': [{'Label': 'WORK_OF_ART', 'Matches': [{'End': 37, 'Start': 16, 'Text': \"Parable of the Sower'\"}], 'Name': \"Parable of the Sower'\"}, {'Label': 'ORG', 'Matches': [{'End': 45, 'Start': 39, 'Text': 'Butler'}], 'Name': 'Butler'}, {'Label': 'GPE', 'Matches': [{'End': 105, 'Start': 98, 'Text': 'Kindred'}], 'Name': 'Kindred'}, {'Label': 'WORK_OF_ART', 'Matches': [{'End': 144, 'Start': 121, 'Text': \"Parable of the Talents'\"}], 'Name': \"Parable of the Talents'\"}]}}, 'token_count': 39})]"
]
},
"execution_count": 5,
@@ -245,7 +294,7 @@
],
"source": [
"from langchain.retrievers import ZepRetriever\n",
"from langchain.retrievers.zep import SearchType\n",
"from langchain.retrievers.zep import SearchType, SearchScope\n",
"\n",
"zep_retriever = ZepRetriever(\n",
" session_id=session_id, # Ensure that you provide the session_id when instantiating the Retriever\n",
@@ -279,11 +328,11 @@
{
"data": {
"text/plain": [
"[Document(page_content='Parable of the Sower is a science fiction novel by Octavia Butler, published in 1993. It follows the story of Lauren Olamina, a young woman living in a dystopian future where society has collapsed due to environmental disasters, poverty, and violence.', metadata={'score': 0.8897120952606201, 'uuid': 'f99ecec3-f778-4bfd-8bb7-c3c00ae919c0', 'created_at': '2023-10-17T22:53:08.664849Z', 'updated_at': '0001-01-01T00:00:00Z', 'role': 'ai', 'metadata': {'system': {'entities': [{'Label': 'GPE', 'Matches': [{'End': 20, 'Start': 15, 'Text': 'Sower'}], 'Name': 'Sower'}, {'Label': 'PERSON', 'Matches': [{'End': 65, 'Start': 51, 'Text': 'Octavia Butler'}], 'Name': 'Octavia Butler'}, {'Label': 'DATE', 'Matches': [{'End': 84, 'Start': 80, 'Text': '1993'}], 'Name': '1993'}, {'Label': 'PERSON', 'Matches': [{'End': 124, 'Start': 110, 'Text': 'Lauren Olamina'}], 'Name': 'Lauren Olamina'}]}}, 'token_count': 56}),\n",
" Document(page_content=\"Write a short synopsis of Butler's book, Parable of the Sower. What is it about?\", metadata={'score': 0.8857351541519165, 'uuid': 'f6aba470-f15f-4b22-84ef-1c0d315a31de', 'created_at': '2023-10-17T22:53:08.642659Z', 'updated_at': '0001-01-01T00:00:00Z', 'role': 'human', 'metadata': {'system': {'entities': [{'Label': 'ORG', 'Matches': [{'End': 32, 'Start': 26, 'Text': 'Butler'}], 'Name': 'Butler'}, {'Label': 'WORK_OF_ART', 'Matches': [{'End': 61, 'Start': 41, 'Text': 'Parable of the Sower'}], 'Name': 'Parable of the Sower'}]}}, 'token_count': 23}),\n",
" Document(page_content='Who was Octavia Butler?', metadata={'score': 0.7759560942649841, 'uuid': '26aab7b5-34b1-4aff-9be0-7834a7702be4', 'created_at': '2023-10-17T22:53:08.585297Z', 'updated_at': '0001-01-01T00:00:00Z', 'role': 'human', 'metadata': {'system': {'entities': [{'Label': 'PERSON', 'Matches': [{'End': 22, 'Start': 8, 'Text': 'Octavia Butler'}], 'Name': 'Octavia Butler'}], 'intent': 'The subject is asking for information about Octavia Butler, a specific person.'}}, 'token_count': 8}),\n",
" Document(page_content=\"Octavia Butler's contemporaries included Ursula K. Le Guin, Samuel R. Delany, and Joanna Russ.\", metadata={'score': 0.7602507472038269, 'uuid': 'ee4aa8e9-9913-4e69-a2a5-77a85294d24e', 'created_at': '2023-10-17T22:53:08.611466Z', 'updated_at': '0001-01-01T00:00:00Z', 'role': 'ai', 'metadata': {'system': {'entities': [{'Label': 'PERSON', 'Matches': [{'End': 16, 'Start': 0, 'Text': \"Octavia Butler's\"}], 'Name': \"Octavia Butler's\"}, {'Label': 'ORG', 'Matches': [{'End': 58, 'Start': 41, 'Text': 'Ursula K. Le Guin'}], 'Name': 'Ursula K. Le Guin'}, {'Label': 'PERSON', 'Matches': [{'End': 76, 'Start': 60, 'Text': 'Samuel R. Delany'}], 'Name': 'Samuel R. Delany'}, {'Label': 'PERSON', 'Matches': [{'End': 93, 'Start': 82, 'Text': 'Joanna Russ'}], 'Name': 'Joanna Russ'}], 'intent': \"The subject is stating a fact about Octavia Butler's contemporaries, including Ursula K. Le Guin, Samuel R. Delany, and Joanna Russ.\"}}, 'token_count': 27}),\n",
" Document(page_content='You might want to read Ursula K. Le Guin or Joanna Russ.', metadata={'score': 0.7595934867858887, 'uuid': '9fa630e6-0b17-4d77-80b0-ba99249850c0', 'created_at': '2023-10-17T22:53:08.630731Z', 'updated_at': '0001-01-01T00:00:00Z', 'role': 'ai', 'metadata': {'system': {'entities': [{'Label': 'ORG', 'Matches': [{'End': 40, 'Start': 23, 'Text': 'Ursula K. Le Guin'}], 'Name': 'Ursula K. Le Guin'}, {'Label': 'PERSON', 'Matches': [{'End': 55, 'Start': 44, 'Text': 'Joanna Russ'}], 'Name': 'Joanna Russ'}]}}, 'token_count': 18})]"
"[Document(page_content=\"What is the 'Parable of the Sower'?\", metadata={'score': 0.9250596761703491, 'uuid': '4cbfb1c0-6027-4678-af43-1e18acb224bb', 'created_at': '2023-11-01T00:32:40.224256Z', 'updated_at': '0001-01-01T00:00:00Z', 'role': 'human', 'metadata': {'system': {'entities': [{'Label': 'WORK_OF_ART', 'Matches': [{'End': 34, 'Start': 13, 'Text': \"Parable of the Sower'\"}], 'Name': \"Parable of the Sower'\"}]}}, 'token_count': 13}),\n",
" Document(page_content='Parable of the Sower is a science fiction novel by Octavia Butler, published in 1993. It follows the story of Lauren Olamina, a young woman living in a dystopian future where society has collapsed due to environmental disasters, poverty, and violence.', metadata={'score': 0.8897120952606201, 'uuid': '3dd9f5ed-9dc9-4427-9da6-aba1b8278a5c', 'created_at': '2023-11-01T00:32:40.192527Z', 'updated_at': '0001-01-01T00:00:00Z', 'role': 'ai', 'metadata': {'system': {'entities': [{'Label': 'GPE', 'Matches': [{'End': 20, 'Start': 15, 'Text': 'Sower'}], 'Name': 'Sower'}, {'Label': 'PERSON', 'Matches': [{'End': 65, 'Start': 51, 'Text': 'Octavia Butler'}], 'Name': 'Octavia Butler'}, {'Label': 'DATE', 'Matches': [{'End': 84, 'Start': 80, 'Text': '1993'}], 'Name': '1993'}, {'Label': 'PERSON', 'Matches': [{'End': 124, 'Start': 110, 'Text': 'Lauren Olamina'}], 'Name': 'Lauren Olamina'}], 'intent': 'Providing information'}}, 'token_count': 56}),\n",
" Document(page_content=\"Write a short synopsis of Butler's book, Parable of the Sower. What is it about?\", metadata={'score': 0.885666012763977, 'uuid': '81761dcb-38f3-4686-a4f5-6cb1007eaf29', 'created_at': '2023-11-01T00:32:40.187543Z', 'updated_at': '0001-01-01T00:00:00Z', 'role': 'human', 'metadata': {'system': {'entities': [{'Label': 'ORG', 'Matches': [{'End': 32, 'Start': 26, 'Text': 'Butler'}], 'Name': 'Butler'}, {'Label': 'WORK_OF_ART', 'Matches': [{'End': 61, 'Start': 41, 'Text': 'Parable of the Sower'}], 'Name': 'Parable of the Sower'}], 'intent': \"The subject is asking for a brief summary of Butler's book, Parable of the Sower, and what it is about.\"}}, 'token_count': 23}),\n",
" Document(page_content=\"The 'Parable of the Sower' is a biblical parable that Butler uses as a metaphor in the book. In the parable, a sower scatters seeds, some of which fall on fertile ground and grow, while others fall on rocky ground or among thorns and fail to grow. The parable is used to illustrate the importance of receptivity and preparedness in the face of change.\", metadata={'score': 0.878172755241394, 'uuid': '1a8c5f99-2fec-425d-bc37-176ab91e7080', 'created_at': '2023-11-01T00:32:40.22836Z', 'updated_at': '0001-01-01T00:00:00Z', 'role': 'ai', 'metadata': {'system': {'entities': [{'Label': 'WORK_OF_ART', 'Matches': [{'End': 26, 'Start': 5, 'Text': \"Parable of the Sower'\"}], 'Name': \"Parable of the Sower'\"}, {'Label': 'ORG', 'Matches': [{'End': 60, 'Start': 54, 'Text': 'Butler'}], 'Name': 'Butler'}]}}, 'token_count': 84}),\n",
" Document(page_content=\"In addition to 'Parable of the Sower', Butler has written several other notable works, including 'Kindred', 'Dawn', and 'Parable of the Talents'.\", metadata={'score': 0.8745154142379761, 'uuid': '45d8aa08-85ab-432f-8902-81712fe363b9', 'created_at': '2023-11-01T00:32:40.245081Z', 'updated_at': '0001-01-01T00:00:00Z', 'role': 'ai', 'metadata': {'system': {'entities': [{'Label': 'WORK_OF_ART', 'Matches': [{'End': 37, 'Start': 16, 'Text': \"Parable of the Sower'\"}], 'Name': \"Parable of the Sower'\"}, {'Label': 'ORG', 'Matches': [{'End': 45, 'Start': 39, 'Text': 'Butler'}], 'Name': 'Butler'}, {'Label': 'GPE', 'Matches': [{'End': 105, 'Start': 98, 'Text': 'Kindred'}], 'Name': 'Kindred'}, {'Label': 'WORK_OF_ART', 'Matches': [{'End': 144, 'Start': 121, 'Text': \"Parable of the Talents'\"}], 'Name': \"Parable of the Talents'\"}]}}, 'token_count': 39})]"
]
},
"execution_count": 6,
@@ -316,22 +365,14 @@
"collapsed": false
},
"outputs": [
{
"name": "stderr",
"output_type": "stream",
"text": [
"/Users/danielchalef/dev/langchain/.venv/lib/python3.11/site-packages/zep_python/zep_client.py:86: Warning: You are using an incompatible Zep server version. Please upgrade to {MINIMUM_SERVER_VERSION} or later.\n",
" self._healthcheck(base_url)\n"
]
},
{
"data": {
"text/plain": [
"[Document(page_content='Parable of the Sower is a science fiction novel by Octavia Butler, published in 1993. It follows the story of Lauren Olamina, a young woman living in a dystopian future where society has collapsed due to environmental disasters, poverty, and violence.', metadata={'score': 0.8897120952606201, 'uuid': 'f99ecec3-f778-4bfd-8bb7-c3c00ae919c0', 'created_at': '2023-10-17T22:53:08.664849Z', 'updated_at': '0001-01-01T00:00:00Z', 'role': 'ai', 'metadata': {'system': {'entities': [{'Label': 'GPE', 'Matches': [{'End': 20, 'Start': 15, 'Text': 'Sower'}], 'Name': 'Sower'}, {'Label': 'PERSON', 'Matches': [{'End': 65, 'Start': 51, 'Text': 'Octavia Butler'}], 'Name': 'Octavia Butler'}, {'Label': 'DATE', 'Matches': [{'End': 84, 'Start': 80, 'Text': '1993'}], 'Name': '1993'}, {'Label': 'PERSON', 'Matches': [{'End': 124, 'Start': 110, 'Text': 'Lauren Olamina'}], 'Name': 'Lauren Olamina'}]}}, 'token_count': 56}),\n",
" Document(page_content='Which books of hers were made into movies?', metadata={'score': 0.7496200799942017, 'uuid': '1047ff15-96f1-4101-bb0f-9ed073b8081d', 'created_at': '2023-10-17T22:53:08.596614Z', 'updated_at': '0001-01-01T00:00:00Z', 'role': 'human', 'metadata': {'system': {'intent': 'The subject is inquiring about the books of the person referred to as \"hers\" that have been made into movies.'}}, 'token_count': 11}),\n",
" Document(page_content=\"Write a short synopsis of Butler's book, Parable of the Sower. What is it about?\", metadata={'score': 0.8857351541519165, 'uuid': 'f6aba470-f15f-4b22-84ef-1c0d315a31de', 'created_at': '2023-10-17T22:53:08.642659Z', 'updated_at': '0001-01-01T00:00:00Z', 'role': 'human', 'metadata': {'system': {'entities': [{'Label': 'ORG', 'Matches': [{'End': 32, 'Start': 26, 'Text': 'Butler'}], 'Name': 'Butler'}, {'Label': 'WORK_OF_ART', 'Matches': [{'End': 61, 'Start': 41, 'Text': 'Parable of the Sower'}], 'Name': 'Parable of the Sower'}]}}, 'token_count': 23}),\n",
" Document(page_content='You might want to read Ursula K. Le Guin or Joanna Russ.', metadata={'score': 0.7595934867858887, 'uuid': '9fa630e6-0b17-4d77-80b0-ba99249850c0', 'created_at': '2023-10-17T22:53:08.630731Z', 'updated_at': '0001-01-01T00:00:00Z', 'role': 'ai', 'metadata': {'system': {'entities': [{'Label': 'ORG', 'Matches': [{'End': 40, 'Start': 23, 'Text': 'Ursula K. Le Guin'}], 'Name': 'Ursula K. Le Guin'}, {'Label': 'PERSON', 'Matches': [{'End': 55, 'Start': 44, 'Text': 'Joanna Russ'}], 'Name': 'Joanna Russ'}]}}, 'token_count': 18}),\n",
" Document(page_content='Who were her contemporaries?', metadata={'score': 0.7575579881668091, 'uuid': 'b2dfd1f7-cac6-4e37-94ea-7c15b0a5af2c', 'created_at': '2023-10-17T22:53:08.606283Z', 'updated_at': '0001-01-01T00:00:00Z', 'role': 'human', 'metadata': {'system': {'intent': 'The subject is asking about the people who were contemporaries of someone else.'}}, 'token_count': 8})]"
"[Document(page_content=\"What is the 'Parable of the Sower'?\", metadata={'score': 0.9250596761703491, 'uuid': '4cbfb1c0-6027-4678-af43-1e18acb224bb', 'created_at': '2023-11-01T00:32:40.224256Z', 'updated_at': '0001-01-01T00:00:00Z', 'role': 'human', 'metadata': {'system': {'entities': [{'Label': 'WORK_OF_ART', 'Matches': [{'End': 34, 'Start': 13, 'Text': \"Parable of the Sower'\"}], 'Name': \"Parable of the Sower'\"}]}}, 'token_count': 13}),\n",
" Document(page_content='What other books has she written?', metadata={'score': 0.77488774061203, 'uuid': '1b3c5079-9cab-46f3-beae-fb56c572e0fd', 'created_at': '2023-11-01T00:32:40.240135Z', 'updated_at': '0001-01-01T00:00:00Z', 'role': 'human', 'token_count': 9}),\n",
" Document(page_content=\"In addition to 'Parable of the Sower', Butler has written several other notable works, including 'Kindred', 'Dawn', and 'Parable of the Talents'.\", metadata={'score': 0.8745154142379761, 'uuid': '45d8aa08-85ab-432f-8902-81712fe363b9', 'created_at': '2023-11-01T00:32:40.245081Z', 'updated_at': '0001-01-01T00:00:00Z', 'role': 'ai', 'metadata': {'system': {'entities': [{'Label': 'WORK_OF_ART', 'Matches': [{'End': 37, 'Start': 16, 'Text': \"Parable of the Sower'\"}], 'Name': \"Parable of the Sower'\"}, {'Label': 'ORG', 'Matches': [{'End': 45, 'Start': 39, 'Text': 'Butler'}], 'Name': 'Butler'}, {'Label': 'GPE', 'Matches': [{'End': 105, 'Start': 98, 'Text': 'Kindred'}], 'Name': 'Kindred'}, {'Label': 'WORK_OF_ART', 'Matches': [{'End': 144, 'Start': 121, 'Text': \"Parable of the Talents'\"}], 'Name': \"Parable of the Talents'\"}]}}, 'token_count': 39}),\n",
" Document(page_content='Parable of the Sower is a science fiction novel by Octavia Butler, published in 1993. It follows the story of Lauren Olamina, a young woman living in a dystopian future where society has collapsed due to environmental disasters, poverty, and violence.', metadata={'score': 0.8897120952606201, 'uuid': '3dd9f5ed-9dc9-4427-9da6-aba1b8278a5c', 'created_at': '2023-11-01T00:32:40.192527Z', 'updated_at': '0001-01-01T00:00:00Z', 'role': 'ai', 'metadata': {'system': {'entities': [{'Label': 'GPE', 'Matches': [{'End': 20, 'Start': 15, 'Text': 'Sower'}], 'Name': 'Sower'}, {'Label': 'PERSON', 'Matches': [{'End': 65, 'Start': 51, 'Text': 'Octavia Butler'}], 'Name': 'Octavia Butler'}, {'Label': 'DATE', 'Matches': [{'End': 84, 'Start': 80, 'Text': '1993'}], 'Name': '1993'}, {'Label': 'PERSON', 'Matches': [{'End': 124, 'Start': 110, 'Text': 'Lauren Olamina'}], 'Name': 'Lauren Olamina'}], 'intent': 'Providing information'}}, 'token_count': 56}),\n",
" Document(page_content='Who is the protagonist?', metadata={'score': 0.7858647704124451, 'uuid': 'ee514b37-a0b0-4d24-b0c9-3e9f8ad9d52d', 'created_at': '2023-11-01T00:32:40.203891Z', 'updated_at': '0001-01-01T00:00:00Z', 'role': 'human', 'metadata': {'system': {'intent': 'The subject is asking about the identity of the protagonist in a specific context, such as a story, movie, or game.'}}, 'token_count': 7})]"
]
},
"execution_count": 7,
@@ -366,20 +407,20 @@
},
{
"cell_type": "code",
"execution_count": 9,
"execution_count": 8,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"[Document(page_content='Parable of the Sower is a science fiction novel by Octavia Butler, published in 1993. It follows the story of Lauren Olamina, a young woman living in a dystopian future where society has collapsed due to environmental disasters, poverty, and violence.', metadata={'score': 0.8897120952606201, 'uuid': 'f99ecec3-f778-4bfd-8bb7-c3c00ae919c0', 'created_at': '2023-10-17T22:53:08.664849Z', 'updated_at': '0001-01-01T00:00:00Z', 'role': 'ai', 'metadata': {'system': {'entities': [{'Label': 'GPE', 'Matches': [{'End': 20, 'Start': 15, 'Text': 'Sower'}], 'Name': 'Sower'}, {'Label': 'PERSON', 'Matches': [{'End': 65, 'Start': 51, 'Text': 'Octavia Butler'}], 'Name': 'Octavia Butler'}, {'Label': 'DATE', 'Matches': [{'End': 84, 'Start': 80, 'Text': '1993'}], 'Name': '1993'}, {'Label': 'PERSON', 'Matches': [{'End': 124, 'Start': 110, 'Text': 'Lauren Olamina'}], 'Name': 'Lauren Olamina'}], 'intent': 'None'}}, 'token_count': 56}),\n",
" Document(page_content='Which books of hers were made into movies?', metadata={'score': 0.7496200799942017, 'uuid': '1047ff15-96f1-4101-bb0f-9ed073b8081d', 'created_at': '2023-10-17T22:53:08.596614Z', 'updated_at': '0001-01-01T00:00:00Z', 'role': 'human', 'metadata': {'system': {'intent': 'The subject is inquiring about the books of the person referred to as \"hers\" that have been made into movies.'}}, 'token_count': 11}),\n",
" Document(page_content=\"Write a short synopsis of Butler's book, Parable of the Sower. What is it about?\", metadata={'score': 0.8857351541519165, 'uuid': 'f6aba470-f15f-4b22-84ef-1c0d315a31de', 'created_at': '2023-10-17T22:53:08.642659Z', 'updated_at': '0001-01-01T00:00:00Z', 'role': 'human', 'metadata': {'system': {'entities': [{'Label': 'ORG', 'Matches': [{'End': 32, 'Start': 26, 'Text': 'Butler'}], 'Name': 'Butler'}, {'Label': 'WORK_OF_ART', 'Matches': [{'End': 61, 'Start': 41, 'Text': 'Parable of the Sower'}], 'Name': 'Parable of the Sower'}], 'intent': 'The subject is requesting a brief summary or description of Butler\\'s book, \"Parable of the Sower.\"'}}, 'token_count': 23}),\n",
" Document(page_content='You might want to read Ursula K. Le Guin or Joanna Russ.', metadata={'score': 0.7595934867858887, 'uuid': '9fa630e6-0b17-4d77-80b0-ba99249850c0', 'created_at': '2023-10-17T22:53:08.630731Z', 'updated_at': '0001-01-01T00:00:00Z', 'role': 'ai', 'metadata': {'system': {'entities': [{'Label': 'ORG', 'Matches': [{'End': 40, 'Start': 23, 'Text': 'Ursula K. Le Guin'}], 'Name': 'Ursula K. Le Guin'}, {'Label': 'PERSON', 'Matches': [{'End': 55, 'Start': 44, 'Text': 'Joanna Russ'}], 'Name': 'Joanna Russ'}], 'intent': 'The subject is providing a suggestion or recommendation for the person to read Ursula K. Le Guin or Joanna Russ.'}}, 'token_count': 18}),\n",
" Document(page_content='Who were her contemporaries?', metadata={'score': 0.7575579881668091, 'uuid': 'b2dfd1f7-cac6-4e37-94ea-7c15b0a5af2c', 'created_at': '2023-10-17T22:53:08.606283Z', 'updated_at': '0001-01-01T00:00:00Z', 'role': 'human', 'metadata': {'system': {'intent': 'The subject is asking about the people who were contemporaries of someone else.'}}, 'token_count': 8})]"
"[Document(page_content=\"What is the 'Parable of the Sower'?\", metadata={'score': 0.9251098036766052, 'uuid': '4cbfb1c0-6027-4678-af43-1e18acb224bb', 'created_at': '2023-11-01T00:32:40.224256Z', 'updated_at': '0001-01-01T00:00:00Z', 'role': 'human', 'metadata': {'system': {'entities': [{'Label': 'WORK_OF_ART', 'Matches': [{'End': 34, 'Start': 13, 'Text': \"Parable of the Sower'\"}], 'Name': \"Parable of the Sower'\"}]}}, 'token_count': 13}),\n",
" Document(page_content='What other books has she written?', metadata={'score': 0.7747920155525208, 'uuid': '1b3c5079-9cab-46f3-beae-fb56c572e0fd', 'created_at': '2023-11-01T00:32:40.240135Z', 'updated_at': '0001-01-01T00:00:00Z', 'role': 'human', 'token_count': 9}),\n",
" Document(page_content=\"In addition to 'Parable of the Sower', Butler has written several other notable works, including 'Kindred', 'Dawn', and 'Parable of the Talents'.\", metadata={'score': 0.8745266795158386, 'uuid': '45d8aa08-85ab-432f-8902-81712fe363b9', 'created_at': '2023-11-01T00:32:40.245081Z', 'updated_at': '0001-01-01T00:00:00Z', 'role': 'ai', 'metadata': {'system': {'entities': [{'Label': 'WORK_OF_ART', 'Matches': [{'End': 37, 'Start': 16, 'Text': \"Parable of the Sower'\"}], 'Name': \"Parable of the Sower'\"}, {'Label': 'ORG', 'Matches': [{'End': 45, 'Start': 39, 'Text': 'Butler'}], 'Name': 'Butler'}, {'Label': 'GPE', 'Matches': [{'End': 105, 'Start': 98, 'Text': 'Kindred'}], 'Name': 'Kindred'}, {'Label': 'WORK_OF_ART', 'Matches': [{'End': 144, 'Start': 121, 'Text': \"Parable of the Talents'\"}], 'Name': \"Parable of the Talents'\"}]}}, 'token_count': 39}),\n",
" Document(page_content='Parable of the Sower is a science fiction novel by Octavia Butler, published in 1993. It follows the story of Lauren Olamina, a young woman living in a dystopian future where society has collapsed due to environmental disasters, poverty, and violence.', metadata={'score': 0.8897372484207153, 'uuid': '3dd9f5ed-9dc9-4427-9da6-aba1b8278a5c', 'created_at': '2023-11-01T00:32:40.192527Z', 'updated_at': '0001-01-01T00:00:00Z', 'role': 'ai', 'metadata': {'system': {'entities': [{'Label': 'GPE', 'Matches': [{'End': 20, 'Start': 15, 'Text': 'Sower'}], 'Name': 'Sower'}, {'Label': 'PERSON', 'Matches': [{'End': 65, 'Start': 51, 'Text': 'Octavia Butler'}], 'Name': 'Octavia Butler'}, {'Label': 'DATE', 'Matches': [{'End': 84, 'Start': 80, 'Text': '1993'}], 'Name': '1993'}, {'Label': 'PERSON', 'Matches': [{'End': 124, 'Start': 110, 'Text': 'Lauren Olamina'}], 'Name': 'Lauren Olamina'}], 'intent': 'Providing information'}}, 'token_count': 56}),\n",
" Document(page_content='Who is the protagonist?', metadata={'score': 0.7858127355575562, 'uuid': 'ee514b37-a0b0-4d24-b0c9-3e9f8ad9d52d', 'created_at': '2023-11-01T00:32:40.203891Z', 'updated_at': '0001-01-01T00:00:00Z', 'role': 'human', 'metadata': {'system': {'intent': 'The subject is asking about the identity of the protagonist in a specific context, such as a story, movie, or game.'}}, 'token_count': 7})]"
]
},
"execution_count": 9,
"execution_count": 8,
"metadata": {},
"output_type": "execute_result"
}
@@ -392,6 +433,50 @@
")"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Searching over Summaries with MMR Reranking\n",
"\n",
"Zep automatically generates summaries of chat messages. These summaries can be searched over using the Zep Retriever. Since a summary is a distillation of a conversation, they're more likely to match your search query and offer rich, succinct context to the LLM.\n",
"\n",
"Successive summaries may include similar content, with Zep's similarity search returning the highest matching results but with little diversity.\n",
"MMR re-ranks the results to ensure that the summaries you populate into your prompt are both relevant and each offers additional information to the LLM."
]
},
{
"cell_type": "code",
"execution_count": 9,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"[Document(page_content='The human asks about Octavia Butler and the AI informs them that she was an American science fiction author. The human\\nasks which of her books were made into movies and the AI mentions the FX series Kindred. The human then asks about her\\ncontemporaries and the AI lists Ursula K. Le Guin, Samuel R. Delany, and Joanna Russ. The human also asks about the awards\\nshe won and the AI mentions the Hugo Award, the Nebula Award, and the MacArthur Fellowship. The human asks about other women sci-fi writers to read and the AI suggests Ursula K. Le Guin and Joanna Russ. The human then asks for a synopsis of Butler\\'s book \"Parable of the Sower\" and the AI describes it.', metadata={'score': 0.7882999777793884, 'uuid': '3c95a29a-52dc-4112-b8a7-e6b1dc414d45', 'created_at': '2023-11-01T00:32:47.76449Z', 'token_count': 155}),\n",
" Document(page_content='The human asks about Octavia Butler. The AI informs the human that Octavia Estelle Butler was an American science \\nfiction author. The human then asks which books of hers were made into movies and the AI mentions the FX series Kindred, \\nbased on her novel of the same name.', metadata={'score': 0.7407922744750977, 'uuid': '0e027f4d-d71f-42ae-977f-696b8948b8bf', 'created_at': '2023-11-01T00:32:41.637098Z', 'token_count': 59}),\n",
" Document(page_content='The human asks about Octavia Butler and the AI informs them that she was an American science fiction author. The human\\nasks which of her books were made into movies and the AI mentions the FX series Kindred. The human then asks about her\\ncontemporaries and the AI lists Ursula K. Le Guin, Samuel R. Delany, and Joanna Russ. The human also asks about the awards\\nshe won and the AI mentions the Hugo Award, the Nebula Award, and the MacArthur Fellowship.', metadata={'score': 0.7436535358428955, 'uuid': 'b3500d1b-1a78-4aef-9e24-6b196cfa83cb', 'created_at': '2023-11-01T00:32:44.24744Z', 'token_count': 104})]"
]
},
"execution_count": 9,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"zep_retriever = ZepRetriever(\n",
" session_id=session_id, # Ensure that you provide the session_id when instantiating the Retriever\n",
" url=ZEP_API_URL,\n",
" top_k=3,\n",
" api_key=zep_api_key,\n",
" search_scope=SearchScope.summary,\n",
" search_type=SearchType.mmr,\n",
" mmr_lambda=0.5,\n",
")\n",
"\n",
"await zep_retriever.aget_relevant_documents(\"Who wrote Parable of the Sower?\")"
]
},
{
"cell_type": "code",
"execution_count": null,
@@ -416,7 +501,7 @@
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.11.5"
"version": "3.11.6"
}
},
"nbformat": 4,

View File

@@ -5,9 +5,100 @@
"id": "c3852491",
"metadata": {},
"source": [
"# AzureOpenAI\n",
"# Azure OpenAI\n",
"\n",
"Let's load the OpenAI Embedding class with environment variables set to indicate to use Azure endpoints."
"Let's load the Azure OpenAI Embedding class with environment variables set to indicate to use Azure endpoints."
]
},
{
"cell_type": "code",
"execution_count": 1,
"id": "8a6ed30d-806f-4800-b5fd-d04126be9060",
"metadata": {},
"outputs": [],
"source": [
"import os\n",
"\n",
"os.environ[\"AZURE_OPENAI_API_KEY\"] = \"...\"\n",
"os.environ[\"AZURE_OPENAI_ENDPOINT\"] = \"https://<your-endpoint>.openai.azure.com/\""
]
},
{
"cell_type": "code",
"execution_count": 2,
"id": "20179bc7-3f71-4909-be12-d38bce009b18",
"metadata": {},
"outputs": [],
"source": [
"from langchain.embeddings import AzureOpenAIEmbeddings\n",
"\n",
"embeddings = AzureOpenAIEmbeddings(\n",
" azure_deployment=\"<your-embeddings-deployment-name>\",\n",
" openai_api_version=\"2023-05-15\",\n",
")"
]
},
{
"cell_type": "code",
"execution_count": 3,
"id": "f8cb9dca-738b-450f-9986-5c3efd3c6eb3",
"metadata": {},
"outputs": [],
"source": [
"text = \"this is a test document\""
]
},
{
"cell_type": "code",
"execution_count": 4,
"id": "0fae0295-b117-4a5a-8b98-500c79306551",
"metadata": {},
"outputs": [],
"source": [
"query_result = embeddings.embed_query(text)"
]
},
{
"cell_type": "code",
"execution_count": 5,
"id": "65a01ddd-0bbf-444f-a87f-93af25ef902c",
"metadata": {},
"outputs": [],
"source": [
"doc_result = embeddings.embed_documents([text])"
]
},
{
"cell_type": "code",
"execution_count": 6,
"id": "45771052-68ca-4e03-9c4f-a0c7796d9442",
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"[-0.012222584727053133,\n",
" 0.0072103982392216145,\n",
" -0.014818063280923775,\n",
" -0.026444746872933557,\n",
" -0.0034330499700826883]"
]
},
"execution_count": 6,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"doc_result[0][:5]"
]
},
{
"cell_type": "markdown",
"id": "e66ec1f2-6768-4ee5-84bf-a2d76adc20c8",
"metadata": {},
"source": [
"## [Legacy] When using `openai<1`"
]
},
{
@@ -79,9 +170,9 @@
],
"metadata": {
"kernelspec": {
"display_name": "Python 3 (ipykernel)",
"display_name": "poetry-venv",
"language": "python",
"name": "python3"
"name": "poetry-venv"
},
"language_info": {
"codemirror_mode": {

View File

@@ -0,0 +1,154 @@
{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Qdrant FastEmbed\n",
"\n",
"[FastEmbed](https://qdrant.github.io/fastembed/) is a lightweight, fast, Python library built for embedding generation. \n",
"\n",
"- Quantized model weights\n",
"- ONNX Runtime, no PyTorch dependency\n",
"- CPU-first design\n",
"- Data-parallelism for encoding of large datasets."
]
},
{
"attachments": {},
"cell_type": "markdown",
"id": "2a773d8d",
"metadata": {},
"source": [
"## Dependencies\n",
"\n",
"To use FastEmbed with LangChain, install the `fastembed` Python package."
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "91ea14ce-831d-409a-a88f-30353acdabd1",
"metadata": {
"tags": []
},
"outputs": [],
"source": [
"%pip install fastembed"
]
},
{
"attachments": {},
"cell_type": "markdown",
"id": "426f1156",
"metadata": {},
"source": [
"## Imports"
]
},
{
"cell_type": "code",
"execution_count": 2,
"id": "3f5dc9d7-65e3-4b5b-9086-3327d016cfe0",
"metadata": {
"tags": []
},
"outputs": [],
"source": [
"from langchain.embeddings.fastembed import FastEmbedEmbeddings"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Instantiating FastEmbed\n",
" \n",
"### Parameters\n",
"- `model_name: str` (default: \"BAAI/bge-small-en-v1.5\")\n",
" > Name of the FastEmbedding model to use. You can find the list of supported models [here](https://qdrant.github.io/fastembed/examples/Supported_Models/).\n",
"\n",
"- `max_length: int` (default: 512)\n",
" > The maximum number of tokens. Unknown behavior for values > 512.\n",
"\n",
"- `cache_dir: Optional[str]`\n",
" > The path to the cache directory. Defaults to `local_cache` in the parent directory.\n",
"\n",
"- `threads: Optional[int]`\n",
" > The number of threads a single onnxruntime session can use. Defaults to None.\n",
"\n",
"- `doc_embed_type: Literal[\"default\", \"passage\"]` (default: \"default\")\n",
" > \"default\": Uses FastEmbed's default embedding method.\n",
" \n",
" > \"passage\": Prefixes the text with \"passage\" before embedding."
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "6fb585dd",
"metadata": {
"tags": []
},
"outputs": [],
"source": [
"embeddings = FastEmbedEmbeddings()"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Usage\n",
"\n",
"### Generating document embeddings"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"document_embeddings = embeddings.embed_documents([\"This is a document\", \"This is some other document\"])"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Generating query embeddings"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"query_embeddings = embeddings.embed_query(\"This is a query\")"
]
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3 (ipykernel)",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.11.6"
}
},
"nbformat": 4,
"nbformat_minor": 5
}

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,228 @@
{
"cells": [
{
"cell_type": "markdown",
"id": "278b6c63",
"metadata": {},
"source": [
"# Voyage AI\n",
"\n",
"Let's load the Voyage Embedding class."
]
},
{
"cell_type": "code",
"execution_count": 1,
"id": "0be1af71",
"metadata": {},
"outputs": [],
"source": [
"from langchain.embeddings import VoyageEmbeddings"
]
},
{
"cell_type": "markdown",
"id": "137cfde9-b88c-409a-9394-a9e31a6bf30d",
"metadata": {},
"source": [
"Voyage AI utilizes API keys to monitor usage and manage permissions. To obtain your key, create an account on our [homepage](https://www.voyageai.com). Then, create a VoyageEmbeddings model with your API key."
]
},
{
"cell_type": "code",
"execution_count": 2,
"id": "2c66e5da",
"metadata": {},
"outputs": [],
"source": [
"embeddings = VoyageEmbeddings(voyage_api_key=\"[ Your Voyage API key ]\")"
]
},
{
"cell_type": "markdown",
"id": "459dffb3-9bff-41f2-8507-642de7431b2d",
"metadata": {},
"source": [
"Prepare the documents and use `embed_documents` to get their embeddings."
]
},
{
"cell_type": "code",
"execution_count": 3,
"id": "c85e948f-85fd-4d56-8d21-6e2f7e65cab8",
"metadata": {},
"outputs": [],
"source": [
"documents = [\n",
" \"Caching embeddings enables the storage or temporary caching of embeddings, eliminating the necessity to recompute them each time.\",\n",
" \"An LLMChain is a chain that composes basic LLM functionality. It consists of a PromptTemplate and a language model (either an LLM or chat model). It formats the prompt template using the input key values provided (and also memory key values, if available), passes the formatted string to LLM and returns the LLM output.\",\n",
" \"A Runnable represents a generic unit of work that can be invoked, batched, streamed, and/or transformed.\",\n",
"]"
]
},
{
"cell_type": "code",
"execution_count": 4,
"id": "5a77a12d-6ac6-4ab8-b103-80ff24487019",
"metadata": {},
"outputs": [],
"source": [
"documents_embds = embeddings.embed_documents(documents)"
]
},
{
"cell_type": "code",
"execution_count": 5,
"id": "2c89167c-816c-487e-8704-90908a4190bb",
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"[0.0562174916267395,\n",
" 0.018221192061901093,\n",
" 0.0025736060924828053,\n",
" -0.009720131754875183,\n",
" 0.04108370840549469]"
]
},
"execution_count": 5,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"documents_embds[0][:5]"
]
},
{
"cell_type": "markdown",
"id": "f8d796d1-4ced-44d3-81bf-282721edb6bb",
"metadata": {},
"source": [
"Similarly, use `embed_query` to embed the query."
]
},
{
"cell_type": "code",
"execution_count": 6,
"id": "bfb6142c",
"metadata": {},
"outputs": [],
"source": [
"query = \"What's an LLMChain?\""
]
},
{
"cell_type": "code",
"execution_count": 7,
"id": "91bc875d-829b-4c3d-8e6f-fc2dda30a3bd",
"metadata": {},
"outputs": [],
"source": [
"query_embd = embeddings.embed_query(query)"
]
},
{
"cell_type": "code",
"execution_count": 8,
"id": "a4b0d49e-0c73-44b6-aed5-5b426564e085",
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"[-0.0052348352037370205,\n",
" -0.040072452276945114,\n",
" 0.0033957737032324076,\n",
" 0.01763271726667881,\n",
" -0.019235141575336456]"
]
},
"execution_count": 8,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"query_embd[:5]"
]
},
{
"cell_type": "markdown",
"id": "b16ddbb2-61f0-49ec-92c3-a6f236d9517f",
"metadata": {},
"source": [
"## A minimalist retrieval system"
]
},
{
"cell_type": "markdown",
"id": "5464cb0a-6967-4f1e-ac7c-0aab80b2795a",
"metadata": {},
"source": [
"The main feature of the embeddings is that the cosine similarity between two embeddings captures the semantic relatedness of the corresponding original passages. This allows us to use the embeddings to do semantic retrieval / search."
]
},
{
"cell_type": "markdown",
"id": "a0bd3ad2-ca68-4e75-9172-76aea28ba46e",
"metadata": {},
"source": [
" We can find a few closest embeddings in the documents embeddings based on the cosine similarity, and retrieve the corresponding document using the `KNNRetriever` class from LangChain."
]
},
{
"cell_type": "code",
"execution_count": 9,
"id": "0a3fc579-85a9-4bd0-a944-4e32ac62e2d4",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"An LLMChain is a chain that composes basic LLM functionality. It consists of a PromptTemplate and a language model (either an LLM or chat model). It formats the prompt template using the input key values provided (and also memory key values, if available), passes the formatted string to LLM and returns the LLM output.\n"
]
}
],
"source": [
"from langchain.retrievers import KNNRetriever\n",
"\n",
"retriever = KNNRetriever.from_texts(documents, embeddings)\n",
"\n",
"# retrieve the most relevant documents\n",
"result = retriever.get_relevant_documents(query)\n",
"top1_retrieved_doc = result[0].page_content # return the top1 retrieved result\n",
"\n",
"print(top1_retrieved_doc)"
]
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3 (ipykernel)",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.9.18"
},
"vscode": {
"interpreter": {
"hash": "e971737741ff4ec9aff7dc6155a1060a59a8a6d52c757dbbe66bf8ee389494b1"
}
}
},
"nbformat": 4,
"nbformat_minor": 5
}

View File

@@ -34,7 +34,7 @@
"source": [
"## Using `ZERO_SHOT_REACT_DESCRIPTION`\n",
"\n",
"This shows how to initialize the agent using the `ZERO_SHOT_REACT_DESCRIPTION` agent type. Note that this is an alternative to the above."
"This shows how to initialize the agent using the `ZERO_SHOT_REACT_DESCRIPTION` agent type."
]
},
{

View File

@@ -14,7 +14,7 @@
"E2B Data Analysis sandbox allows you to:\n",
"- Run Python code\n",
"- Generate charts via matplotlib\n",
"- Install Python packages dynamically durint runtime\n",
"- Install Python packages dynamically during runtime\n",
"- Install system packages dynamically during runtime\n",
"- Run shell commands\n",
"- Upload and download files\n",

View File

@@ -0,0 +1,94 @@
{
"cells": [
{
"cell_type": "markdown",
"id": "a991a6f8-1897-4f49-a191-ae3bdaeda856",
"metadata": {},
"source": [
"# Google Cloud Text-to-Speech\n",
"\n",
"This notebook shows how to interact with the `Google Cloud Text-to-Speech API` to achieve speech synthesis capabilities."
]
},
{
"cell_type": "markdown",
"id": "9eeb311e-e1bd-4959-8536-4d267f302eb3",
"metadata": {},
"source": [
"First, you need to set up an Google Cloud project. You can follow the instructions [here](https://cloud.google.com/text-to-speech/docs/before-you-begin)."
]
},
{
"cell_type": "code",
"execution_count": 1,
"id": "0a309c0e-5310-4eaa-8af9-bcbc252e45da",
"metadata": {},
"outputs": [],
"source": [
"# !pip install google-cloud-text-to-speech"
]
},
{
"cell_type": "markdown",
"id": "434b2454-2bff-484d-822c-4026a9dc1383",
"metadata": {},
"source": [
"## Usage"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "2f57a647-9214-4562-a8cf-f263a15d1f40",
"metadata": {},
"outputs": [],
"source": [
"from langchain.tools import GoogleCloudTextToSpeechTool\n",
"\n",
"text_to_speak = \"Hello world!\"\n",
"\n",
"tts = GoogleCloudTextToSpeechTool()\n",
"tts.name"
]
},
{
"cell_type": "markdown",
"id": "d4613fed-66f0-47c6-be50-7e7670654427",
"metadata": {},
"source": [
"We can generate audio, save it to the temporary file and then play it."
]
},
{
"cell_type": "code",
"execution_count": 7,
"id": "f1984844-aa75-4f83-9d42-1c8052d87cc0",
"metadata": {},
"outputs": [],
"source": [
"speech_file = tts.run(text_to_speak)"
]
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3 (ipykernel)",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.11.0"
}
},
"nbformat": 4,
"nbformat_minor": 5
}

View File

@@ -0,0 +1,204 @@
{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Memorize\n",
"\n",
"Fine-tuning LLM itself to memorize information using unsupervised learning.\n",
"\n",
"This tool requires LLMs that support fine-tuning. Currently, only `langchain.llms import GradientLLM` is supported."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Imports"
]
},
{
"cell_type": "code",
"execution_count": 16,
"metadata": {},
"outputs": [],
"source": [
"import os\n",
"from langchain.llms import GradientLLM\n",
"from langchain.chains import LLMChain\n",
"from langchain.agents import AgentExecutor, AgentType, initialize_agent, load_tools\n",
"from langchain.memory import ConversationBufferMemory"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Set the Environment API Key\n",
"Make sure to get your API key from Gradient AI. You are given $10 in free credits to test and fine-tune different models."
]
},
{
"cell_type": "code",
"execution_count": 17,
"metadata": {},
"outputs": [],
"source": [
"from getpass import getpass\n",
"\n",
"\n",
"if not os.environ.get(\"GRADIENT_ACCESS_TOKEN\", None):\n",
" # Access token under https://auth.gradient.ai/select-workspace\n",
" os.environ[\"GRADIENT_ACCESS_TOKEN\"] = getpass(\"gradient.ai access token:\")\n",
"if not os.environ.get(\"GRADIENT_WORKSPACE_ID\", None):\n",
" # `ID` listed in `$ gradient workspace list`\n",
" # also displayed after login at at https://auth.gradient.ai/select-workspace\n",
" os.environ[\"GRADIENT_WORKSPACE_ID\"] = getpass(\"gradient.ai workspace id:\")\n",
"if not os.environ.get(\"GRADIENT_MODEL_ADAPTER_ID\", None):\n",
" # `ID` listed in `$ gradient model list --workspace-id \"$GRADIENT_WORKSPACE_ID\"`\n",
" os.environ[\"GRADIENT_MODEL_ID\"] = getpass(\"gradient.ai model id:\")"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Optional: Validate your Environment variables ```GRADIENT_ACCESS_TOKEN``` and ```GRADIENT_WORKSPACE_ID``` to get currently deployed models."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Create the `GradientLLM` instance\n",
"You can specify different parameters such as the model name, max tokens generated, temperature, etc."
]
},
{
"cell_type": "code",
"execution_count": 18,
"metadata": {},
"outputs": [],
"source": [
"llm = GradientLLM(\n",
" model_id=os.environ[\"GRADIENT_MODEL_ID\"],\n",
" # # optional: set new credentials, they default to environment variables\n",
" # gradient_workspace_id=os.environ[\"GRADIENT_WORKSPACE_ID\"],\n",
" # gradient_access_token=os.environ[\"GRADIENT_ACCESS_TOKEN\"],\n",
")"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Load tools"
]
},
{
"cell_type": "code",
"execution_count": 19,
"metadata": {},
"outputs": [],
"source": [
"tools = load_tools([\"memorize\"], llm=llm)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Initiate the Agent"
]
},
{
"cell_type": "code",
"execution_count": 20,
"metadata": {},
"outputs": [],
"source": [
"agent = initialize_agent(\n",
" tools,\n",
" llm,\n",
" agent=AgentType.ZERO_SHOT_REACT_DESCRIPTION,\n",
" verbose=True,\n",
" # memory=ConversationBufferMemory(memory_key=\"chat_history\", return_messages=True),\n",
")"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Run the agent\n",
"Ask the agent to memorize a piece of text."
]
},
{
"cell_type": "code",
"execution_count": 21,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"\n",
"\n",
"\u001b[1m> Entering new AgentExecutor chain...\u001b[0m\n",
"\u001b[32;1m\u001b[1;3mI should memorize this fact.\n",
"Action: Memorize\n",
"Action Input: Zara T\u001b[0m\n",
"Observation: \u001b[36;1m\u001b[1;3mTrain complete. Loss: 1.6853971333333335\u001b[0m\n",
"Thought:\u001b[32;1m\u001b[1;3mI now know the final answer.\n",
"Final Answer: Zara Tubikova set a world\u001b[0m\n",
"\n",
"\u001b[1m> Finished chain.\u001b[0m\n"
]
},
{
"data": {
"text/plain": [
"'Zara Tubikova set a world'"
]
},
"execution_count": 21,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"agent.run(\n",
" \"Please remember the fact in detail:\\nWith astonishing dexterity, Zara Tubikova set a world record by solving a 4x4 Rubik's Cube variation blindfolded in under 20 seconds, employing only their feet.\"\n",
")"
]
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3 (ipykernel)",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.11.6"
},
"vscode": {
"interpreter": {
"hash": "a0a0263b650d907a3bfe41c0f8d6a63a071b884df3cfdc1579f00cdc1aed6b03"
}
}
},
"nbformat": 4,
"nbformat_minor": 4
}

View File

@@ -0,0 +1,758 @@
{
"cells": [
{
"cell_type": "markdown",
"id": "d2d6ca14-fb7e-4172-9aa0-a3119a064b96",
"metadata": {},
"source": [
"# Astra DB\n",
"\n",
"This page provides a quickstart for using [Astra DB](https://docs.datastax.com/en/astra/home/astra.html) and [Apache Cassandra®](https://cassandra.apache.org/) as a Vector Store.\n",
"\n",
"_Note: in addition to access to the database, an OpenAI API Key is required to run the full example._"
]
},
{
"cell_type": "markdown",
"id": "bb9be7ce-8c70-4d46-9f11-71c42a36e928",
"metadata": {},
"source": [
"### Setup and general dependencies"
]
},
{
"cell_type": "markdown",
"id": "dbe7c156-0413-47e3-9237-4769c4248869",
"metadata": {},
"source": [
"Use of the integration requires the following Python package."
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "8d00fcf4-9798-4289-9214-d9734690adfc",
"metadata": {},
"outputs": [],
"source": [
"!pip install --quiet \"astrapy>=0.5.3\""
]
},
{
"cell_type": "markdown",
"id": "2453d83a-bc8f-41e1-a692-befe4dd90156",
"metadata": {},
"source": [
"_Note: depending on your LangChain setup, you may need to install/upgrade other dependencies needed for this demo_\n",
"_(specifically, recent versions of `datasets` `openai` `pypdf` and `tiktoken` are required)._"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "b06619af-fea2-4863-8149-7f239a8c9c82",
"metadata": {},
"outputs": [],
"source": [
"import os\n",
"from getpass import getpass\n",
"\n",
"from datasets import (\n",
" load_dataset,\n",
") # if not present yet, run: pip install \"datasets==2.14.6\"\n",
"\n",
"from langchain.schema import Document\n",
"from langchain.embeddings import OpenAIEmbeddings\n",
"from langchain.document_loaders import PyPDFLoader\n",
"from langchain.text_splitter import RecursiveCharacterTextSplitter\n",
"from langchain.chat_models import ChatOpenAI\n",
"from langchain.prompts import ChatPromptTemplate\n",
"from langchain.schema.runnable import RunnablePassthrough\n",
"from langchain.schema.output_parser import StrOutputParser"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "1983f1da-0ae7-4a9b-bf4c-4ade328f7a3a",
"metadata": {},
"outputs": [],
"source": [
"os.environ[\"OPENAI_API_KEY\"] = getpass(\"OPENAI_API_KEY = \")"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "c656df06-e938-4bc5-b570-440b8b7a0189",
"metadata": {},
"outputs": [],
"source": [
"embe = OpenAIEmbeddings()"
]
},
{
"cell_type": "markdown",
"id": "dd8caa76-bc41-429e-a93b-989ba13aff01",
"metadata": {},
"source": [
"_Keep reading to connect with Astra DB. For usage with Apache Cassandra and Astra DB through CQL, scroll to the section below._"
]
},
{
"cell_type": "markdown",
"id": "22866f09-e10d-4f05-a24b-b9420129462e",
"metadata": {},
"source": [
"## Astra DB"
]
},
{
"cell_type": "markdown",
"id": "5fba47cc-3533-42fc-84b7-9dc14cd68b2b",
"metadata": {},
"source": [
"DataStax [Astra DB](https://docs.datastax.com/en/astra/home/astra.html) is a serverless vector-capable database built on Cassandra and made conveniently available through an easy-to-use JSON API."
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "0b32730d-176e-414c-9d91-fd3644c54211",
"metadata": {},
"outputs": [],
"source": [
"from langchain.vectorstores import AstraDB"
]
},
{
"cell_type": "markdown",
"id": "68f61b01-3e09-47c1-9d67-5d6915c86626",
"metadata": {},
"source": [
"### Astra DB connection parameters\n",
"\n",
"- the API Endpoint looks like `https://01234567-89ab-cdef-0123-456789abcdef-us-east1.apps.astra.datastax.com`\n",
"- the Token looks like `AstraCS:6gBhNmsk135....`"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "d78af8ed-cff9-4f14-aa5d-016f99ab547c",
"metadata": {},
"outputs": [],
"source": [
"ASTRA_DB_API_ENDPOINT = input(\"ASTRA_DB_API_ENDPOINT = \")\n",
"ASTRA_DB_TOKEN = getpass(\"ASTRA_DB_TOKEN = \")"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "8b77553b-8bb5-4949-b87b-8c6abac56a26",
"metadata": {},
"outputs": [],
"source": [
"vstore = AstraDB(\n",
" embedding=embe,\n",
" collection_name=\"astra_vector_demo\",\n",
" api_endpoint=ASTRA_DB_API_ENDPOINT,\n",
" token=ASTRA_DB_TOKEN,\n",
")"
]
},
{
"cell_type": "markdown",
"id": "9a348678-b2f6-46ca-9a0d-2eb4cc6b66b1",
"metadata": {},
"source": [
"### Load a dataset"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "3a1f532f-ad63-4256-9730-a183841bd8e9",
"metadata": {},
"outputs": [],
"source": [
"philo_dataset = load_dataset(\"datastax/philosopher-quotes\")[\"train\"]\n",
"\n",
"docs = []\n",
"for entry in philo_dataset:\n",
" metadata = {\"author\": entry[\"author\"]}\n",
" doc = Document(page_content=entry[\"quote\"], metadata=metadata)\n",
" docs.append(doc)\n",
"\n",
"inserted_ids = vstore.add_documents(docs)\n",
"print(f\"\\nInserted {len(inserted_ids)} documents.\")"
]
},
{
"cell_type": "markdown",
"id": "084d8802-ab39-4262-9a87-42eafb746f92",
"metadata": {},
"source": [
"Add some more entries, this time with `add_texts`:"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "b6b157f5-eb31-4907-a78e-2e2b06893936",
"metadata": {},
"outputs": [],
"source": [
"texts = [\"I think, therefore I am.\", \"To the things themselves!\"]\n",
"metadatas = [{\"author\": \"descartes\"}, {\"author\": \"husserl\"}]\n",
"ids = [\"desc_01\", \"huss_xy\"]\n",
"\n",
"inserted_ids_2 = vstore.add_texts(texts=texts, metadatas=metadatas, ids=ids)\n",
"print(f\"\\nInserted {len(inserted_ids_2)} documents.\")"
]
},
{
"cell_type": "markdown",
"id": "c031760a-1fc5-4855-adf2-02ed52fe2181",
"metadata": {},
"source": [
"### Run simple searches"
]
},
{
"cell_type": "markdown",
"id": "02a77d8e-1aae-4054-8805-01c77947c49f",
"metadata": {},
"source": [
"This section demonstrates metadata filtering and getting the similarity scores back:"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "1761806a-1afd-4491-867c-25a80d92b9fe",
"metadata": {},
"outputs": [],
"source": [
"results = vstore.similarity_search(\"Our life is what we make of it\", k=3)\n",
"for res in results:\n",
" print(f\"* {res.page_content} [{res.metadata}]\")"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "eebc4f7c-f61a-438e-b3c8-17e6888d8a0b",
"metadata": {},
"outputs": [],
"source": [
"results_filtered = vstore.similarity_search(\n",
" \"Our life is what we make of it\",\n",
" k=3,\n",
" filter={\"author\": \"plato\"},\n",
")\n",
"for res in results_filtered:\n",
" print(f\"* {res.page_content} [{res.metadata}]\")"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "11bbfe64-c0cd-40c6-866a-a5786538450e",
"metadata": {},
"outputs": [],
"source": [
"results = vstore.similarity_search_with_score(\"Our life is what we make of it\", k=3)\n",
"for res, score in results:\n",
" print(f\"* [SIM={score:3f}] {res.page_content} [{res.metadata}]\")"
]
},
{
"cell_type": "markdown",
"id": "b14ea558-bfbe-41ce-807e-d70670060ada",
"metadata": {},
"source": [
"### MMR (Maximal-marginal-relevance) search"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "76381ce8-780a-4e3b-97b1-056d6782d7d5",
"metadata": {},
"outputs": [],
"source": [
"results = vstore.max_marginal_relevance_search(\n",
" \"Our life is what we make of it\",\n",
" k=3,\n",
" filter={\"author\": \"aristotle\"},\n",
")\n",
"for res in results:\n",
" print(f\"* {res.page_content} [{res.metadata}]\")"
]
},
{
"cell_type": "markdown",
"id": "1cc86edd-692b-4495-906c-ccfd13b03c23",
"metadata": {},
"source": [
"### Deleting stored documents"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "38a70ec4-b522-4d32-9ead-c642864fca37",
"metadata": {},
"outputs": [],
"source": [
"delete_1 = vstore.delete(inserted_ids[:3])\n",
"print(f\"all_succeed={delete_1}\") # True, all documents deleted"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "d4cf49ed-9d29-4ed9-bdab-51a308c41b8e",
"metadata": {},
"outputs": [],
"source": [
"delete_2 = vstore.delete(inserted_ids[2:5])\n",
"print(f\"some_succeeds={delete_2}\") # True, though some IDs were gone already"
]
},
{
"cell_type": "markdown",
"id": "847181ba-77d1-4a17-b7f9-9e2c3d8efd13",
"metadata": {},
"source": [
"### A minimal RAG chain"
]
},
{
"cell_type": "markdown",
"id": "cd64b844-846f-43c5-a7dd-c26b9ed417d0",
"metadata": {},
"source": [
"The next cells will implement a simple RAG pipeline:\n",
"- download a sample PDF file and load it onto the store;\n",
"- create a RAG chain with LCEL (LangChain Expression Language), with the vector store at its heart;\n",
"- run the question-answering chain."
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "5cbc4dba-0d5e-4038-8fc5-de6cadd1c2a9",
"metadata": {},
"outputs": [],
"source": [
"!curl -L \\\n",
" \"https://github.com/awesome-astra/datasets/blob/main/demo-resources/what-is-philosophy/what-is-philosophy.pdf?raw=true\" \\\n",
" -o \"what-is-philosophy.pdf\""
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "459385be-5e9c-47ff-ba53-2b7ae6166b09",
"metadata": {},
"outputs": [],
"source": [
"pdf_loader = PyPDFLoader(\"what-is-philosophy.pdf\")\n",
"splitter = RecursiveCharacterTextSplitter(chunk_size=512, chunk_overlap=64)\n",
"docs_from_pdf = pdf_loader.load_and_split(text_splitter=splitter)\n",
"\n",
"print(f\"Documents from PDF: {len(docs_from_pdf)}.\")\n",
"inserted_ids_from_pdf = vstore.add_documents(docs_from_pdf)\n",
"print(f\"Inserted {len(inserted_ids_from_pdf)} documents.\")"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "5010a66c-4298-4e32-82b5-2da0d36a5c70",
"metadata": {},
"outputs": [],
"source": [
"retriever = vstore.as_retriever(search_kwargs={\"k\": 3})\n",
"\n",
"philo_template = \"\"\"\n",
"You are a philosopher that draws inspiration from great thinkers of the past\n",
"to craft well-thought answers to user questions. Use the provided context as the basis\n",
"for your answers and do not make up new reasoning paths - just mix-and-match what you are given.\n",
"Your answers must be concise and to the point, and refrain from answering about other topics than philosophy.\n",
"\n",
"CONTEXT:\n",
"{context}\n",
"\n",
"QUESTION: {question}\n",
"\n",
"YOUR ANSWER:\"\"\"\n",
"\n",
"philo_prompt = ChatPromptTemplate.from_template(philo_template)\n",
"\n",
"llm = ChatOpenAI()\n",
"\n",
"chain = (\n",
" {\"context\": retriever, \"question\": RunnablePassthrough()}\n",
" | philo_prompt\n",
" | llm\n",
" | StrOutputParser()\n",
")"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "fcbc1296-6c7c-478b-b55b-533ba4e54ddb",
"metadata": {},
"outputs": [],
"source": [
"chain.invoke(\"How does Russel elaborate on Peirce's idea of the security blanket?\")"
]
},
{
"cell_type": "markdown",
"id": "869ab448-a029-4692-aefc-26b85513314d",
"metadata": {},
"source": [
"For more, check out a complete RAG template using Astra DB [here](https://github.com/langchain-ai/langchain/tree/master/templates/rag-astradb)."
]
},
{
"cell_type": "markdown",
"id": "177610c7-50d0-4b7b-8634-b03338054c8e",
"metadata": {},
"source": [
"### Cleanup"
]
},
{
"cell_type": "markdown",
"id": "0da4d19f-9878-4d3d-82c9-09cafca20322",
"metadata": {},
"source": [
"If you want to completely delete the collection from your Astra DB instance, run this.\n",
"\n",
"_(You will lose the data you stored in it.)_"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "fd405a13-6f71-46fa-87e6-167238e9c25e",
"metadata": {},
"outputs": [],
"source": [
"vstore.delete_collection()"
]
},
{
"cell_type": "markdown",
"id": "94ebaab1-7cbf-4144-a147-7b0e32c43069",
"metadata": {},
"source": [
"## Apache Cassandra and Astra DB through CQL"
]
},
{
"cell_type": "markdown",
"id": "bc3931b4-211d-4f84-bcc0-51c127e3027c",
"metadata": {},
"source": [
"[Cassandra](https://cassandra.apache.org/) is a NoSQL, row-oriented, highly scalable and highly available database.Starting with version 5.0, the database ships with [vector search capabilities](https://cassandra.apache.org/doc/trunk/cassandra/vector-search/overview.html).\n",
"\n",
"DataStax [Astra DB through CQL](https://docs.datastax.com/en/astra-serverless/docs/vector-search/quickstart.html) is a managed serverless database built on Cassandra, offering the same interface and strengths."
]
},
{
"cell_type": "markdown",
"id": "a0055fbf-448d-4e46-9c40-28d43df25ca3",
"metadata": {},
"source": [
"#### What sets this case apart from \"Astra DB\" above?\n",
"\n",
"Thanks to LangChain having a standardized `VectorStore` interface, most of the \"Astra DB\" section above applies to this case as well. However, this time the database uses the CQL protocol, which means you'll use a _different_ class this time and instantiate it in another way.\n",
"\n",
"The cells below show how you should get your `vstore` object in this case and how you can clean up the database resources at the end: for the rest, i.e. the actual usage of the vector store, you will be able to run the very code that was shown above.\n",
"\n",
"In other words, running this demo in full with Cassandra or Astra DB through CQL means:\n",
"\n",
"- **initialization as shown below**\n",
"- \"Load a dataset\", _see above section_\n",
"- \"Run simple searches\", _see above section_\n",
"- \"MMR search\", _see above section_\n",
"- \"Deleting stored documents\", _see above section_\n",
"- \"A minimal RAG chain\", _see above section_\n",
"- **cleanup as shown below**"
]
},
{
"cell_type": "markdown",
"id": "23d12be2-745f-4e72-a82c-334a887bc7cd",
"metadata": {},
"source": [
"### Initialization"
]
},
{
"cell_type": "markdown",
"id": "e3212542-79be-423e-8e1f-b8d725e3cda8",
"metadata": {},
"source": [
"The class to use is the following:"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "941af73e-a090-4fba-b23c-595757d470eb",
"metadata": {},
"outputs": [],
"source": [
"from langchain.vectorstores import Cassandra"
]
},
{
"cell_type": "markdown",
"id": "414d1e72-f7c9-4b6d-bf6f-16075712c7e3",
"metadata": {},
"source": [
"Now, depending on whether you connect to a Cassandra cluster or to Astra DB through CQL, you will provide different parameters when creating the vector store object."
]
},
{
"cell_type": "markdown",
"id": "48ecca56-71a4-4a91-b198-29384c44ce27",
"metadata": {},
"source": [
"#### Initialization (Cassandra cluster)"
]
},
{
"cell_type": "markdown",
"id": "55ebe958-5654-43e0-9aed-d607ffd3fa48",
"metadata": {},
"source": [
"In this case, you first need to create a `cassandra.cluster.Session` object, as described in the [Cassandra driver documentation](https://docs.datastax.com/en/developer/python-driver/latest/api/cassandra/cluster/#module-cassandra.cluster). The details vary (e.g. with network settings and authentication), but this might be something like:"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "4642dafb-a065-4063-b58c-3d276f5ad07e",
"metadata": {},
"outputs": [],
"source": [
"from cassandra.cluster import Cluster\n",
"\n",
"cluster = Cluster([\"127.0.0.1\"])\n",
"session = cluster.connect()"
]
},
{
"cell_type": "markdown",
"id": "624c93bf-fb46-4350-bcfa-09ca09dc068f",
"metadata": {},
"source": [
"You can now set the session, along with your desired keyspace name, as a global CassIO parameter:"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "92a4ab28-1c4f-4dad-9671-d47e0b1dde7b",
"metadata": {},
"outputs": [],
"source": [
"import cassio\n",
"\n",
"CASSANDRA_KEYSPACE = input(\"CASSANDRA_KEYSPACE = \")\n",
"\n",
"cassio.init(session=session, keyspace=CASSANDRA_KEYSPACE)"
]
},
{
"cell_type": "markdown",
"id": "3b87a824-36f1-45b4-b54c-efec2a2de216",
"metadata": {},
"source": [
"Now you can create the vector store:"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "853a2a88-a565-4e24-8789-d78c213954a6",
"metadata": {},
"outputs": [],
"source": [
"vstore = Cassandra(\n",
" embedding=embe,\n",
" table_name=\"cassandra_vector_demo\",\n",
" # session=None, keyspace=None # Uncomment on older versions of LangChain\n",
")"
]
},
{
"cell_type": "markdown",
"id": "768ddf7a-0c3e-4134-ad38-25ac53c3da7a",
"metadata": {},
"source": [
"#### Initialization (Astra DB through CQL)"
]
},
{
"cell_type": "markdown",
"id": "4ed4269a-b7e7-4503-9e66-5a11335c7681",
"metadata": {},
"source": [
"In this case you initialize CassIO with the following connection parameters:\n",
"\n",
"- the Database ID, e.g. `01234567-89ab-cdef-0123-456789abcdef`\n",
"- the Token, e.g. `AstraCS:6gBhNmsk135....` (it must be a \"Database Administrator\" token)\n",
"- Optionally a Keyspace name (if omitted, the default one for the database will be used)"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "5fa6bd74-d4b2-45c5-9757-96dddc6242fb",
"metadata": {},
"outputs": [],
"source": [
"ASTRA_DB_ID = input(\"ASTRA_DB_ID = \")\n",
"ASTRA_DB_TOKEN = getpass(\"ASTRA_DB_TOKEN = \")\n",
"\n",
"desired_keyspace = input(\"ASTRA_DB_KEYSPACE (optional, can be left empty) = \")\n",
"if desired_keyspace:\n",
" ASTRA_DB_KEYSPACE = desired_keyspace\n",
"else:\n",
" ASTRA_DB_KEYSPACE = None"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "add6e585-17ff-452e-8ef6-7e485ead0b06",
"metadata": {},
"outputs": [],
"source": [
"import cassio\n",
"\n",
"cassio.init(\n",
" database_id=ASTRA_DB_ID,\n",
" token=ASTRA_DB_TOKEN,\n",
" keyspace=ASTRA_DB_KEYSPACE,\n",
")"
]
},
{
"cell_type": "markdown",
"id": "b305823c-bc98-4f3d-aabb-d7eb663ea421",
"metadata": {},
"source": [
"Now you can create the vector store:"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "f45f3038-9d59-41cc-8b43-774c6aa80295",
"metadata": {},
"outputs": [],
"source": [
"vstore = Cassandra(\n",
" embedding=embe,\n",
" table_name=\"cassandra_vector_demo\",\n",
" # session=None, keyspace=None # Uncomment on older versions of LangChain\n",
")"
]
},
{
"cell_type": "markdown",
"id": "39284918-cf8a-49bb-a2d3-aef285bb2ffa",
"metadata": {},
"source": [
"### Usage of the vector store"
]
},
{
"cell_type": "markdown",
"id": "3cc1aead-d6ec-48a3-affe-1d0cffa955a9",
"metadata": {},
"source": [
"_See the sections \"Load a dataset\" through \"A minimal RAG chain\" above._\n",
"\n",
"Speaking of the latter, you can check out a full RAG template for Astra DB through CQL [here](https://github.com/langchain-ai/langchain/tree/master/templates/cassandra-entomology-rag)."
]
},
{
"cell_type": "markdown",
"id": "096397d8-6622-4685-9f9d-7e238beca467",
"metadata": {},
"source": [
"### Cleanup"
]
},
{
"cell_type": "markdown",
"id": "cc1e74f9-5500-41aa-836f-235b1ed5f20c",
"metadata": {},
"source": [
"the following essentially retrieves the `Session` object from CassIO and runs a CQL `DROP TABLE` statement with it:"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "b5b82c33-0e77-4a37-852c-8d50edbdd991",
"metadata": {},
"outputs": [],
"source": [
"cassio.config.resolve_session().execute(\n",
" f\"DROP TABLE {cassio.config.resolve_keyspace()}.cassandra_vector_demo;\"\n",
")"
]
},
{
"cell_type": "markdown",
"id": "c10ece4d-ae06-42ab-baf4-4d0ac2051743",
"metadata": {},
"source": [
"### Learn more"
]
},
{
"cell_type": "markdown",
"id": "51ea8b69-7e15-458f-85aa-9fa199f95f9c",
"metadata": {},
"source": [
"For more information, extended quickstarts and additional usage examples, please visit the [CassIO documentation](https://cassio.org/frameworks/langchain/about/) for more on using the LangChain `Cassandra` vector store."
]
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3 (ipykernel)",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.10.12"
}
},
"nbformat": 4,
"nbformat_minor": 5
}

View File

@@ -0,0 +1,604 @@
{
"cells": [
{
"cell_type": "markdown",
"id": "683953b3",
"metadata": {},
"source": [
"# Faiss\n",
"\n",
">[Facebook AI Similarity Search (Faiss)](https://engineering.fb.com/2017/03/29/data-infrastructure/faiss-a-library-for-efficient-similarity-search/) is a library for efficient similarity search and clustering of dense vectors. It contains algorithms that search in sets of vectors of any size, up to ones that possibly do not fit in RAM. It also contains supporting code for evaluation and parameter tuning.\n",
"\n",
"[Faiss documentation](https://faiss.ai/).\n",
"\n",
"This notebook shows how to use functionality related to the `FAISS` vector database using asyncio.\n",
"\n",
"See synchronous version [here](https://python.langchain.com/docs/integrations/vectorstores/faiss)."
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "497fcd89-e832-46a7-a74a-c71199666206",
"metadata": {
"tags": []
},
"outputs": [],
"source": [
"!pip install faiss-gpu # For CUDA 7.5+ Supported GPU's.\n",
"# OR\n",
"!pip install faiss-cpu # For CPU Installation"
]
},
{
"cell_type": "markdown",
"id": "38237514-b3fa-44a4-9cff-30cd6bf50073",
"metadata": {},
"source": [
"We want to use OpenAIEmbeddings so we have to get the OpenAI API Key. "
]
},
{
"cell_type": "code",
"execution_count": 1,
"id": "47f9b495-88f1-4286-8d5d-1416103931a7",
"metadata": {
"tags": []
},
"outputs": [],
"source": [
"import os\n",
"import getpass\n",
"\n",
"os.environ[\"OPENAI_API_KEY\"] = getpass.getpass(\"OpenAI API Key:\")\n",
"\n",
"# Uncomment the following line if you need to initialize FAISS with no AVX2 optimization\n",
"# os.environ['FAISS_NO_AVX2'] = '1'"
]
},
{
"cell_type": "code",
"execution_count": 4,
"id": "aac9563e",
"metadata": {
"tags": []
},
"outputs": [],
"source": [
"from langchain.embeddings.openai import OpenAIEmbeddings\n",
"from langchain.text_splitter import CharacterTextSplitter\n",
"from langchain.vectorstores import FAISS\n",
"from langchain.document_loaders import TextLoader"
]
},
{
"cell_type": "code",
"execution_count": 5,
"id": "a3c3999a",
"metadata": {
"tags": []
},
"outputs": [],
"source": [
"from langchain.document_loaders import TextLoader\n",
"\n",
"loader = TextLoader(\"../../../extras/modules/state_of_the_union.txt\")\n",
"documents = loader.load()\n",
"text_splitter = CharacterTextSplitter(chunk_size=1000, chunk_overlap=0)\n",
"docs = text_splitter.split_documents(documents)\n",
"\n",
"embeddings = OpenAIEmbeddings()"
]
},
{
"cell_type": "code",
"execution_count": 6,
"id": "5eabdb75",
"metadata": {
"tags": []
},
"outputs": [],
"source": [
"db = await FAISS.afrom_documents(docs, embeddings)\n",
"\n",
"query = \"What did the president say about Ketanji Brown Jackson\"\n",
"docs = await db.asimilarity_search(query)"
]
},
{
"cell_type": "code",
"execution_count": 7,
"id": "4b172de8",
"metadata": {
"tags": []
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Tonight. I call on the Senate to: Pass the Freedom to Vote Act. Pass the John Lewis Voting Rights Act. And while youre at it, pass the Disclose Act so Americans can know who is funding our elections. \n",
"\n",
"Tonight, Id like to honor someone who has dedicated his life to serve this country: Justice Stephen Breyer—an Army veteran, Constitutional scholar, and retiring Justice of the United States Supreme Court. Justice Breyer, thank you for your service. \n",
"\n",
"One of the most serious constitutional responsibilities a President has is nominating someone to serve on the United States Supreme Court. \n",
"\n",
"And I did that 4 days ago, when I nominated Circuit Court of Appeals Judge Ketanji Brown Jackson. One of our nations top legal minds, who will continue Justice Breyers legacy of excellence.\n"
]
}
],
"source": [
"print(docs[0].page_content)"
]
},
{
"cell_type": "markdown",
"id": "f13473b5",
"metadata": {},
"source": [
"## Similarity Search with score\n",
"There are some FAISS specific methods. One of them is `similarity_search_with_score`, which allows you to return not only the documents but also the distance score of the query to them. The returned distance score is L2 distance. Therefore, a lower score is better."
]
},
{
"cell_type": "code",
"execution_count": 8,
"id": "186ee1d8",
"metadata": {},
"outputs": [],
"source": [
"docs_and_scores = await db.asimilarity_search_with_score(query)"
]
},
{
"cell_type": "code",
"execution_count": 9,
"id": "284e04b5",
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"(Document(page_content='Tonight. I call on the Senate to: Pass the Freedom to Vote Act. Pass the John Lewis Voting Rights Act. And while youre at it, pass the Disclose Act so Americans can know who is funding our elections. \\n\\nTonight, Id like to honor someone who has dedicated his life to serve this country: Justice Stephen Breyer—an Army veteran, Constitutional scholar, and retiring Justice of the United States Supreme Court. Justice Breyer, thank you for your service. \\n\\nOne of the most serious constitutional responsibilities a President has is nominating someone to serve on the United States Supreme Court. \\n\\nAnd I did that 4 days ago, when I nominated Circuit Court of Appeals Judge Ketanji Brown Jackson. One of our nations top legal minds, who will continue Justice Breyers legacy of excellence.', metadata={'source': './state_of_the_union.txt'}),\n",
" 0.36871302)"
]
},
"execution_count": 9,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"docs_and_scores[0]"
]
},
{
"cell_type": "markdown",
"id": "f34420cf",
"metadata": {},
"source": [
"It is also possible to do a search for documents similar to a given embedding vector using `similarity_search_by_vector` which accepts an embedding vector as a parameter instead of a string."
]
},
{
"cell_type": "code",
"execution_count": 10,
"id": "b558ebb7",
"metadata": {},
"outputs": [],
"source": [
"embedding_vector = await embeddings.aembed_query(query)\n",
"docs_and_scores = await db.asimilarity_search_by_vector(embedding_vector)"
]
},
{
"cell_type": "markdown",
"id": "31bda7fd",
"metadata": {},
"source": [
"## Saving and loading\n",
"You can also save and load a FAISS index. This is useful so you don't have to recreate it everytime you use it."
]
},
{
"cell_type": "code",
"execution_count": 11,
"id": "428a6816",
"metadata": {},
"outputs": [],
"source": [
"db.save_local(\"faiss_index\")"
]
},
{
"cell_type": "code",
"execution_count": 14,
"id": "56d1841c",
"metadata": {},
"outputs": [],
"source": [
"new_db = FAISS.load_local(\"faiss_index\", embeddings, asynchronous=True)"
]
},
{
"cell_type": "code",
"execution_count": 15,
"id": "39055525",
"metadata": {},
"outputs": [],
"source": [
"docs = await new_db.asimilarity_search(query)"
]
},
{
"cell_type": "code",
"execution_count": 16,
"id": "98378c4e",
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"Document(page_content='Tonight. I call on the Senate to: Pass the Freedom to Vote Act. Pass the John Lewis Voting Rights Act. And while youre at it, pass the Disclose Act so Americans can know who is funding our elections. \\n\\nTonight, Id like to honor someone who has dedicated his life to serve this country: Justice Stephen Breyer—an Army veteran, Constitutional scholar, and retiring Justice of the United States Supreme Court. Justice Breyer, thank you for your service. \\n\\nOne of the most serious constitutional responsibilities a President has is nominating someone to serve on the United States Supreme Court. \\n\\nAnd I did that 4 days ago, when I nominated Circuit Court of Appeals Judge Ketanji Brown Jackson. One of our nations top legal minds, who will continue Justice Breyers legacy of excellence.', metadata={'source': './state_of_the_union.txt'})"
]
},
"execution_count": 16,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"docs[0]"
]
},
{
"cell_type": "markdown",
"id": "30c8f57b",
"metadata": {},
"source": [
"# Serializing and De-Serializing to bytes\n",
"\n",
"you can pickle the FAISS Index by these functions. If you use embeddings model which is of 90 mb (sentence-transformers/all-MiniLM-L6-v2 or any other model), the resultant pickle size would be more than 90 mb. the size of the model is also included in the overall size. To overcome this, use the below functions. These functions only serializes FAISS index and size would be much lesser. this can be helpful if you wish to store the index in database like sql."
]
},
{
"cell_type": "code",
"execution_count": 17,
"id": "d8faead5",
"metadata": {},
"outputs": [],
"source": [
"pkl = db.serialize_to_bytes() # serializes the faiss index"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "eb083247",
"metadata": {},
"outputs": [],
"source": [
"embeddings = HuggingFaceEmbeddings(model_name=\"all-MiniLM-L6-v2\")"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "e36e220b",
"metadata": {},
"outputs": [],
"source": [
"db = FAISS.deserialize_from_bytes(\n",
" embeddings=embeddings, serialized=pkl, asynchronous=True\n",
") # Load the index"
]
},
{
"cell_type": "markdown",
"id": "57da60d4",
"metadata": {},
"source": [
"## Merging\n",
"You can also merge two FAISS vectorstores"
]
},
{
"cell_type": "code",
"execution_count": 19,
"id": "6dfd2b78",
"metadata": {},
"outputs": [],
"source": [
"db1 = await FAISS.afrom_texts([\"foo\"], embeddings)\n",
"db2 = await FAISS.afrom_texts([\"bar\"], embeddings)"
]
},
{
"cell_type": "code",
"execution_count": 20,
"id": "29960da7",
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"{'8164a453-9643-4959-87f7-9ba79f9e8fb0': Document(page_content='foo')}"
]
},
"execution_count": 20,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"db1.docstore._dict"
]
},
{
"cell_type": "code",
"execution_count": 21,
"id": "83392605",
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"{'4fbcf8a2-e80f-4f65-9308-2f4cb27cb6e7': Document(page_content='bar')}"
]
},
"execution_count": 21,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"db2.docstore._dict"
]
},
{
"cell_type": "code",
"execution_count": 22,
"id": "a3fcc1c7",
"metadata": {},
"outputs": [],
"source": [
"db1.merge_from(db2)"
]
},
{
"cell_type": "code",
"execution_count": 23,
"id": "41c51f89",
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"{'8164a453-9643-4959-87f7-9ba79f9e8fb0': Document(page_content='foo'),\n",
" '4fbcf8a2-e80f-4f65-9308-2f4cb27cb6e7': Document(page_content='bar')}"
]
},
"execution_count": 23,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"db1.docstore._dict"
]
},
{
"cell_type": "markdown",
"id": "f4294b96",
"metadata": {},
"source": [
"## Similarity Search with filtering\n",
"FAISS vectorstore can also support filtering, since the FAISS does not natively support filtering we have to do it manually. This is done by first fetching more results than `k` and then filtering them. You can filter the documents based on metadata. You can also set the `fetch_k` parameter when calling any search method to set how many documents you want to fetch before filtering. Here is a small example:"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "6740107a",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Content: foo, Metadata: {'page': 1}, Score: 5.159960813797904e-15\n",
"Content: foo, Metadata: {'page': 2}, Score: 5.159960813797904e-15\n",
"Content: foo, Metadata: {'page': 3}, Score: 5.159960813797904e-15\n",
"Content: foo, Metadata: {'page': 4}, Score: 5.159960813797904e-15\n"
]
}
],
"source": [
"from langchain.schema import Document\n",
"\n",
"list_of_documents = [\n",
" Document(page_content=\"foo\", metadata=dict(page=1)),\n",
" Document(page_content=\"bar\", metadata=dict(page=1)),\n",
" Document(page_content=\"foo\", metadata=dict(page=2)),\n",
" Document(page_content=\"barbar\", metadata=dict(page=2)),\n",
" Document(page_content=\"foo\", metadata=dict(page=3)),\n",
" Document(page_content=\"bar burr\", metadata=dict(page=3)),\n",
" Document(page_content=\"foo\", metadata=dict(page=4)),\n",
" Document(page_content=\"bar bruh\", metadata=dict(page=4)),\n",
"]\n",
"db = FAISS.from_documents(list_of_documents, embeddings)\n",
"results_with_scores = db.similarity_search_with_score(\"foo\")\n",
"for doc, score in results_with_scores:\n",
" print(f\"Content: {doc.page_content}, Metadata: {doc.metadata}, Score: {score}\")"
]
},
{
"cell_type": "markdown",
"id": "3d33c126",
"metadata": {},
"source": [
"Now we make the same query call but we filter for only `page = 1` "
]
},
{
"cell_type": "code",
"execution_count": 26,
"id": "83159330",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Content: foo, Metadata: {'page': 1}, Score: 5.159960813797904e-15\n",
"Content: bar, Metadata: {'page': 1}, Score: 0.3131446838378906\n"
]
}
],
"source": [
"results_with_scores = await db.asimilarity_search_with_score(\"foo\", filter=dict(page=1))\n",
"for doc, score in results_with_scores:\n",
" print(f\"Content: {doc.page_content}, Metadata: {doc.metadata}, Score: {score}\")"
]
},
{
"cell_type": "markdown",
"id": "0be136e0",
"metadata": {},
"source": [
"Same thing can be done with the `max_marginal_relevance_search` as well."
]
},
{
"cell_type": "code",
"execution_count": 27,
"id": "432c6980",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Content: foo, Metadata: {'page': 1}\n",
"Content: bar, Metadata: {'page': 1}\n"
]
}
],
"source": [
"results = await db.amax_marginal_relevance_search(\"foo\", filter=dict(page=1))\n",
"for doc in results:\n",
" print(f\"Content: {doc.page_content}, Metadata: {doc.metadata}\")"
]
},
{
"cell_type": "markdown",
"id": "1b4ecd86",
"metadata": {},
"source": [
"Here is an example of how to set `fetch_k` parameter when calling `similarity_search`. Usually you would want the `fetch_k` parameter >> `k` parameter. This is because the `fetch_k` parameter is the number of documents that will be fetched before filtering. If you set `fetch_k` to a low number, you might not get enough documents to filter from."
]
},
{
"cell_type": "code",
"execution_count": 4,
"id": "1fd60fd1",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Content: foo, Metadata: {'page': 1}\n"
]
}
],
"source": [
"results = await db.asimilarity_search(\"foo\", filter=dict(page=1), k=1, fetch_k=4)\n",
"for doc in results:\n",
" print(f\"Content: {doc.page_content}, Metadata: {doc.metadata}\")"
]
},
{
"cell_type": "markdown",
"id": "1becca53",
"metadata": {},
"source": [
"## Delete\n",
"\n",
"You can also delete ids. Note that the ids to delete should be the ids in the docstore."
]
},
{
"cell_type": "code",
"execution_count": 4,
"id": "1408b870",
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"True"
]
},
"execution_count": 4,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"db.delete([db.index_to_docstore_id[0]])"
]
},
{
"cell_type": "code",
"execution_count": 6,
"id": "d13daf33",
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"False"
]
},
"execution_count": 6,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"# Is now missing\n",
"0 in db.index_to_docstore_id"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "30ace43e",
"metadata": {},
"outputs": [],
"source": []
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3 (ipykernel)",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.11.3"
}
},
"nbformat": 4,
"nbformat_minor": 5
}

View File

@@ -0,0 +1,165 @@
{
"cells": [
{
"attachments": {},
"cell_type": "markdown",
"metadata": {},
"source": [
"# Baidu Cloud ElasticSearch VectorSearch\n",
"\n",
">[Baidu Cloud VectorSearch](https://cloud.baidu.com/doc/BES/index.html?from=productToDoc) is a fully managed, enterprise-level distributed search and analysis service which is 100% compatible to open source. Baidu Cloud VectorSearch provides low-cost, high-performance, and reliable retrieval and analysis platform level product services for structured/unstructured data. As a vector database , it supports multiple index types and similarity distance methods. \n",
"\n",
">`Baidu Cloud ElasticSearch` provides a privilege management mechanism, for you to configure the cluster privileges freely, so as to further ensure data security.\n",
"\n",
"This notebook shows how to use functionality related to the `Baidu Cloud ElasticSearch VectorStore`.\n",
"To run, you should have an [Baidu Cloud ElasticSearch](https://cloud.baidu.com/product/bes.html) instance up and running:\n",
"\n",
"Read the [help document](https://cloud.baidu.com/doc/BES/s/8llyn0hh4 ) to quickly familiarize and configure Baidu Cloud ElasticSearch instance."
]
},
{
"attachments": {},
"cell_type": "markdown",
"metadata": {},
"source": [
"After the instance is up and running, follow these steps to split documents, get embeddings, connect to the baidu cloud elasticsearch instance, index documents, and perform vector retrieval."
]
},
{
"attachments": {},
"cell_type": "markdown",
"metadata": {},
"source": [
"We need to install the following Python packages first."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"#!pip install elasticsearch == 7.11.0"
]
},
{
"attachments": {},
"cell_type": "markdown",
"metadata": {},
"source": [
"First, we want to use `QianfanEmbeddings` so we have to get the Qianfan AK and SK. Details for QianFan is related to [Baidu Qianfan Workshop](https://cloud.baidu.com/product/wenxinworkshop)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"import os\n",
"import getpass\n",
"\n",
"os.environ[\"QIANFAN_AK\"] = getpass.getpass(\"Your Qianfan AK:\")\n",
"os.environ[\"QIANFAN_SK\"] = getpass.getpass(\"Your Qianfan SK:\")"
]
},
{
"attachments": {},
"cell_type": "markdown",
"metadata": {},
"source": [
"Secondly, split documents and get embeddings."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"from langchain.document_loaders import TextLoader\n",
"\n",
"loader = TextLoader(\"../../../state_of_the_union.txt\")\n",
"documents = loader.load()\n",
"text_splitter = CharacterTextSplitter(chunk_size=1000, chunk_overlap=0)\n",
"docs = text_splitter.split_documents(documents)\n",
"\n",
"from langchain.embeddings import QianfanEmbeddingsEndpoint\n",
"\n",
"embeddings = QianfanEmbeddingsEndpoint()"
]
},
{
"attachments": {},
"cell_type": "markdown",
"metadata": {},
"source": [
"Then, create a Baidu ElasticeSearch accessable instance."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"# Create a bes instance and index docs.\n",
"from langchain.vectorstores import BESVectorStore\n",
"\n",
"bes = BESVectorStore.from_documents(\n",
" documents=docs,\n",
" embedding=embeddings,\n",
" bes_url=\"your bes cluster url\",\n",
" index_name=\"your vector index\",\n",
")\n",
"bes.client.indices.refresh(index=\"your vector index\")"
]
},
{
"attachments": {},
"cell_type": "markdown",
"metadata": {},
"source": [
"Finally, Query and retrive data"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"query = \"What did the president say about Ketanji Brown Jackson\"\n",
"docs = bes.similarity_search(query)\n",
"print(docs[0].page_content)"
]
},
{
"attachments": {},
"cell_type": "markdown",
"metadata": {},
"source": [
"Please feel free to contact <liuboyao@baidu.com> or <chenweixu01@baidu.com> if you encounter any problems during use, and we will do our best to support you."
]
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3",
"language": "python",
"name": "python3"
},
"language_info": {
"name": "python",
"version": "3.9.17"
},
"orig_nbformat": 4,
"vscode": {
"interpreter": {
"hash": "aee8b7b246df8f9039afb4144a1f6fd8d2ca17a180786b69acc140d282b71a49"
}
}
},
"nbformat": 4,
"nbformat_minor": 2
}

View File

@@ -1,326 +0,0 @@
{
"cells": [
{
"cell_type": "markdown",
"id": "683953b3",
"metadata": {},
"source": [
"# Cassandra\n",
"\n",
">[Apache Cassandra®](https://cassandra.apache.org) is a NoSQL, row-oriented, highly scalable and highly available database.\n",
"\n",
"Newest Cassandra releases natively [support](https://cwiki.apache.org/confluence/display/CASSANDRA/CEP-30%3A+Approximate+Nearest+Neighbor(ANN)+Vector+Search+via+Storage-Attached+Indexes) Vector Similarity Search.\n",
"\n",
"To run this notebook you need either a running Cassandra cluster equipped with Vector Search capabilities (in pre-release at the time of writing) or a DataStax Astra DB instance running in the cloud (you can get one for free at [datastax.com](https://astra.datastax.com)). Check [cassio.org](https://cassio.org/start_here/) for more information."
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "b4c41cad-08ef-4f72-a545-2151e4598efe",
"metadata": {
"tags": []
},
"outputs": [],
"source": [
"!pip install \"cassio>=0.1.0\""
]
},
{
"cell_type": "markdown",
"id": "b7e46bb0",
"metadata": {},
"source": [
"### Please provide database connection parameters and secrets:"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "36128a32",
"metadata": {},
"outputs": [],
"source": [
"import os\n",
"import getpass\n",
"\n",
"database_mode = (input(\"\\n(C)assandra or (A)stra DB? \")).upper()\n",
"\n",
"keyspace_name = input(\"\\nKeyspace name? \")\n",
"\n",
"if database_mode == \"A\":\n",
" ASTRA_DB_APPLICATION_TOKEN = getpass.getpass('\\nAstra DB Token (\"AstraCS:...\") ')\n",
" #\n",
" ASTRA_DB_SECURE_BUNDLE_PATH = input(\"Full path to your Secure Connect Bundle? \")\n",
"elif database_mode == \"C\":\n",
" CASSANDRA_CONTACT_POINTS = input(\n",
" \"Contact points? (comma-separated, empty for localhost) \"\n",
" ).strip()"
]
},
{
"cell_type": "markdown",
"id": "4f22aac2",
"metadata": {},
"source": [
"#### depending on whether local or cloud-based Astra DB, create the corresponding database connection \"Session\" object"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "677f8576",
"metadata": {},
"outputs": [],
"source": [
"from cassandra.cluster import Cluster\n",
"from cassandra.auth import PlainTextAuthProvider\n",
"\n",
"if database_mode == \"C\":\n",
" if CASSANDRA_CONTACT_POINTS:\n",
" cluster = Cluster(\n",
" [cp.strip() for cp in CASSANDRA_CONTACT_POINTS.split(\",\") if cp.strip()]\n",
" )\n",
" else:\n",
" cluster = Cluster()\n",
" session = cluster.connect()\n",
"elif database_mode == \"A\":\n",
" ASTRA_DB_CLIENT_ID = \"token\"\n",
" cluster = Cluster(\n",
" cloud={\n",
" \"secure_connect_bundle\": ASTRA_DB_SECURE_BUNDLE_PATH,\n",
" },\n",
" auth_provider=PlainTextAuthProvider(\n",
" ASTRA_DB_CLIENT_ID,\n",
" ASTRA_DB_APPLICATION_TOKEN,\n",
" ),\n",
" )\n",
" session = cluster.connect()\n",
"else:\n",
" raise NotImplementedError"
]
},
{
"cell_type": "markdown",
"id": "320af802-9271-46ee-948f-d2453933d44b",
"metadata": {},
"source": [
"### Please provide OpenAI access key\n",
"\n",
"We want to use `OpenAIEmbeddings` so we have to get the OpenAI API Key."
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "ffea66e4-bc23-46a9-9580-b348dfe7b7a7",
"metadata": {},
"outputs": [],
"source": [
"os.environ[\"OPENAI_API_KEY\"] = getpass.getpass(\"OpenAI API Key:\")"
]
},
{
"cell_type": "markdown",
"id": "e98a139b",
"metadata": {},
"source": [
"### Creation and usage of the Vector Store"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "aac9563e",
"metadata": {
"tags": []
},
"outputs": [],
"source": [
"from langchain.embeddings.openai import OpenAIEmbeddings\n",
"from langchain.text_splitter import CharacterTextSplitter\n",
"from langchain.vectorstores import Cassandra\n",
"from langchain.document_loaders import TextLoader"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "a3c3999a",
"metadata": {},
"outputs": [],
"source": [
"from langchain.document_loaders import TextLoader\n",
"\n",
"SOURCE_FILE_NAME = \"../../modules/state_of_the_union.txt\"\n",
"\n",
"loader = TextLoader(SOURCE_FILE_NAME)\n",
"documents = loader.load()\n",
"text_splitter = CharacterTextSplitter(chunk_size=1000, chunk_overlap=0)\n",
"docs = text_splitter.split_documents(documents)\n",
"\n",
"embedding_function = OpenAIEmbeddings()"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "6e104aee",
"metadata": {},
"outputs": [],
"source": [
"table_name = \"my_vector_db_table\"\n",
"\n",
"docsearch = Cassandra.from_documents(\n",
" documents=docs,\n",
" embedding=embedding_function,\n",
" session=session,\n",
" keyspace=keyspace_name,\n",
" table_name=table_name,\n",
")\n",
"\n",
"query = \"What did the president say about Ketanji Brown Jackson\"\n",
"docs = docsearch.similarity_search(query)"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "f509ee02",
"metadata": {},
"outputs": [],
"source": [
"## if you already have an index, you can load it and use it like this:\n",
"\n",
"# docsearch_preexisting = Cassandra(\n",
"# embedding=embedding_function,\n",
"# session=session,\n",
"# keyspace=keyspace_name,\n",
"# table_name=table_name,\n",
"# )\n",
"\n",
"# docs = docsearch_preexisting.similarity_search(query, k=2)"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "9c608226",
"metadata": {},
"outputs": [],
"source": [
"print(docs[0].page_content)"
]
},
{
"cell_type": "markdown",
"id": "d46d1452",
"metadata": {},
"source": [
"### Maximal Marginal Relevance Searches\n",
"\n",
"In addition to using similarity search in the retriever object, you can also use `mmr` as retriever.\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "a359ed74",
"metadata": {},
"outputs": [],
"source": [
"retriever = docsearch.as_retriever(search_type=\"mmr\")\n",
"matched_docs = retriever.get_relevant_documents(query)\n",
"for i, d in enumerate(matched_docs):\n",
" print(f\"\\n## Document {i}\\n\")\n",
" print(d.page_content)"
]
},
{
"cell_type": "markdown",
"id": "7c477287",
"metadata": {},
"source": [
"Or use `max_marginal_relevance_search` directly:"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "9ca82740",
"metadata": {},
"outputs": [],
"source": [
"found_docs = docsearch.max_marginal_relevance_search(query, k=2, fetch_k=10)\n",
"for i, doc in enumerate(found_docs):\n",
" print(f\"{i + 1}.\", doc.page_content, \"\\n\")"
]
},
{
"cell_type": "markdown",
"id": "da791c5f",
"metadata": {},
"source": [
"### Metadata filtering\n",
"\n",
"You can specify filtering on metadata when running searches in the vector store. By default, when inserting documents, the only metadata is the `\"source\"` (but you can customize the metadata at insertion time).\n",
"\n",
"Since only one files was inserted, this is just a demonstration of how filters are passed:"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "93f132fa",
"metadata": {},
"outputs": [],
"source": [
"filter = {\"source\": SOURCE_FILE_NAME}\n",
"filtered_docs = docsearch.similarity_search(query, filter=filter, k=5)\n",
"print(f\"{len(filtered_docs)} documents retrieved.\")\n",
"print(f\"{filtered_docs[0].page_content[:64]} ...\")"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "1b413ec4",
"metadata": {},
"outputs": [],
"source": [
"filter = {\"source\": \"nonexisting_file.txt\"}\n",
"filtered_docs2 = docsearch.similarity_search(query, filter=filter)\n",
"print(f\"{len(filtered_docs2)} documents retrieved.\")"
]
},
{
"cell_type": "markdown",
"id": "a0fea764",
"metadata": {},
"source": [
"Please visit the [cassIO documentation](https://cassio.org/frameworks/langchain/about/) for more on using vector stores with Langchain."
]
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3 (ipykernel)",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.10.12"
}
},
"nbformat": 4,
"nbformat_minor": 5
}

View File

@@ -104,11 +104,14 @@
"source": [
"from dingodb import DingoDB\n",
"\n",
"index_name = \"langchain-demo\"\n",
"index_name = \"langchain_demo\"\n",
"\n",
"dingo_client = DingoDB(user=\"\", password=\"\", host=[\"127.0.0.1:13000\"])\n",
"# First, check if our index already exists. If it doesn't, we create it\n",
"if index_name not in dingo_client.get_index():\n",
"if (\n",
" index_name not in dingo_client.get_index()\n",
" and index_name.upper() not in dingo_client.get_index()\n",
"):\n",
" # we create a new index, modify to your own\n",
" dingo_client.create_index(\n",
" index_name=index_name, dimension=1536, metric_type=\"cosine\", auto_id=False\n",

View File

@@ -0,0 +1,431 @@
{
"cells": [
{
"cell_type": "markdown",
"source": [
"## Hippo\n",
"\n",
">[Hippo](https://www.transwarp.cn/starwarp) Please visit our official website for how to run a Hippo instance and\n",
"how to use functionality related to the Hippo vector database\n",
"\n",
"## Getting Started\n",
"\n",
"The only prerequisite here is an API key from the OpenAI website. Make sure you have already started a Hippo instance."
],
"metadata": {
"collapsed": false
},
"id": "357f24224a8e818f"
},
{
"cell_type": "markdown",
"source": [
"## Installing Dependencies\n",
"\n",
"Initially, we require the installation of certain dependencies, such as OpenAI, Langchain, and Hippo-API. Please note, you should install the appropriate versions tailored to your environment."
],
"metadata": {
"collapsed": false
},
"id": "a92d2ce26df7ac4c"
},
{
"cell_type": "code",
"execution_count": 15,
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Requirement already satisfied: hippo-api==1.1.0.rc3 in /Users/daochengzhang/miniforge3/envs/py310/lib/python3.10/site-packages (1.1.0rc3)\r\n",
"Requirement already satisfied: pyyaml>=6.0 in /Users/daochengzhang/miniforge3/envs/py310/lib/python3.10/site-packages (from hippo-api==1.1.0.rc3) (6.0.1)\r\n"
]
}
],
"source": [
"!pip install langchain tiktoken openai\n",
"!pip install hippo-api==1.1.0.rc3"
],
"metadata": {
"collapsed": false,
"ExecuteTime": {
"end_time": "2023-10-30T06:47:54.718488Z",
"start_time": "2023-10-30T06:47:53.563129Z"
}
},
"id": "13b1d1ae153ff434"
},
{
"cell_type": "markdown",
"source": [
"Note: Python version needs to be >=3.8.\n",
"\n",
"## Best Practice\n",
"### Importing Dependency Packages"
],
"metadata": {
"collapsed": false
},
"id": "554081137df2c252"
},
{
"cell_type": "code",
"execution_count": 16,
"outputs": [],
"source": [
"from langchain.chat_models import AzureChatOpenAI, ChatOpenAI\n",
"from langchain.document_loaders import TextLoader\n",
"from langchain.embeddings import OpenAIEmbeddings\n",
"from langchain.text_splitter import CharacterTextSplitter\n",
"from langchain.vectorstores.hippo import Hippo\n",
"import os"
],
"metadata": {
"collapsed": false,
"ExecuteTime": {
"end_time": "2023-10-30T06:47:56.003409Z",
"start_time": "2023-10-30T06:47:55.998839Z"
}
},
"id": "5ff3296ce812aeb8"
},
{
"cell_type": "markdown",
"source": [
"### Loading Knowledge Documents"
],
"metadata": {
"collapsed": false
},
"id": "dad255dae8aea755"
},
{
"cell_type": "code",
"execution_count": 17,
"outputs": [],
"source": [
"os.environ[\"OPENAI_API_KEY\"] = \"YOUR OPENAI KEY\"\n",
"loader = TextLoader(\"../../modules/state_of_the_union.txt\")\n",
"documents = loader.load()"
],
"metadata": {
"collapsed": false,
"ExecuteTime": {
"end_time": "2023-10-30T06:47:59.027869Z",
"start_time": "2023-10-30T06:47:59.023934Z"
}
},
"id": "f02d66a7fd653dc1"
},
{
"cell_type": "markdown",
"source": [
"### Segmenting the Knowledge Document\n",
"\n",
"Here, we use Langchain's CharacterTextSplitter for segmentation. The delimiter is a period. After segmentation, the text segment does not exceed 1000 characters, and the number of repeated characters is 0."
],
"metadata": {
"collapsed": false
},
"id": "e9b93c330f1c6160"
},
{
"cell_type": "code",
"execution_count": 18,
"outputs": [],
"source": [
"text_splitter = CharacterTextSplitter(chunk_size=500, chunk_overlap=0)\n",
"docs = text_splitter.split_documents(documents)"
],
"metadata": {
"collapsed": false,
"ExecuteTime": {
"end_time": "2023-10-30T06:48:00.279351Z",
"start_time": "2023-10-30T06:48:00.275763Z"
}
},
"id": "fe6b43175318331f"
},
{
"cell_type": "markdown",
"source": [
"### Declaring the Embedding Model\n",
"Below, we create the OpenAI or Azure embedding model using the OpenAIEmbeddings method from Langchain."
],
"metadata": {
"collapsed": false
},
"id": "eefe28c7c993ffdf"
},
{
"cell_type": "code",
"execution_count": 19,
"outputs": [],
"source": [
"# openai\n",
"embeddings = OpenAIEmbeddings()\n",
"# azure\n",
"# embeddings = OpenAIEmbeddings(\n",
"# openai_api_type=\"azure\",\n",
"# openai_api_base=\"x x x\",\n",
"# openai_api_version=\"x x x\",\n",
"# model=\"x x x\",\n",
"# deployment=\"x x x\",\n",
"# openai_api_key=\"x x x\"\n",
"# )"
],
"metadata": {
"collapsed": false,
"ExecuteTime": {
"end_time": "2023-10-30T06:48:11.686166Z",
"start_time": "2023-10-30T06:48:11.664355Z"
}
},
"id": "8619f16b9f7355ea"
},
{
"cell_type": "markdown",
"source": [
"### Declaring Hippo Client"
],
"metadata": {
"collapsed": false
},
"id": "e60235602ed91d3c"
},
{
"cell_type": "code",
"execution_count": 20,
"outputs": [],
"source": [
"HIPPO_CONNECTION = {\"host\": \"IP\", \"port\": \"PORT\"}"
],
"metadata": {
"collapsed": false,
"ExecuteTime": {
"end_time": "2023-10-30T06:48:48.594298Z",
"start_time": "2023-10-30T06:48:48.585267Z"
}
},
"id": "c666b70dcab78129"
},
{
"cell_type": "markdown",
"source": [
"### Storing the Document"
],
"metadata": {
"collapsed": false
},
"id": "43ee6dbd765c3172"
},
{
"cell_type": "code",
"execution_count": 23,
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"input...\n",
"success\n"
]
}
],
"source": [
"print(\"input...\")\n",
"# insert docs\n",
"vector_store = Hippo.from_documents(\n",
" docs,\n",
" embedding=embeddings,\n",
" table_name=\"langchain_test\",\n",
" connection_args=HIPPO_CONNECTION,\n",
")\n",
"print(\"success\")"
],
"metadata": {
"collapsed": false,
"ExecuteTime": {
"end_time": "2023-10-30T06:51:12.661741Z",
"start_time": "2023-10-30T06:51:06.257156Z"
}
},
"id": "79372c869844bdc9"
},
{
"cell_type": "markdown",
"source": [
"### Conducting Knowledge-based Question and Answer\n",
"#### Creating a Large Language Question-Answering Model\n",
"Below, we create the OpenAI or Azure large language question-answering model respectively using the AzureChatOpenAI and ChatOpenAI methods from Langchain."
],
"metadata": {
"collapsed": false
},
"id": "89077cc9763d5dd0"
},
{
"cell_type": "code",
"execution_count": 24,
"outputs": [],
"source": [
"# llm = AzureChatOpenAI(\n",
"# openai_api_base=\"x x x\",\n",
"# openai_api_version=\"xxx\",\n",
"# deployment_name=\"xxx\",\n",
"# openai_api_key=\"xxx\",\n",
"# openai_api_type=\"azure\"\n",
"# )\n",
"\n",
"llm = ChatOpenAI(openai_api_key=\"YOUR OPENAI KEY\", model_name=\"gpt-3.5-turbo-16k\")"
],
"metadata": {
"collapsed": false,
"ExecuteTime": {
"end_time": "2023-10-30T06:51:28.329351Z",
"start_time": "2023-10-30T06:51:28.318713Z"
}
},
"id": "c9f2c42e9884f628"
},
{
"cell_type": "markdown",
"source": [
"### Acquiring Related Knowledge Based on the Question"
],
"metadata": {
"collapsed": false
},
"id": "a4c5d73016a9db0c"
},
{
"cell_type": "code",
"execution_count": 25,
"outputs": [],
"source": [
"query = \"Please introduce COVID-19\"\n",
"# query = \"Please introduce Hippo Core Architecture\"\n",
"# query = \"What operations does the Hippo Vector Database support for vector data?\"\n",
"# query = \"Does Hippo use hardware acceleration technology? Briefly introduce hardware acceleration technology.\"\n",
"\n",
"\n",
"# Retrieve similar content from the knowledge base,fetch the top two most similar texts.\n",
"res = vector_store.similarity_search(query, 2)\n",
"content_list = [item.page_content for item in res]\n",
"text = \"\".join(content_list)"
],
"metadata": {
"collapsed": false,
"ExecuteTime": {
"end_time": "2023-10-30T06:51:33.195634Z",
"start_time": "2023-10-30T06:51:32.196493Z"
}
},
"id": "8656e80519da1f97"
},
{
"cell_type": "markdown",
"source": [
"### Constructing a Prompt Template"
],
"metadata": {
"collapsed": false
},
"id": "e5adbaaa7086d1ae"
},
{
"cell_type": "code",
"execution_count": 26,
"outputs": [],
"source": [
"prompt = f\"\"\"\n",
"Please use the content of the following [Article] to answer my question. If you don't know, please say you don't know, and the answer should be concise.\"\n",
"[Article]:{text}\n",
"Please answer this question in conjunction with the above article:{query}\n",
"\"\"\""
],
"metadata": {
"collapsed": false,
"ExecuteTime": {
"end_time": "2023-10-30T06:51:35.649376Z",
"start_time": "2023-10-30T06:51:35.645763Z"
}
},
"id": "b915d3001a2741c1"
},
{
"cell_type": "markdown",
"source": [
"### Waiting for the Large Language Model to Generate an Answer"
],
"metadata": {
"collapsed": false
},
"id": "b36b6a9adbec8a82"
},
{
"cell_type": "code",
"execution_count": 27,
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"response_with_hippo:COVID-19 is a virus that has impacted every aspect of our lives for over two years. It is a highly contagious and mutates easily, requiring us to remain vigilant in combating its spread. However, due to progress made and the resilience of individuals, we are now able to move forward safely and return to more normal routines.\n",
"==========================================\n",
"response_without_hippo:COVID-19 is a contagious respiratory illness caused by the novel coronavirus SARS-CoV-2. It was first identified in December 2019 in Wuhan, China and has since spread globally, leading to a pandemic. The virus primarily spreads through respiratory droplets when an infected person coughs, sneezes, talks, or breathes, and can also spread by touching contaminated surfaces and then touching the face. COVID-19 symptoms include fever, cough, shortness of breath, fatigue, muscle or body aches, sore throat, loss of taste or smell, headache, and in severe cases, pneumonia and organ failure. While most people experience mild to moderate symptoms, it can lead to severe illness and even death, particularly among older adults and those with underlying health conditions. To combat the spread of the virus, various preventive measures have been implemented globally, including social distancing, wearing face masks, practicing good hand hygiene, and vaccination efforts.\n"
]
}
],
"source": [
"response_with_hippo = llm.predict(prompt)\n",
"print(f\"response_with_hippo:{response_with_hippo}\")\n",
"response = llm.predict(query)\n",
"print(\"==========================================\")\n",
"print(f\"response_without_hippo:{response}\")"
],
"metadata": {
"collapsed": false,
"ExecuteTime": {
"end_time": "2023-10-30T06:52:17.967885Z",
"start_time": "2023-10-30T06:51:37.692819Z"
}
},
"id": "58eb5d2396321001"
},
{
"cell_type": "code",
"execution_count": null,
"outputs": [],
"source": [],
"metadata": {
"collapsed": false,
"ExecuteTime": {
"start_time": "2023-10-30T06:42:42.172639Z"
}
},
"id": "b2b7ce4e1850ecf1"
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 2
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython2",
"version": "2.7.6"
}
},
"nbformat": 4,
"nbformat_minor": 5
}

View File

@@ -0,0 +1,214 @@
{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# PGVecto.rs\n",
"\n",
"This notebook shows how to use functionality related to the Postgres vector database ([pgvecto.rs](https://github.com/tensorchord/pgvecto.rs)). You need to install SQLAlchemy >= 2 manually."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"## Loading Environment Variables\n",
"from dotenv import load_dotenv\n",
"\n",
"load_dotenv()"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"from typing import List\n",
"from langchain.embeddings.openai import OpenAIEmbeddings\n",
"from langchain.text_splitter import CharacterTextSplitter\n",
"from langchain.vectorstores.pgvecto_rs import PGVecto_rs\n",
"from langchain.document_loaders import TextLoader\n",
"from langchain.docstore.document import Document"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"loader = TextLoader(\"../../../state_of_the_union.txt\")\n",
"documents = loader.load()\n",
"text_splitter = CharacterTextSplitter(chunk_size=1000, chunk_overlap=0)\n",
"docs = text_splitter.split_documents(documents)\n",
"\n",
"embeddings = OpenAIEmbeddings()"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Start the database with the [official demo docker image](https://github.com/tensorchord/pgvecto.rs#installation)."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"vscode": {
"languageId": "shellscript"
}
},
"outputs": [],
"source": [
"docker run --name pgvecto-rs-demo -e POSTGRES_PASSWORD=mysecretpassword -p 5432:5432 -d tensorchord/pgvecto-rs:latest"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Then contruct the db URL"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"## PGVecto.rs needs the connection string to the database.\n",
"## We will load it from the environment variables.\n",
"import os\n",
"\n",
"PORT = os.getenv(\"DB_PORT\", 5432)\n",
"HOST = os.getenv(\"DB_HOST\", \"localhost\")\n",
"USER = os.getenv(\"DB_USER\", \"postgres\")\n",
"PASS = os.getenv(\"DB_PASS\", \"mysecretpassword\")\n",
"DB_NAME = os.getenv(\"DB_NAME\", \"postgres\")\n",
"\n",
"# Run tests with shell:\n",
"URL = \"postgresql+psycopg://{username}:{password}@{host}:{port}/{db_name}\".format(\n",
" port=PORT,\n",
" host=HOST,\n",
" username=USER,\n",
" password=PASS,\n",
" db_name=DB_NAME,\n",
")"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Finally, create the VectorStore from the documents:"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"db1 = PGVecto_rs.from_documents(\n",
" documents=docs,\n",
" embedding=embeddings,\n",
" db_url=URL,\n",
" # The table name is f\"collection_{collection_name}\", so that it should be unique.\n",
" collection_name=\"state_of_the_union\",\n",
")"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"You can connect to the table laterly with:"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"# Create new empty vectorstore with collection_name.\n",
"# Or connect to an existing vectorstore in database if exists.\n",
"# Arguments should be the same as when the vectorstore was created.\n",
"db1 = PGVecto_rs.from_collection_name(\n",
" embedding=embeddings,\n",
" db_url=URL,\n",
" collection_name=\"state_of_the_union\",\n",
")"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Make sure that the user is permitted to create a table."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Similarity search with score"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Similarity Search with Euclidean Distance (Default)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"query = \"What did the president say about Ketanji Brown Jackson\"\n",
"docs: List[Document] = db1.similarity_search(query, k=4)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"for doc in docs:\n",
" print(doc.page_content)\n",
" print(\"======================\")"
]
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3 (ipykernel)",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.11.3"
}
},
"nbformat": 4,
"nbformat_minor": 2
}

View File

@@ -0,0 +1,178 @@
{
"cells": [
{
"cell_type": "markdown",
"id": "25bce5eb-8599-40fe-947e-4932cfae8184",
"metadata": {},
"source": [
"# TileDB\n",
"\n",
"> [TileDB](https://github.com/TileDB-Inc/TileDB) is a powerful engine for indexing and querying dense and sparse multi-dimensional arrays.\n",
"\n",
"> TileDB offers ANN search capabilities using the [TileDB-Vector-Search](https://github.com/TileDB-Inc/TileDB-Vector-Search) module. It provides serverless execution of ANN queries and storage of vector indexes both on local disk and cloud object stores (i.e. AWS S3).\n",
"\n",
"More details in:\n",
"- [Why TileDB as a Vector Database](https://tiledb.com/blog/why-tiledb-as-a-vector-database)\n",
"- [TileDB 101: Vector Search](https://tiledb.com/blog/tiledb-101-vector-search)\n",
"\n",
"This notebook shows how to use the `TileDB` vector database."
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "f45f46f2-7229-4859-9797-30bbead1b8e0",
"metadata": {},
"outputs": [],
"source": [
"!pip install tiledb-vector-search"
]
},
{
"cell_type": "markdown",
"id": "2f65caa9-8383-409a-bccb-6e91fc8d5e8f",
"metadata": {},
"source": [
"## Basic Example"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "c96d4fe0",
"metadata": {},
"outputs": [],
"source": [
"from langchain.document_loaders import TextLoader\n",
"from langchain.embeddings import HuggingFaceEmbeddings\n",
"from langchain.text_splitter import CharacterTextSplitter\n",
"from langchain.vectorstores import TileDB\n",
"\n",
"raw_documents = TextLoader(\"../../modules/state_of_the_union.txt\").load()\n",
"text_splitter = CharacterTextSplitter(chunk_size=1000, chunk_overlap=0)\n",
"documents = text_splitter.split_documents(raw_documents)\n",
"embeddings = HuggingFaceEmbeddings()\n",
"db = TileDB.from_documents(\n",
" documents, embeddings, index_uri=\"/tmp/tiledb_index\", index_type=\"FLAT\"\n",
")"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "b0a6797c-2bb0-45db-a636-5d2437f7a4c0",
"metadata": {},
"outputs": [],
"source": [
"query = \"What did the president say about Ketanji Brown Jackson\"\n",
"docs = db.similarity_search(query)\n",
"docs[0].page_content"
]
},
{
"cell_type": "markdown",
"id": "c4c4e06d-6def-44ce-ac9a-4c01673c29a2",
"metadata": {},
"source": [
"### Similarity search by vector"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "1eb72610-d451-4158-880c-9f0d45fa5909",
"metadata": {},
"outputs": [],
"source": [
"embedding_vector = embeddings.embed_query(query)\n",
"docs = db.similarity_search_by_vector(embedding_vector)\n",
"docs[0].page_content"
]
},
{
"cell_type": "markdown",
"id": "d33588d4-67c2-4bd3-b251-76ae783cbafb",
"metadata": {},
"source": [
"### Similarity search with score"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "1a41e382-0336-4e6d-b2ef-44cc77db2696",
"metadata": {},
"outputs": [],
"source": [
"docs_and_scores = db.similarity_search_with_score(query)\n",
"docs_and_scores[0]"
]
},
{
"cell_type": "markdown",
"id": "57f930f2-41a0-4795-ad9e-44a33c8f88ec",
"metadata": {},
"source": [
"## Maximal Marginal Relevance Search (MMR)"
]
},
{
"cell_type": "markdown",
"id": "4790e437-3207-45cb-b121-d857ab5aabd8",
"metadata": {},
"source": [
"In addition to using similarity search in the retriever object, you can also use `mmr` as retriever."
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "495754b1-5cdb-4af6-9733-f68700bb7232",
"metadata": {},
"outputs": [],
"source": [
"retriever = db.as_retriever(search_type=\"mmr\")\n",
"retriever.get_relevant_documents(query)"
]
},
{
"cell_type": "markdown",
"id": "e213d957-e439-4bd6-90f2-8909323f5f09",
"metadata": {},
"source": [
"Or use `max_marginal_relevance_search` directly:"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "99d928d0-3b79-4588-925e-32230e12af47",
"metadata": {},
"outputs": [],
"source": [
"db.max_marginal_relevance_search(query, k=2, fetch_k=10)"
]
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3 (ipykernel)",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.9.18"
}
},
"nbformat": 4,
"nbformat_minor": 5
}

View File

@@ -10,7 +10,7 @@
"This notebook shows how to use the Postgres vector database `Timescale Vector`. You'll learn how to use TimescaleVector for (1) semantic search, (2) time-based vector search, (3) self-querying, and (4) how to create indexes to speed up queries.\n",
"\n",
"## What is Timescale Vector?\n",
"**[Timescale Vector](https://www.timescale.com/ai) is PostgreSQL++ for AI applications.**\n",
"**[Timescale Vector](https://www.timescale.com/ai?utm_campaign=vectorlaunch&utm_source=langchain&utm_medium=referral) is PostgreSQL++ for AI applications.**\n",
"\n",
"Timescale Vector enables you to efficiently store and query millions of vector embeddings in `PostgreSQL`.\n",
"- Enhances `pgvector` with faster and more accurate similarity search on 100M+ vectors via `DiskANN` inspired indexing algorithm.\n",
@@ -23,7 +23,7 @@
"- Enables a worry-free experience with enterprise-grade security and compliance.\n",
"\n",
"## How to access Timescale Vector\n",
"Timescale Vector is available on [Timescale](https://www.timescale.com/ai), the cloud PostgreSQL platform. (There is no self-hosted version at this time.)\n",
"Timescale Vector is available on [Timescale](https://www.timescale.com/ai?utm_campaign=vectorlaunch&utm_source=langchain&utm_medium=referral), the cloud PostgreSQL platform. (There is no self-hosted version at this time.)\n",
"\n",
"LangChain users get a 90-day free trial for Timescale Vector.\n",
"- To get started, [signup](https://console.cloud.timescale.com/signup?utm_campaign=vectorlaunch&utm_source=langchain&utm_medium=referral) to Timescale, create a new database and follow this notebook!\n",
@@ -180,7 +180,7 @@
"# Specify directly if testing\n",
"# SERVICE_URL = \"postgres://tsdbadmin:<password>@<id>.tsdb.cloud.timescale.com:<port>/tsdb?sslmode=require\"\n",
"\n",
"# # You can get also it from an enviornment variables. We suggest using a .env file.\n",
"# # You can get also it from an environment variables. We suggest using a .env file.\n",
"# import os\n",
"# SERVICE_URL = os.environ.get(\"TIMESCALE_SERVICE_URL\", \"\")"
]

View File

@@ -10,9 +10,19 @@
"\n",
">[Weaviate](https://weaviate.io/) is an open-source vector database. It allows you to store data objects and vector embeddings from your favorite ML-models, and scale seamlessly into billions of data objects.\n",
"\n",
"This notebook shows how to use functionality related to the `Weaviate`vector database.\n",
"This notebook shows how to use the functionality related to the `Weaviate` vector database.\n",
"\n",
"See the `Weaviate` [installation instructions](https://weaviate.io/developers/weaviate/installation)."
"`Weaviate` can be deployed in many different ways depending on your requirements. For example, you can either connect to a [Weaviate Cloud Services](https://console.weaviate.cloud) instance or a [local Docker instance](https://weaviate.io/developers/weaviate/installation/docker-compose). \n",
"See the `Weaviate` [installation instructions](https://weaviate.io/developers/weaviate/installation) for more information."
]
},
{
"cell_type": "markdown",
"id": "5fb59dec",
"metadata": {},
"source": [
"## Prerequisites\n",
"Install the `weaviate-client` package and set the relevant environment variables."
]
},
{
@@ -27,19 +37,21 @@
"name": "stdout",
"output_type": "stream",
"text": [
"Requirement already satisfied: weaviate-client in /workspaces/langchain/.venv/lib/python3.9/site-packages (3.19.1)\n",
"Requirement already satisfied: requests<2.29.0,>=2.28.0 in /workspaces/langchain/.venv/lib/python3.9/site-packages (from weaviate-client) (2.28.2)\n",
"Requirement already satisfied: validators<=0.21.0,>=0.18.2 in /workspaces/langchain/.venv/lib/python3.9/site-packages (from weaviate-client) (0.20.0)\n",
"Requirement already satisfied: tqdm<5.0.0,>=4.59.0 in /workspaces/langchain/.venv/lib/python3.9/site-packages (from weaviate-client) (4.65.0)\n",
"Requirement already satisfied: authlib>=1.1.0 in /workspaces/langchain/.venv/lib/python3.9/site-packages (from weaviate-client) (1.2.0)\n",
"Requirement already satisfied: cryptography>=3.2 in /workspaces/langchain/.venv/lib/python3.9/site-packages (from authlib>=1.1.0->weaviate-client) (40.0.2)\n",
"Requirement already satisfied: charset-normalizer<4,>=2 in /workspaces/langchain/.venv/lib/python3.9/site-packages (from requests<2.29.0,>=2.28.0->weaviate-client) (3.1.0)\n",
"Requirement already satisfied: idna<4,>=2.5 in /workspaces/langchain/.venv/lib/python3.9/site-packages (from requests<2.29.0,>=2.28.0->weaviate-client) (3.4)\n",
"Requirement already satisfied: urllib3<1.27,>=1.21.1 in /workspaces/langchain/.venv/lib/python3.9/site-packages (from requests<2.29.0,>=2.28.0->weaviate-client) (1.26.15)\n",
"Requirement already satisfied: certifi>=2017.4.17 in /workspaces/langchain/.venv/lib/python3.9/site-packages (from requests<2.29.0,>=2.28.0->weaviate-client) (2023.5.7)\n",
"Requirement already satisfied: decorator>=3.4.0 in /workspaces/langchain/.venv/lib/python3.9/site-packages (from validators<=0.21.0,>=0.18.2->weaviate-client) (5.1.1)\n",
"Requirement already satisfied: cffi>=1.12 in /workspaces/langchain/.venv/lib/python3.9/site-packages (from cryptography>=3.2->authlib>=1.1.0->weaviate-client) (1.15.1)\n",
"Requirement already satisfied: pycparser in /workspaces/langchain/.venv/lib/python3.9/site-packages (from cffi>=1.12->cryptography>=3.2->authlib>=1.1.0->weaviate-client) (2.21)\n"
"Requirement already satisfied: weaviate-client in /opt/homebrew/lib/python3.11/site-packages (3.23.1)\n",
"Requirement already satisfied: requests<=2.31.0,>=2.28.0 in /opt/homebrew/lib/python3.11/site-packages (from weaviate-client) (2.31.0)\n",
"Requirement already satisfied: validators<=0.21.0,>=0.18.2 in /opt/homebrew/lib/python3.11/site-packages (from weaviate-client) (0.21.0)\n",
"Requirement already satisfied: tqdm<5.0.0,>=4.59.0 in /opt/homebrew/lib/python3.11/site-packages (from weaviate-client) (4.66.1)\n",
"Requirement already satisfied: authlib>=1.1.0 in /opt/homebrew/lib/python3.11/site-packages (from weaviate-client) (1.2.1)\n",
"Requirement already satisfied: cryptography>=3.2 in /opt/homebrew/lib/python3.11/site-packages (from authlib>=1.1.0->weaviate-client) (41.0.4)\n",
"Requirement already satisfied: charset-normalizer<4,>=2 in /opt/homebrew/lib/python3.11/site-packages (from requests<=2.31.0,>=2.28.0->weaviate-client) (2.0.12)\n",
"Requirement already satisfied: idna<4,>=2.5 in /opt/homebrew/lib/python3.11/site-packages (from requests<=2.31.0,>=2.28.0->weaviate-client) (3.4)\n",
"Requirement already satisfied: urllib3<3,>=1.21.1 in /opt/homebrew/lib/python3.11/site-packages (from requests<=2.31.0,>=2.28.0->weaviate-client) (1.26.17)\n",
"Requirement already satisfied: certifi>=2017.4.17 in /opt/homebrew/lib/python3.11/site-packages (from requests<=2.31.0,>=2.28.0->weaviate-client) (2023.7.22)\n",
"Requirement already satisfied: cffi>=1.12 in /opt/homebrew/lib/python3.11/site-packages (from cryptography>=3.2->authlib>=1.1.0->weaviate-client) (1.16.0)\n",
"Requirement already satisfied: pycparser in /opt/homebrew/lib/python3.11/site-packages (from cffi>=1.12->cryptography>=3.2->authlib>=1.1.0->weaviate-client) (2.21)\n",
"\n",
"\u001b[1m[\u001b[0m\u001b[34;49mnotice\u001b[0m\u001b[1;39;49m]\u001b[0m\u001b[39;49m A new release of pip is available: \u001b[0m\u001b[31;49m23.2.1\u001b[0m\u001b[39;49m -> \u001b[0m\u001b[32;49m23.3.1\u001b[0m\n",
"\u001b[1m[\u001b[0m\u001b[34;49mnotice\u001b[0m\u001b[1;39;49m]\u001b[0m\u001b[39;49m To update, run: \u001b[0m\u001b[32;49mpython3.11 -m pip install --upgrade pip\u001b[0m\n"
]
}
],
@@ -48,7 +60,6 @@
]
},
{
"attachments": {},
"cell_type": "markdown",
"id": "6b34828d-e627-4d85-aabd-eeb15d9f4b00",
"metadata": {},
@@ -81,7 +92,7 @@
},
{
"cell_type": "code",
"execution_count": 21,
"execution_count": 4,
"id": "53b7ce2d-3c09-4d1c-b66b-5769ce6746ae",
"metadata": {},
"outputs": [],
@@ -90,9 +101,18 @@
"WEAVIATE_API_KEY = os.environ[\"WEAVIATE_API_KEY\"]"
]
},
{
"cell_type": "markdown",
"id": "b867eb31",
"metadata": {},
"source": [
"## Similarity search\n",
"Below you can see a minimal example of how to approach a simple similarity search."
]
},
{
"cell_type": "code",
"execution_count": 7,
"execution_count": 5,
"id": "aac9563e",
"metadata": {
"tags": []
@@ -107,7 +127,7 @@
},
{
"cell_type": "code",
"execution_count": 12,
"execution_count": 6,
"id": "a3c3999a",
"metadata": {},
"outputs": [],
@@ -124,17 +144,22 @@
},
{
"cell_type": "code",
"execution_count": 14,
"execution_count": 7,
"id": "21e9e528",
"metadata": {},
"outputs": [],
"source": [
"db = Weaviate.from_documents(docs, embeddings, weaviate_url=WEAVIATE_URL, by_text=False)"
"db = Weaviate.from_documents(\n",
" docs, \n",
" embeddings, \n",
" weaviate_url=WEAVIATE_URL, \n",
" by_text=False\n",
")"
]
},
{
"cell_type": "code",
"execution_count": 15,
"execution_count": 8,
"id": "b4170176",
"metadata": {},
"outputs": [],
@@ -145,7 +170,7 @@
},
{
"cell_type": "code",
"execution_count": 16,
"execution_count": 9,
"id": "ecf3b890",
"metadata": {},
"outputs": [
@@ -186,7 +211,7 @@
},
{
"cell_type": "code",
"execution_count": 23,
"execution_count": 10,
"id": "f6604f1d",
"metadata": {},
"outputs": [
@@ -202,7 +227,8 @@
"import weaviate\n",
"\n",
"client = weaviate.Client(\n",
" url=WEAVIATE_URL, auth_client_secret=weaviate.AuthApiKey(WEAVIATE_API_KEY)\n",
" url=WEAVIATE_URL, \n",
" auth_client_secret=weaviate.AuthApiKey(WEAVIATE_API_KEY)\n",
")\n",
"\n",
"# client = weaviate.Client(\n",
@@ -214,7 +240,10 @@
"# )\n",
"\n",
"vectorstore = Weaviate.from_documents(\n",
" documents, embeddings, client=client, by_text=False\n",
" documents, \n",
" embeddings, \n",
" client=client, \n",
" by_text=False\n",
")"
]
},
@@ -239,7 +268,7 @@
},
{
"cell_type": "code",
"execution_count": 17,
"execution_count": 11,
"id": "102105a1",
"metadata": {},
"outputs": [
@@ -265,7 +294,7 @@
"id": "8fc3487b",
"metadata": {},
"source": [
"# Persistence"
"## Persistence"
]
},
{
@@ -273,7 +302,7 @@
"id": "281c0fcc",
"metadata": {},
"source": [
"Anything uploaded to weaviate is automatically persistent into the database. You do not need to call any specific method or pass any param for this to happen."
"Anything uploaded to Weaviate is automatically persistent into the database. You do not need to call any specific method or pass any parameters for this to happen."
]
},
{
@@ -285,14 +314,14 @@
"\n",
"This section goes over different options for how to use Weaviate as a retriever.\n",
"\n",
"### MMR\n",
"### Maximal marginal relevance search (MMR)\n",
"\n",
"In addition to using similarity search in the retriever object, you can also use `mmr`."
]
},
{
"cell_type": "code",
"execution_count": null,
"execution_count": 12,
"id": "8b7df7ae",
"metadata": {},
"outputs": [
@@ -312,12 +341,53 @@
"retriever.get_relevant_documents(query)[0]"
]
},
{
"cell_type": "markdown",
"id": "4b14a3a5",
"metadata": {},
"source": [
"### Hybrid search\n",
"Weaviate also offers hybrid search. See [`WeaviateHybridSearchRetriever`](https://python.langchain.com/docs/integrations/retrievers/weaviate-hybrid) for reference."
]
},
{
"cell_type": "markdown",
"id": "508016e8",
"metadata": {},
"source": [
"## Use cases\n",
"As the following example shows, LLMs don't have access to knowledge outside of their training data. Thus, vector stores come in handy to provide LLMs with additional context."
]
},
{
"cell_type": "code",
"execution_count": 13,
"id": "5299b13b",
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"\"As an AI language model, I don't have real-time information or the ability to browse the internet. Therefore, I cannot provide you with the most recent statements made by the president about Justice Breyer. However, it's worth noting that the president's opinions on Justice Breyer may vary depending on the specific context and time period. It would be best to refer to reliable news sources or official statements to get the most accurate and up-to-date information on this topic.\""
]
},
"execution_count": 13,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"from langchain.chat_models import ChatOpenAI\n",
"llm = ChatOpenAI(model_name=\"gpt-3.5-turbo\", temperature=0)\n",
"llm.predict(\"What did the president say about Justice Breyer\")"
]
},
{
"cell_type": "markdown",
"id": "fbd7a6cb",
"metadata": {},
"source": [
"## Question Answering with Sources"
"### Question Answering with Sources"
]
},
{
@@ -330,7 +400,7 @@
},
{
"cell_type": "code",
"execution_count": null,
"execution_count": 14,
"id": "5e824f3b",
"metadata": {},
"outputs": [],
@@ -341,7 +411,7 @@
},
{
"cell_type": "code",
"execution_count": null,
"execution_count": 15,
"id": "61209cc3",
"metadata": {},
"outputs": [],
@@ -354,7 +424,7 @@
},
{
"cell_type": "code",
"execution_count": null,
"execution_count": 16,
"id": "4abc3d37",
"metadata": {},
"outputs": [],
@@ -370,7 +440,7 @@
},
{
"cell_type": "code",
"execution_count": null,
"execution_count": 17,
"id": "c7062393",
"metadata": {},
"outputs": [],
@@ -382,7 +452,7 @@
},
{
"cell_type": "code",
"execution_count": null,
"execution_count": 18,
"id": "7e41b773",
"metadata": {},
"outputs": [
@@ -404,6 +474,115 @@
" return_only_outputs=True,\n",
")"
]
},
{
"cell_type": "markdown",
"id": "05007f8a",
"metadata": {},
"source": [
"### Retrieval-Augmented Generation"
]
},
{
"cell_type": "code",
"execution_count": 19,
"id": "30f285a1",
"metadata": {},
"outputs": [],
"source": [
"with open(\"../../modules/state_of_the_union.txt\") as f:\n",
" state_of_the_union = f.read()\n",
"text_splitter = CharacterTextSplitter(chunk_size=1000, chunk_overlap=0)\n",
"texts = text_splitter.split_text(state_of_the_union)"
]
},
{
"cell_type": "code",
"execution_count": 20,
"id": "08490f15",
"metadata": {},
"outputs": [],
"source": [
"docsearch = Weaviate.from_texts(\n",
" texts,\n",
" embeddings,\n",
" weaviate_url=WEAVIATE_URL,\n",
" by_text=False,\n",
" metadatas=[{\"source\": f\"{i}-pl\"} for i in range(len(texts))],\n",
")\n",
"\n",
"retriever = docsearch.as_retriever()"
]
},
{
"cell_type": "code",
"execution_count": 21,
"id": "499cb1f5",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"input_variables=['context', 'question'] messages=[HumanMessagePromptTemplate(prompt=PromptTemplate(input_variables=['context', 'question'], template=\"You are an assistant for question-answering tasks. Use the following pieces of retrieved context to answer the question. If you don't know the answer, just say that you don't know. Use three sentences maximum and keep the answer concise.\\nQuestion: {question} \\nContext: {context} \\nAnswer:\\n\"))]\n"
]
}
],
"source": [
"from langchain.prompts import ChatPromptTemplate\n",
"\n",
"template = \"\"\"You are an assistant for question-answering tasks. Use the following pieces of retrieved context to answer the question. If you don't know the answer, just say that you don't know. Use three sentences maximum and keep the answer concise.\n",
"Question: {question} \n",
"Context: {context} \n",
"Answer:\n",
"\"\"\"\n",
"prompt = ChatPromptTemplate.from_template(template)\n",
"\n",
"print(prompt)"
]
},
{
"cell_type": "code",
"execution_count": 22,
"id": "28d95686",
"metadata": {},
"outputs": [],
"source": [
"from langchain.chat_models import ChatOpenAI\n",
"\n",
"llm = ChatOpenAI(model_name=\"gpt-3.5-turbo\", temperature=0)"
]
},
{
"cell_type": "code",
"execution_count": 23,
"id": "c697d0cd",
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"'The president thanked Justice Breyer for his service and dedication to the country.'"
]
},
"execution_count": 23,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"from langchain.schema.runnable import RunnablePassthrough\n",
"from langchain.schema.output_parser import StrOutputParser\n",
"\n",
"rag_chain = (\n",
" {\"context\": retriever, \"question\": RunnablePassthrough()} \n",
" | prompt \n",
" | llm\n",
" | StrOutputParser() \n",
")\n",
"\n",
"rag_chain.invoke(\"What did the president say about Justice Breyer\")"
]
}
],
"metadata": {
@@ -422,7 +601,7 @@
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.10.9"
"version": "3.11.4"
}
},
"nbformat": 4,

View File

@@ -2,21 +2,37 @@
"cells": [
{
"cell_type": "markdown",
"id": "9eb8dfa6fdb71ef5",
"metadata": {
"collapsed": false
},
"source": [
"# Zep\n",
"## VectorStore Example for [Zep](https://docs.getzep.com/) - Fast, scalable building blocks for LLM Apps\n",
"\n",
"Zep is an open-source long-term memory store for LLM applications. Zep makes it easy to add relevant documents,\n",
"chat history memory & rich user data to your LLM app's prompts.\n",
"### More on Zep:\n",
"\n",
"Zep is an open source platform for productionizing LLM apps. Go from a prototype\n",
"built in LangChain or LlamaIndex, or a custom app, to production in minutes without\n",
"rewriting code.\n",
"\n",
"## Fast, Scalable Building Blocks for LLM Apps\n",
"Zep is an open source platform for productionizing LLM apps. Go from a prototype\n",
"built in LangChain or LlamaIndex, or a custom app, to production in minutes without\n",
"rewriting code.\n",
"\n",
"Key Features:\n",
"\n",
"- **Fast!** Zep operates independently of the your chat loop, ensuring a snappy user experience.\n",
"- **Chat History Memory, Archival, and Enrichment**, populate your prompts with relevant chat history, sumamries, named entities, intent data, and more.\n",
"- **Vector Search over Chat History and Documents** Automatic embedding of documents, chat histories, and summaries. Use Zep's similarity or native MMR Re-ranked search to find the most relevant.\n",
"- **Manage Users and their Chat Sessions** Users and their Chat Sessions are first-class citizens in Zep, allowing you to manage user interactions with your bots or agents easily.\n",
"- **Records Retention and Privacy Compliance** Comply with corporate and regulatory mandates for records retention while ensuring compliance with privacy regulations such as CCPA and GDPR. Fulfill *Right To Be Forgotten* requests with a single API call\n",
"\n",
"**Note:** The `ZepVectorStore` works with `Documents` and is intended to be used as a `Retriever`.\n",
"It offers separate functionality to Zep's `ZepMemory` class, which is designed for persisting, enriching\n",
"and searching your user's chat history.\n",
"\n",
"## Why Zep's VectorStore? 🤖🚀\n",
"Zep automatically embeds documents added to the Zep Vector Store using low-latency models local to the Zep server.\n",
"The Zep client also offers async interfaces for all document operations. These two together with Zep's chat memory\n",
" functionality make Zep ideal for building conversational LLM apps where latency and performance are important.\n",
"\n",
"## Installation\n",
"Follow the [Zep Quickstart Guide](https://docs.getzep.com/deployment/quickstart/) to install and get started with Zep.\n",
"\n",
@@ -33,25 +49,29 @@
"- If you pass in an `Embeddings` instance Zep will use this to embed documents rather than auto-embed them.\n",
"You must also set your document collection to `isAutoEmbedded === false`. \n",
"- If you set your collection to `isAutoEmbedded === false`, you must pass in an `Embeddings` instance."
],
"metadata": {
"collapsed": false
},
"id": "9eb8dfa6fdb71ef5"
]
},
{
"cell_type": "markdown",
"source": [
"## Load or create a Collection from documents"
],
"id": "9a3a11aab1412d98",
"metadata": {
"collapsed": false
},
"id": "9a3a11aab1412d98"
"source": [
"## Load or create a Collection from documents"
]
},
{
"cell_type": "code",
"execution_count": 1,
"id": "519418421a32e4d",
"metadata": {
"ExecuteTime": {
"end_time": "2023-08-13T01:07:50.672390Z",
"start_time": "2023-08-13T01:07:48.777799Z"
},
"collapsed": false
},
"outputs": [],
"source": [
"from uuid import uuid4\n",
@@ -91,28 +111,33 @@
" config=config,\n",
" api_url=ZEP_API_URL,\n",
" api_key=ZEP_API_KEY,\n",
" embedding=None, # we'll have Zep embed our documents using its low-latency embedder\n",
")"
],
"metadata": {
"collapsed": false,
"ExecuteTime": {
"end_time": "2023-08-13T01:07:50.672390Z",
"start_time": "2023-08-13T01:07:48.777799Z"
}
},
"id": "519418421a32e4d"
]
},
{
"cell_type": "code",
"execution_count": 2,
"id": "201dc57b124cb6d7",
"metadata": {
"ExecuteTime": {
"end_time": "2023-08-13T01:07:53.807663Z",
"start_time": "2023-08-13T01:07:50.671241Z"
},
"collapsed": false
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Embedding status: 0/402 documents embedded\n",
"Embedding status: 0/402 documents embedded\n",
"Embedding status: 402/402 documents embedded\n"
"Embedding status: 0/401 documents embedded\n",
"Embedding status: 0/401 documents embedded\n",
"Embedding status: 0/401 documents embedded\n",
"Embedding status: 0/401 documents embedded\n",
"Embedding status: 0/401 documents embedded\n",
"Embedding status: 0/401 documents embedded\n",
"Embedding status: 401/401 documents embedded\n"
]
}
],
@@ -138,61 +163,62 @@
"\n",
"\n",
"await wait_for_ready(collection_name)"
],
"metadata": {
"collapsed": false,
"ExecuteTime": {
"end_time": "2023-08-13T01:07:53.807663Z",
"start_time": "2023-08-13T01:07:50.671241Z"
}
},
"id": "201dc57b124cb6d7"
]
},
{
"cell_type": "markdown",
"source": [
"## Simarility Search Query over the Collection"
],
"id": "94ca9dfa7d0ecaa5",
"metadata": {
"collapsed": false
},
"id": "94ca9dfa7d0ecaa5"
"source": [
"## Simarility Search Query over the Collection"
]
},
{
"cell_type": "code",
"execution_count": 3,
"id": "1998de0a96fe89c3",
"metadata": {
"ExecuteTime": {
"end_time": "2023-08-13T01:07:54.195988Z",
"start_time": "2023-08-13T01:07:53.808550Z"
},
"collapsed": false
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Tables necessary to determine the places of the planets are not less\r\n",
"necessary than those for the sun, moon, and stars. Some notion of the\r\n",
"number and complexity of these tables may be formed, when we state that\r\n",
"the positions of the two principal planets, (and these are the most\r\n",
"necessary for the navigator,) Jupiter and Saturn, require each not less\r\n",
"than one hundred and sixteen tables. Yet it is not only necessary to\r\n",
"predict the position of these bodies, but it is likewise expedient to -> 0.8998482592744614 \n",
"the positions of the two principal planets, (and these the most\n",
"necessary for the navigator,) Jupiter and Saturn, require each not less\n",
"than one hundred and sixteen tables. Yet it is not only necessary to\n",
"predict the position of these bodies, but it is likewise expedient to\n",
"tabulate the motions of the four satellites of Jupiter, to predict the\n",
"exact times at which they enter his shadow, and at which their shadows\n",
"cross his disc, as well as the times at which they are interposed -> 0.9003241539387915 \n",
"====\n",
"\n",
"tabulate the motions of the four satellites of Jupiter, to predict the\r\n",
"exact times at which they enter his shadow, and at which their shadows\r\n",
"cross his disc, as well as the times at which they are interposed\r\n",
"between him and the Earth, and he between them and the Earth.\r\n",
"\r\n",
"Among the extensive classes of tables here enumerated, there are several\r\n",
"which are in their nature permanent and unalterable, and would never\r\n",
"require to be recomputed, if they could once be computed with perfect -> 0.8976143854195493 \n",
"furnish more than a small fraction of that aid to navigation (in the\n",
"large sense of that term), which, with greater facility, expedition, and\n",
"economy in the calculation and printing of tables, it might be made to\n",
"supply.\n",
"\n",
"Tables necessary to determine the places of the planets are not less\n",
"necessary than those for the sun, moon, and stars. Some notion of the\n",
"number and complexity of these tables may be formed, when we state that -> 0.8911165633479508 \n",
"====\n",
"\n",
"the scheme of notation thus applied, immediately suggested the\r\n",
"advantages which must attend it as an instrument for expressing the\r\n",
"structure, operation, and circulation of the animal system; and we\r\n",
"entertain no doubt of its adequacy for that purpose. Not only the\r\n",
"mechanical connexion of the solid members of the bodies of men and\r\n",
"animals, but likewise the structure and operation of the softer parts,\r\n",
"including the muscles, integuments, membranes, &c. the nature, motion, -> 0.889982614061763 \n",
"====\n"
"the scheme of notation thus applied, immediately suggested the\n",
"advantages which must attend it as an instrument for expressing the\n",
"structure, operation, and circulation of the animal system; and we\n",
"entertain no doubt of its adequacy for that purpose. Not only the\n",
"mechanical connexion of the solid members of the bodies of men and\n",
"animals, but likewise the structure and operation of the softer parts,\n",
"including the muscles, integuments, membranes, &c. the nature, motion, -> 0.8899750214770481 \n",
"====\n",
"\n"
]
}
],
@@ -204,61 +230,64 @@
"# print results\n",
"for d, s in docs_scores:\n",
" print(d.page_content, \" -> \", s, \"\\n====\\n\")"
],
"metadata": {
"collapsed": false,
"ExecuteTime": {
"end_time": "2023-08-13T01:07:54.195988Z",
"start_time": "2023-08-13T01:07:53.808550Z"
}
},
"id": "1998de0a96fe89c3"
]
},
{
"cell_type": "markdown",
"source": [
"## Search over Collection Re-ranked by MMR"
],
"id": "e02b61a9af0b2c80",
"metadata": {
"collapsed": false
},
"id": "e02b61a9af0b2c80"
"source": [
"## Search over Collection Re-ranked by MMR\n",
"\n",
"Zep offers native, hardware-accelerated MMR re-ranking of search results."
]
},
{
"cell_type": "code",
"execution_count": 4,
"id": "488112da752b1d58",
"metadata": {
"ExecuteTime": {
"end_time": "2023-08-13T01:07:54.394873Z",
"start_time": "2023-08-13T01:07:54.180901Z"
},
"collapsed": false
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Tables necessary to determine the places of the planets are not less\r\n",
"necessary than those for the sun, moon, and stars. Some notion of the\r\n",
"number and complexity of these tables may be formed, when we state that\r\n",
"the positions of the two principal planets, (and these the most\r\n",
"necessary for the navigator,) Jupiter and Saturn, require each not less\r\n",
"than one hundred and sixteen tables. Yet it is not only necessary to\r\n",
"predict the position of these bodies, but it is likewise expedient to \n",
"the positions of the two principal planets, (and these the most\n",
"necessary for the navigator,) Jupiter and Saturn, require each not less\n",
"than one hundred and sixteen tables. Yet it is not only necessary to\n",
"predict the position of these bodies, but it is likewise expedient to\n",
"tabulate the motions of the four satellites of Jupiter, to predict the\n",
"exact times at which they enter his shadow, and at which their shadows\n",
"cross his disc, as well as the times at which they are interposed \n",
"====\n",
"\n",
"the scheme of notation thus applied, immediately suggested the\r\n",
"advantages which must attend it as an instrument for expressing the\r\n",
"structure, operation, and circulation of the animal system; and we\r\n",
"entertain no doubt of its adequacy for that purpose. Not only the\r\n",
"mechanical connexion of the solid members of the bodies of men and\r\n",
"animals, but likewise the structure and operation of the softer parts,\r\n",
"the scheme of notation thus applied, immediately suggested the\n",
"advantages which must attend it as an instrument for expressing the\n",
"structure, operation, and circulation of the animal system; and we\n",
"entertain no doubt of its adequacy for that purpose. Not only the\n",
"mechanical connexion of the solid members of the bodies of men and\n",
"animals, but likewise the structure and operation of the softer parts,\n",
"including the muscles, integuments, membranes, &c. the nature, motion, \n",
"====\n",
"\n",
"tabulate the motions of the four satellites of Jupiter, to predict the\r\n",
"exact times at which they enter his shadow, and at which their shadows\r\n",
"cross his disc, as well as the times at which they are interposed\r\n",
"between him and the Earth, and he between them and the Earth.\r\n",
"\r\n",
"Among the extensive classes of tables here enumerated, there are several\r\n",
"which are in their nature permanent and unalterable, and would never\r\n",
"require to be recomputed, if they could once be computed with perfect \n",
"====\n"
"resistance, economizing time, harmonizing the mechanism, and giving to\n",
"the whole mechanical action the utmost practical perfection.\n",
"\n",
"The system of mechanical contrivances by which the results, here\n",
"attempted to be described, are attained, form only one order of\n",
"expedients adopted in this machinery;--although such is the perfection\n",
"of their action, that in any ordinary case they would be regarded as\n",
"having attained the ends in view with an almost superfluous degree of \n",
"====\n",
"\n"
]
}
],
@@ -268,47 +297,53 @@
"\n",
"for d in docs:\n",
" print(d.page_content, \"\\n====\\n\")"
],
"metadata": {
"collapsed": false,
"ExecuteTime": {
"end_time": "2023-08-13T01:07:54.394873Z",
"start_time": "2023-08-13T01:07:54.180901Z"
}
},
"id": "488112da752b1d58"
]
},
{
"cell_type": "markdown",
"id": "42455e31d4ab0d68",
"metadata": {
"collapsed": false
},
"source": [
"# Filter by Metadata\n",
"\n",
"Use a metadata filter to narrow down results. First, load another book: \"Adventures of Sherlock Holmes\""
],
"metadata": {
"collapsed": false
},
"id": "42455e31d4ab0d68"
]
},
{
"cell_type": "code",
"execution_count": 5,
"id": "146c8a96201c0ab9",
"metadata": {
"ExecuteTime": {
"end_time": "2023-08-13T01:08:06.323569Z",
"start_time": "2023-08-13T01:07:54.381822Z"
},
"collapsed": false
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Embedding status: 402/1692 documents embedded\n",
"Embedding status: 402/1692 documents embedded\n",
"Embedding status: 552/1692 documents embedded\n",
"Embedding status: 702/1692 documents embedded\n",
"Embedding status: 1002/1692 documents embedded\n",
"Embedding status: 1002/1692 documents embedded\n",
"Embedding status: 1152/1692 documents embedded\n",
"Embedding status: 1302/1692 documents embedded\n",
"Embedding status: 1452/1692 documents embedded\n",
"Embedding status: 1602/1692 documents embedded\n",
"Embedding status: 1692/1692 documents embedded\n"
"Embedding status: 401/1691 documents embedded\n",
"Embedding status: 401/1691 documents embedded\n",
"Embedding status: 401/1691 documents embedded\n",
"Embedding status: 401/1691 documents embedded\n",
"Embedding status: 401/1691 documents embedded\n",
"Embedding status: 401/1691 documents embedded\n",
"Embedding status: 901/1691 documents embedded\n",
"Embedding status: 901/1691 documents embedded\n",
"Embedding status: 901/1691 documents embedded\n",
"Embedding status: 901/1691 documents embedded\n",
"Embedding status: 901/1691 documents embedded\n",
"Embedding status: 901/1691 documents embedded\n",
"Embedding status: 1401/1691 documents embedded\n",
"Embedding status: 1401/1691 documents embedded\n",
"Embedding status: 1401/1691 documents embedded\n",
"Embedding status: 1401/1691 documents embedded\n",
"Embedding status: 1691/1691 documents embedded\n"
]
}
],
@@ -325,61 +360,61 @@
"await vs.aadd_documents(docs)\n",
"\n",
"await wait_for_ready(collection_name)"
],
"metadata": {
"collapsed": false,
"ExecuteTime": {
"end_time": "2023-08-13T01:08:06.323569Z",
"start_time": "2023-08-13T01:07:54.381822Z"
}
},
"id": "146c8a96201c0ab9"
]
},
{
"cell_type": "markdown",
"source": [
"### We see results from both books. Note the `source` metadata"
],
"id": "5b225f3ae1e61de8",
"metadata": {
"collapsed": false
},
"id": "5b225f3ae1e61de8"
"source": [
"### We see results from both books. Note the `source` metadata"
]
},
{
"cell_type": "code",
"execution_count": 6,
"id": "53700a9cd817cde4",
"metadata": {
"ExecuteTime": {
"end_time": "2023-08-13T01:08:06.504769Z",
"start_time": "2023-08-13T01:08:06.325435Z"
},
"collapsed": false
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"by that body to Mr Babbage:--'In no department of science, or of the\r\n",
"arts, does this discovery promise to be so eminently useful as in that\r\n",
"of astronomy, and its kindred sciences, with the various arts dependent\r\n",
"on them. In none are computations more operose than those which\r\n",
"astronomy in particular requires;--in none are preparatory facilities\r\n",
"more needful;--in none is error more detrimental. The practical\r\n",
"astronomer is interrupted in his pursuit, and diverted from his task of -> {'source': 'https://www.gutenberg.org/cache/epub/71292/pg71292.txt'} \n",
"or remotely, for this purpose. But in addition to these, a great number\n",
"of tables, exclusively astronomical, are likewise indispensable. The\n",
"predictions of the astronomer, with respect to the positions and motions\n",
"of the bodies of the firmament, are the means, and the only means, which\n",
"enable the mariner to prosecute his art. By these he is enabled to\n",
"discover the distance of his ship from the Line, and the extent of his -> {'source': 'https://www.gutenberg.org/cache/epub/71292/pg71292.txt'} \n",
"====\n",
"\n",
"possess all knowledge which is likely to be useful to him in his work,\r\n",
"and this I have endeavored in my case to do. If I remember rightly, you\r\n",
"on one occasion, in the early days of our friendship, defined my limits\r\n",
"in a very precise fashion.”\r\n",
"\r\n",
"“Yes,” I answered, laughing. “It was a singular document. Philosophy,\r\n",
"astronomy, and politics were marked at zero, I remember. Botany\r\n",
"possess all knowledge which is likely to be useful to him in his work,\n",
"and this I have endeavored in my case to do. If I remember rightly, you\n",
"on one occasion, in the early days of our friendship, defined my limits\n",
"in a very precise fashion.”\n",
"\n",
"“Yes,” I answered, laughing. “It was a singular document. Philosophy,\n",
"astronomy, and politics were marked at zero, I remember. Botany\n",
"variable, geology profound as regards the mud-stains from any region -> {'source': 'https://www.gutenberg.org/files/48320/48320-0.txt'} \n",
"====\n",
"\n",
"in all its relations; but above all, with Astronomy and Navigation. So\r\n",
"important have they been considered, that in many instances large sums\r\n",
"have been appropriated by the most enlightened nations in the production\r\n",
"of them; and yet so numerous and insurmountable have been the\r\n",
"difficulties attending the attainment of this end, that after all, even\r\n",
"navigators, putting aside every other department of art and science,\r\n",
"have, until very recently, been scantily and imperfectly supplied with -> {'source': 'https://www.gutenberg.org/cache/epub/71292/pg71292.txt'} \n",
"====\n"
"of astronomy, and its kindred sciences, with the various arts dependent\n",
"on them. In none are computations more operose than those which\n",
"astronomy in particular requires;--in none are preparatory facilities\n",
"more needful;--in none is error more detrimental. The practical\n",
"astronomer is interrupted in his pursuit, and diverted from his task of\n",
"observation by the irksome labours of computation, or his diligence in\n",
"observing becomes ineffectual for want of yet greater industry of -> {'source': 'https://www.gutenberg.org/cache/epub/71292/pg71292.txt'} \n",
"====\n",
"\n"
]
}
],
@@ -389,73 +424,76 @@
"\n",
"for d in docs:\n",
" print(d.page_content, \" -> \", d.metadata, \"\\n====\\n\")"
],
"metadata": {
"collapsed": false,
"ExecuteTime": {
"end_time": "2023-08-13T01:08:06.504769Z",
"start_time": "2023-08-13T01:08:06.325435Z"
}
},
"id": "53700a9cd817cde4"
]
},
{
"cell_type": "markdown",
"source": [
"### Let's try again using a filter for only the Sherlock Holmes document."
],
"id": "7b81d7cae351a1ec",
"metadata": {
"collapsed": false
},
"id": "7b81d7cae351a1ec"
"source": [
"### Let's try again using a filter for only the Sherlock Holmes document."
]
},
{
"cell_type": "code",
"execution_count": 7,
"id": "8f1bdcba03979d22",
"metadata": {
"ExecuteTime": {
"end_time": "2023-08-13T01:08:06.672836Z",
"start_time": "2023-08-13T01:08:06.505944Z"
},
"collapsed": false
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"possess all knowledge which is likely to be useful to him in his work,\r\n",
"and this I have endeavored in my case to do. If I remember rightly, you\r\n",
"on one occasion, in the early days of our friendship, defined my limits\r\n",
"in a very precise fashion.”\r\n",
"\r\n",
"“Yes,” I answered, laughing. “It was a singular document. Philosophy,\r\n",
"astronomy, and politics were marked at zero, I remember. Botany\r\n",
"possess all knowledge which is likely to be useful to him in his work,\n",
"and this I have endeavored in my case to do. If I remember rightly, you\n",
"on one occasion, in the early days of our friendship, defined my limits\n",
"in a very precise fashion.”\n",
"\n",
"“Yes,” I answered, laughing. “It was a singular document. Philosophy,\n",
"astronomy, and politics were marked at zero, I remember. Botany\n",
"variable, geology profound as regards the mud-stains from any region -> {'source': 'https://www.gutenberg.org/files/48320/48320-0.txt'} \n",
"====\n",
"\n",
"the light shining upon his strong-set aquiline features. So he sat as I\r\n",
"dropped off to sleep, and so he sat when a sudden ejaculation caused me\r\n",
"to wake up, and I found the summer sun shining into the apartment. The\r\n",
"pipe was still between his lips, the smoke still curled upward, and the\r\n",
"room was full of a dense tobacco haze, but nothing remained of the heap\r\n",
"of shag which I had seen upon the previous night.\r\n",
"\r\n",
"“Awake, Watson?” he asked.\r\n",
"\r\n",
"“Yes.”\r\n",
"\r\n",
"the light shining upon his strong-set aquiline features. So he sat as I\n",
"dropped off to sleep, and so he sat when a sudden ejaculation caused me\n",
"to wake up, and I found the summer sun shining into the apartment. The\n",
"pipe was still between his lips, the smoke still curled upward, and the\n",
"room was full of a dense tobacco haze, but nothing remained of the heap\n",
"of shag which I had seen upon the previous night.\n",
"\n",
"“Awake, Watson?” he asked.\n",
"\n",
"“Yes.”\n",
"\n",
"“Game for a morning drive?” -> {'source': 'https://www.gutenberg.org/files/48320/48320-0.txt'} \n",
"====\n",
"\n",
"“I glanced at the books upon the table, and in spite of my ignorance\r\n",
"of German I could see that two of them were treatises on science, the\r\n",
"others being volumes of poetry. Then I walked across to the window,\r\n",
"hoping that I might catch some glimpse of the country-side, but an oak\r\n",
"shutter, heavily barred, was folded across it. It was a wonderfully\r\n",
"silent house. There was an old clock ticking loudly somewhere in the\r\n",
"“I glanced at the books upon the table, and in spite of my ignorance\n",
"of German I could see that two of them were treatises on science, the\n",
"others being volumes of poetry. Then I walked across to the window,\n",
"hoping that I might catch some glimpse of the country-side, but an oak\n",
"shutter, heavily barred, was folded across it. It was a wonderfully\n",
"silent house. There was an old clock ticking loudly somewhere in the\n",
"passage, but otherwise everything was deadly still. A vague feeling of -> {'source': 'https://www.gutenberg.org/files/48320/48320-0.txt'} \n",
"====\n"
"====\n",
"\n"
]
}
],
"source": [
"filter = {\n",
" \"where\": {\n",
" \"jsonpath\": \"$[*] ? (@.source == 'https://www.gutenberg.org/files/48320/48320-0.txt')\"\n",
" \"jsonpath\": (\n",
" \"$[*] ? (@.source == 'https://www.gutenberg.org/files/48320/48320-0.txt')\"\n",
" )\n",
" },\n",
"}\n",
"\n",
@@ -463,15 +501,15 @@
"\n",
"for d in docs:\n",
" print(d.page_content, \" -> \", d.metadata, \"\\n====\\n\")"
],
"metadata": {
"collapsed": false,
"ExecuteTime": {
"end_time": "2023-08-13T01:08:06.672836Z",
"start_time": "2023-08-13T01:08:06.505944Z"
}
},
"id": "8f1bdcba03979d22"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "96132aa6",
"metadata": {},
"outputs": [],
"source": []
}
],
"metadata": {
@@ -483,14 +521,14 @@
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 2
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython2",
"version": "2.7.6"
"pygments_lexer": "ipython3",
"version": "3.11.6"
}
},
"nbformat": 4,

View File

Before

Width:  |  Height:  |  Size: 766 KiB

After

Width:  |  Height:  |  Size: 766 KiB

View File

Before

Width:  |  Height:  |  Size: 815 KiB

After

Width:  |  Height:  |  Size: 815 KiB

View File

@@ -1,11 +1,13 @@
# LangSmith
---
sidebar_class_name: hidden
---
import DocCardList from "@theme/DocCardList";
# LangSmith
[LangSmith](https://smith.langchain.com) helps you trace and evaluate your language model applications and intelligent agents to help you
move from prototype to production.
Check out the [interactive walkthrough](/docs/guides/langsmith/walkthrough) below to get started.
Check out the [interactive walkthrough](/docs/langsmith/walkthrough) to get started.
For more information, please refer to the [LangSmith documentation](https://docs.smith.langchain.com/).
@@ -18,5 +20,3 @@ check out the [LangSmith Cookbook](https://github.com/langchain-ai/langsmith-coo
- How to fine-tune a LLM on real usage data ([link](https://github.com/langchain-ai/langsmith-cookbook/blob/main/fine-tuning-examples/export-to-openai/fine-tuning-on-chat-runs.ipynb)).
- How to use the [LangChain Hub](https://smith.langchain.com/hub) to version your prompts ([link](https://github.com/langchain-ai/langsmith-cookbook/blob/main/hub-examples/retrieval-qa-chain/retrieval-qa.ipynb))
<DocCardList />

View File

@@ -8,7 +8,7 @@
},
"source": [
"# LangSmith Walkthrough\n",
"[![Open In Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/langchain-ai/langchain/blob/master/docs/docs/guides/langsmith/walkthrough.ipynb)\n",
"[![Open In Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/langchain-ai/langchain/blob/master/docs/docs/langsmith/walkthrough.ipynb)\n",
"\n",
"LangChain makes it easy to prototype LLM applications and Agents. However, delivering LLM applications to production can be deceptively difficult. You will likely have to heavily customize and iterate on your prompts, chains, and other components to create a high-quality product.\n",
"\n",
@@ -140,7 +140,7 @@
"source": [
"from langchain import hub\n",
"from langchain.agents import AgentExecutor\n",
"from langchain.agents.format_scratchpad import format_to_openai_functions\n",
"from langchain.agents.format_scratchpad import format_to_openai_function_messages\n",
"from langchain.agents.output_parsers import OpenAIFunctionsAgentOutputParser\n",
"from langchain.chat_models import ChatOpenAI\n",
"from langchain.tools import DuckDuckGoSearchResults\n",
@@ -165,7 +165,7 @@
"runnable_agent = (\n",
" {\n",
" \"input\": lambda x: x[\"input\"],\n",
" \"agent_scratchpad\": lambda x: format_to_openai_functions(\n",
" \"agent_scratchpad\": lambda x: format_to_openai_function_messages(\n",
" x[\"intermediate_steps\"]\n",
" ),\n",
" }\n",
@@ -335,7 +335,7 @@
"source": [
"from langchain.chat_models import ChatOpenAI\n",
"from langchain.agents import AgentType, initialize_agent, load_tools, AgentExecutor\n",
"from langchain.agents.format_scratchpad import format_to_openai_functions\n",
"from langchain.agents.format_scratchpad import format_to_openai_function_messages\n",
"from langchain.agents.output_parsers import OpenAIFunctionsAgentOutputParser\n",
"from langchain.tools.render import format_tool_to_openai_function\n",
"from langchain import hub\n",
@@ -351,7 +351,7 @@
" runnable_agent = (\n",
" {\n",
" \"input\": lambda x: x[\"input\"],\n",
" \"agent_scratchpad\": lambda x: format_to_openai_functions(\n",
" \"agent_scratchpad\": lambda x: format_to_openai_function_messages(\n",
" x[\"intermediate_steps\"]\n",
" ),\n",
" }\n",
@@ -790,7 +790,7 @@
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.11.2"
"version": "3.9.1"
}
},
"nbformat": 4,

View File

@@ -38,7 +38,7 @@ It uses the ReAct framework to decide which tool to use, and uses memory to reme
## [Self-ask with search](/docs/modules/agents/agent_types/self_ask_with_search)
This agent utilizes a single tool that should be named `Intermediate Answer`.
This tool should be able to lookup factual answers to questions. This agent
This tool should be able to look up factual answers to questions. This agent
is equivalent to the original [self-ask with search paper](https://ofir.io/self-ask.pdf),
where a Google search API was provided as the tool.
@@ -46,7 +46,7 @@ where a Google search API was provided as the tool.
This agent uses the ReAct framework to interact with a docstore. Two tools must
be provided: a `Search` tool and a `Lookup` tool (they must be named exactly as so).
The `Search` tool should search for a document, while the `Lookup` tool should lookup
The `Search` tool should search for a document, while the `Lookup` tool should look up
a term in the most recently found document.
This agent is equivalent to the
original [ReAct paper](https://arxiv.org/pdf/2210.03629.pdf), specifically the Wikipedia example.

View File

@@ -143,7 +143,7 @@
"metadata": {},
"outputs": [],
"source": [
"from langchain.agents.format_scratchpad import format_to_openai_functions\n",
"from langchain.agents.format_scratchpad import format_to_openai_function_messages\n",
"from langchain.agents.output_parsers import OpenAIFunctionsAgentOutputParser"
]
},
@@ -157,7 +157,7 @@
"agent = (\n",
" {\n",
" \"input\": lambda x: x[\"input\"],\n",
" \"agent_scratchpad\": lambda x: format_to_openai_functions(\n",
" \"agent_scratchpad\": lambda x: format_to_openai_function_messages(\n",
" x[\"intermediate_steps\"]\n",
" ),\n",
" }\n",

View File

@@ -115,9 +115,7 @@
"cell_type": "code",
"execution_count": 6,
"id": "ba8e4cbe",
"metadata": {
"scrolled": false
},
"metadata": {},
"outputs": [
{
"name": "stdout",
@@ -254,9 +252,7 @@
"cell_type": "code",
"execution_count": 19,
"id": "4362ebc7",
"metadata": {
"scrolled": false
},
"metadata": {},
"outputs": [
{
"name": "stdout",
@@ -458,7 +454,7 @@
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.10.1"
"version": "3.9.1"
}
},
"nbformat": 4,

View File

@@ -0,0 +1,250 @@
{
"cells": [
{
"cell_type": "markdown",
"id": "e10aa932",
"metadata": {},
"source": [
"# OpenAI tools\n",
"\n",
"With LCEL we can easily construct agents that take advantage of [OpenAI parallel function calling](https://platform.openai.com/docs/guides/function-calling/parallel-function-calling) (a.k.a. tool calling)."
]
},
{
"cell_type": "code",
"execution_count": 1,
"id": "ec89be68",
"metadata": {},
"outputs": [],
"source": [
"# !pip install -U openai duckduckgo-search"
]
},
{
"cell_type": "code",
"execution_count": 2,
"id": "b812b982",
"metadata": {},
"outputs": [],
"source": [
"from langchain.agents import initialize_agent, AgentExecutor, AgentType, Tool\n",
"from langchain.agents.format_scratchpad.openai_tools import (\n",
" format_to_openai_tool_messages,\n",
")\n",
"from langchain.agents.output_parsers.openai_tools import OpenAIToolsAgentOutputParser\n",
"from langchain.chat_models import ChatOpenAI\n",
"from langchain.prompts import ChatPromptTemplate, MessagesPlaceholder\n",
"from langchain.tools import DuckDuckGoSearchRun, BearlyInterpreterTool\n",
"from langchain.tools.render import format_tool_to_openai_tool"
]
},
{
"cell_type": "markdown",
"id": "6ef71dfc-074b-409a-8451-863feef937ae",
"metadata": {},
"source": [
"## Tools\n",
"\n",
"For this agent let's give it the ability to search [DuckDuckGo](/docs/integrations/tools/ddg) and use [Bearly's code interpreter](/docs/integrations/tools/bearly). You'll need a Bearly API key, which you can [get here](https://bearly.ai/dashboard)."
]
},
{
"cell_type": "code",
"execution_count": 24,
"id": "23fc0aa6",
"metadata": {},
"outputs": [],
"source": [
"lc_tools = [DuckDuckGoSearchRun(), BearlyInterpreterTool(api_key=\"...\").as_tool()]\n",
"oai_tools = [format_tool_to_openai_tool(tool) for tool in lc_tools]"
]
},
{
"cell_type": "markdown",
"id": "90c293df-ce11-4600-b912-e937215ec644",
"metadata": {},
"source": [
"## Prompt template\n",
"\n",
"We need to make sure we have a user input message and an \"agent_scratchpad\" messages placeholder, which is where the AgentExecutor will track AI messages invoking tools and Tool messages returning the tool output."
]
},
{
"cell_type": "code",
"execution_count": 18,
"id": "55292bed",
"metadata": {},
"outputs": [],
"source": [
"prompt = ChatPromptTemplate.from_messages(\n",
" [\n",
" (\"system\", \"You are a helpful assistant\"),\n",
" (\"user\", \"{input}\"),\n",
" MessagesPlaceholder(variable_name=\"agent_scratchpad\"),\n",
" ]\n",
")"
]
},
{
"cell_type": "markdown",
"id": "32904250-c53e-415e-abdf-7ce8b1357fb7",
"metadata": {},
"source": [
"## Model\n",
"\n",
"Only certain models support parallel function calling, so make sure you're using a compatible model."
]
},
{
"cell_type": "code",
"execution_count": 19,
"id": "552421b3",
"metadata": {},
"outputs": [],
"source": [
"llm = ChatOpenAI(temperature=0, model=\"gpt-3.5-turbo-1106\")"
]
},
{
"cell_type": "markdown",
"id": "6fc73aa5-e185-4c6a-8770-1279c3ae5530",
"metadata": {},
"source": [
"## Agent\n",
"\n",
"We use the `OpenAIToolsAgentOutputParser` to convert the tool calls returned by the model into `AgentAction`s objects that our `AgentExecutor` can then route to the appropriate tool."
]
},
{
"cell_type": "code",
"execution_count": 20,
"id": "bf514eb4",
"metadata": {},
"outputs": [],
"source": [
"agent = (\n",
" {\n",
" \"input\": lambda x: x[\"input\"],\n",
" \"agent_scratchpad\": lambda x: format_to_openai_tool_messages(\n",
" x[\"intermediate_steps\"]\n",
" ),\n",
" }\n",
" | prompt\n",
" | llm.bind(tools=oai_tools)\n",
" | OpenAIToolsAgentOutputParser()\n",
")"
]
},
{
"cell_type": "markdown",
"id": "ea032e1c-523d-4509-a008-e693529324be",
"metadata": {},
"source": [
"## Agent executor"
]
},
{
"cell_type": "code",
"execution_count": 21,
"id": "bdc7e506",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"['memory', 'callbacks', 'callback_manager', 'verbose', 'tags', 'metadata', 'agent', 'tools', 'return_intermediate_steps', 'max_iterations', 'max_execution_time', 'early_stopping_method', 'handle_parsing_errors', 'trim_intermediate_steps']\n"
]
}
],
"source": [
"agent_executor = AgentExecutor(agent=agent, tools=lc_tools, verbose=True)"
]
},
{
"cell_type": "code",
"execution_count": 22,
"id": "2cd65218",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"\n",
"\n",
"\u001b[1m> Entering new AgentExecutor chain...\u001b[0m\n",
"\u001b[32;1m\u001b[1;3m\n",
"Invoking: `duckduckgo_search` with `average temperature in Los Angeles today`\n",
"\n",
"\n",
"\u001b[0m\u001b[36;1m\u001b[1;3mNext week, there is a growing potential for 1 to 2 storms Tuesday through Friday bringing a 90% chance of rain to the area. There is a 50% chance of a moderate storm with 1 to 3 inches of total rainfall, and a 10% chance of a major storm of 3 to 6+ inches. Quick Facts Today's weather: Sunny, windy Beaches: 70s-80s Mountains: 60s-70s/63-81 Inland: 70s Warnings and advisories: Red Flag Warning, Wind Advisory Todays highs along the coast will be in... yesterday temp 66.6 °F Surf Forecast in Los Angeles for today Another important indicators for a comfortable holiday on the beach are the presence and height of the waves, as well as the speed and direction of the wind. Please find below data on the swell size for Los Angeles. Daily max (°C) 19 JAN 18 FEB 19 MAR 20 APR 21 MAY 22 JUN 24 JUL 24 AUG 24 SEP 23 OCT 21 NOV 19 DEC Rainfall (mm) 61 JAN 78° | 53° 60 °F like 60° Clear N 0 Today's temperature is forecast to be NEARLY THE SAME as yesterday. Radar Satellite WunderMap |Nexrad Today Wed 11/08 High 78 °F 0% Precip. / 0.00 in Sunny....\u001b[0m\u001b[32;1m\u001b[1;3m\n",
"Invoking: `duckduckgo_search` with `average temperature in New York City today`\n",
"\n",
"\n",
"\u001b[0m\u001b[36;1m\u001b[1;3mWeather Underground provides local & long-range weather forecasts, weatherreports, maps & tropical weather conditions for the New York City area. ... Today Tue 11/07 High 68 ... Climate Central's prediction for an even more distant date — 2100 — is that the average temperature in 247 cities across the country will be 8 degrees higher than it is now. New York will ... Extended Forecast for New York NY Similar City Names Overnight Mostly Cloudy Low: 48 °F Saturday Partly Sunny High: 58 °F Saturday Night Mostly Cloudy Low: 48 °F Sunday Mostly Sunny High: 64 °F Sunday Night Mostly Clear Low: 45 °F Monday Weather report for New York City. Night and day a few clouds are expected. It is a sunny day. Temperatures peaking at 62 °F. During the night and in the first hours of the day blows a light breeze (4 to 8 mph). For the afternoon a gentle breeze is expected (8 to 12 mph). Graphical Climatology of New York Central Park - Daily Temperatures, Precipitation, and Snowfall (1869 - Present) The following is a graphical climatology of New York Central Park daily temperatures, precipitation, and snowfall, from January 1869 into 2023. The graphics consist of summary overview charts (in some cases including data back into the late 1860's) followed […]\u001b[0m\u001b[32;1m\u001b[1;3m\n",
"Invoking: `duckduckgo_search` with `average temperature in San Francisco today`\n",
"\n",
"\n",
"\u001b[0m\u001b[36;1m\u001b[1;3mToday Hourly 10-Day Calendar History Wundermap access_time 10:24 PM PST on November 4, 2023 (GMT -8) | Updated 1 day ago 63° | 48° 59 °F like 59° Partly Cloudy N 0 Today's temperature is... The National Weather Service forecast for the greater San Francisco Bay Area on Thursday calls for clouds increasing over the region during the day. Daytime highs are expected to be in the 60s on ... San Francisco (United States of America) weather - Met Office Today 17° 9° Sunny. Sunrise: 06:41 Sunset: 17:05 M UV Wed 8 Nov 19° 8° Thu 9 Nov 16° 9° Fri 10 Nov 16° 10° Sat 11 Nov 18° 9° Sun 12... Today's weather in San Francisco Bay. The sun rose at 6:42am and the sunset will be at 5:04pm. There will be 10 hours and 22 minutes of sun and the average temperature is 54°F. At the moment water temperature is 58°F and the average water temperature is 58°F. Wintry Impacts in Alaska and New England; Critical Fire Conditions in Southern California. A winter storm continues to bring hazardous travel conditions to south-central Alaska with heavy snow, a wintry mix, ice accumulation, and rough seas. A wintry mix including freezing rain is expected in Upstate New York and interior New England.\u001b[0m\u001b[32;1m\u001b[1;3m\n",
"Invoking: `duckduckgo_search` with `current temperature in Los Angeles`\n",
"responded: It seems that the search results did not provide the specific average temperatures for today in Los Angeles, New York City, and San Francisco. Let me try another approach to gather this information for you.\n",
"\n",
"\u001b[0m\u001b[36;1m\u001b[1;3mFire Weather Show Caption Click a location below for detailed forecast. Last Map Update: Tue, Nov. 7, 2023 at 5:03:23 pm PST Watches, Warnings & Advisories Zoom Out Gale Warning Small Craft Advisory Wind Advisory Fire Weather Watch Text Product Selector (Selected product opens in current window) Hazards Observations Marine Weather Fire Weather 78° | 53° 60 °F like 60° Clear N 0 Today's temperature is forecast to be NEARLY THE SAME as yesterday. Radar Satellite WunderMap |Nexrad Today Wed 11/08 High 78 °F 0% Precip. / 0.00 in Sunny.... Los Angeles and Orange counties will see a few clouds in the morning, but they'll clear up in the afternoon to bring a high of 76 degrees. Daytime temperatures should stay in the 70s most of... Weather Forecast Office NWS Forecast Office Los Angeles, CA Weather.gov > Los Angeles, CA Current Hazards Current Conditions Radar Forecasts Rivers and Lakes Climate and Past Weather Local Programs Click a location below for detailed forecast. Last Map Update: Fri, Oct. 13, 2023 at 12:44:23 am PDT Watches, Warnings & Advisories Zoom Out Want a minute-by-minute forecast for Los-Angeles, CA? MSN Weather tracks it all, from precipitation predictions to severe weather warnings, air quality updates, and even wildfire alerts.\u001b[0m\u001b[32;1m\u001b[1;3m\n",
"Invoking: `duckduckgo_search` with `current temperature in New York City`\n",
"responded: It seems that the search results did not provide the specific average temperatures for today in Los Angeles, New York City, and San Francisco. Let me try another approach to gather this information for you.\n",
"\n",
"\u001b[0m\u001b[36;1m\u001b[1;3mCurrent Weather for Popular Cities . San Francisco, CA 55 ... New York City, NY Weather Conditions star_ratehome. 55 ... Low: 47°F Sunday Mostly Sunny High: 62°F change location New York, NY Weather Forecast Office NWS Forecast Office New York, NY Weather.gov > New York, NY Current Hazards Current Conditions Radar Forecasts Rivers and Lakes Climate and Past Weather Local Programs Click a location below for detailed forecast. Today Increasing Clouds High: 50 °F Tonight Mostly Cloudy Low: 47 °F Thursday Slight Chance Rain High: 67 °F Thursday Night Mostly Cloudy Low: 48 °F Friday Mostly Cloudy then Slight Chance Rain High: 54 °F Friday Weather report for New York City Night and day a few clouds are expected. It is a sunny day. Temperatures peaking at 62 °F. During the night and in the first hours of the day blows a light breeze (4 to 8 mph). For the afternoon a gentle breeze is expected (8 to 12 mph). Today 13 October, weather in New York City +61°F. Clear sky, Light Breeze, Northwest 5.1 mph. Atmosphere pressure 29.9 inHg. Relative humidity 45%. Tomorrow's night air temperature will drop to +54°F, wind will change to North 2.7 mph. Pressure will remain unchanged 29.9 inHg. Day temperature will remain unchanged +54°F, and night 15 October ...\u001b[0m\u001b[32;1m\u001b[1;3m\n",
"Invoking: `duckduckgo_search` with `current temperature in San Francisco`\n",
"responded: It seems that the search results did not provide the specific average temperatures for today in Los Angeles, New York City, and San Francisco. Let me try another approach to gather this information for you.\n",
"\n",
"\u001b[0m\u001b[36;1m\u001b[1;3m59 °F like 59° Partly Cloudy N 0 Today's temperature is forecast to be COOLER than yesterday. Radar Satellite WunderMap |Nexrad Today Thu 11/09 High 63 °F 3% Precip. / 0.00 in A mix of clouds and... Weather Forecast Office NWS Forecast Office San Francisco, CA Weather.gov > San Francisco Bay Area, CA Current Hazards Current Conditions Radar Forecasts Rivers and Lakes Climate and Past Weather Local Programs Click a location below for detailed forecast. Last Map Update: Wed, Nov. 8, 2023 at 5:03:31 am PST Watches, Warnings & Advisories Zoom Out The weather right now in San Francisco, CA is Cloudy. The current temperature is 62°F, and the expected high and low for today, Sunday, November 5, 2023, are 67° high temperature and 57°F low temperature. The wind is currently blowing at 5 miles per hour, and coming from the South Southwest. The wind is gusting to 5 mph. With the wind and ... San Francisco 7 day weather forecast including weather warnings, temperature, rain, wind, visibility, humidity and UV National - Current Temperatures National - First Alert Doppler Latest Stories More ... San Francisco's 'Rev. G' honored with national Jefferson Award for service, seeking peace\u001b[0m\u001b[32;1m\u001b[1;3m\n",
"Invoking: `bearly_interpreter` with `{'python_code': '(78 + 53 + 55) / 3'}`\n",
"\n",
"\n",
"\u001b[0m\u001b[33;1m\u001b[1;3m{'stdout': '', 'stderr': '', 'fileLinks': [], 'exitCode': 0}\u001b[0m\u001b[32;1m\u001b[1;3mThe average of the temperatures in Los Angeles, New York City, and San Francisco today is approximately 62 degrees Fahrenheit.\u001b[0m\n",
"\n",
"\u001b[1m> Finished chain.\u001b[0m\n"
]
},
{
"data": {
"text/plain": [
"{'input': \"What's the average of the temperatures in LA, NYC, and SF today?\",\n",
" 'output': 'The average of the temperatures in Los Angeles, New York City, and San Francisco today is approximately 62 degrees Fahrenheit.'}"
]
},
"execution_count": 22,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"agent_executor.invoke(\n",
" {\"input\": \"What's the average of the temperatures in LA, NYC, and SF today?\"}\n",
")"
]
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3 (ipykernel)",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.9.1"
}
},
"nbformat": 4,
"nbformat_minor": 5
}

View File

@@ -205,7 +205,7 @@
"\n",
"- prompt: a simple prompt with placeholders for the user's question and then the `agent_scratchpad` (any intermediate steps)\n",
"- tools: we can attach the tools and `Response` format to the LLM as functions\n",
"- format scratchpad: in order to format the `agent_scratchpad` from intermediate steps, we will use the standard `format_to_openai_functions`. This takes intermediate steps and formats them as AIMessages and FunctionMessages.\n",
"- format scratchpad: in order to format the `agent_scratchpad` from intermediate steps, we will use the standard `format_to_openai_function_messages`. This takes intermediate steps and formats them as AIMessages and FunctionMessages.\n",
"- output parser: we will use our custom parser above to parse the response of the LLM\n",
"- AgentExecutor: we will use the standard AgentExecutor to run the loop of agent-tool-agent-tool..."
]
@@ -220,7 +220,7 @@
"from langchain.prompts import ChatPromptTemplate, MessagesPlaceholder\n",
"from langchain.chat_models import ChatOpenAI\n",
"from langchain.tools.render import format_tool_to_openai_function\n",
"from langchain.agents.format_scratchpad import format_to_openai_functions\n",
"from langchain.agents.format_scratchpad import format_to_openai_function_messages\n",
"from langchain.agents import AgentExecutor"
]
},
@@ -278,7 +278,7 @@
" {\n",
" \"input\": lambda x: x[\"input\"],\n",
" # Format agent scratchpad from intermediate steps\n",
" \"agent_scratchpad\": lambda x: format_to_openai_functions(\n",
" \"agent_scratchpad\": lambda x: format_to_openai_function_messages(\n",
" x[\"intermediate_steps\"]\n",
" ),\n",
" }\n",

View File

@@ -1,4 +1,4 @@
# Custom LLM agent
# Custom LLM Agent
This notebook goes through how to create your own custom LLM agent.

View File

@@ -1,13 +1,13 @@
# Custom LLM Agent (with a ChatModel)
# Custom LLM Chat Agent
This notebook goes through how to create your own custom agent based on a chat model.
This notebook explains how to create your own custom agent based on a chat model.
An LLM chat agent consists of three parts:
An LLM chat agent consists of four key components:
- `PromptTemplate`: This is the prompt template that can be used to instruct the language model on what to do
- `ChatModel`: This is the language model that powers the agent
- `stop` sequence: Instructs the LLM to stop generating as soon as this string is found
- `OutputParser`: This determines how to parse the LLM output into an `AgentAction` or `AgentFinish` object
- `PromptTemplate`: This is the prompt template that instructs the language model on what to do.
- `ChatModel`: This is the language model that powers the agent.
- `stop` sequence: Instructs the LLM to stop generating as soon as this string is found.
- `OutputParser`: This determines how to parse the LLM output into an `AgentAction` or `AgentFinish` object.
The LLM Agent is used in an `AgentExecutor`. This `AgentExecutor` can largely be thought of as a loop that:
1. Passes user input and any previous steps to the Agent (in this case, the LLM Agent)

View File

@@ -3,7 +3,7 @@
This walkthrough demonstrates how to replicate the [MRKL](https://arxiv.org/pdf/2205.00445.pdf) system using agents.
This uses the example Chinook database.
To set it up follow the instructions on https://database.guide/2-sample-databases-sqlite/, placing the `.db` file in a notebooks folder at the root of this repository.
To set it up, follow the instructions on https://database.guide/2-sample-databases-sqlite/ and place the `.db` file in a "notebooks" folder at the root of this repository.
```python
from langchain.chains import LLMMathChain
@@ -127,7 +127,7 @@ mrkl.run("What is the full name of the artist who recently released an album cal
</CodeOutputBlock>
## With a chat model
## Using a Chat Model
```python
from langchain.chat_models import ChatOpenAI

View File

@@ -0,0 +1,670 @@
{
"cells": [
{
"cell_type": "raw",
"id": "97e00fdb-f771-473f-90fc-d6038e19fd9a",
"metadata": {},
"source": [
"---\n",
"sidebar_position: 3\n",
"sidebar_class_name: hidden\n",
"title: Agents\n",
"---"
]
},
{
"cell_type": "markdown",
"id": "f4c03f40-1328-412d-8a48-1db0cd481b77",
"metadata": {},
"source": [
"The core idea of agents is to use a language model to choose a sequence of actions to take.\n",
"In chains, a sequence of actions is hardcoded (in code).\n",
"In agents, a language model is used as a reasoning engine to determine which actions to take and in which order.\n",
"\n",
"## Concepts\n",
"There are several key components here:\n",
"\n",
"### Agent\n",
"\n",
"This is the chain responsible for deciding what step to take next.\n",
"This is powered by a language model and a prompt.\n",
"The inputs to this chain are:\n",
"\n",
"1. Tools: Descriptions of available tools\n",
"2. User input: The high level objective\n",
"3. Intermediate steps: Any (action, tool output) pairs previously executed in order to achieve the user input\n",
"\n",
"The output is the next action(s) to take or the final response to send to the user (`AgentAction`s or `AgentFinish`). An action specifies a tool and the input to that tool. \n",
"\n",
"Different agents have different prompting styles for reasoning, different ways of encoding inputs, and different ways of parsing the output.\n",
"For a full list of built-in agents see [agent types](/docs/modules/agents/agent_types/).\n",
"You can also **easily build custom agents**, which we show how to do in the Get started section below.\n",
"\n",
"### Tools\n",
"\n",
"Tools are functions that an agent can invoke.\n",
"There are two important design considerations around tools:\n",
"\n",
"1. Giving the agent access to the right tools\n",
"2. Describing the tools in a way that is most helpful to the agent\n",
"\n",
"Without thinking through both, you won't be able to build a working agent.\n",
"If you don't give the agent access to a correct set of tools, it will never be able to accomplish the objectives you give it.\n",
"If you don't describe the tools well, the agent won't know how to use them properly.\n",
"\n",
"LangChain provides a wide set of built-in tools, but also makes it easy to define your own (including custom descriptions).\n",
"For a full list of built-in tools, see the [tools integrations section](/docs/integrations/tools/)\n",
"\n",
"### Toolkits\n",
"\n",
"For many common tasks, an agent will need a set of related tools.\n",
"For this LangChain provides the concept of toolkits - groups of around 3-5 tools needed to accomplish specific objectives.\n",
"For example, the GitHub toolkit has a tool for searching through GitHub issues, a tool for reading a file, a tool for commenting, etc.\n",
"\n",
"LangChain provides a wide set of toolkits to get started.\n",
"For a full list of built-in toolkits, see the [toolkits integrations section](/docs/integrations/toolkits/)\n",
"\n",
"### AgentExecutor\n",
"\n",
"The agent executor is the runtime for an agent.\n",
"This is what actually calls the agent, executes the actions it chooses, passes the action outputs back to the agent, and repeats.\n",
"In pseudocode, this looks roughly like:\n",
"\n",
"```python\n",
"next_action = agent.get_action(...)\n",
"while next_action != AgentFinish:\n",
" observation = run(next_action)\n",
" next_action = agent.get_action(..., next_action, observation)\n",
"return next_action\n",
"```\n",
"\n",
"While this may seem simple, there are several complexities this runtime handles for you, including:\n",
"\n",
"1. Handling cases where the agent selects a non-existent tool\n",
"2. Handling cases where the tool errors\n",
"3. Handling cases where the agent produces output that cannot be parsed into a tool invocation\n",
"4. Logging and observability at all levels (agent decisions, tool calls) to stdout and/or to [LangSmith](/docs/langsmith).\n",
"\n",
"### Other types of agent runtimes\n",
"\n",
"The `AgentExecutor` class is the main agent runtime supported by LangChain.\n",
"However, there are other, more experimental runtimes we also support.\n",
"These include:\n",
"\n",
"- [Plan-and-execute Agent](/docs/use_cases/more/agents/autonomous_agents/plan_and_execute)\n",
"- [Baby AGI](/docs/use_cases/more/agents/autonomous_agents/baby_agi)\n",
"- [Auto GPT](/docs/use_cases/more/agents/autonomous_agents/autogpt)\n",
"\n",
"You can also always create your own custom execution logic, which we show how to do below.\n",
"\n",
"## Get started\n",
"\n",
"To best understand the agent framework, lets build an agent from scratch using LangChain Expression Language (LCEL).\n",
"We'll need to build the agent itself, define custom tools, and run the agent and tools in a custom loop. At the end we'll show how to use the standard LangChain `AgentExecutor` to make execution easier.\n",
"\n",
"Some important terminology (and schema) to know:\n",
"\n",
"1. `AgentAction`: This is a dataclass that represents the action an agent should take. It has a `tool` property (which is the name of the tool that should be invoked) and a `tool_input` property (the input to that tool)\n",
"2. `AgentFinish`: This is a dataclass that signifies that the agent has finished and should return to the user. It has a `return_values` parameter, which is a dictionary to return. It often only has one key - `output` - that is a string, and so often it is just this key that is returned.\n",
"3. `intermediate_steps`: These represent previous agent actions and corresponding outputs that are passed around. These are important to pass to future iteration so the agent knows what work it has already done. This is typed as a `List[Tuple[AgentAction, Any]]`. Note that observation is currently left as type `Any` to be maximally flexible. In practice, this is often a string.\n",
"\n",
"### Setup: LangSmith\n",
"\n",
"By definition, agents take a self-determined, input-dependent sequence of steps before returning a user-facing output. This makes debugging these systems particularly tricky, and observability particularly important. [LangSmith](/docs/langsmith) is especially useful for such cases.\n",
"\n",
"When building with LangChain, any built-in agent or custom agent built with LCEL will automatically be traced in LangSmith. And if we use the `AgentExecutor`, we'll get full tracing of not only the agent planning steps but also the tool inputs and outputs.\n",
"\n",
"To set up LangSmith we just need set the following environment variables:\n",
"\n",
"```bash\n",
"export LANGCHAIN_TRACING_V2=\"true\"\n",
"export LANGCHAIN_API_KEY=\"<your-api-key>\"\n",
"```\n",
"\n",
"### Define the agent\n",
"\n",
"We first need to create our agent.\n",
"This is the chain responsible for determining what action to take next.\n",
"\n",
"In this example, we will use OpenAI Function Calling to create this agent.\n",
"**This is generally the most reliable way to create agents.**\n",
"\n",
"For this guide, we will construct a custom agent that has access to a custom tool.\n",
"We are choosing this example because for most real world use cases you will NEED to customize either the agent or the tools. \n",
"We'll create a simple tool that computes the length of a word.\n",
"This is useful because it's actually something LLMs can mess up due to tokenization.\n",
"We will first create it WITHOUT memory, but we will then show how to add memory in.\n",
"Memory is needed to enable conversation.\n",
"\n",
"First, let's load the language model we're going to use to control the agent."
]
},
{
"cell_type": "code",
"execution_count": 1,
"id": "89cf72b4-6046-4b47-8f27-5522d8cb8036",
"metadata": {},
"outputs": [],
"source": [
"from langchain.chat_models import ChatOpenAI\n",
"\n",
"llm = ChatOpenAI(model=\"gpt-3.5-turbo\", temperature=0)"
]
},
{
"cell_type": "markdown",
"id": "0afe32b4-5b67-49fd-9f05-e94c46fbcc08",
"metadata": {},
"source": [
"We can see that it struggles to count the letters in the string \"educa\"."
]
},
{
"cell_type": "code",
"execution_count": 12,
"id": "d8eafbad-4084-4f27-b880-308430c44bcf",
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"AIMessage(content='There are 6 letters in the word \"educa\".')"
]
},
"execution_count": 12,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"llm.invoke(\"how many letters in the word educa?\")"
]
},
{
"cell_type": "markdown",
"id": "20f353a1-7b03-4692-ba6c-581d82de454b",
"metadata": {},
"source": [
"Next, let's define some tools to use.\n",
"Let's write a really simple Python function to calculate the length of a word that is passed in."
]
},
{
"cell_type": "code",
"execution_count": 2,
"id": "6bf6c6a6-4aa2-44fc-9d90-5981de827c2f",
"metadata": {},
"outputs": [],
"source": [
"from langchain.agents import tool\n",
"\n",
"@tool\n",
"def get_word_length(word: str) -> int:\n",
" \"\"\"Returns the length of a word.\"\"\"\n",
" return len(word)\n",
"\n",
"\n",
"tools = [get_word_length]"
]
},
{
"cell_type": "markdown",
"id": "22dc3aeb-012f-4fe6-a980-2bd6d7612e1d",
"metadata": {},
"source": [
"Now let us create the prompt.\n",
"Because OpenAI Function Calling is finetuned for tool usage, we hardly need any instructions on how to reason, or how to output format.\n",
"We will just have two input variables: `input` and `agent_scratchpad`. `input` should be a string containing the user objective. `agent_scratchpad` should be a sequence of messages that contains the previous agent tool invocations and the corresponding tool outputs."
]
},
{
"cell_type": "code",
"execution_count": 3,
"id": "62c98f77-d203-42cf-adcf-7da9ee93f7c8",
"metadata": {},
"outputs": [],
"source": [
"from langchain.prompts import ChatPromptTemplate, MessagesPlaceholder\n",
"\n",
"prompt = ChatPromptTemplate.from_messages(\n",
" [\n",
" (\n",
" \"system\",\n",
" \"You are very powerful assistant, but bad at calculating lengths of words.\",\n",
" ),\n",
" (\"user\", \"{input}\"),\n",
" MessagesPlaceholder(variable_name=\"agent_scratchpad\"),\n",
" ]\n",
")"
]
},
{
"cell_type": "markdown",
"id": "be29b821-b988-4921-8a1f-f04ec87e2863",
"metadata": {},
"source": [
"How does the agent know what tools it can use?\n",
"In this case we're relying on OpenAI function calling LLMs, which take functions as a separate argument and have been specifically trained to know when to invoke those functions.\n",
"\n",
"To pass in our tools to the agent, we just need to format them to the OpenAI function format and pass them to our model. (By `bind`-ing the functions, we're making sure that they're passed in each time the model is invoked.)"
]
},
{
"cell_type": "code",
"execution_count": 4,
"id": "5231ffd7-a044-4ebd-8e31-d1fe334334c6",
"metadata": {},
"outputs": [],
"source": [
"from langchain.tools.render import format_tool_to_openai_function\n",
"\n",
"llm_with_tools = llm.bind(functions=[format_tool_to_openai_function(t) for t in tools])"
]
},
{
"cell_type": "markdown",
"id": "6efbf02b-8686-4559-8b4c-c2be803cb475",
"metadata": {},
"source": [
"Putting those pieces together, we can now create the agent.\n",
"We will import two last utility functions: a component for formatting intermediate steps (agent action, tool output pairs) to input messages that can be sent to the model, and a component for converting the output message into an agent action/agent finish."
]
},
{
"cell_type": "code",
"execution_count": 5,
"id": "b2f24d11-1133-48f3-ba70-fc3dd1da5f2c",
"metadata": {},
"outputs": [],
"source": [
"from langchain.agents.format_scratchpad import format_to_openai_function_messages\n",
"from langchain.agents.output_parsers import OpenAIFunctionsAgentOutputParser\n",
"\n",
"agent = (\n",
" {\n",
" \"input\": lambda x: x[\"input\"],\n",
" \"agent_scratchpad\": lambda x: format_to_openai_function_messages(\n",
" x[\"intermediate_steps\"]\n",
" ),\n",
" }\n",
" | prompt\n",
" | llm_with_tools\n",
" | OpenAIFunctionsAgentOutputParser()\n",
")"
]
},
{
"cell_type": "markdown",
"id": "7d55d2ad-6608-44ab-9949-b16ae8031f53",
"metadata": {},
"source": [
"Now that we have our agent, let's play around with it!\n",
"Let's pass in a simple question and empty intermediate steps and see what it returns:"
]
},
{
"cell_type": "code",
"execution_count": 7,
"id": "01cb7adc-97b6-4713-890e-5d1ddeba909c",
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"AgentActionMessageLog(tool='get_word_length', tool_input={'word': 'educa'}, log=\"\\nInvoking: `get_word_length` with `{'word': 'educa'}`\\n\\n\\n\", message_log=[AIMessage(content='', additional_kwargs={'function_call': {'arguments': '{\\n \"word\": \"educa\"\\n}', 'name': 'get_word_length'}})])"
]
},
"execution_count": 7,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"agent.invoke({\"input\": \"how many letters in the word educa?\", \"intermediate_steps\": []})"
]
},
{
"cell_type": "markdown",
"id": "689ec562-3ec1-4b28-928b-c78c788aa097",
"metadata": {},
"source": [
"We can see that it responds with an `AgentAction` to take (it's actually an `AgentActionMessageLog` - a subclass of `AgentAction` which also tracks the full message log). \n",
"\n",
"If we've set up LangSmith, we'll see a trace that let's us inspect the input and output to each step in the sequence: https://smith.langchain.com/public/04110122-01a8-413c-8cd0-b4df6eefa4b7/r\n",
"\n",
"### Define the runtime\n",
"\n",
"So this is just the first step - now we need to write a runtime for this.\n",
"The simplest one is just one that continuously loops, calling the agent, then taking the action, and repeating until an `AgentFinish` is returned.\n",
"Let's code that up below:"
]
},
{
"cell_type": "code",
"execution_count": 9,
"id": "29bbf63b-f866-4b8c-aeea-2f9cffe70b78",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"TOOL NAME: get_word_length\n",
"TOOL INPUT: {'word': 'educa'}\n",
"There are 5 letters in the word \"educa\".\n"
]
}
],
"source": [
"from langchain.schema.agent import AgentFinish\n",
"\n",
"user_input = \"how many letters in the word educa?\"\n",
"intermediate_steps = []\n",
"while True:\n",
" output = agent.invoke(\n",
" {\n",
" \"input\": user_input,\n",
" \"intermediate_steps\": intermediate_steps,\n",
" }\n",
" )\n",
" if isinstance(output, AgentFinish):\n",
" final_result = output.return_values[\"output\"]\n",
" break\n",
" else:\n",
" print(f\"TOOL NAME: {output.tool}\")\n",
" print(f\"TOOL INPUT: {output.tool_input}\")\n",
" tool = {\"get_word_length\": get_word_length}[output.tool]\n",
" observation = tool.run(output.tool_input)\n",
" intermediate_steps.append((output, observation))\n",
"print(final_result)"
]
},
{
"cell_type": "markdown",
"id": "2de8e688-fed4-4efc-a2bc-8d3c504dd764",
"metadata": {},
"source": [
"Woo! It's working.\n",
"\n",
"### Using AgentExecutor\n",
"\n",
"To simplify this a bit, we can import and use the `AgentExecutor` class.\n",
"This bundles up all of the above and adds in error handling, early stopping, tracing, and other quality-of-life improvements that reduce safeguards you need to write."
]
},
{
"cell_type": "code",
"execution_count": 10,
"id": "9c94ee41-f146-403e-bd0a-5756a53d7842",
"metadata": {},
"outputs": [],
"source": [
"from langchain.agents import AgentExecutor\n",
"\n",
"agent_executor = AgentExecutor(agent=agent, tools=tools, verbose=True)"
]
},
{
"cell_type": "markdown",
"id": "9cbd94a2-b456-45e6-835c-a33be3475119",
"metadata": {},
"source": [
"Now let's test it out!"
]
},
{
"cell_type": "code",
"execution_count": 11,
"id": "6e1e64c7-627c-4713-82ca-8f6db3d9c8f5",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"\n",
"\n",
"\u001b[1m> Entering new AgentExecutor chain...\u001b[0m\n",
"\u001b[32;1m\u001b[1;3m\n",
"Invoking: `get_word_length` with `{'word': 'educa'}`\n",
"\n",
"\n",
"\u001b[0m\u001b[36;1m\u001b[1;3m5\u001b[0m\u001b[32;1m\u001b[1;3mThere are 5 letters in the word \"educa\".\u001b[0m\n",
"\n",
"\u001b[1m> Finished chain.\u001b[0m\n"
]
},
{
"data": {
"text/plain": [
"{'input': 'how many letters in the word educa?',\n",
" 'output': 'There are 5 letters in the word \"educa\".'}"
]
},
"execution_count": 11,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"agent_executor.invoke({\"input\": \"how many letters in the word educa?\"})"
]
},
{
"cell_type": "markdown",
"id": "1578aede-2ad2-4c15-832e-3e0a1660b342",
"metadata": {},
"source": [
"And looking at the trace, we can see that all of our agent calls and tool invocations are automatically logged: https://smith.langchain.com/public/957b7e26-bef8-4b5b-9ca3-4b4f1c96d501/r"
]
},
{
"cell_type": "markdown",
"id": "a29c0705-b9bc-419f-aae4-974fc092faab",
"metadata": {},
"source": [
"### Adding memory\n",
"\n",
"This is great - we have an agent!\n",
"However, this agent is stateless - it doesn't remember anything about previous interactions.\n",
"This means you can't ask follow up questions easily.\n",
"Let's fix that by adding in memory.\n",
"\n",
"In order to do this, we need to do two things:\n",
"\n",
"1. Add a place for memory variables to go in the prompt\n",
"2. Keep track of the chat history\n",
"\n",
"First, let's add a place for memory in the prompt.\n",
"We do this by adding a placeholder for messages with the key `\"chat_history\"`.\n",
"Notice that we put this ABOVE the new user input (to follow the conversation flow)."
]
},
{
"cell_type": "code",
"execution_count": 13,
"id": "ceef8c26-becc-4893-b55c-efcf52c4b9d9",
"metadata": {},
"outputs": [],
"source": [
"from langchain.prompts import MessagesPlaceholder\n",
"\n",
"MEMORY_KEY = \"chat_history\"\n",
"prompt = ChatPromptTemplate.from_messages(\n",
" [\n",
" (\n",
" \"system\",\n",
" \"You are very powerful assistant, but bad at calculating lengths of words.\",\n",
" ),\n",
" MessagesPlaceholder(variable_name=MEMORY_KEY),\n",
" (\"user\", \"{input}\"),\n",
" MessagesPlaceholder(variable_name=\"agent_scratchpad\"),\n",
" ]\n",
")"
]
},
{
"cell_type": "markdown",
"id": "fc4f1e1b-695d-4b25-88aa-d46c015e6342",
"metadata": {},
"source": [
"We can then set up a list to track the chat history"
]
},
{
"cell_type": "code",
"execution_count": 14,
"id": "935abfee-ab5d-4e9a-b33c-6a40a6fa4777",
"metadata": {},
"outputs": [],
"source": [
"from langchain.schema.messages import HumanMessage, AIMessage\n",
"\n",
"chat_history = []"
]
},
{
"cell_type": "markdown",
"id": "c107b5dd-b934-48a0-a8c5-3b5bd76f2b98",
"metadata": {},
"source": [
"We can then put it all together!"
]
},
{
"cell_type": "code",
"execution_count": 15,
"id": "24b094ff-bbea-45c4-8000-ed2b5de459a9",
"metadata": {},
"outputs": [],
"source": [
"agent = (\n",
" {\n",
" \"input\": lambda x: x[\"input\"],\n",
" \"agent_scratchpad\": lambda x: format_to_openai_function_messages(\n",
" x[\"intermediate_steps\"]\n",
" ),\n",
" \"chat_history\": lambda x: x[\"chat_history\"],\n",
" }\n",
" | prompt\n",
" | llm_with_tools\n",
" | OpenAIFunctionsAgentOutputParser()\n",
")\n",
"agent_executor = AgentExecutor(agent=agent, tools=tools, verbose=True)"
]
},
{
"cell_type": "markdown",
"id": "e34ee9bd-20be-4ab7-b384-a5f0335e7611",
"metadata": {},
"source": [
"When running, we now need to track the inputs and outputs as chat history\n"
]
},
{
"cell_type": "code",
"execution_count": 17,
"id": "f238022b-3348-45cd-bd6a-c6770b7dc600",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"\n",
"\n",
"\u001b[1m> Entering new AgentExecutor chain...\u001b[0m\n",
"\u001b[32;1m\u001b[1;3m\n",
"Invoking: `get_word_length` with `{'word': 'educa'}`\n",
"\n",
"\n",
"\u001b[0m\u001b[36;1m\u001b[1;3m5\u001b[0m\u001b[32;1m\u001b[1;3mThere are 5 letters in the word \"educa\".\u001b[0m\n",
"\n",
"\u001b[1m> Finished chain.\u001b[0m\n",
"\n",
"\n",
"\u001b[1m> Entering new AgentExecutor chain...\u001b[0m\n",
"\u001b[32;1m\u001b[1;3mNo, \"educa\" is not a real word in English.\u001b[0m\n",
"\n",
"\u001b[1m> Finished chain.\u001b[0m\n"
]
},
{
"data": {
"text/plain": [
"{'input': 'is that a real word?',\n",
" 'chat_history': [HumanMessage(content='how many letters in the word educa?'),\n",
" AIMessage(content='There are 5 letters in the word \"educa\".')],\n",
" 'output': 'No, \"educa\" is not a real word in English.'}"
]
},
"execution_count": 17,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"input1 = \"how many letters in the word educa?\"\n",
"result = agent_executor.invoke({\"input\": input1, \"chat_history\": chat_history})\n",
"chat_history.extend([\n",
" HumanMessage(content=input1),\n",
" AIMessage(content=result[\"output\"]),\n",
"])\n",
"agent_executor.invoke({\"input\": \"is that a real word?\", \"chat_history\": chat_history})"
]
},
{
"cell_type": "markdown",
"id": "6ba072cd-eb58-409d-83be-55c8110e37f0",
"metadata": {},
"source": [
"Here's the LangSmith trace: https://smith.langchain.com/public/1e1b7e07-3220-4a6c-8a1e-f04182a755b3/r"
]
},
{
"cell_type": "markdown",
"id": "9e8b9127-758b-4dab-b093-2e6357dca3e6",
"metadata": {},
"source": [
"## Next Steps\n",
"\n",
"Awesome! You've now run your first end-to-end agent.\n",
"To dive deeper, you can:\n",
"\n",
"- Check out all the different [agent types](/docs/modules/agents/agent_types/) supported\n",
"- Learn all the controls for [AgentExecutor](/docs/modules/agents/how_to/)\n",
"- Explore the how-to's of [tools](/docs/modules/agents/tools/) and all the [tool integrations](/docs/integrations/tools)\n",
"- See a full list of all the off-the-shelf [toolkits](/docs/integrations/toolkits/) we provide"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "abbe7160-7c82-48ba-a4d3-4426c62edd2a",
"metadata": {},
"outputs": [],
"source": []
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3 (ipykernel)",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.9.1"
}
},
"nbformat": 4,
"nbformat_minor": 5
}

Some files were not shown because too many files have changed in this diff Show More