Compare commits

..

159 Commits

Author SHA1 Message Date
Bagatur
61644408c2 docs 2024-01-19 14:16:47 -08:00
Bagatur
43700be083 wip: classification chain 2024-01-19 14:10:46 -08:00
Eugene Yurtsev
4ef0ed4ddc astream_events: Add version parameter while method is in beta (#16290)
Add a version parameter while the method is in beta phase.

The idea is to make it possible to minimize making breaking changes for users while we're iterating on schema.

Once the API is stable we can assign a default version requirement.
2024-01-19 13:20:02 -05:00
Bagatur
91230ef5d1 openai[patch]: Release 0.0.3 (#16289) 2024-01-19 10:15:08 -08:00
Hamza Kyamanywa
39b3c6d94c langchain[patch]: Add konlpy based text splitting for Korean (#16003)
- **Description:** Adds a text splitter based on
[Konlpy](https://konlpy.org/en/latest/#start) which is a Python package
for natural language processing (NLP) of the Korean language. (It is
like Spacy or NLTK for Korean)
- **Dependencies:** Konlpy would have to be installed before this
splitter is used,
  - **Twitter handle:** @untilhamza
2024-01-19 09:44:56 -08:00
Hongyu Lin
9b0a531aa2 doc: Fix small typo in quickstart (#16164)
- **Description:** fix small typo in quickstart

---------

Co-authored-by: Bagatur <baskaryan@gmail.com>
2024-01-19 09:44:22 -08:00
Sagar B Manjunath
63e2acc964 docs: Fix minor issues in NVIDIA RAG canonical template (#16189)
- **Description:** Fixes a few issues in NVIDIAcanonical RAG template's
README, and adds a notebook for the template
- **Dependencies:** Adds the pypdf dependency which is needed for
ingestion, and updates the lock file

---------

Co-authored-by: Erick Friis <erick@langchain.dev>
2024-01-19 09:44:08 -08:00
Lance Martin
881d1c3ec5 Update MultiON toolkit docs (#16286) 2024-01-19 09:37:20 -08:00
Bagatur
e3828bee43 core[patch]: Release 0.1.13 (#16287) 2024-01-19 09:28:31 -08:00
Bagatur
2454fefc53 docs: agent prompt docs (#16105) 2024-01-19 09:19:22 -08:00
Bagatur
84bf5787a7 core[patch], openai[patch]: Chat openai stream logprobs (#16218) 2024-01-19 09:16:09 -08:00
Bagatur
6f7a414955 docs: fix links (#16284) 2024-01-19 08:51:12 -08:00
Eugene Yurtsev
cc2e30fa13 CI: update the description used for privileged issue template (#16277)
Update description
2024-01-19 10:13:33 -05:00
Eugene Yurtsev
3b649f4331 CI: Add privileged version for issue creation (#16276)
Add privileged version for issue creation.

This adds a version of issue creation which is unstructured by design to
make it easier for maintainers to create issues.

Maintainers are expected to write / describe issues clearly.
2024-01-19 09:53:51 -05:00
Eugene Yurtsev
c0d453d8ac CI: Disable blank issues, add links to QA discussions & show and tell (#16275)
Update the issue template
2024-01-19 09:34:23 -05:00
Carey
021b0484a8 community[patch]: add skipped test for inner product normalization (#14989)
---------

Co-authored-by: Erick Friis <erick@langchain.dev>
2024-01-18 23:03:15 -08:00
Lance Martin
f63906a9c2 Test and update MultiON agent toolkit docs (#16235) 2024-01-18 20:24:35 -08:00
Christophe Bornet
3ccbe11363 community[minor]: Add Cassandra document loader (#16215)
- **Description:** document loader for Apache Cassandra
  - **Twitter handle:** cbornet_
2024-01-18 18:49:02 -08:00
Tomaz Bratanic
fc84083ce5 docs: Add neo4j semantic blog post link to templates (#16225) 2024-01-18 18:45:22 -08:00
mikeFore4
9d32af72ce community[patch]: huggingface hub character removal bug fix (#16233)
- **Description:** Some text-generation models on huggingface repeat the
prompt in their generated response, but not all do! The tests use "gpt2"
which DOES repeat the prompt and as such, the HuggingFaceHub class is
hardcoded to remove the first few characters of the response (to match
the len(prompt)). However, if you are using a model (such as the very
popular "meta-llama/Llama-2-7b-chat-hf") that DOES NOT repeat the prompt
in it's generated text, then the beginning of the generated text will be
cut off. This code change fixes that bug by first checking whether the
prompt is repeated in the generated response and removing it
conditionally.
  - **Issue:** #16232 
  - **Dependencies:** N/A
  - **Twitter handle:** N/A
2024-01-18 18:44:10 -08:00
Andreas Motl
3613d8a2ad community[patch]: Use SQLAlchemy's bulk_save_objects method to improve insert performance (#16244)
- **Description:** Improve [pgvector vector store
adapter](https://github.com/langchain-ai/langchain/blob/v0.1.1/libs/community/langchain_community/vectorstores/pgvector.py)
to save embeddings in batches, to improve its performance.
  - **Issue:** NA
  - **Dependencies:** NA
  - **References:** https://github.com/crate-workbench/langchain/pull/1


Hi again from the CrateDB team,

following up on GH-16243, this is another minor patch to the pgvector
vector store adapter. Inserting embeddings in batches, using
[SQLAlchemy's
`bulk_save_objects`](https://docs.sqlalchemy.org/en/20/orm/session_api.html#sqlalchemy.orm.Session.bulk_save_objects)
method, can deliver substantial performance gains.

With kind regards,
Andreas.

NB: As I am seeing just now that this method is a legacy feature of SA
2.0, it will need to be reworked on a future iteration. However, it is
not deprecated yet, and I haven't been able to come up with a different
implementation, yet.
2024-01-18 18:35:39 -08:00
Ashley Xu
0f99646ca6 docs: add the enrollment form forBigQueryVectorSearch (#16240)
This PR adds the enrollment form for BigQueryVectorSearch.
2024-01-18 18:34:06 -08:00
Eugene Yurtsev
177af65dc4 core[minor]: RFC Add astream_events to Runnables (#16172)
This PR adds `astream_events` method to Runnables to make it easier to
stream data from arbitrary chains.

* Streaming only works properly in async right now
* One should use `astream()` with if mixing in imperative code as might
be done with tool implementations
* Astream_log has been modified with minimal additive changes, so no
breaking changes are expected
* Underlying callback code / tracing code should be refactored at some
point to handle things more consistently (OK for now)

- ~~[ ] verify event for on_retry~~ does not work until we implement
streaming for retry
- ~~[ ] Any rrenaming? Should we rename "event" to "hook"?~~
- [ ] Any other feedback from community?
- [x] throw NotImplementedError for `RunnableEach` for now

## Example

See this [Example
Notebook](dbbc7fa0d6/docs/docs/modules/agents/how_to/streaming_events.ipynb)
for an example with streaming in the context of an Agent

## Event Hooks Reference

Here is a reference table that shows some events that might be emitted
by the various Runnable objects.
Definitions for some of the Runnable are included after the table.


| event | name | chunk | input | output |

|----------------------|------------------|---------------------------------|-----------------------------------------------|-------------------------------------------------|
| on_chat_model_start | [model name] | | {"messages": [[SystemMessage,
HumanMessage]]} | |
| on_chat_model_stream | [model name] | AIMessageChunk(content="hello")
| | |
| on_chat_model_end | [model name] | | {"messages": [[SystemMessage,
HumanMessage]]} | {"generations": [...], "llm_output": None, ...} |
| on_llm_start | [model name] | | {'input': 'hello'} | |
| on_llm_stream | [model name] | 'Hello' | | |
| on_llm_end | [model name] | | 'Hello human!' |
| on_chain_start | format_docs | | | |
| on_chain_stream | format_docs | "hello world!, goodbye world!" | | |
| on_chain_end | format_docs | | [Document(...)] | "hello world!,
goodbye world!" |
| on_tool_start | some_tool | | {"x": 1, "y": "2"} | |
| on_tool_stream | some_tool | {"x": 1, "y": "2"} | | |
| on_tool_end | some_tool | | | {"x": 1, "y": "2"} |
| on_retriever_start | [retriever name] | | {"query": "hello"} | |
| on_retriever_chunk | [retriever name] | {documents: [...]} | | |
| on_retriever_end | [retriever name] | | {"query": "hello"} |
{documents: [...]} |
| on_prompt_start | [template_name] | | {"question": "hello"} | |
| on_prompt_end | [template_name] | | {"question": "hello"} |
ChatPromptValue(messages: [SystemMessage, ...]) |


Here are declarations associated with the events shown above:

`format_docs`:

```python
def format_docs(docs: List[Document]) -> str:
    '''Format the docs.'''
    return ", ".join([doc.page_content for doc in docs])

format_docs = RunnableLambda(format_docs)
```

`some_tool`:

```python
@tool
def some_tool(x: int, y: str) -> dict:
    '''Some_tool.'''
    return {"x": x, "y": y}
```

`prompt`:

```python
template = ChatPromptTemplate.from_messages(
    [("system", "You are Cat Agent 007"), ("human", "{question}")]
).with_config({"run_name": "my_template", "tags": ["my_template"]})
```
2024-01-18 21:27:01 -05:00
SN
f175bf7d7b Use env for revision id if not passed in as param; use git describe as backup (#16227)
Co-authored-by: William Fu-Hinthorn <13333726+hinthornw@users.noreply.github.com>
2024-01-18 16:15:26 -08:00
Erick Friis
e5878c467a infra: scheduled testing env (#16239) 2024-01-18 14:28:01 -08:00
Erick Friis
2f348c695a infra: add nvidia api secret to integration testing (#15972) 2024-01-18 14:20:02 -08:00
Erick Friis
50959abf0c infra: google cse id integration test (#16238) 2024-01-18 14:12:00 -08:00
Erick Friis
b9495da92d langchain[patch]: fix stuff documents chain api docs render (#16159) 2024-01-18 14:07:44 -08:00
Erick Friis
eec3347939 docs: together cookbook import (#16236) 2024-01-18 14:07:19 -08:00
Erick Friis
92bc80483a infra: google search api key (#16237) 2024-01-18 14:06:38 -08:00
Erick Friis
0e76d84137 google-vertexai[patch]: more integration test fixes (#16234) 2024-01-18 13:59:23 -08:00
Erick Friis
aa35b43bcd docs, google-vertex[patch]: function docs (#16231) 2024-01-18 13:15:09 -08:00
Erick Friis
f2b2d59e82 docs: transport and client options docs (#16226)
<!-- Thank you for contributing to LangChain!

Please title your PR "<package>: <description>", where <package> is
whichever of langchain, community, core, experimental, etc. is being
modified.

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,
- **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` from the root
of the package you've modified to check this locally.

See contribution guidelines for more information on how to write/run
tests, lint, etc: https://python.langchain.com/docs/contributing/

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/docs/integrations` directory.

If no one reviews your PR within a few days, please @-mention one of
@baskaryan, @eyurtsev, @hwchase17.
 -->
2024-01-18 12:23:04 -08:00
Harrison Chase
f60f59d69f google-vertexai[patch]: Harrison/vertex function calling (#16223)
Co-authored-by: Erick Friis <erick@langchain.dev>
2024-01-18 12:17:40 -08:00
Rajesh Thallam
6bc6d64a12 langchain_google_vertexai[patch]: Add support for SystemMessage for Gemini chat model (#15933)
- **Description:** In Google Vertex AI, Gemini Chat models currently
doesn't have a support for SystemMessage. This PR adds support for it
only if a user provides additional convert_system_message_to_human flag
during model initialization (in this case, SystemMessage would be
prepended to the first HumanMessage). **NOTE:** The implementation is
similar to #14824


- **Twitter handle:** rajesh_thallam

---------

Co-authored-by: Erick Friis <erick@langchain.dev>
2024-01-18 10:22:07 -08:00
Erick Friis
65b231d40b mistralai[patch]: async integration tests (#16214) 2024-01-18 09:45:44 -08:00
jzaldi
ed118950fe docs: Updated integration docs structure for llm/google_vertex_ai_palm (#16091)
- **Description**: Updated doc for llm/google_vertex_ai_palm with new
functions: `invoke`, `stream`... Changed structure of the document to
match the required one.
- **Issue**: #15664 
- **Dependencies**: None
- **Twitter handle**: None

---------

Co-authored-by: Jorge Zaldívar <jzaldivar@google.com>
2024-01-18 09:45:27 -08:00
Bagatur
aa2e642ce3 docs: tool use nits (#16211) 2024-01-18 09:17:53 -08:00
Eugene Zapolsky
6b9e3ed9e9 google-vertexai[minor]: added safety_settings property to gemini wrapper (#15344)
**Description:** Gemini model has quite annoying default safety_settings
settings. In addition, current VertexAI class doesn't provide a property
to override such settings.
So, this PR aims to 
 - add safety_settings property to VertexAI
- fix issue with incorrect LLM output parsing when LLM responds with
appropriate 'blocked' response
- fix issue with incorrect parsing LLM output when Gemini API blocks
prompt itself as inappropriate
- add safety_settings related tests

I'm not enough familiar with langchain code base and guidelines. So, any
comments and/or suggestions are very welcome.
 
**Issue:** it will likely fix #14841

---------

Co-authored-by: Erick Friis <erick@langchain.dev>
2024-01-18 08:54:30 -08:00
Eugene Yurtsev
ecd4f0a7ec core[patch]: testing add chat model for unit-tests (#16209)
This PR adds a fake chat model for testing purposes.

Used in this PR: https://github.com/langchain-ai/langchain/pull/16172
2024-01-18 11:30:53 -05:00
Bagatur
27ad65cc68 docs: add tool use diagrams (#16207) 2024-01-18 07:59:54 -08:00
SN
7d444724d7 Add revision identifier to run_on_dataset (#16167)
Allow specifying revision identifier for better project versioning
2024-01-17 20:27:43 -08:00
Eugene Yurtsev
5d8c147332 docs: Document and test PydanticOutputFunctionsParser (#15759)
This PR adds documentation and testing to
`PydanticOutputFunctionsParser(OutputFunctionsParser)`.
2024-01-17 18:21:18 -08:00
Christophe Bornet
3502a407d9 infra: Use dotenv in langchain-community's integration tests (#16137)
* Removed some env vars not used in langchain package IT
* Added Astra DB env vars in langchain package, used for cache tests
* Added conftest.py to load env vars in langchain_community IT
* Added .env.example in  langchain_community IT
2024-01-17 18:18:26 -08:00
Nuno Campos
ca014d5b04 Update readme (#16160)
<!-- Thank you for contributing to LangChain!

Please title your PR "<package>: <description>", where <package> is
whichever of langchain, community, core, experimental, etc. is being
modified.

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,
- **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` from the root
of the package you've modified to check this locally.

See contribution guidelines for more information on how to write/run
tests, lint, etc: https://python.langchain.com/docs/contributing/

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/docs/integrations` directory.

If no one reviews your PR within a few days, please @-mention one of
@baskaryan, @eyurtsev, @hwchase17.
 -->
2024-01-17 13:56:07 -08:00
Tomaz Bratanic
1e80113ac9 community[patch]: Add neo4j timeout and value sanitization option (#16138)
The timeout function comes in handy when you want to kill longrunning
queries.
The value sanitization removes all lists that are larger than 128
elements. The idea here is to remove embedding properties from results.
2024-01-17 13:22:19 -08:00
Bagatur
27ed2673da docs: model io order (#16163) 2024-01-17 13:13:31 -08:00
Krishna Shedbalkar
f238217cea community[patch]: Basic Logging and Human input to ShellTool (#15932)
- **Description:** As Shell tool is very versatile, while integrating it
into applications as openai functions, developers have no clue about
what command is being executed using the ShellTool. All one can see is:

![image](https://github.com/langchain-ai/langchain/assets/60742358/540e274a-debc-4564-9027-046b91424df3)

Summarising my feature request:
1. There's no visibility about what command was executed.
2. There's no mechanism to prevent a command to be executed using
ShellTool, like a y/n human input which can be accepted from user to
proceed with executing the command.,
  - **Issue:** the issue #15931 it fixes if applicable,
  - **Dependencies:** There isn't any dependancy,
  - **Twitter handle:** @krishnashed
2024-01-17 12:57:51 -08:00
Bagatur
2af813c7eb docs: bump sphinx>=5 (#16162) 2024-01-17 12:57:34 -08:00
Bagatur
679a3ae933 openai[patch]: clarify azure error (#16157) 2024-01-17 12:43:14 -08:00
Bagatur
7ad9eba8f4 core[patch]: Release 0.1.12 (#16161) 2024-01-17 12:39:45 -08:00
Leonid Kuligin
58f0ba306b changed default params for gemini (#16044)
Replace this entire comment with:
- **Description:** changed default values for Vertex LLMs (to be handled
on the SDK's side)
2024-01-17 12:19:18 -08:00
David DeCaprio
ec9642d667 docs: Updated MongoDB Chat history example notebook to use LCEL format. (#15750)
- **Description:** Updated the MongoDB example integration notebook to
latest standards
- **Issue:**
[15664](https://github.com/langchain-ai/langchain/issues/15664)
  - **Dependencies:** None
  - **Twitter handle:** @davedecaprio

---------

Co-authored-by: Harrison Chase <hw.chase.17@gmail.com>
2024-01-17 12:07:17 -08:00
Bagatur
5c73fd5bba core[patch]: support old core namespaces (#16155) 2024-01-17 11:26:25 -08:00
Christophe Bornet
fb940d11df community[patch]: Use newer MetadataVectorCassandraTable in Cassandra vector store (#15987)
as VectorTable is deprecated

Tested manually with `test_cassandra.py` vector store integration test.
2024-01-17 10:37:07 -08:00
Mohammad Mohtashim
1fa056c324 community[patch]: Don't set search path for unknown SQL dialects (#16047)
- **Description:** Made a small fix for the `SQLDatabase` highlighted in
an issue. The issue pertains to switching schema for different SQL
engines. 
  - **Issue:** #16023
@baskaryan
2024-01-17 10:31:11 -08:00
Erick Friis
11327e6b64 google-vertexai[patch]: typing, release 0.0.2 (#16153) 2024-01-17 10:16:59 -08:00
Leonid Ganeline
2709d3e5f2 langchain[patch]: updated imports for langchain.callbacks (#16060)
Updated imports from 'langchain` to `core` where it is possible

---------

Co-authored-by: Bagatur <baskaryan@gmail.com>
2024-01-17 10:06:59 -08:00
Leonid Ganeline
c5f6b828ad langchain[patch], community[minor]: move output_parsers.ernie_functions (#16057)
`output_parsers.ernie_functions` moved into `community`
2024-01-17 10:06:18 -08:00
Bagatur
e7ddec1f2c docs: change parallel doc name (#16152) 2024-01-17 10:04:34 -08:00
Leonid Ganeline
49aff3ea5b langchain[patch]: updated agents imports (#16061)
Updated imports into `langchain` to `core` where it is possible

---------

Co-authored-by: Bagatur <baskaryan@gmail.com>
2024-01-17 10:02:29 -08:00
Leonid Ganeline
60b1bd02d7 langchain[patch]: updated imports for output_parsers (#16059)
Updated imports from `langchain` to `core` where it is possible
2024-01-17 10:02:12 -08:00
Leonid Ganeline
9e9ad9b0e9 langchain[patch]: updated retrievers imports (#16062)
Updated imports into `langchain` to `core` where it is possible

---------

Co-authored-by: Bagatur <baskaryan@gmail.com>
2024-01-17 10:01:06 -08:00
Leonid Ganeline
d350be959d langchain[patch]: updated chains imports (#16064)
Updated imports into `langchain` to `core` where it is possible

---------

Co-authored-by: Bagatur <baskaryan@gmail.com>
2024-01-17 09:58:42 -08:00
Fei Wang
d0e101e4e0 community[patch]: fix ollama astream (#16070)
Update ollama.py
2024-01-17 09:42:41 -08:00
Joshua Carroll
bc0cb1148a docs: Fix StreamlitChatMessageHistory docs to latest API (#16072)
- **Description:** Update [this
page](https://python.langchain.com/docs/integrations/memory/streamlit_chat_message_history)
to use the latest API
  - **Issue:** https://github.com/langchain-ai/langchain/issues/13995
  - **Dependencies:** None
  - **Twitter handle:** @OhSynap
2024-01-17 09:42:10 -08:00
ChengZi
8597484195 langchain[patch]: support more comparators in Milvus self-querying retriever (#16076)
- **Description:** Support IN and LIKE comparators in Milvus
self-querying retriever, based on [Boolean Expression
Rules](https://milvus.io/docs/boolean.md)
  - **Issue:** No
  - **Dependencies:** No
  - **Twitter handle:** No

Signed-off-by: ChengZi <chen.zhang@zilliz.com>
2024-01-17 09:41:23 -08:00
David DeCaprio
9c2f1f07a0 docs: Updated SQLite example to use LCEL and SQLChatMessageHistory (#16094)
- **Description:** Updated the SQLite example integration notebook to
latest standards
- **Issue:**
[15664](https://github.com/langchain-ai/langchain/issues/15664)
  - **Dependencies:** None
  - **Twitter handle:** @davedecaprio
2024-01-17 09:39:44 -08:00
Kapil Sachdeva
f406dc3872 docs: in RunnableRetry, correct the example snippet that uses with_retry method on Runnable (#16108)
The example code snippet for with_retry is using incorrect argument
names. This PR fixes that
2024-01-17 09:11:27 -08:00
Abhinav
da96c511d1 docs: Replace azure_cosmos_db_vector_search with azure_cosmos_db in Cosmos DB Documentation (#16122)
**Description**: This PR fixes an error in the documentation for Azure
Cosmos DB Integration.
**Issue**: The correct way to import `AzureCosmosDBVectorSearch` is
```python
from langchain_community.vectorstores.azure_cosmos_db import (
    AzureCosmosDBVectorSearch,
)
```
While the
[documentation](https://python.langchain.com/docs/integrations/vectorstores/azure_cosmos_db)
states it to be
```python
from langchain_community.vectorstores.azure_cosmos_db_vector_search import (
    AzureCosmosDBVectorSearch,
    CosmosDBSimilarityType,
)
```
As you can see in
[azure_cosmos_db.py](c323742f4f/libs/langchain/langchain/vectorstores/azure_cosmos_db.py (L1C45-L2))
**Dependencies:**: None
**Twitter handle**: None
2024-01-17 09:11:16 -08:00
BeatrixCohere
b0c3e3db2b community[patch]: Handle when documents are not provided in the Cohere response (#16144)
- **Description:** This handles the cohere response when documents
aren't included in the response
  - **Issue:** N/A
  - **Dependencies:** N/A
  - **Twitter handle:** N/A
2024-01-17 09:11:00 -08:00
Felix Krones
d91126fc64 community[patch]: missing unpack operator for or_clause in pgvector document filter (#16148)
- Fix for #16146 
- Adding unpack operation to "or" and "and" filter for pgvector
retriever. #
2024-01-17 09:10:43 -08:00
purificant
3606c5d5e9 infra: update poetry 1.6.1 -> 1.7.1 (#15027) 2024-01-17 08:51:20 -08:00
Ikko Eltociear Ashimine
a35e5f19a8 docs: Update gradient.ipynb (#16149)
Enviroment -> Environment
2024-01-17 08:48:24 -08:00
Erick Friis
06fe2f4fb0 partners: add license field (#16117)
- bumps package post versions for packages without current unreleased
updates
- will bump package version in release prs associated with packages that
do have changes (mistral, vertex)
2024-01-17 08:37:13 -08:00
Erick Friis
ce10fe0c2f mistralai[patch]: release 0.0.3 (#16116)
embeddings
2024-01-17 08:36:05 -08:00
William FH
e5cf1e2414 Community[patch]use secret str in Tavily and HuggingFaceInferenceEmbeddings (#16109)
So the api keys don't show up in repr's 

Still need to do tests
2024-01-17 00:30:07 -08:00
William FH
f3601b0aaf Community[Patch] Remove docs form bm25 repr (#16110)
Resolves: https://github.com/langchain-ai/langsmith-sdk/issues/356
2024-01-17 00:00:55 -08:00
David
c323742f4f mistralai[minor]: Add embeddings (#15282)
- **Description:** Adds MistralAIEmbeddings class for embeddings, using
the new official API.
- **Dependencies:** mistralai
- **Tag maintainer**: @efriis, @hwchase17
- **Twitter handle:** @LMS_David_RS

Create `integrations/text_embedding/mistralai.ipynb`: an example
notebook for MistralAIEmbeddings class
Modify `embeddings/__init__.py`: Import the class
Create `embeddings/mistralai.py`: The embedding class
Create `integration_tests/embeddings/test_mistralai.py`: The test file.

---------

Co-authored-by: Erick Friis <erick@langchain.dev>
2024-01-16 17:48:37 -08:00
Leonid Ganeline
f974eb5b8b docs: updated Anyscale page (#16107)
- added description
- fixed broken links
- added setting instructions
- added the Chat model reference
2024-01-16 17:13:51 -08:00
Leonid Kuligin
4df14a61fc google-vertexai[minor]: add function calling on VertexAI (#15822)
Replace this entire comment with:
  - **Description:** Description: added support for tools on VertexAI
  - **Issue:** #15073 
  - **Twitter handle:**  lkuligin

---------

Co-authored-by: Erick Friis <erick@langchain.dev>
2024-01-16 17:01:26 -08:00
Bagatur
8840a8cc95 docs: tool-use use case (#15783)
Co-authored-by: Harrison Chase <hw.chase.17@gmail.com>
2024-01-16 10:41:14 -08:00
Bagatur
3d34347a85 langchain[patch]: bump core dep to 0.1.9 (#16104) 2024-01-16 10:39:07 -08:00
Bagatur
62a2e9ee19 langchain[patch]: Release 0.1.1 (#16103) 2024-01-16 10:17:38 -08:00
Christophe Bornet
6b6269441c docs: Add page for AstraDB self retriever (#16077)
Preview:
https://langchain-git-fork-cbornet-astra-self-retriever-docs-langchain.vercel.app/docs/integrations/retrievers/self_query/astradb
2024-01-16 09:50:30 -08:00
Juan Bustos
5f057f24ac docs: Update elasticsearch.ipynb (#16090)
Fixed a typo, the parameter used for the Elasticsearch API key was
called api_key, but the parameter is called es_api_key.
2024-01-16 09:49:42 -08:00
Bagatur
076593382a core[patch]: Release 0.1.11 (#16100) 2024-01-16 09:46:04 -08:00
Bagatur
c5656a4905 core[patch]: pass exceptions to fallbacks (#16048) 2024-01-16 09:36:43 -08:00
Nuno Campos
770f57196e Add unit test for overridden lc_namespace (#16093) 2024-01-16 09:22:52 -08:00
Erick Friis
52114bdfac community[patch]: release 0.0.13 (#16087) 2024-01-16 06:25:28 -08:00
James Briggs
ca288d8f2c community[patch]: add vector param to index query for pinecone vec store (#16054) 2024-01-16 06:12:19 -08:00
Antonio Morales
476fb328ee community[patch]: implement adelete from VectorStore in Qdrant (#16005)
**Description:**
Implement `adelete` function from `VectorStore` in `Qdrant` to support
other asynchronous flows such as async indexing (`aindex`) which
requires `adelete` to be implemented. Since `Qdrant` can be passed an
async qdrant client, this can be supported easily.

---------

Co-authored-by: Bagatur <baskaryan@gmail.com>
2024-01-15 19:57:09 -08:00
Bagatur
697a6f2c80 langchain[patch]: fix requests lint (#16049) 2024-01-15 12:54:30 -08:00
高远
061e63eef2 community[minor]: add vikingdb vecstore (#15155)
---------

Co-authored-by: gaoyuan <gaoyuan.20001218@bytedance.com>
2024-01-15 12:34:01 -08:00
andrijdavid
d196646811 community[patch]: Refactor OpenAIWhisperParserLocal (#15150)
This PR addresses an issue in OpenAIWhisperParserLocal where requesting
CUDA without availability leads to an AttributeError #15143

Changes:

- Refactored Logic for CUDA Availability: The initialization now
includes a check for CUDA availability. If CUDA is not available, the
code falls back to using the CPU. This ensures seamless operation
without manual intervention.
- Parameterizing Batch Size and Chunk Size: The batch_size and
chunk_size are now configurable parameters, offering greater flexibility
and optimization options based on the specific requirements of the use
case.

---------

Co-authored-by: Harrison Chase <hw.chase.17@gmail.com>
2024-01-15 12:29:14 -08:00
Zhichao HAN
5cf06db3b3 community[minor]: add JsonRequestsWrapper tool (#15374)
**Description:** This new feature enhances the flexibility of pipeline
integration, particularly when working with RESTful APIs.
``JsonRequestsWrapper`` allows for the decoding of JSON output, instead
of the only option for text output.

---------

Co-authored-by: Zhichao HAN <hanzhichao2000@hotmail.com>
2024-01-15 12:27:19 -08:00
chyroc
d334efc848 community[patch]: fix top_p type hint (#15452)
fix: https://github.com/langchain-ai/langchain/issues/15341

@efriis
2024-01-15 11:59:39 -08:00
Mateusz Szewczyk
251afda549 community[patch]: fix stop (stop_sequences) param on WatsonxLLM (#15541)
- **Description:** Fix to IBM
[watsonx.ai](https://www.ibm.com/products/watsonx-ai) LLM provider (stop
(`stop_sequences`) param on watsonxLLM)
- **Dependencies:**
[ibm-watsonx-ai](https://pypi.org/project/ibm-watsonx-ai/),
2024-01-15 11:44:57 -08:00
Funkeke
7220124368 community[patch]: fix tongyi completion and params error (#15544)
fix tongyi completion json parse error and prompt's params error

---------

Co-authored-by: fangkeke <3339698829@qq.com>
Co-authored-by: Harrison Chase <hw.chase.17@gmail.com>
2024-01-15 11:43:13 -08:00
Averi Kitsch
ee378a0f40 docs: add page for Firestore Chat Message History integration (#15554)
- **Description:** Adds documentation for the
`FirestoreChatMessageHistory` integration and lists integration in
Google's documentation
  - **Issue:** NA
  - **Dependencies:** No

---------

Co-authored-by: Harrison Chase <hw.chase.17@gmail.com>
2024-01-15 11:42:33 -08:00
盐粒 Yanli
ddf4e7c633 community[minor]: Update pgvecto_rs to use its high level sdk (#15574)
- **Description:** Update pgvecto_rs to use its high level sdk, 
  - **Issue:** fix #15173
2024-01-15 11:41:59 -08:00
YHW
ce21392a21 community: add a flag that determines whether to load the milvus collection (#15693)
fix https://github.com/langchain-ai/langchain/issues/15694

---------

Co-authored-by: hyungwookyang <hyungwookyang@worksmobile.com>
Co-authored-by: Bagatur <baskaryan@gmail.com>
2024-01-15 11:25:23 -08:00
Mohammad Mohtashim
9e779ca846 community[patch]: Fixing the SlackGetChannel Tool Input Error (#15725)
Fixed the issue mentioned in #15698 for SlackGetChannel Tool.

@baskaryan.

---------

Co-authored-by: Harrison Chase <hw.chase.17@gmail.com>
Co-authored-by: Bagatur <baskaryan@gmail.com>
2024-01-15 11:23:55 -08:00
axiangcoding
daa9ccae52 community[patch]: deprecate ErnieBotChat and ErnieEmbeddings classes (#15862)
- **Description:** add deprecated warning for ErnieBotChat and
ErnieEmbeddings.
- These two classes **lack maintenance** and do not use the sdk provided
by qianfan, which means hard to implement some key feature like
streaming.
- The alternative `langchain_community.chat_models.QianfanChatEndpoint`
and `langchain_community.embeddings.QianfanEmbeddingsEndpoint` can
completely replace these two classes, only need to change configuration
items.
  - **Issue:** None,
  - **Dependencies:** None,
  - **Twitter handle:** None

---------

Co-authored-by: Bagatur <baskaryan@gmail.com>
2024-01-15 11:14:44 -08:00
Eugene Yurtsev
7c57cfd8f0 docs: Update OpenAI functions agent (#15894)
Add info and a tip explaining when to use this agent.
2024-01-15 11:14:29 -08:00
Eugene Yurtsev
beec7259c8 docs: Add info admonitions to a few agents (#15899)
Add admonitions directly in the agent page to explain constraints and
include a
link to agent types.
2024-01-15 11:14:11 -08:00
JaguarDB
b11fd3bedc community[patch]: jaguar vector store fix integer-element error when joining metadata values (#15939)
- **Description:** some document loaders add integer-type metadata
values which cause error
  - **Issue:** 15937
  - **Dependencies:** none

---------

Co-authored-by: JY <jyjy@jaguardb>
2024-01-15 11:13:45 -08:00
Bigtable123
7306032dcf docs: update baidu_qianfan_endpoint.ipynb doc (#15940)
- **Description:** Updated the docs for the chat integration module
baidu_qianfan_endpoint.ipynb
  - **Issue:**  #15664 
  - **Dependencies:**N/A
2024-01-15 11:13:21 -08:00
Neo Zhao
21e0df937f community[patch]: fix a bug that mistakenly handle zip iterator in FAISS.from_embeddings (#16020)
**Description**: `zip` is iterator that will only produce result once,
so the previous code will cause the `embeddings` to be an empty list.

**Issue**: I could not find a related issue.

**Dependencies**: this PR does not introduce or affect dependencies.

---------

Co-authored-by: Bagatur <baskaryan@gmail.com>
2024-01-15 11:13:14 -08:00
Christophe Bornet
15c2b4a47e community[minor]: Add AstraDB self query retriever (#15738)
- **Description:** this change adds a self-query retriever for AstraDB
  - **Twitter handle:** cbornet_
2024-01-15 11:04:11 -08:00
Leonid Ganeline
fb676d8a9b community[minor], langchain[minor]: refactor output_parsers Rail (#15852)
Moved Rail parser to `community` package.
2024-01-15 10:54:49 -08:00
Bhadresh Savani
6137c7608d docs: Integration Documentation updated run to invoke for llms/ai21.ipynb (#15889)
- **Description:** Updated Integration Documentation for
[llms/ai21.ipynb](https://github.com/langchain-ai/langchain/blob/master/docs/docs/integrations/llms/ai21.ipynb)
  - **Issue:** #15664,
  - **Dependencies:** NA,
  - **Twitter handle:** @BhadreshSavani
2024-01-15 10:53:22 -08:00
Massimiliano Pronesti
e80aab2275 docs(community): update Amadeus toolkit to langchain v0.1 (#15976)
- **Description:** docs update following the changes introduced in
#15879

<!-- Thank you for contributing to LangChain!

Please title your PR "<package>: <description>", where <package> is
whichever of langchain, community, core, experimental, etc. is being
modified.

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,
- **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` from the root
of the package you've modified to check this locally.

See contribution guidelines for more information on how to write/run
tests, lint, etc: https://python.langchain.com/docs/contributing/

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/docs/integrations` directory.

If no one reviews your PR within a few days, please @-mention one of
@baskaryan, @eyurtsev, @hwchase17.
 -->
2024-01-15 10:50:47 -08:00
Ashley Xu
ce7723c1e5 community[minor]: add additional support for BigQueryVectorSearch (#15904)
BigQuery vector search lets you use GoogleSQL to do semantic search,
using vector indexes for fast but approximate results, or using brute
force for exact results.

This PR:
1. Add `metadata[_job_ib]` in Document returned by any similarity search
2. Add `explore_job_stats` to enable users to explore job statistics and
better the debuggability
3. Set the minimum row limit for running create vector index.
2024-01-15 10:45:15 -08:00
Mohammed Naqi
8799b028a6 community[minor]: Adding asynchronous function implementation for Doctran (#15941)
## Description 
In this update, I addressed the missing implementation for
atransform_document, which is the asynchronous counterpart of
transform_document in Doctran.

### Usage Example:
```py
# Instantiate DoctranPropertyExtractor with specified properties
property_extractor = DoctranPropertyExtractor(properties=properties)

# Asynchronously extract properties from a list of documents
extracted_document = await property_extractor.atransform_documents(
    documents, properties=properties
)

# Display metadata of the first extracted document
print(json.dumps(extracted_document[0].metadata, indent=2))

```

## Issue
- Pull request #14525 has caused a break in the aforementioned code.
Instead of removing an asynchronous implementation of a function,
consider implementing a synchronous version alongside it.
2024-01-15 10:39:25 -08:00
Antonio Mindov
fb7e66b809 docs: fix typo in inspect runnables docs (#15994)
- **Description:** Fixing a typo related to prompts in the inspecting
runnables docs
2024-01-15 10:35:26 -08:00
Raunak
c0773ab329 community[patch]: Fixed 'coroutine' object is not subscriptable error (#15986)
- **Description:** Added parenthesis in return statement of
aembed_query() funtion to fix 'coroutine' object is not subscriptable
error.
  - **Dependencies:** NA

Co-authored-by: H161961 <Raunak.Raunak@Honeywell.com>
2024-01-15 10:34:10 -08:00
Karim Lalani
14244bd7e5 community[minor]: Added document loader for SurrealDB (#15995)
Added a simple document loader to work with SurrealDB.
2024-01-15 10:32:42 -08:00
Karim Lalani
768e5e33bc community[minor]: Fix to match SurrealDB 0.3.2 SDK (#15996)
New version of SurrealDB python sdk was causing the integration to
break.
This fix addresses that change.
2024-01-15 10:31:59 -08:00
shahrin014
86321a949f community: Ollama - Parameter structure to follow official documentation (#16035)
## Feature
- Follow parameter structure as per official documentation 
- top level parameters (e.g. model, system, template) will be passed as
top level parameters
  - other parameters will be sent in options unless options is provided

![image](https://github.com/langchain-ai/langchain/assets/17451563/d14715d9-9701-4ee3-b44b-89fffea62389)

## Tests
- Test if top level parameters handled properly
- Test if parameters that are not top level parameters are handled as
options
- Test if options is provided, it will be passed as is
2024-01-15 10:17:58 -08:00
Bagatur
60d6a416e6 docs: fix self query diagram (#16043) 2024-01-15 10:09:20 -08:00
Mahad
f7706637a8 docs: fix documentation broken link in integrations chroma (#16041)
- **Description:** Fixed broken link in the documentation for Chroma.,
  - **Issue:** 
  - **Dependencies:**
2024-01-15 08:37:03 -08:00
Nir Kopler
0fa06732b7 community: add new gpt-3.5-turbo-1106 finetuned for cost calculation (#16039)
**Description:** Added the new gpt-3.5-turbo-1106 for **finetuned** cost
calculation,
**Issue:** no issue found open

By the information in OpenAI the pricing is the same as the older model
(0613)
2024-01-15 08:36:54 -08:00
Erick Friis
7b084b4cc7 docs: more pip installs (#15771)
- vertex chat
- google
- some pip openai
- percent and openai
- all percent
- more
- pip
- fmt
- docs: google vertex partner docs
- fmt
- docs: more pip installs
2024-01-12 18:16:00 -08:00
Bagatur
bccb07f93e core[patch]: simple prompt pretty printing (#15968) 2024-01-12 21:08:51 -05:00
Bagatur
3f75fd41cc docs: agent table fix (#15964) 2024-01-12 17:54:55 -08:00
Virat Singh
eb6e385dc5 community: Add PolygonAPIWrapper and get_last_quote endpoint (#15971)
- **Description:** Added a `PolygonAPIWrapper` and an initial
`get_last_quote` endpoint, which allows us to get the last price quote
for a given `ticker`. Once merged, I can add a Polygon tool in `tools/`
for agents to use.
- **Twitter handle:** [@virattt](https://twitter.com/virattt)

The Polygon.io Stocks API provides REST endpoints that let you query the
latest market data from all US stock exchanges.
2024-01-12 17:52:09 -08:00
Erick Friis
74bac7bda1 community[patch]: core min 0.1.9 (#15974) 2024-01-12 15:32:06 -08:00
Erick Friis
845e407e08 community[patch]: release 0.0.12 (#15973) 2024-01-12 15:27:05 -08:00
Jonathan Algar
a74f3a4979 Batch update of alt text and title attributes for images in md/mdx files across repo (#15357)
**Description:** Batch update of alt text and title attributes for
images in `md` & `mdx` files across the repo using
[alttexter](https://github.com/jonathanalgar/alttexter)/[alttexter-ghclient](https://github.com/jonathanalgar/alttexter-ghclient)
(built using LangChain/LangSmith).

**Limitation:** cannot update `ipynb` files because of [this
issue](https://github.com/langchain-ai/langchain/pull/15357#issuecomment-1885037250).
Can revisit when Docusaurus is bumped to v3.

I checked all the generated alt texts and titles and didn't find any
technical inaccuracies. That's not to say they're _perfect_, but a lot
better than what's there currently.


[Deployed](https://langchain-819yf1tbk-langchain.vercel.app/docs/modules/model_io/)
image example:


![chrome_yZQ7BF2GTj](https://github.com/langchain-ai/langchain/assets/93204286/43a9a4d4-70fd-41c4-8978-b6240ff63ffa)

You can see LangSmith traces for all the calls out to the LLM in the PRs
merged into this one:

* https://github.com/jonathanalgar/langchain/pull/6
* https://github.com/jonathanalgar/langchain/pull/4
* https://github.com/jonathanalgar/langchain/pull/3

I didn't add the following files to the PR as the images already have OK
alt texts:

*
27dca2d92f/docs/docs/integrations/providers/argilla.mdx (L3)
*
27dca2d92f/docs/docs/integrations/providers/apify.mdx (L11)

---------

Co-authored-by: github-actions <github-actions@github.com>
2024-01-12 14:37:48 -08:00
Varik Matevosyan
efe6cfafe2 community: Added Lantern as VectorStore (#12951)
Support [Lantern](https://github.com/lanterndata/lantern) as a new
VectorStore type.

- Added Lantern as VectorStore.
It will support 3 distance functions `l2 squared`, `cosine` and
`hamming` and will use `HNSW` index.
- Added tests
- Added example notebook
2024-01-12 12:00:16 -08:00
Harrison Chase
1afac77439 stop making copies of inputs (#15926) 2024-01-12 11:49:26 -08:00
Edwin Wenink
9fb09c1c30 community: fix the "page" mode in the AzureAIDocumentIntelligenceParser (bug) (#15958)
**Description**: the "page" mode in the
AzureAIDocumentIntelligenceParser is not accessible due to a wrong
membership test. The mode argument can only be a string (also see the
assertion in the `__init__`: `assert self.mode in ["single", "page",
"object", "markdown"]`, so the check `elif self.mode == ["page"]:`
always fails.
As a result, effectively the "object" mode is used when selecting the
"page" mode, which may lead to errors.

The docstring of the `AzureAIDocumentIntelligenceLoader` also ommitted
the `mode` parameter alltogether, so I added it.

**Issue**: I could not find a related issue (this class is only 3 weeks
old anyways)

**Dependencies**: this PR does not introduce or affect dependencies.

The current demo notebook and examples are not affected because they all
use the default markdown mode.
2024-01-12 11:01:28 -08:00
Mahdi Setayesh
eb76f9c9fe community: Fixing a performance issue with AzureSearch to perform batch embedding (#15594)
- **Description:** Azure Cognitive Search vector DB store performs slow
embedding as it does not utilize the batch embedding functionality. This
PR provide a fix to improve the performance of Azure Search class when
adding documents to the vector search,
  - **Issue:** #11313 ,
  - **Dependencies:** any dependencies required for this change,
- **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` from the root
of the package you've modified to check this locally.

See contribution guidelines for more information on how to write/run
tests, lint, etc: https://python.langchain.com/docs/contributing/

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/docs/integrations` directory.

If no one reviews your PR within a few days, please @-mention one of
@baskaryan, @eyurtsev, @hwchase17.
 -->
2024-01-12 10:58:55 -08:00
Christophe Bornet
bc60203d0f Add documentation for AstraDBStore (#15953)
Preview:
https://langchain-git-fork-cbornet-astradb-store-doc-langchain.vercel.app/docs/integrations/stores/astradb
2024-01-12 10:44:46 -08:00
Bagatur
c697c89ca4 docs: add agent prompt creation examples (#15957) 2024-01-12 10:26:12 -08:00
Erick Friis
69533c8628 multiple[patch]: .post releases and pyproject metadata (#15962) 2024-01-12 10:09:02 -08:00
Rihards Gravis
6a48ea43ec docs: Update Robocorp Action Server installation instructions (#15943)
**Description:**

Remove section on how to install Action Server and direct the users t o
the instructions on Robocorp repository.

**Reason:**

Robocorp Action Server has moved from a pip installation to a standalone
cli application and is due for changes. Because of that, leaving only
LangChain integration relevant part in the documentation.
2024-01-12 09:46:18 -08:00
Erick Friis
6a2889a4ec infra: retry release if not found on test pypi (#15913)
<!-- Thank you for contributing to LangChain!

Please title your PR "<package>: <description>", where <package> is
whichever of langchain, community, core, experimental, etc. is being
modified.

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,
- **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` from the root
of the package you've modified to check this locally.

See contribution guidelines for more information on how to write/run
tests, lint, etc: https://python.langchain.com/docs/contributing/

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/docs/integrations` directory.

If no one reviews your PR within a few days, please @-mention one of
@baskaryan, @eyurtsev, @hwchase17.
 -->
2024-01-12 09:36:52 -08:00
Erick Friis
95020637bc openai[patch]: 0.0.2.post1, urls (#15961) 2024-01-12 09:36:37 -08:00
ChengZi
d5808f786c community: Support milvus partition key. (#15740)
- **Description:** Milvus's partition key is an important feature. It
can support multi-tenancy. We hope to introduce this feature.
https://milvus.io/docs/partition_key.md
  - **Issue:** No
  - **Dependencies:** No
  - **Twitter handle:** No

---------

Signed-off-by: ChengZi <chen.zhang@zilliz.com>
Co-authored-by: Harrison Chase <hw.chase.17@gmail.com>
2024-01-12 09:15:03 -08:00
enfeng
13b90232c1 langchain-google-genai[patch]: Add support for end_point and transport parameters to the Gemini API (#15532)
Add support for end_point and transport parameters to the Gemini API

---------

Co-authored-by: yangenfeng <yangenfeng@xiaoniangao.com>
Co-authored-by: Erick Friis <erick@langchain.dev>
2024-01-12 08:52:00 -08:00
ohbeep
9b3962fc25 community: Add support of "http" URI for Milvus (#12710) (#15683)
- **Description:** Add support of HTTP URI for Milvus
  - **Issue:** #12710 
  - **Dependencies:** N/A,
2024-01-11 21:55:35 -08:00
Raunak
e26e1f8b37 community: Added functions to make async calls to HuggingFaceHub's embedding endpoint in HuggingFaceHubEmbeddings class (#15737)
**Description:**
Added aembed_documents() and aembed_query() async functions in
HuggingFaceHubEmbeddings class in
langchain_community\embeddings\huggingface_hub.py file. It will support
to make async calls to HuggingFaceHub's
embedding endpoint and generate embeddings asynchronously.

Test Cases: Added test_huggingfacehub_embedding_async_documents() and
test_huggingfacehub_embedding_async_query()
functions in test_huggingface_hub.py file to test the two async
functions created in HuggingFaceHubEmbeddings class.

Documentation: Updated huggingfacehub.ipynb with steps to install
huggingface_hub package and use
HuggingFaceHubEmbeddings.

**Dependencies:** None,
**Twitter handle:** I do not have a Twitter account

---------

Co-authored-by: H161961 <Raunak.Raunak@Honeywell.com>
2024-01-11 21:52:55 -08:00
Tal
eb9b334a6b Enable customizing the output parser of OpenAIFunctionsAgent (#15827)
- **Description:** This PR defines the output parser of
OpenAIFunctionsAgent as an attribute, enabling customization and
subclassing of the parser logic.
- **Issue:** Subclassing is currently impossible as the
`OpenAIFunctionsAgentOutputParser` class is hard coded into the `plan`
and `aplan` methods
  - **Dependencies:** None

<!-- Thank you for contributing to LangChain!

Please title your PR "<package>: <description>", where <package> is
whichever of langchain, community, core, experimental, etc. is being
modified.

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,
- **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` from the root
of the package you've modified to check this locally.

See contribution guidelines for more information on how to write/run
tests, lint, etc: https://python.langchain.com/docs/contributing/

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/docs/integrations` directory.

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

---------

Co-authored-by: Harrison Chase <hw.chase.17@gmail.com>
2024-01-11 21:52:36 -08:00
Mu Xian Ming
560bb49c99 docs: redis_chat_message_history.ipynb integration doc (#15789)
- **Description:** Updated the docs for the memory integration module
redis_chat_message_history.ipynb
  - **Issue:** #15664
  - **Dependencies:** N/A

Co-authored-by: Mu Xianming <mu.xianming@lmwn.com>
2024-01-11 21:42:31 -08:00
Christophe Bornet
81d1ba05dc Add a BaseStore backed by AstraDB (#15812)
- **Description:** this change adds a `BaseStore` backed by AstraDB
  - **Twitter handle:** cbornet_
2024-01-11 21:41:24 -08:00
manishsahni2000
74d9fc2f9e PR community:Removing knn beta content in mongodb atlas vectorstore (#15865)
<!-- Thank you for contributing to LangChain!

Please title your PR "<package>: <description>", where <package> is
whichever of langchain, community, core, experimental, etc. is being
modified.

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,
- **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` from the root
of the package you've modified to check this locally.

See contribution guidelines for more information on how to write/run
tests, lint, etc: https://python.langchain.com/docs/contributing/

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/docs/integrations` directory.

If no one reviews your PR within a few days, please @-mention one of
@baskaryan, @eyurtsev, @hwchase17.
 -->
2024-01-11 21:40:54 -08:00
shahrin014
bdd90ae2ee community: Ollama - Pass headers to post request (#15881)
## Feature
- Set additional headers in constructor
- Headers will be sent in post request

This feature is useful if deploying Ollama on a cloud service such as
hugging face, which requires authentication tokens to be passed in the
request header.

## Tests
- Test if header is passed
- Test if header is not passed
2024-01-11 21:40:35 -08:00
Xin Liu
5efec068c9 feat: Implement stream interface (#15875)
<!-- Thank you for contributing to LangChain!

Please title your PR "<package>: <description>", where <package> is
whichever of langchain, community, core, experimental, etc. is being
modified.

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,
- **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` from the root
of the package you've modified to check this locally.

See contribution guidelines for more information on how to write/run
tests, lint, etc: https://python.langchain.com/docs/contributing/

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/docs/integrations` directory.

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

Major changes:

- Rename `wasm_chat.py` to `llama_edge.py`
- Rename the `WasmChatService` class to `ChatService`
- Implement the `stream` interface for `ChatService`
- Add `test_chat_wasm_service_streaming` in the integration test
- Update `llama_edge.ipynb`

---------

Signed-off-by: Xin Liu <sam@secondstate.io>
2024-01-11 21:32:48 -08:00
Massimiliano Pronesti
ec4dab0449 feat(community): make Amadeus toolkit LLM-agnostic (#15879)
- **Description:** `AmadeusToolkit` and `AmadeusClosestAirport`
contained a hardcoded call to `ChatOpenAI`. This PR makes it
LLM-independent, while guaranteeing backward compatibility.
  - **Issue:** #15847 
  - **Dependencies:** None
   
@baskaryan 

<!-- Thank you for contributing to LangChain!

Please title your PR "<package>: <description>", where <package> is
whichever of langchain, community, core, experimental, etc. is being
modified.

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,
- **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` from the root
of the package you've modified to check this locally.

See contribution guidelines for more information on how to write/run
tests, lint, etc: https://python.langchain.com/docs/contributing/

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/docs/integrations` directory.

If no one reviews your PR within a few days, please @-mention one of
@baskaryan, @eyurtsev, @hwchase17.
 -->
2024-01-11 21:32:03 -08:00
JanHorcicka
f454e95461 langchain: fix OutputParserException (#15914) (#15916)
**Description:**

Fixes OutputParserException thrown by the output_parser when 'query' is
'Null'.

Replace this entire comment with:
- **Description:** Current implentation of output_parser throws
OutputParserException if the response from the LLM contains `query:
null`. This unfortunately happens for my use case. And since there is no
way to modify the prompt used in SelfQueryRetriever, then we have to fix
it here, so it doesn't crash.
  - **Issue:** https://github.com/langchain-ai/langchain/issues/15914

Didn't run tests. `make test` is not working. There is no `test` rule in
the `Makefile`.

Co-authored-by: Jan Horcicka <jhorcick@amazon.com>
2024-01-11 21:26:45 -08:00
Yacine
782dd44be9 <langchain_community.vectorstores>:<Fix pinecone.py __init__ docsrting instruction> (#15922)
- **Description:** The pinecone docstring instructs to pass the
embedding query text causing the warning below. It should be the
embeddings object.
warning message: UserWarning: Passing in `embedding` as a Callable is
deprecated. Please pass in an Embeddings object instead.
  - **Issue:** NA
  - **Dependencies:** None


@baskaryan
2024-01-11 21:26:33 -08:00
Nuno Campos
112208baa5 Passthrough configurable primitive values as tracer metadata (#15915)
<!-- Thank you for contributing to LangChain!

Please title your PR "<package>: <description>", where <package> is
whichever of langchain, community, core, experimental, etc. is being
modified.

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,
- **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` from the root
of the package you've modified to check this locally.

See contribution guidelines for more information on how to write/run
tests, lint, etc: https://python.langchain.com/docs/contributing/

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/docs/integrations` directory.

If no one reviews your PR within a few days, please @-mention one of
@baskaryan, @eyurtsev, @hwchase17.
 -->
2024-01-11 18:47:55 -08:00
William FH
129552e3d6 Rm deprecated (#15920)
Remove the usage of deprecated methods in the test runner.
2024-01-11 18:10:49 -08:00
Nuno Campos
438beb6c94 Pass config specs through ensemble retriever (#15917)
<!-- Thank you for contributing to LangChain!

Please title your PR "<package>: <description>", where <package> is
whichever of langchain, community, core, experimental, etc. is being
modified.

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,
- **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` from the root
of the package you've modified to check this locally.

See contribution guidelines for more information on how to write/run
tests, lint, etc: https://python.langchain.com/docs/contributing/

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/docs/integrations` directory.

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

---------

Co-authored-by: Harrison Chase <hw.chase.17@gmail.com>
2024-01-11 16:22:17 -08:00
Erick Friis
ebb6ad4f7a mistralai[patch]: release 0.0.2 (#15912) 2024-01-11 13:42:04 -08:00
Erick Friis
437cebc955 core[patch]: release 0.1.10 (#15911) 2024-01-11 13:39:06 -08:00
Harrison Chase
80d41a8da3 add old serializable mapping (#15906) 2024-01-11 13:03:12 -08:00
392 changed files with 20272 additions and 3468 deletions

View File

@@ -1,9 +1,12 @@
blank_issues_enabled: true
blank_issues_enabled: false
version: 2.1
contact_links:
- name: 🤔 Question or Problem
about: Ask a question or ask about a problem in GitHub Discussions.
url: https://github.com/langchain-ai/langchain/discussions
url: https://www.github.com/langchain-ai/langchain/discussions/categories/q-a
- name: Discord
url: https://discord.gg/6adMQxSpJS
about: General community discussions
- name: Show and tell
about: Show what you built with LangChain
url: https://www.github.com/langchain-ai/langchain/discussions/categories/show-and-tell

25
.github/ISSUE_TEMPLATE/privileged.yml vendored Normal file
View File

@@ -0,0 +1,25 @@
name: 🔒 Privileged
description: You are a LangChain maintainer, or was asked directly by a maintainer to create an issue here. If not, check the other options.
body:
- type: markdown
attributes:
value: |
Thanks for your interest in LangChain! 🚀
If you are not a LangChain maintainer or were not asked directly by a maintainer to create an issue, then please start the conversation in a [Question in GitHub Discussions](https://github.com/langchain-ai/langchain/discussions/categories/q-a) instead.
You are a LangChain maintainer if you maintain any of the packages inside of the LangChain repository
or are a regular contributor to LangChain with previous merged merged pull requests.
- type: checkboxes
id: privileged
attributes:
label: Privileged issue
description: Confirm that you are allowed to create an issue here.
options:
- label: I am a LangChain maintainer, or was asked directly by a LangChain maintainer to create an issue here.
required: true
- type: textarea
id: content
attributes:
label: Issue Content
description: Add the content of the issue here.

View File

@@ -32,7 +32,7 @@ concurrency:
cancel-in-progress: true
env:
POETRY_VERSION: "1.6.1"
POETRY_VERSION: "1.7.1"
jobs:
lint:

View File

@@ -9,7 +9,7 @@ on:
description: "From which folder this pipeline executes"
env:
POETRY_VERSION: "1.6.1"
POETRY_VERSION: "1.7.1"
jobs:
build:

View File

@@ -13,7 +13,7 @@ on:
description: "Relative path to the langchain library folder"
env:
POETRY_VERSION: "1.6.1"
POETRY_VERSION: "1.7.1"
jobs:
build:

View File

@@ -8,10 +8,11 @@ on:
type: string
env:
POETRY_VERSION: "1.6.1"
POETRY_VERSION: "1.7.1"
jobs:
build:
environment: Scheduled testing
defaults:
run:
working-directory: ${{ inputs.working-directory }}
@@ -51,6 +52,9 @@ jobs:
MISTRAL_API_KEY: ${{ secrets.MISTRAL_API_KEY }}
TOGETHER_API_KEY: ${{ secrets.TOGETHER_API_KEY }}
OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }}
NVIDIA_API_KEY: ${{ secrets.NVIDIA_API_KEY }}
GOOGLE_SEARCH_API_KEY: ${{ secrets.GOOGLE_SEARCH_API_KEY }}
GOOGLE_CSE_ID: ${{ secrets.GOOGLE_CSE_ID }}
run: |
make integration_tests

View File

@@ -13,7 +13,7 @@ on:
description: "Relative path to the langchain library folder"
env:
POETRY_VERSION: "1.6.1"
POETRY_VERSION: "1.7.1"
WORKDIR: ${{ inputs.working-directory == '' && '.' || inputs.working-directory }}
# This env var allows us to get inline annotations when ruff has complaints.

View File

@@ -16,11 +16,12 @@ on:
env:
PYTHON_VERSION: "3.10"
POETRY_VERSION: "1.6.1"
POETRY_VERSION: "1.7.1"
jobs:
build:
if: github.ref == 'refs/heads/master'
environment: Scheduled testing
runs-on: ubuntu-latest
outputs:
@@ -117,11 +118,18 @@ jobs:
# are not found on test PyPI can be resolved and installed anyway.
# (https://test.pypi.org/simple). This will include the PKG_NAME==VERSION
# package because VERSION will not have been uploaded to regular PyPI yet.
#
# - attempt install again after 5 seconds if it fails because there is
# sometimes a delay in availability on test pypi
run: |
poetry run pip install \
--extra-index-url https://test.pypi.org/simple/ \
"$PKG_NAME==$VERSION"
"$PKG_NAME==$VERSION" || \
( \
sleep 5 && \
poetry run pip install \
--extra-index-url https://test.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.
@@ -163,6 +171,9 @@ jobs:
MISTRAL_API_KEY: ${{ secrets.MISTRAL_API_KEY }}
TOGETHER_API_KEY: ${{ secrets.TOGETHER_API_KEY }}
OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }}
NVIDIA_API_KEY: ${{ secrets.NVIDIA_API_KEY }}
GOOGLE_SEARCH_API_KEY: ${{ secrets.GOOGLE_SEARCH_API_KEY }}
GOOGLE_CSE_ID: ${{ secrets.GOOGLE_CSE_ID }}
run: make integration_tests
working-directory: ${{ inputs.working-directory }}

View File

@@ -13,7 +13,7 @@ on:
description: "Relative path to the langchain library folder"
env:
POETRY_VERSION: "1.6.1"
POETRY_VERSION: "1.7.1"
jobs:
build:

View File

@@ -9,7 +9,7 @@ on:
description: "From which folder this pipeline executes"
env:
POETRY_VERSION: "1.6.1"
POETRY_VERSION: "1.7.1"
PYTHON_VERSION: "3.10"
jobs:

View File

@@ -6,7 +6,7 @@ on:
- cron: '0 13 * * *'
env:
POETRY_VERSION: "1.6.1"
POETRY_VERSION: "1.7.1"
jobs:
build:

View File

@@ -24,7 +24,7 @@ concurrency:
cancel-in-progress: true
env:
POETRY_VERSION: "1.6.1"
POETRY_VERSION: "1.7.1"
WORKDIR: "templates"
jobs:

View File

@@ -49,7 +49,7 @@ The LangChain libraries themselves are made up of several different packages.
- **[`langchain-community`](libs/community)**: Third party integrations.
- **[`langchain`](libs/langchain)**: Chains, agents, and retrieval strategies that make up an application's cognitive architecture.
![LangChain Stack](docs/static/img/langchain_stack.png)
![Diagram outlining the hierarchical organization of the LangChain framework, displaying the interconnected parts across multiple layers.](docs/static/img/langchain_stack.png "LangChain Architecture Overview")
## 🧱 What can you build with LangChain?
**❓ Retrieval augmented generation**

View File

@@ -82,7 +82,7 @@
"prompt = ChatPromptTemplate.from_template(template)\n",
"\n",
"# LLM\n",
"from langchain_community.llms import Together\n",
"from langchain_together import Together\n",
"\n",
"llm = Together(\n",
" model=\"mistralai/Mixtral-8x7B-Instruct-v0.1\",\n",

View File

@@ -6,7 +6,7 @@ pydantic<2
autodoc_pydantic==1.8.0
myst_parser
nbsphinx==0.8.9
sphinx==4.5.0
sphinx>=5
sphinx-autobuild==2021.3.14
sphinx_rtd_theme==1.0.0
sphinx-typlog-theme==0.8.0

View File

@@ -32,7 +32,7 @@ For a [development container](https://containers.dev/), see the [.devcontainer f
### Dependency Management: Poetry and other env/dependency managers
This project utilizes [Poetry](https://python-poetry.org/) v1.6.1+ as a dependency manager.
This project utilizes [Poetry](https://python-poetry.org/) v1.7.1+ as a dependency manager.
❗Note: *Before installing Poetry*, if you use `Conda`, create and activate a new Conda env (e.g. `conda create -n langchain python=3.9`)
@@ -75,7 +75,7 @@ make test
If during installation you receive a `WheelFileValidationError` for `debugpy`, please make sure you are running
Poetry v1.6.1+. This bug was present in older versions of Poetry (e.g. 1.4.1) and has been resolved in newer releases.
If you are still seeing this bug on v1.6.1, you may also try disabling "modern installation"
If you are still seeing this bug on v1.6.1+, you may also try disabling "modern installation"
(`poetry config installer.modern-installation false`) and re-installing requirements.
See [this `debugpy` issue](https://github.com/microsoft/debugpy/issues/1246) for more details.

View File

@@ -177,7 +177,7 @@
"source": [
"## Get the prompts\n",
"\n",
"An important part of every chain is the prompts that are used. You can get the graphs present in the chain:"
"An important part of every chain is the prompts that are used. You can get the prompts present in the chain:"
]
},
{

View File

@@ -14,7 +14,7 @@ This framework consists of several parts.
- **[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.
![LangChain Diagram](/svg/langchain_stack.svg)
![Diagram outlining the hierarchical organization of the LangChain framework, displaying the interconnected parts across multiple layers.](/svg/langchain_stack.svg "LangChain Framework Overview")
Together, these products simplify the entire application lifecycle:
- **Develop**: Write your applications in LangChain/LangChain.js. Hit the ground running using Templates for reference.

View File

@@ -59,7 +59,7 @@ In this quickstart, we will walk through a few different ways of doing that.
We will start with a simple LLM chain, which just relies on information in the prompt template to respond.
Next, we will build a retrieval chain, which fetches data from a separate database and passes that into the prompt template.
We will then add in chat history, to create a conversation retrieval chain. This allows you interact in a chat manner with this LLM, so it remembers previous questions.
Finally, we will build an agent - which utilizes and LLM to determine whether or not it needs to fetch data to answer questions.
Finally, we will build an agent - which utilizes an LLM to determine whether or not it needs to fetch data to answer questions.
We will cover these at a high level, but there are lot of details to all of these!
We will link to relevant docs.

View File

@@ -12,7 +12,7 @@ Platforms with tracing capabilities like [LangSmith](/docs/langsmith/) and [Wand
For anyone building production-grade LLM applications, we highly recommend using a platform like this.
![LangSmith run](../../static/img/run_details.png)
![Screenshot of the LangSmith debugging interface showing an AgentExecutor run with input and output details, and a run tree visualization.](../../static/img/run_details.png "LangSmith Debugging Interface")
## `set_debug` and `set_verbose`

View File

@@ -53,9 +53,16 @@
"- AquilaChat-7B"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Set up"
]
},
{
"cell_type": "code",
"execution_count": null,
"execution_count": 1,
"metadata": {},
"outputs": [],
"source": [
@@ -65,83 +72,105 @@
"from langchain_community.chat_models import QianfanChatEndpoint\n",
"from langchain_core.language_models.chat_models import HumanMessage\n",
"\n",
"os.environ[\"QIANFAN_AK\"] = \"your_ak\"\n",
"os.environ[\"QIANFAN_SK\"] = \"your_sk\"\n",
"\n",
"chat = QianfanChatEndpoint(\n",
" streaming=True,\n",
")\n",
"res = chat([HumanMessage(content=\"write a funny joke\")])"
"os.environ[\"QIANFAN_AK\"] = \"Your_api_key\"\n",
"os.environ[\"QIANFAN_SK\"] = \"You_secret_Key\""
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Usage"
]
},
{
"cell_type": "code",
"execution_count": 6,
"execution_count": 2,
"metadata": {},
"outputs": [
{
"name": "stderr",
"output_type": "stream",
"text": [
"[INFO] [09-15 20:00:36] logging.py:55 [t:139698882193216]: requesting llm api endpoint: /chat/eb-instant\n",
"[INFO] [09-15 20:00:37] logging.py:55 [t:139698882193216]: async requesting llm api endpoint: /chat/eb-instant\n"
]
},
"data": {
"text/plain": [
"AIMessage(content='您好!请问您需要什么帮助?我将尽力回答您的问题。')"
]
},
"execution_count": 2,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"chat = QianfanChatEndpoint(streaming=True)\n",
"messages = [HumanMessage(content=\"Hello\")]\n",
"chat.invoke(messages)"
]
},
{
"cell_type": "code",
"execution_count": 3,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"AIMessage(content='您好!有什么我可以帮助您的吗?')"
]
},
"execution_count": 3,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"await chat.ainvoke(messages)"
]
},
{
"cell_type": "code",
"execution_count": 4,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"[AIMessage(content='您好!有什么我可以帮助您的吗?')]"
]
},
"execution_count": 4,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"chat.batch([messages])"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Streaming"
]
},
{
"cell_type": "code",
"execution_count": 5,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"chat resp: content='您好,您似乎输入' additional_kwargs={} example=False\n",
"chat resp: content='了一个话题标签,请问需要我帮您找到什么资料或者帮助您解答什么问题吗?' additional_kwargs={} example=False\n",
"chat resp: content='' additional_kwargs={} example=False\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"[INFO] [09-15 20:00:39] logging.py:55 [t:139698882193216]: async requesting llm api endpoint: /chat/eb-instant\n"
]
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"generations=[[ChatGeneration(text=\"The sea is a vast expanse of water that covers much of the Earth's surface. It is a source of travel, trade, and entertainment, and is also a place of scientific exploration and marine conservation. The sea is an important part of our world, and we should cherish and protect it.\", generation_info={'finish_reason': 'finished'}, message=AIMessage(content=\"The sea is a vast expanse of water that covers much of the Earth's surface. It is a source of travel, trade, and entertainment, and is also a place of scientific exploration and marine conservation. The sea is an important part of our world, and we should cherish and protect it.\", additional_kwargs={}, example=False))]] llm_output={} run=[RunInfo(run_id=UUID('d48160a6-5960-4c1d-8a0e-90e6b51a209b'))]\n",
"astream content='The sea is a vast' additional_kwargs={} example=False\n",
"astream content=' expanse of water, a place of mystery and adventure. It is the source of many cultures and civilizations, and a center of trade and exploration. The sea is also a source of life and beauty, with its unique marine life and diverse' additional_kwargs={} example=False\n",
"astream content=' coral reefs. Whether you are swimming, diving, or just watching the sea, it is a place that captivates the imagination and transforms the spirit.' additional_kwargs={} example=False\n"
"您好!有什么我可以帮助您的吗?\n"
]
}
],
"source": [
"from langchain.schema import HumanMessage\n",
"from langchain_community.chat_models import QianfanChatEndpoint\n",
"\n",
"chatLLM = QianfanChatEndpoint()\n",
"res = chatLLM.stream([HumanMessage(content=\"hi\")], streaming=True)\n",
"for r in res:\n",
" print(\"chat resp:\", r)\n",
"\n",
"\n",
"async def run_aio_generate():\n",
" resp = await chatLLM.agenerate(\n",
" messages=[[HumanMessage(content=\"write a 20 words sentence about sea.\")]]\n",
" )\n",
" print(resp)\n",
"\n",
"\n",
"await run_aio_generate()\n",
"\n",
"\n",
"async def run_aio_stream():\n",
" async for res in chatLLM.astream(\n",
" [HumanMessage(content=\"write a 20 words sentence about sea.\")]\n",
" ):\n",
" print(\"astream\", res)\n",
"\n",
"\n",
"await run_aio_stream()"
"try:\n",
" for chunk in chat.stream(messages):\n",
" print(chunk.content, end=\"\", flush=True)\n",
"except TypeError as e:\n",
" print(\"\")"
]
},
{
@@ -151,39 +180,36 @@
"source": [
"## Use different models in Qianfan\n",
"\n",
"In the case you want to deploy your own model based on Ernie Bot or third-party open-source model, you could follow these steps:\n",
"The default model is ERNIE-Bot-turbo, in the case you want to deploy your own model based on Ernie Bot or third-party open-source model, you could follow these steps:\n",
"\n",
"- 1. Optional, if the model are included in the default models, skip itDeploy your model in Qianfan Console, get your own customized deploy endpoint.\n",
"- 2. Set up the field called `endpoint` in the initialization:"
"1. (Optional, if the model are included in the default models, skip it) Deploy your model in Qianfan Console, get your own customized deploy endpoint.\n",
"2. Set up the field called `endpoint` in the initialization:"
]
},
{
"cell_type": "code",
"execution_count": 7,
"execution_count": 6,
"metadata": {},
"outputs": [
{
"name": "stderr",
"output_type": "stream",
"text": [
"[INFO] [09-15 20:00:50] logging.py:55 [t:139698882193216]: requesting llm api endpoint: /chat/bloomz_7b1\n"
]
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"content='你好!很高兴见到你。' additional_kwargs={} example=False\n"
]
"data": {
"text/plain": [
"AIMessage(content='Hello可以回答问题了我会竭尽全力为您解答请问有什么问题吗')"
]
},
"execution_count": 6,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"chatBloom = QianfanChatEndpoint(\n",
"chatBot = QianfanChatEndpoint(\n",
" streaming=True,\n",
" model=\"BLOOMZ-7B\",\n",
" model=\"ERNIE-Bot\",\n",
")\n",
"res = chatBloom([HumanMessage(content=\"hi\")])\n",
"print(res)"
"\n",
"messages = [HumanMessage(content=\"Hello\")]\n",
"chatBot.invoke(messages)"
]
},
{
@@ -202,35 +228,25 @@
},
{
"cell_type": "code",
"execution_count": 8,
"execution_count": 7,
"metadata": {},
"outputs": [
{
"name": "stderr",
"output_type": "stream",
"text": [
"[INFO] [09-15 20:00:57] logging.py:55 [t:139698882193216]: requesting llm api endpoint: /chat/eb-instant\n"
]
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"content='您好,您似乎输入' additional_kwargs={} example=False\n",
"content='了一个文本字符串,但并没有给出具体的问题或场景。' additional_kwargs={} example=False\n",
"content='如果您能提供更多信息,我可以更好地回答您的问题。' additional_kwargs={} example=False\n",
"content='' additional_kwargs={} example=False\n"
]
"data": {
"text/plain": [
"AIMessage(content='您好!有什么我可以帮助您的吗?')"
]
},
"execution_count": 7,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"res = chat.stream(\n",
" [HumanMessage(content=\"hi\")],\n",
"chat.invoke(\n",
" [HumanMessage(content=\"Hello\")],\n",
" **{\"top_p\": 0.4, \"temperature\": 0.1, \"penalty_score\": 1},\n",
")\n",
"\n",
"for r in res:\n",
" print(r)"
")"
]
}
],
@@ -250,7 +266,7 @@
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.11.5"
"version": "3.9.18"
},
"vscode": {
"interpreter": {

View File

@@ -16,29 +16,58 @@
"# ErnieBotChat\n",
"\n",
"[ERNIE-Bot](https://cloud.baidu.com/doc/WENXINWORKSHOP/s/jlil56u11) is a large language model developed by Baidu, covering a huge amount of Chinese data.\n",
"This notebook covers how to get started with ErnieBot chat models.\n",
"This notebook covers how to get started with ErnieBot chat models."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"**Deprecated Warning**\n",
"\n",
"We recommend users using `langchain_community.chat_models.ErnieBotChat` \n",
"to use `langchain_community.chat_models.QianfanChatEndpoint` instead.\n",
"\n",
"documentation for `QianfanChatEndpoint` is [here](./baidu_qianfan_endpoint).\n",
"\n",
"they are 4 why we recommend users to use `QianfanChatEndpoint`:\n",
"\n",
"**Note:** We recommend users using this class to switch to [Baidu Qianfan](./baidu_qianfan_endpoint). they are 3 why we recommend users to use `QianfanChatEndpoint`:\n",
"1. `QianfanChatEndpoint` support more LLM in the Qianfan platform.\n",
"2. `QianfanChatEndpoint` support streaming mode.\n",
"3. `QianfanChatEndpoint` support function calling usgage.\n",
"\n",
"4. `ErnieBotChat` is lack of maintenance and deprecated."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Some tips for migration:\n",
"\n",
"- change `ernie_client_id` to `qianfan_ak`, also change `ernie_client_secret` to `qianfan_sk`.\n",
"- install `qianfan` package. \n",
" ```\n",
" pip install qianfan\n",
" ```"
"- install `qianfan` package. like `pip install qianfan`\n",
"- change `ErnieBotChat` to `QianfanChatEndpoint`."
]
},
{
"cell_type": "code",
"execution_count": 7,
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"from langchain.schema import HumanMessage\n",
"from langchain_community.chat_models import ErnieBotChat"
"from langchain_community.chat_models.baidu_qianfan_endpoint import QianfanChatEndpoint\n",
"\n",
"chat = QianfanChatEndpoint(\n",
" qianfan_ak=\"your qianfan ak\",\n",
" qianfan_sk=\"your qianfan sk\",\n",
")"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Usage"
]
},
{
@@ -47,6 +76,9 @@
"metadata": {},
"outputs": [],
"source": [
"from langchain.schema import HumanMessage\n",
"from langchain_community.chat_models import ErnieBotChat\n",
"\n",
"chat = ErnieBotChat(\n",
" ernie_client_id=\"YOUR_CLIENT_ID\", ernie_client_secret=\"YOUR_CLIENT_SECRET\"\n",
")"

View File

@@ -320,11 +320,26 @@
"4. Message may be blocked if they violate the safety checks of the LLM. In this case, the model will return an empty response."
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "75fdfad6",
"metadata": {},
"outputs": [],
"source": []
},
{
"cell_type": "markdown",
"id": "92b5aca5",
"metadata": {},
"source": []
"source": [
"## Additional Configuraation\n",
"\n",
"You can pass the following parameters to ChatGoogleGenerativeAI in order to customize the SDK's behavior:\n",
"\n",
"- `client_options`: [Client Options](https://googleapis.dev/python/google-api-core/latest/client_options.html#module-google.api_core.client_options) to pass to the Google API Client, such as a custom `client_options[\"api_endpoint\"]`\n",
"- `transport`: The transport method to use, such as `rest`, `grpc`, or `grpc_asyncio`."
]
}
],
"metadata": {

View File

@@ -11,7 +11,6 @@
]
},
{
"attachments": {},
"cell_type": "markdown",
"metadata": {},
"source": [
@@ -35,29 +34,18 @@
},
{
"cell_type": "code",
"execution_count": 3,
"execution_count": null,
"metadata": {
"tags": []
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"\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.2\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;49mpip install --upgrade pip\u001b[0m\n",
"Note: you may need to restart the kernel to use updated packages.\n"
]
}
],
"outputs": [],
"source": [
"%pip install --upgrade --quiet langchain-google-vertexai"
]
},
{
"cell_type": "code",
"execution_count": 1,
"execution_count": 2,
"metadata": {},
"outputs": [],
"source": [
@@ -67,7 +55,7 @@
},
{
"cell_type": "code",
"execution_count": 2,
"execution_count": null,
"metadata": {},
"outputs": [
{
@@ -76,7 +64,7 @@
"AIMessage(content=\" J'aime la programmation.\")"
]
},
"execution_count": 2,
"execution_count": 8,
"metadata": {},
"output_type": "execute_result"
}
@@ -92,6 +80,40 @@
"chain.invoke({})"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Gemini doesn't support SystemMessage at the moment, but it can be added to the first human message in the row. If you want such behavior, just set the `convert_system_message_to_human` to `True`:"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"AIMessage(content=\"J'aime la programmation.\")"
]
},
"execution_count": 9,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"system = \"You are a helpful assistant who translate English to French\"\n",
"human = \"Translate this sentence from English to French. I love programming.\"\n",
"prompt = ChatPromptTemplate.from_messages([(\"system\", system), (\"human\", human)])\n",
"\n",
"chat = ChatVertexAI(model_name=\"gemini-pro\", convert_system_message_to_human=True)\n",
"\n",
"chain = prompt | chat\n",
"chain.invoke({})"
]
},
{
"cell_type": "markdown",
"metadata": {},
@@ -101,7 +123,7 @@
},
{
"cell_type": "code",
"execution_count": 3,
"execution_count": 4,
"metadata": {},
"outputs": [
{
@@ -110,7 +132,7 @@
"AIMessage(content=' プログラミングが大好きです')"
]
},
"execution_count": 3,
"execution_count": 4,
"metadata": {},
"output_type": "execute_result"
}
@@ -122,6 +144,8 @@
"human = \"{text}\"\n",
"prompt = ChatPromptTemplate.from_messages([(\"system\", system), (\"human\", human)])\n",
"\n",
"chat = ChatVertexAI()\n",
"\n",
"chain = prompt | chat\n",
"\n",
"chain.invoke(\n",
@@ -134,7 +158,6 @@
]
},
{
"attachments": {},
"cell_type": "markdown",
"metadata": {
"execution": {
@@ -154,7 +177,7 @@
},
{
"cell_type": "code",
"execution_count": 4,
"execution_count": null,
"metadata": {
"tags": []
},
@@ -165,27 +188,51 @@
"text": [
" ```python\n",
"def is_prime(n):\n",
" if n <= 1:\n",
" return False\n",
" for i in range(2, n):\n",
" if n % i == 0:\n",
" return False\n",
" return True\n",
" \"\"\"\n",
" Check if a number is prime.\n",
"\n",
" Args:\n",
" n: The number to check.\n",
"\n",
" Returns:\n",
" True if n is prime, False otherwise.\n",
" \"\"\"\n",
"\n",
" # If n is 1, it is not prime.\n",
" if n == 1:\n",
" return False\n",
"\n",
" # Iterate over all numbers from 2 to the square root of n.\n",
" for i in range(2, int(n ** 0.5) + 1):\n",
" # If n is divisible by any number from 2 to its square root, it is not prime.\n",
" if n % i == 0:\n",
" return False\n",
"\n",
" # If n is divisible by no number from 2 to its square root, it is prime.\n",
" return True\n",
"\n",
"\n",
"def find_prime_numbers(n):\n",
" prime_numbers = []\n",
" for i in range(2, n + 1):\n",
" if is_prime(i):\n",
" prime_numbers.append(i)\n",
" return prime_numbers\n",
" \"\"\"\n",
" Find all prime numbers up to a given number.\n",
"\n",
"print(find_prime_numbers(100))\n",
"```\n",
" Args:\n",
" n: The upper bound for the prime numbers to find.\n",
"\n",
"Output:\n",
" Returns:\n",
" A list of all prime numbers up to n.\n",
" \"\"\"\n",
"\n",
"```\n",
"[2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97]\n",
" # Create a list of all numbers from 2 to n.\n",
" numbers = list(range(2, n + 1))\n",
"\n",
" # Iterate over the list of numbers and remove any that are not prime.\n",
" for number in numbers:\n",
" if not is_prime(number):\n",
" numbers.remove(number)\n",
"\n",
" # Return the list of prime numbers.\n",
" return numbers\n",
"```\n"
]
}
@@ -199,6 +246,143 @@
"print(message.content)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Full generation info\n",
"\n",
"We can use the `generate` method to get back extra metadata like [safety attributes](https://cloud.google.com/vertex-ai/docs/generative-ai/learn/responsible-ai#safety_attribute_confidence_scoring) and not just chat completions\n",
"\n",
"Note that the `generation_info` will be different depending if you're using a gemini model or not.\n",
"\n",
"### Gemini model\n",
"\n",
"`generation_info` will include:\n",
"\n",
"- `is_blocked`: whether generation was blocked or not\n",
"- `safety_ratings`: safety ratings' categories and probability labels"
]
},
{
"cell_type": "code",
"execution_count": 12,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"{'is_blocked': False,\n",
" 'safety_ratings': [{'category': 'HARM_CATEGORY_HARASSMENT',\n",
" 'probability_label': 'NEGLIGIBLE'},\n",
" {'category': 'HARM_CATEGORY_HATE_SPEECH',\n",
" 'probability_label': 'NEGLIGIBLE'},\n",
" {'category': 'HARM_CATEGORY_SEXUALLY_EXPLICIT',\n",
" 'probability_label': 'NEGLIGIBLE'},\n",
" {'category': 'HARM_CATEGORY_DANGEROUS_CONTENT',\n",
" 'probability_label': 'NEGLIGIBLE'}]}\n"
]
}
],
"source": [
"from pprint import pprint\n",
"\n",
"from langchain_core.messages import HumanMessage\n",
"from langchain_google_vertexai import ChatVertexAI, HarmBlockThreshold, HarmCategory\n",
"\n",
"human = \"Translate this sentence from English to French. I love programming.\"\n",
"messages = [HumanMessage(content=human)]\n",
"\n",
"\n",
"chat = ChatVertexAI(\n",
" model_name=\"gemini-pro\",\n",
" safety_settings={\n",
" HarmCategory.HARM_CATEGORY_HATE_SPEECH: HarmBlockThreshold.BLOCK_LOW_AND_ABOVE\n",
" },\n",
")\n",
"\n",
"result = chat.generate([messages])\n",
"pprint(result.generations[0][0].generation_info)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Non-gemini model\n",
"\n",
"`generation_info` will include:\n",
"\n",
"- `is_blocked`: whether generation was blocked or not\n",
"- `safety_attributes`: a dictionary mapping safety attributes to their scores"
]
},
{
"cell_type": "code",
"execution_count": 13,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"{'is_blocked': False,\n",
" 'safety_attributes': {'Derogatory': 0.1,\n",
" 'Finance': 0.3,\n",
" 'Insult': 0.1,\n",
" 'Sexual': 0.1}}\n"
]
}
],
"source": [
"chat = ChatVertexAI() # default is `chat-bison`\n",
"\n",
"result = chat.generate([messages])\n",
"pprint(result.generations[0][0].generation_info)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Function Calling with Gemini\n",
"\n",
"We can call Gemini models with tools."
]
},
{
"cell_type": "code",
"execution_count": 3,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"MyModel(name='Erick', age=27)"
]
},
"execution_count": 3,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"from langchain.pydantic_v1 import BaseModel\n",
"from langchain_google_vertexai import create_structured_runnable\n",
"\n",
"llm = ChatVertexAI(model_name=\"gemini-pro\")\n",
"\n",
"\n",
"class MyModel(BaseModel):\n",
" name: str\n",
" age: int\n",
"\n",
"\n",
"chain = create_structured_runnable(MyModel, llm)\n",
"chain.invoke(\"My name is Erick and I'm 27 years old\")"
]
},
{
"cell_type": "markdown",
"metadata": {},
@@ -210,7 +394,7 @@
},
{
"cell_type": "code",
"execution_count": 5,
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
@@ -224,7 +408,7 @@
},
{
"cell_type": "code",
"execution_count": 6,
"execution_count": null,
"metadata": {},
"outputs": [
{
@@ -268,7 +452,7 @@
},
{
"cell_type": "code",
"execution_count": 7,
"execution_count": null,
"metadata": {},
"outputs": [
{
@@ -309,8 +493,14 @@
}
],
"metadata": {
"environment": {
"kernel": "python3",
"name": "common-cpu.m108",
"type": "gcloud",
"uri": "gcr.io/deeplearning-platform-release/base-cpu:m108"
},
"kernelspec": {
"display_name": "Python 3 (ipykernel)",
"display_name": "Python 3",
"language": "python",
"name": "python3"
},
@@ -324,7 +514,7 @@
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.11.4"
"version": "3.10.10"
},
"vscode": {
"interpreter": {

View File

@@ -0,0 +1,135 @@
{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# LlamaEdge\n",
"\n",
"[LlamaEdge](https://github.com/second-state/LlamaEdge) allows you to chat with LLMs of [GGUF](https://github.com/ggerganov/llama.cpp/blob/master/gguf-py/README.md) format both locally and via chat service.\n",
"\n",
"- `LlamaEdgeChatService` provides developers an OpenAI API compatible service to chat with LLMs via HTTP requests.\n",
"\n",
"- `LlamaEdgeChatLocal` enables developers to chat with LLMs locally (coming soon).\n",
"\n",
"Both `LlamaEdgeChatService` and `LlamaEdgeChatLocal` run on the infrastructure driven by [WasmEdge Runtime](https://wasmedge.org/), which provides a lightweight and portable WebAssembly container environment for LLM inference tasks.\n",
"\n",
"## Chat via API Service\n",
"\n",
"`LlamaEdgeChatService` works on the `llama-api-server`. Following the steps in [llama-api-server quick-start](https://github.com/second-state/llama-utils/tree/main/api-server#readme), you can host your own API service so that you can chat with any models you like on any device you have anywhere as long as the internet is available."
]
},
{
"cell_type": "code",
"execution_count": 2,
"metadata": {},
"outputs": [],
"source": [
"from langchain_community.chat_models.llama_edge import LlamaEdgeChatService\n",
"from langchain_core.messages import HumanMessage, SystemMessage"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Chat with LLMs in the non-streaming mode"
]
},
{
"cell_type": "code",
"execution_count": 5,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"[Bot] Hello! The capital of France is Paris.\n"
]
}
],
"source": [
"# service url\n",
"service_url = \"https://b008-54-186-154-209.ngrok-free.app\"\n",
"\n",
"# create wasm-chat service instance\n",
"chat = LlamaEdgeChatService(service_url=service_url)\n",
"\n",
"# create message sequence\n",
"system_message = SystemMessage(content=\"You are an AI assistant\")\n",
"user_message = HumanMessage(content=\"What is the capital of France?\")\n",
"messages = [system_message, user_message]\n",
"\n",
"# chat with wasm-chat service\n",
"response = chat(messages)\n",
"\n",
"print(f\"[Bot] {response.content}\")"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Chat with LLMs in the streaming mode"
]
},
{
"cell_type": "code",
"execution_count": 4,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"[Bot] Hello! I'm happy to help you with your question. The capital of Norway is Oslo.\n"
]
}
],
"source": [
"# service url\n",
"service_url = \"https://b008-54-186-154-209.ngrok-free.app\"\n",
"\n",
"# create wasm-chat service instance\n",
"chat = LlamaEdgeChatService(service_url=service_url, streaming=True)\n",
"\n",
"# create message sequence\n",
"system_message = SystemMessage(content=\"You are an AI assistant\")\n",
"user_message = HumanMessage(content=\"What is the capital of Norway?\")\n",
"messages = [\n",
" system_message,\n",
" user_message,\n",
"]\n",
"\n",
"output = \"\"\n",
"for chunk in chat.stream(messages):\n",
" # print(chunk.content, end=\"\", flush=True)\n",
" output += chunk.content\n",
"\n",
"print(f\"[Bot] {output}\")"
]
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3",
"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.7"
}
},
"nbformat": 4,
"nbformat_minor": 2
}

View File

@@ -1,85 +0,0 @@
{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Wasm Chat\n",
"\n",
"`Wasm-chat` allows you to chat with LLMs of [GGUF](https://github.com/ggerganov/llama.cpp/blob/master/gguf-py/README.md) format both locally and via chat service.\n",
"\n",
"- `WasmChatService` provides developers an OpenAI API compatible service to chat with LLMs via HTTP requests.\n",
"\n",
"- `WasmChatLocal` enables developers to chat with LLMs locally (coming soon).\n",
"\n",
"Both `WasmChatService` and `WasmChatLocal` run on the infrastructure driven by [WasmEdge Runtime](https://wasmedge.org/), which provides a lightweight and portable WebAssembly container environment for LLM inference tasks.\n",
"\n",
"## Chat via API Service\n",
"\n",
"`WasmChatService` provides chat services by the `llama-api-server`. Following the steps in [llama-api-server quick-start](https://github.com/second-state/llama-utils/tree/main/api-server#readme), you can host your own API service so that you can chat with any models you like on any device you have anywhere as long as the internet is available."
]
},
{
"cell_type": "code",
"execution_count": 1,
"metadata": {},
"outputs": [],
"source": [
"from langchain_community.chat_models.wasm_chat import WasmChatService\n",
"from langchain_core.messages import AIMessage, HumanMessage, SystemMessage"
]
},
{
"cell_type": "code",
"execution_count": 2,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"[Bot] Paris\n"
]
}
],
"source": [
"# service url\n",
"service_url = \"https://b008-54-186-154-209.ngrok-free.app\"\n",
"\n",
"# create wasm-chat service instance\n",
"chat = WasmChatService(service_url=service_url)\n",
"\n",
"# create message sequence\n",
"system_message = SystemMessage(content=\"You are an AI assistant\")\n",
"user_message = HumanMessage(content=\"What is the capital of France?\")\n",
"messages = [system_message, user_message]\n",
"\n",
"# chat with wasm-chat service\n",
"response = chat(messages)\n",
"\n",
"print(f\"[Bot] {response.content}\")"
]
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3",
"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.7"
}
},
"nbformat": 4,
"nbformat_minor": 2
}

View File

@@ -8,7 +8,7 @@
"This notebook covers how to load documents from `Psychic`. See [here](/docs/integrations/providers/psychic) for more details.\n",
"\n",
"## Prerequisites\n",
"1. Follow the Quick Start section in [this document](/docs/ecosystem/integrations/psychic)\n",
"1. Follow the Quick Start section in [this document](/docs/integrations/providers/psychic)\n",
"2. Log into the [Psychic dashboard](https://dashboard.psychic.dev/) and get your secret key\n",
"3. Install the frontend react library into your web app and have a user authenticate a connection. The connection will be created using the connection id that you specify."
]

View File

@@ -0,0 +1,236 @@
{
"cells": [
{
"cell_type": "markdown",
"id": "5812b612-3e77-4be2-aefb-fbb16141ab79",
"metadata": {},
"source": [
"# SurrealDB\n",
"\n",
">[SurrealDB](https://surrealdb.com/) is an end-to-end cloud-native database designed for modern applications, including web, mobile, serverless, Jamstack, backend, and traditional applications. With SurrealDB, you can simplify your database and API infrastructure, reduce development time, and build secure, performant apps quickly and cost-effectively.\n",
">\n",
">**Key features of SurrealDB include:**\n",
">\n",
">* **Reduces development time:** SurrealDB simplifies your database and API stack by removing the need for most server-side components, allowing you to build secure, performant apps faster and cheaper.\n",
">* **Real-time collaborative API backend service:** SurrealDB functions as both a database and an API backend service, enabling real-time collaboration.\n",
">* **Support for multiple querying languages:** SurrealDB supports SQL querying from client devices, GraphQL, ACID transactions, WebSocket connections, structured and unstructured data, graph querying, full-text indexing, and geospatial querying.\n",
">* **Granular access control:** SurrealDB provides row-level permissions-based access control, giving you the ability to manage data access with precision.\n",
">\n",
">View the [features](https://surrealdb.com/features), the latest [releases](https://surrealdb.com/releases), and [documentation](https://surrealdb.com/docs).\n",
"\n",
"This notebook shows how to use functionality related to the `SurrealDBLoader`."
]
},
{
"cell_type": "markdown",
"id": "f56ccec5-24b3-4762-91a6-91385e041fee",
"metadata": {},
"source": [
"## Overview\n",
"\n",
"The SurrealDB Document Loader returns a list of Langchain Documents from a SurrealDB database.\n",
"\n",
"The Document Loader takes the following optional parameters:\n",
"\n",
"* `dburl`: connection string to the websocket endpoint. default: `ws://localhost:8000/rpc`\n",
"* `ns`: name of the namespace. default: `langchain`\n",
"* `db`: name of the database. default: `database`\n",
"* `table`: name of the table. default: `documents`\n",
"* `db_user`: SurrealDB credentials if needed: db username.\n",
"* `db_pass`: SurrealDB credentails if needed: db password.\n",
"* `filter_criteria`: dictionary to construct the `WHERE` clause for filtering results from table.\n",
"\n",
"The output `Document` takes the following shape:\n",
"```\n",
"Document(\n",
" page_content=<json encoded string containing the result document>,\n",
" metadata={\n",
" 'id': <document id>,\n",
" 'ns': <namespace name>,\n",
" 'db': <database_name>,\n",
" 'table': <table name>,\n",
" ... <additional fields from metadata property of the document>\n",
" }\n",
")\n",
"```"
]
},
{
"cell_type": "markdown",
"id": "77b024e0-c804-4b19-9f5e-0099eb61ba79",
"metadata": {},
"source": [
"## Setup\n",
"\n",
"Uncomment the below cells to install surrealdb and langchain."
]
},
{
"cell_type": "code",
"execution_count": 1,
"id": "508bc4f3-3aa2-45d3-8e59-cd7d0ffec379",
"metadata": {
"tags": []
},
"outputs": [],
"source": [
"# %pip install --upgrade --quiet surrealdb langchain langchain-community"
]
},
{
"cell_type": "code",
"execution_count": 1,
"id": "3ee3d767-b9ba-4be4-9e80-8fa6376beaba",
"metadata": {},
"outputs": [],
"source": [
"# add this import for running in jupyter notebook\n",
"import nest_asyncio\n",
"\n",
"nest_asyncio.apply()"
]
},
{
"cell_type": "code",
"execution_count": 2,
"id": "1ec629f4-b99a-44f1-a938-29de7439f121",
"metadata": {},
"outputs": [],
"source": [
"import json\n",
"\n",
"from langchain_community.document_loaders.surrealdb import SurrealDBLoader"
]
},
{
"cell_type": "code",
"execution_count": 3,
"id": "8deb90ac-7d4e-422c-a87a-8e6e41390a6d",
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"42"
]
},
"execution_count": 3,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"loader = SurrealDBLoader(\n",
" dburl=\"ws://localhost:8000/rpc\",\n",
" ns=\"langchain\",\n",
" db=\"database\",\n",
" table=\"documents\",\n",
" db_user=\"root\",\n",
" db_pass=\"root\",\n",
" filter_criteria={},\n",
")\n",
"docs = loader.load()\n",
"len(docs)"
]
},
{
"cell_type": "code",
"execution_count": 4,
"id": "0aa9d3f7-56b3-464d-9d3d-1df7164122ba",
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"{'id': 'documents:zzz434sa584xl3b4ohvk',\n",
" 'source': '../../modules/state_of_the_union.txt',\n",
" 'ns': 'langchain',\n",
" 'db': 'database',\n",
" 'table': 'documents'}"
]
},
"execution_count": 4,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"doc = docs[-1]\n",
"doc.metadata"
]
},
{
"cell_type": "code",
"execution_count": 5,
"id": "0378dd34-c690-4b8e-8816-90a8acc2f227",
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"18078"
]
},
"execution_count": 5,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"len(doc.page_content)"
]
},
{
"cell_type": "code",
"execution_count": 6,
"id": "f30f1141-329b-4674-acb4-36d9d5a9ef0a",
"metadata": {},
"outputs": [],
"source": [
"page_content = json.loads(doc.page_content)"
]
},
{
"cell_type": "code",
"execution_count": 7,
"id": "2a58496f-a831-40ec-be6b-92ce70f78133",
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"'When we use taxpayer dollars to rebuild America we are going to Buy American: buy American products to support American jobs. \\n\\nThe federal government spends about $600 Billion a year to keep the country safe and secure. \\n\\nTheres been a law on the books for almost a century \\nto make sure taxpayers dollars support American jobs and businesses. \\n\\nEvery Administration says theyll do it, but we are actually doing it. \\n\\nWe will buy American to make sure everything from the deck of an aircraft carrier to the steel on highway guardrails are made in America. \\n\\nBut to compete for the best jobs of the future, we also need to level the playing field with China and other competitors. \\n\\nThats why it is so important to pass the Bipartisan Innovation Act sitting in Congress that will make record investments in emerging technologies and American manufacturing. \\n\\nLet me give you one example of why its so important to pass it.'"
]
},
"execution_count": 7,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"page_content[\"text\"]"
]
}
],
"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

@@ -14,12 +14,21 @@
},
{
"cell_type": "code",
"execution_count": null,
"execution_count": 1,
"id": "02be122d-04e8-4ec6-84d1-f1d8961d6828",
"metadata": {
"tags": []
},
"outputs": [],
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"\u001b[33mWARNING: There was an error checking the latest version of pip.\u001b[0m\u001b[33m\n",
"\u001b[0mNote: you may need to restart the kernel to use updated packages.\n"
]
}
],
"source": [
"# install the package:\n",
"%pip install --upgrade --quiet ai21"
@@ -27,20 +36,12 @@
},
{
"cell_type": "code",
"execution_count": 7,
"execution_count": 1,
"id": "4229227e-6ca2-41ad-a3c3-5f29e3559091",
"metadata": {
"tags": []
},
"outputs": [
{
"name": "stdin",
"output_type": "stream",
"text": [
" ········\n"
]
}
],
"outputs": [],
"source": [
"# get AI21_API_KEY. Use https://studio.ai21.com/account/account\n",
"\n",
@@ -51,21 +52,20 @@
},
{
"cell_type": "code",
"execution_count": 8,
"execution_count": 7,
"id": "6fb585dd",
"metadata": {
"tags": []
},
"outputs": [],
"source": [
"from langchain.chains import LLMChain\n",
"from langchain.prompts import PromptTemplate\n",
"from langchain_community.llms import AI21"
"from langchain_community.llms import AI21\n",
"from langchain_core.prompts import PromptTemplate"
]
},
{
"cell_type": "code",
"execution_count": 9,
"execution_count": 12,
"id": "035dea0f",
"metadata": {
"tags": []
@@ -76,12 +76,12 @@
"\n",
"Answer: Let's think step by step.\"\"\"\n",
"\n",
"prompt = PromptTemplate(template=template, input_variables=[\"question\"])"
"prompt = PromptTemplate.from_template(template)"
]
},
{
"cell_type": "code",
"execution_count": 10,
"execution_count": 9,
"id": "3f3458d9",
"metadata": {
"tags": []
@@ -93,19 +93,19 @@
},
{
"cell_type": "code",
"execution_count": 11,
"execution_count": 10,
"id": "a641dbd9",
"metadata": {
"tags": []
},
"outputs": [],
"source": [
"llm_chain = LLMChain(prompt=prompt, llm=llm)"
"llm_chain = prompt | llm"
]
},
{
"cell_type": "code",
"execution_count": 12,
"execution_count": 13,
"id": "9f0b1960",
"metadata": {
"tags": []
@@ -114,10 +114,10 @@
{
"data": {
"text/plain": [
"'\\n1. What year was Justin Bieber born?\\nJustin Bieber was born in 1994.\\n2. What team won the Super Bowl in 1994?\\nThe Dallas Cowboys won the Super Bowl in 1994.'"
"'\\nThe Super Bowl in the year Justin Beiber was born was in the year 1991.\\nThe Super Bowl in 1991 was won by the Washington Redskins.\\nFinal answer: Washington Redskins'"
]
},
"execution_count": 12,
"execution_count": 13,
"metadata": {},
"output_type": "execute_result"
}
@@ -125,7 +125,7 @@
"source": [
"question = \"What NFL team won the Super Bowl in the year Justin Beiber was born?\"\n",
"\n",
"llm_chain.run(question)"
"llm_chain.invoke({\"question\": question})"
]
},
{
@@ -153,7 +153,7 @@
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.11.3"
"version": "3.10.13"
}
},
"nbformat": 4,

View File

@@ -11,29 +11,30 @@
},
{
"cell_type": "markdown",
"metadata": {
"id": "xazoWTniN8Xa"
},
"metadata": {},
"source": [
"# Google Cloud Vertex AI\n",
"\n",
"**Note:** This is separate from the `Google Generative AI` integration, it exposes [Vertex AI Generative API](https://cloud.google.com/vertex-ai/docs/generative-ai/learn/overview) on `Google Cloud`.\n"
"**Note:** This is separate from the `Google Generative AI` integration, it exposes [Vertex AI Generative API](https://cloud.google.com/vertex-ai/docs/generative-ai/learn/overview) on `Google Cloud`.\n",
"\n",
"VertexAI exposes all foundational models available in google cloud:\n",
"- Gemini (`gemini-pro` and `gemini-pro-vision`)\n",
"- Palm 2 for Text (`text-bison`)\n",
"- Codey for Code Generation (`code-bison`)\n",
"\n",
"For a full and updated list of available models visit [VertexAI documentation](https://cloud.google.com/vertex-ai/docs/generative-ai/model-reference/overview)"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "Q_UoF2FKN8Xb"
},
"metadata": {},
"source": [
"## Setting up"
"## Setup"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "8uImJzc4N8Xb"
},
"metadata": {},
"source": [
"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",
@@ -52,78 +53,29 @@
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"\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.2\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;49mpip install --upgrade pip\u001b[0m\n",
"Note: you may need to restart the kernel to use updated packages.\n"
]
}
],
"source": [
"%pip install --upgrade --quiet langchain-core langchain-google-vertexai"
]
},
{
"cell_type": "code",
"execution_count": 5,
"cell_type": "markdown",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
" **Pros of Python:**\n",
"\n",
"* **Easy to learn and use:** Python is known for its simple syntax and readability, making it a great choice for beginners. It also has a large and supportive community, with many resources available online.\n",
"* **Versatile:** Python can be used for a wide variety of tasks, including web development, data science, machine learning, and artificial intelligence.\n",
"* **Powerful:** Python has a rich library of built-in functions and modules, making it easy to perform complex tasks without having to write a lot of code.\n",
"* **Cross-platform:** Python can be run on a variety of operating systems\n"
]
}
],
"source": [
"from langchain_google_vertexai import VertexAI\n",
"## Usage\n",
"\n",
"llm = VertexAI()\n",
"print(llm(\"What are some of the pros and cons of Python as a programming language?\"))"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "38S1FS3qN8Xc"
},
"source": [
"You can also use Gemini model (in preview) with VertexAI:"
]
},
{
"cell_type": "code",
"execution_count": 6,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"**Pros of Python:**\n",
"\n",
"* **Easy to learn and use:** Python is known for its simplicity and readability, making it a great choice for beginners and experienced programmers alike. Its syntax is straightforward and intuitive, allowing developers to quickly pick up the language and start writing code.\n",
"\n",
"\n",
"* **Versatile:** Python is a general-purpose language that can be used for a wide range of applications, including web development, data science, machine learning, and scripting. Its extensive standard library and vast ecosystem of third-party modules make it suitable for a variety of tasks.\n",
"\n",
"\n",
"* **Cross-platform:** Python is compatible with multiple operating systems, including\n"
]
}
],
"source": [
"llm = VertexAI(model_name=\"gemini-pro\")\n",
"print(llm(\"What are some of the pros and cons of Python as a programming language?\"))"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "_-9MhhN8N8Xc"
},
"source": [
"## Using in a chain"
"VertexAI supports all [LLM](/docs/modules/model_io/llms/) functionality."
]
},
{
@@ -131,204 +83,199 @@
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"from langchain_google_vertexai import VertexAI"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"model = VertexAI(model_name=\"gemini-pro\")"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"'**Pros:**\\n\\n* **Easy to learn and use:** Python is known for its simple syntax and readability, making it a great choice for beginners and experienced programmers alike.\\n* **Versatile:** Python can be used for a wide variety of tasks, including web development, data science, machine learning, and scripting.\\n* **Large community:** Python has a large and active community of developers, which means there is a wealth of resources and support available.\\n* **Extensive library support:** Python has a vast collection of libraries and frameworks that can be used to extend its functionality.\\n* **Cross-platform:** Python is available for a'"
]
},
"execution_count": null,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"message = \"What are some of the pros and cons of Python as a programming language?\"\n",
"model.invoke(message)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"'**Pros:**\\n\\n* **Easy to learn and use:** Python is known for its simple syntax and readability, making it a great choice for beginners and experienced programmers alike.\\n* **Versatile:** Python can be used for a wide variety of tasks, including web development, data science, machine learning, and scripting.\\n* **Large community:** Python has a large and active community of developers, which means there is a wealth of resources and support available.\\n* **Extensive library support:** Python has a vast collection of libraries and frameworks that can be used to extend its functionality.\\n* **Cross-platform:** Python is available for a'"
]
},
"execution_count": null,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"await model.ainvoke(message)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"**Pros:**\n",
"\n",
"* **Easy to learn and use:** Python is known for its simple syntax and readability, making it a great choice for beginners and experienced programmers alike.\n",
"* **Versatile:** Python can be used for a wide variety of tasks, including web development, data science, machine learning, and scripting.\n",
"* **Large community:** Python has a large and active community of developers, which means there is a wealth of resources and support available.\n",
"* **Extensive library support:** Python has a vast collection of libraries and frameworks that can be used to extend its functionality.\n",
"* **Cross-platform:** Python is available for a"
]
}
],
"source": [
"for chunk in model.stream(message):\n",
" print(chunk, end=\"\", flush=True)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"['**Pros:**\\n\\n* **Easy to learn and use:** Python is known for its simple syntax and readability, making it a great choice for beginners and experienced programmers alike.\\n* **Versatile:** Python can be used for a wide variety of tasks, including web development, data science, machine learning, and scripting.\\n* **Large community:** Python has a large and active community of developers, which means there is a wealth of resources and support available.\\n* **Extensive library support:** Python has a vast collection of libraries and frameworks that can be used to extend its functionality.\\n* **Cross-platform:** Python is available for a']"
]
},
"execution_count": null,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"model.batch([message])"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"We can use the `generate` method to get back extra metadata like [safety attributes](https://cloud.google.com/vertex-ai/docs/generative-ai/learn/responsible-ai#safety_attribute_confidence_scoring) and not just text completions."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"[[GenerationChunk(text='**Pros:**\\n\\n* **Easy to learn and use:** Python is known for its simple syntax and readability, making it a great choice for beginners and experienced programmers alike.\\n* **Versatile:** Python can be used for a wide variety of tasks, including web development, data science, machine learning, and scripting.\\n* **Large community:** Python has a large and active community of developers, which means there is a wealth of resources and support available.\\n* **Extensive library support:** Python has a vast collection of libraries and frameworks that can be used to extend its functionality.\\n* **Cross-platform:** Python is available for a')]]"
]
},
"execution_count": null,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"result = model.generate([message])\n",
"result.generations"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"[[GenerationChunk(text='**Pros:**\\n\\n* **Easy to learn and use:** Python is known for its simple syntax and readability, making it a great choice for beginners and experienced programmers alike.\\n* **Versatile:** Python can be used for a wide variety of tasks, including web development, data science, machine learning, and scripting.\\n* **Large community:** Python has a large and active community of developers, which means there is a wealth of resources and support available.\\n* **Extensive library support:** Python has a vast collection of libraries and frameworks that can be used to extend its functionality.\\n* **Cross-platform:** Python is available for a')]]"
]
},
"execution_count": null,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"result = await model.agenerate([message])\n",
"result.generations"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"You can also easily combine with a prompt template for easy structuring of user input. We can do this using [LCEL](/docs/expression_language)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"1. You start with 5 apples.\n",
"2. You throw away 2 apples, so you have 5 - 2 = 3 apples left.\n",
"3. You eat 1 apple, so you have 3 - 1 = 2 apples left.\n",
"\n",
"Therefore, you have 2 apples left.\n"
]
}
],
"source": [
"from langchain_core.prompts import PromptTemplate\n",
"\n",
"template = \"\"\"Question: {question}\n",
"\n",
"Answer: Let's think step by step.\"\"\"\n",
"prompt = PromptTemplate.from_template(template)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"chain = prompt | llm"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
" Justin Bieber was born on March 1, 1994. Bill Clinton was the president of the United States from January 20, 1993, to January 20, 2001.\n",
"The final answer is Bill Clinton\n"
]
}
],
"source": [
"question = \"Who was the president in the year Justin Beiber was born?\"\n",
"prompt = PromptTemplate.from_template(template)\n",
"\n",
"chain = prompt | model\n",
"\n",
"question = \"\"\"\n",
"I have five apples. I throw two away. I eat one. How many apples do I have left?\n",
"\"\"\"\n",
"print(chain.invoke({\"question\": question}))"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "AV7oXXuHN8Xd"
},
"source": [
"## Code generation example"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "3ZzVtF6tN8Xd"
},
"source": [
"You can now leverage the `Codey API` for code generation within `Vertex AI`.\n",
"\n",
"The model names are:\n",
"- `code-bison`: for code suggestion\n",
"- `code-gecko`: for code completion"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"llm = VertexAI(model_name=\"code-bison\", max_output_tokens=1000, temperature=0.3)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"question = \"Write a python function that checks if a string is a valid email address\""
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"```python\n",
"import re\n",
"\n",
"def is_valid_email(email):\n",
" pattern = re.compile(r\"[^@]+@[^@]+\\.[^@]+\")\n",
" return pattern.match(email)\n",
"```\n"
]
}
],
"source": [
"print(llm(question))"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "0WqyaSC2N8Xd"
},
"source": [
"## Full generation info\n",
"\n",
"We can use the `generate` method to get back extra metadata like [safety attributes](https://cloud.google.com/vertex-ai/docs/generative-ai/learn/responsible-ai#safety_attribute_confidence_scoring) and not just text completions"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"[[GenerationChunk(text='```python\\nimport re\\n\\ndef is_valid_email(email):\\n pattern = re.compile(r\"[^@]+@[^@]+\\\\.[^@]+\")\\n return pattern.match(email)\\n```', generation_info={'is_blocked': False, 'safety_attributes': {'Health': 0.1}})]]"
]
},
"execution_count": 23,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"result = llm.generate([question])\n",
"result.generations"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "Wd5M4BBUN8Xd"
},
"source": [
"## Asynchronous calls\n",
"\n",
"With `agenerate` we can make asynchronous calls"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"# If running in a Jupyter notebook you'll need to install nest_asyncio\n",
"\n",
"%pip install --upgrade --quiet nest_asyncio\n",
"\n",
"import nest_asyncio\n",
"\n",
"nest_asyncio.apply()"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"LLMResult(generations=[[GenerationChunk(text='```python\\nimport re\\n\\ndef is_valid_email(email):\\n pattern = re.compile(r\"[^@]+@[^@]+\\\\.[^@]+\")\\n return pattern.match(email)\\n```', generation_info={'is_blocked': False, 'safety_attributes': {'Health': 0.1}})]], llm_output=None, run=[RunInfo(run_id=UUID('caf74e91-aefb-48ac-8031-0c505fcbbcc6'))])"
]
},
"execution_count": 25,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"import asyncio\n",
"\n",
"asyncio.run(llm.agenerate([question]))"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "VLsy_4bZN8Xd"
},
"source": [
"## Streaming calls\n",
"\n",
"With `stream` we can stream results from the model"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"import sys"
"You can use different foundational models for specialized in different tasks. \n",
"For an updated list of available models visit [VertexAI documentation](https://cloud.google.com/vertex-ai/docs/generative-ai/model-reference/overview)"
]
},
{
@@ -354,49 +301,38 @@
" True if the string is a valid email address, False otherwise.\n",
" \"\"\"\n",
"\n",
" # Check for a valid email address format.\n",
" if not re.match(r\"^[A-Za-z0-9\\.\\+_-]+@[A-Za-z0-9\\._-]+\\.[a-zA-Z]*$\", email):\n",
" return False\n",
" # Compile the regular expression for an email address.\n",
" regex = re.compile(r\"[^@]+@[^@]+\\.[^@]+\")\n",
"\n",
" # Check if the domain name exists.\n",
" try:\n",
" domain = email.split(\"@\")[1]\n",
" socket.gethostbyname(domain)\n",
" except socket.gaierror:\n",
" return False\n",
"\n",
" return True\n",
"```"
" # Check if the string matches the regular expression.\n",
" return regex.match(email) is not None\n",
"```\n"
]
}
],
"source": [
"for chunk in llm.stream(question):\n",
" sys.stdout.write(chunk)\n",
" sys.stdout.flush()"
"llm = VertexAI(model_name=\"code-bison\", max_output_tokens=1000, temperature=0.3)\n",
"question = \"Write a python function that checks if a string is a valid email address\"\n",
"print(model.invoke(question))"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "4VJ8GwhaN8Xd"
},
"metadata": {},
"source": [
"## Multimodality"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "L7BovARaN8Xe"
},
"metadata": {},
"source": [
"With Gemini, you can use LLM in a multimodal mode:"
]
},
{
"cell_type": "code",
"execution_count": 8,
"execution_count": null,
"metadata": {},
"outputs": [
{
@@ -429,16 +365,14 @@
},
{
"cell_type": "markdown",
"metadata": {
"id": "3Vk3gQrrOaL9"
},
"metadata": {},
"source": [
"Let's double-check it's a cat :)"
]
},
{
"cell_type": "code",
"execution_count": 9,
"execution_count": null,
"metadata": {},
"outputs": [
{
@@ -448,7 +382,7 @@
"<vertexai.generative_models._generative_models.Image at 0x791ded5f1ed0>"
]
},
"execution_count": 9,
"execution_count": null,
"metadata": {},
"output_type": "execute_result"
}
@@ -462,16 +396,14 @@
},
{
"cell_type": "markdown",
"metadata": {
"id": "1uEACSSm8AL2"
},
"metadata": {},
"source": [
"You can also pass images as bytes:"
]
},
{
"cell_type": "code",
"execution_count": 18,
"execution_count": null,
"metadata": {},
"outputs": [
{
@@ -506,18 +438,14 @@
},
{
"cell_type": "markdown",
"metadata": {
"id": "AuhF5WQuN8Xe"
},
"metadata": {},
"source": [
"Please, note that you can also use the image stored in GCS (just point the `url` to the full GCS path, starting with `gs://` instead of a local one)."
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "qaC2UmxS9WtB"
},
"metadata": {},
"source": [
"And you can also pass a history of a previous chat to the LLM:"
]
@@ -564,18 +492,14 @@
},
{
"cell_type": "markdown",
"metadata": {
"id": "VEYAfdBpN8Xe"
},
"metadata": {},
"source": [
"## Vertex Model Garden"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "N3ptjr_LN8Xe"
},
"metadata": {},
"source": [
"Vertex Model Garden [exposes](https://cloud.google.com/vertex-ai/docs/start/explore-models) open-sourced models that can be deployed and served on Vertex AI. If you have successfully deployed a model from Vertex Model Garden, you can find a corresponding Vertex AI [endpoint](https://cloud.google.com/vertex-ai/docs/general/deployment#what_happens_when_you_deploy_a_model) in the console or via API."
]
@@ -604,14 +528,12 @@
"metadata": {},
"outputs": [],
"source": [
"print(llm(\"What is the meaning of life?\"))"
"llm.invoke(\"What is the meaning of life?\")"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "TDXoFZ6YN8Xe"
},
"metadata": {},
"source": [
"Like all LLMs, we can then compose it with other components:"
]
@@ -643,8 +565,16 @@
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"version": "3.11.4"
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.11.6"
}
},
"nbformat": 4,

View File

@@ -59,7 +59,7 @@
"cell_type": "markdown",
"metadata": {},
"source": [
"Optional: Validate your Enviroment variables ```GRADIENT_ACCESS_TOKEN``` and ```GRADIENT_WORKSPACE_ID``` to get currently deployed models. Using the `gradientai` Python package."
"Optional: Validate your Environment variables ```GRADIENT_ACCESS_TOKEN``` and ```GRADIENT_WORKSPACE_ID``` to get currently deployed models. Using the `gradientai` Python package."
]
},
{

View File

@@ -318,7 +318,7 @@
"metadata": {},
"source": [
"### Standard Cache\n",
"Use [Redis](/docs/integrations/partners/redis) to cache prompts and responses."
"Use [Redis](/docs/integrations/providers/redis) to cache prompts and responses."
]
},
{
@@ -404,7 +404,7 @@
"metadata": {},
"source": [
"### Semantic Cache\n",
"Use [Redis](/docs/integrations/partners/redis) to cache prompts and responses and evaluate hits based on semantic similarity."
"Use [Redis](/docs/integrations/providers/redis) to cache prompts and responses and evaluate hits based on semantic similarity."
]
},
{
@@ -728,7 +728,7 @@
},
"source": [
"## `Momento` Cache\n",
"Use [Momento](/docs/integrations/partners/momento) to cache prompts and responses.\n",
"Use [Momento](/docs/integrations/providers/momento) to cache prompts and responses.\n",
"\n",
"Requires momento to use, uncomment below to install:"
]

View File

@@ -0,0 +1,147 @@
{
"cells": [
{
"cell_type": "markdown",
"id": "91c6a7ef",
"metadata": {},
"source": [
"# Google Cloud Firestore\n",
"\n",
"> [`Cloud Firestore`](https://cloud.google.com/firestore) is a NoSQL document database built for automatic scaling, high performance, and ease of application development.\n",
"\n",
"This notebook goes over how to use Firestore to store chat message history."
]
},
{
"cell_type": "markdown",
"id": "2d6ed3c8-b70a-498c-bc9e-41b91797d3b7",
"metadata": {},
"source": [
"## Setting up"
]
},
{
"cell_type": "markdown",
"id": "b8eca282",
"metadata": {},
"source": [
"To run this notebook, you will need a Google Cloud Project, a Firestore database instance in Native Mode, and Google credentials, see [Firestore Quickstarts](https://cloud.google.com/firestore/docs/quickstarts)."
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "5a7f3b3f-d9b8-4577-a7ef-bdd8ecaedb70",
"metadata": {},
"outputs": [],
"source": [
"!pip install firebase-admin"
]
},
{
"cell_type": "markdown",
"id": "a8e63850-3e14-46fe-a59e-be6d6bf8fe61",
"metadata": {},
"source": [
"## Basic Usage"
]
},
{
"cell_type": "code",
"execution_count": 5,
"id": "d15e3302",
"metadata": {},
"outputs": [],
"source": [
"from langchain_community.chat_message_histories.firestore import (\n",
" FirestoreChatMessageHistory,\n",
")\n",
"\n",
"message_history = FirestoreChatMessageHistory(\n",
" collection_name=\"langchain-chat-history\",\n",
" session_id=\"user-session-id\",\n",
" user_id=\"user-id\",\n",
")\n",
"\n",
"message_history.add_user_message(\"hi!\")\n",
"message_history.add_ai_message(\"whats up?\")"
]
},
{
"cell_type": "code",
"execution_count": 6,
"id": "64fc465e",
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"[HumanMessage(content='hi!'),\n",
" HumanMessage(content='hi!'),\n",
" AIMessage(content='whats up?')]"
]
},
"execution_count": 6,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"message_history.messages"
]
},
{
"cell_type": "markdown",
"id": "4be8576e",
"metadata": {},
"source": [
"## Custom Firestore Client"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "12999273",
"metadata": {},
"outputs": [],
"source": [
"import firebase_admin\n",
"from firebase_admin import credentials, firestore\n",
"\n",
"# Use a service account.\n",
"cred = credentials.Certificate(\"path/to/serviceAccount.json\")\n",
"\n",
"app = firebase_admin.initialize_app(cred)\n",
"client = firestore.client(app=app)\n",
"\n",
"message_history = FirestoreChatMessageHistory(\n",
" collection_name=\"langchain-chat-history\",\n",
" session_id=\"user-session-id\",\n",
" user_id=\"user-id\",\n",
" firestore_client=client,\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.5"
}
},
"nbformat": 4,
"nbformat_minor": 5
}

View File

@@ -11,7 +11,7 @@
">\n",
">`MongoDB` is developed by MongoDB Inc. and licensed under the Server Side Public License (SSPL). - [Wikipedia](https://en.wikipedia.org/wiki/MongoDB)\n",
"\n",
"This notebook goes over how to use Mongodb to store chat message history.\n"
"This notebook goes over how to use the `MongoDBChatMessageHistory` class to store chat message history in a Mongodb database.\n"
]
},
{
@@ -19,76 +19,230 @@
"id": "2d6ed3c8-b70a-498c-bc9e-41b91797d3b7",
"metadata": {},
"source": [
"## Setting up"
"## Setup\n",
"\n",
"The integration lives in the `langchain-community` package, so we need to install that. We also need to install the `pymongo` package.\n",
"\n",
"```bash\n",
"pip install -U --quiet langchain-community pymongo\n",
"```"
]
},
{
"cell_type": "markdown",
"id": "09c33ad3-9ab1-48b5-bead-9a44f3d86eeb",
"metadata": {},
"source": [
"It's also helpful (but not needed) to set up [LangSmith](https://smith.langchain.com/) for best-in-class observability"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "5a7f3b3f-d9b8-4577-a7ef-bdd8ecaedb70",
"id": "0976204d-c681-4288-bfe5-a550e0340f35",
"metadata": {},
"outputs": [],
"source": [
"%pip install --upgrade --quiet pymongo"
"# os.environ[\"LANGCHAIN_TRACING_V2\"] = \"true\"\n",
"# os.environ[\"LANGCHAIN_API_KEY\"] = getpass.getpass()"
]
},
{
"cell_type": "markdown",
"id": "71a0a5aa-8f12-462a-bcd0-c611d76566f8",
"metadata": {},
"source": [
"## Usage\n",
"\n",
"To use the storage you need to provide only 2 things:\n",
"\n",
"1. Session Id - a unique identifier of the session, like user name, email, chat id etc.\n",
"2. Connection string - a string that specifies the database connection. It will be passed to MongoDB create_engine function.\n",
"\n",
"If you want to customize where the chat histories go, you can also pass:\n",
"1. *database_name* - name of the database to use\n",
"1. *collection_name* - collection to use within that database"
]
},
{
"cell_type": "code",
"execution_count": 3,
"id": "47a601d2",
"metadata": {},
"id": "0179847d-76b6-43bc-b15c-7fecfcb27ac7",
"metadata": {
"ExecuteTime": {
"end_time": "2023-08-28T10:04:38.077748Z",
"start_time": "2023-08-28T10:04:36.105894Z"
},
"collapsed": false,
"jupyter": {
"outputs_hidden": false
}
},
"outputs": [],
"source": [
"# Provide the connection string to connect to the MongoDB database\n",
"connection_string = \"mongodb://mongo_user:password123@mongo:27017\""
]
},
{
"cell_type": "markdown",
"id": "a8e63850-3e14-46fe-a59e-be6d6bf8fe61",
"metadata": {},
"source": [
"## Example"
"from langchain_community.chat_message_histories import MongoDBChatMessageHistory\n",
"\n",
"chat_message_history = MongoDBChatMessageHistory(\n",
" session_id=\"test_session\",\n",
" connection_string=\"mongodb://mongo_user:password123@mongo:27017\",\n",
" database_name=\"my_db\",\n",
" collection_name=\"chat_histories\",\n",
")\n",
"\n",
"chat_message_history.add_user_message(\"Hello\")\n",
"chat_message_history.add_ai_message(\"Hi\")"
]
},
{
"cell_type": "code",
"execution_count": 4,
"id": "d15e3302",
"metadata": {},
"outputs": [],
"source": [
"from langchain.memory import MongoDBChatMessageHistory\n",
"\n",
"message_history = MongoDBChatMessageHistory(\n",
" connection_string=connection_string, session_id=\"test-session\"\n",
")\n",
"\n",
"message_history.add_user_message(\"hi!\")\n",
"\n",
"message_history.add_ai_message(\"whats up?\")"
]
},
{
"cell_type": "code",
"execution_count": 5,
"id": "64fc465e",
"id": "6e7b8653-a8d2-49a7-97ba-4296f7e717e9",
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"[HumanMessage(content='hi!', additional_kwargs={}, example=False),\n",
" AIMessage(content='whats up?', additional_kwargs={}, example=False)]"
"[HumanMessage(content='Hello'), AIMessage(content='Hi')]"
]
},
"execution_count": 5,
"execution_count": 4,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"message_history.messages"
"chat_message_history.messages"
]
},
{
"cell_type": "markdown",
"id": "e352d786-0811-48ec-832a-9f1c0b70690e",
"metadata": {},
"source": [
"## Chaining\n",
"\n",
"We can easily combine this message history class with [LCEL Runnables](/docs/expression_language/how_to/message_history)\n",
"\n",
"To do this we will want to use OpenAI, so we need to install that. You will also need to set the OPENAI_API_KEY environment variable to your OpenAI key.\n"
]
},
{
"cell_type": "code",
"execution_count": 5,
"id": "6558418b-0ece-4d01-9661-56d562d78f7a",
"metadata": {},
"outputs": [],
"source": [
"from typing import Optional\n",
"\n",
"from langchain_core.prompts import ChatPromptTemplate, MessagesPlaceholder\n",
"from langchain_core.runnables.history import RunnableWithMessageHistory\n",
"from langchain_openai import ChatOpenAI"
]
},
{
"cell_type": "code",
"execution_count": 16,
"id": "86ddfd3f-e8cf-477a-a7fd-91be3b8aa928",
"metadata": {},
"outputs": [],
"source": [
"import os\n",
"\n",
"assert os.environ[\n",
" \"OPENAI_API_KEY\"\n",
"], \"Set the OPENAI_API_KEY environment variable with your OpenAI API key.\""
]
},
{
"cell_type": "code",
"execution_count": 10,
"id": "82149122-61d3-490d-9bdb-bb98606e8ba1",
"metadata": {},
"outputs": [],
"source": [
"prompt = ChatPromptTemplate.from_messages(\n",
" [\n",
" (\"system\", \"You are a helpful assistant.\"),\n",
" MessagesPlaceholder(variable_name=\"history\"),\n",
" (\"human\", \"{question}\"),\n",
" ]\n",
")\n",
"\n",
"chain = prompt | ChatOpenAI()"
]
},
{
"cell_type": "code",
"execution_count": 11,
"id": "2df90853-b67c-490f-b7f8-b69d69270b9c",
"metadata": {},
"outputs": [],
"source": [
"chain_with_history = RunnableWithMessageHistory(\n",
" chain,\n",
" lambda session_id: MongoDBChatMessageHistory(\n",
" session_id=\"test_session\",\n",
" connection_string=\"mongodb://mongo_user:password123@mongo:27017\",\n",
" database_name=\"my_db\",\n",
" collection_name=\"chat_histories\",\n",
" ),\n",
" input_messages_key=\"question\",\n",
" history_messages_key=\"history\",\n",
")"
]
},
{
"cell_type": "code",
"execution_count": 12,
"id": "0ce596b8-3b78-48fd-9f92-46dccbbfd58b",
"metadata": {},
"outputs": [],
"source": [
"# This is where we configure the session id\n",
"config = {\"configurable\": {\"session_id\": \"<SESSION_ID>\"}}"
]
},
{
"cell_type": "code",
"execution_count": 13,
"id": "38e1423b-ba86-4496-9151-25932fab1a8b",
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"AIMessage(content='Hi Bob! How can I assist you today?')"
]
},
"execution_count": 13,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"chain_with_history.invoke({\"question\": \"Hi! I'm bob\"}, config=config)"
]
},
{
"cell_type": "code",
"execution_count": 14,
"id": "2ee4ee62-a216-4fb1-bf33-57476a84cf16",
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"AIMessage(content='Your name is Bob. Is there anything else I can help you with, Bob?')"
]
},
"execution_count": 14,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"chain_with_history.invoke({\"question\": \"Whats my name\"}, config=config)"
]
}
],

View File

@@ -12,16 +12,43 @@
"This notebook goes over how to use `Redis` to store chat message history."
]
},
{
"cell_type": "markdown",
"id": "897a4682-f9fc-488b-98f3-ae2acad84600",
"metadata": {},
"source": [
"## Setup\n",
"First we need to install dependencies, and start a redis instance using commands like: `redis-server`."
]
},
{
"cell_type": "code",
"execution_count": 9,
"execution_count": null,
"id": "cda8b56d-baf7-49a2-91a2-4d424a8519cb",
"metadata": {},
"outputs": [],
"source": [
"pip install -U langchain-community redis"
]
},
{
"cell_type": "markdown",
"id": "20b99474-75ea-422e-9809-fbdb9d103afc",
"metadata": {},
"source": [
"## Store and Retrieve Messages"
]
},
{
"cell_type": "code",
"execution_count": 3,
"id": "d15e3302",
"metadata": {},
"outputs": [],
"source": [
"from langchain.memory import RedisChatMessageHistory\n",
"from langchain_community.chat_message_histories import RedisChatMessageHistory\n",
"\n",
"history = RedisChatMessageHistory(\"foo\")\n",
"history = RedisChatMessageHistory(\"foo\", url=\"redis://localhost:6379\")\n",
"\n",
"history.add_user_message(\"hi!\")\n",
"\n",
@@ -30,18 +57,17 @@
},
{
"cell_type": "code",
"execution_count": 10,
"execution_count": 4,
"id": "64fc465e",
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"[AIMessage(content='whats up?', additional_kwargs={}),\n",
" HumanMessage(content='hi!', additional_kwargs={})]"
"[HumanMessage(content='hi!'), AIMessage(content='whats up?')]"
]
},
"execution_count": 10,
"execution_count": 4,
"metadata": {},
"output_type": "execute_result"
}
@@ -50,10 +76,85 @@
"history.messages"
]
},
{
"cell_type": "markdown",
"id": "465fdd8c-b093-4d19-a55a-30f3b646432b",
"metadata": {},
"source": [
"## Using in the Chains"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "8af285f8",
"id": "94d65d2f-e9bb-4b47-a86d-dd6b1b5e8247",
"metadata": {},
"outputs": [],
"source": [
"pip install -U langchain-openai"
]
},
{
"cell_type": "code",
"execution_count": 5,
"id": "ace3e7b2-5e3e-4966-b549-04952a6a9a09",
"metadata": {},
"outputs": [],
"source": [
"from typing import Optional\n",
"\n",
"from langchain_community.chat_message_histories import RedisChatMessageHistory\n",
"from langchain_core.prompts import ChatPromptTemplate, MessagesPlaceholder\n",
"from langchain_core.runnables.history import RunnableWithMessageHistory\n",
"from langchain_openai import ChatOpenAI"
]
},
{
"cell_type": "code",
"execution_count": 6,
"id": "5c1fba0d-d06a-4695-ba14-c42a3461ada1",
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"AIMessage(content='Your name is Bob, as you mentioned earlier. Is there anything specific you would like assistance with, Bob?')"
]
},
"execution_count": 6,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"prompt = ChatPromptTemplate.from_messages(\n",
" [\n",
" (\"system\", \"You're an assistant。\"),\n",
" MessagesPlaceholder(variable_name=\"history\"),\n",
" (\"human\", \"{question}\"),\n",
" ]\n",
")\n",
"\n",
"chain = prompt | ChatOpenAI()\n",
"\n",
"chain_with_history = RunnableWithMessageHistory(\n",
" chain,\n",
" RedisChatMessageHistory,\n",
" input_messages_key=\"question\",\n",
" history_messages_key=\"history\",\n",
")\n",
"\n",
"config = {\"configurable\": {\"session_id\": \"foo\"}}\n",
"\n",
"chain_with_history.invoke({\"question\": \"Hi! I'm bob\"}, config=config)\n",
"\n",
"chain_with_history.invoke({\"question\": \"Whats my name\"}, config=config)"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "76ce3f6b-f4c7-4d27-8031-60f7dd756695",
"metadata": {},
"outputs": [],
"source": []
@@ -75,7 +176,7 @@
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.10.12"
"version": "3.9.18"
}
},
"nbformat": 4,

View File

@@ -6,7 +6,7 @@ This page covers how to use the [Remembrall](https://remembrall.dev) ecosystem w
Remembrall gives your language model long-term memory, retrieval augmented generation, and complete observability with just a few lines of code.
![Remembrall Dashboard](/img/RemembrallDashboard.png)
![Screenshot of the Remembrall dashboard showing request statistics and model interactions.](/img/RemembrallDashboard.png "Remembrall Dashboard Interface")
It works as a light-weight proxy on top of your OpenAI calls and simply augments the context of the chat calls at runtime with relevant facts that have been collected.

View File

@@ -16,172 +16,203 @@
},
{
"cell_type": "code",
"execution_count": 1,
"id": "d0a07a30-028f-4e16-8b11-45b2416f7b0f",
"execution_count": null,
"id": "5c923f56-24a9-4f8f-9b91-138cc025c47e",
"metadata": {},
"outputs": [],
"source": [
"%pip install --upgrade --quiet sqlite3"
"# os.environ[\"LANGCHAIN_TRACING_V2\"] = \"true\"\n",
"# os.environ[\"LANGCHAIN_API_KEY\"] = getpass.getpass()"
]
},
{
"cell_type": "markdown",
"id": "61fda020-23a2-4605-afad-58260535ec8c",
"metadata": {},
"source": [
"## Usage\n",
"\n",
"To use the storage you need to provide only 2 things:\n",
"\n",
"1. Session Id - a unique identifier of the session, like user name, email, chat id etc.\n",
"2. Connection string - a string that specifies the database connection. For SQLite, that string is `slqlite:///` followed by the name of the database file. If that file doesn't exist, it will be created."
]
},
{
"cell_type": "code",
"execution_count": 1,
"id": "db59b901",
"id": "4576e914a866fb40",
"metadata": {
"id": "2wUMSUoF8ffn"
"ExecuteTime": {
"end_time": "2023-08-28T10:04:38.077748Z",
"start_time": "2023-08-28T10:04:36.105894Z"
},
"collapsed": false,
"jupyter": {
"outputs_hidden": false
}
},
"outputs": [],
"source": [
"from langchain.chains import ConversationChain\n",
"from langchain.memory import ConversationEntityMemory\n",
"from langchain.memory.entity import SQLiteEntityStore\n",
"from langchain.memory.prompt import ENTITY_MEMORY_CONVERSATION_TEMPLATE\n",
"from langchain_openai import OpenAI"
"from langchain_community.chat_message_histories import SQLChatMessageHistory\n",
"\n",
"chat_message_history = SQLChatMessageHistory(\n",
" session_id=\"test_session_id\", connection_string=\"sqlite:///sqlite.db\"\n",
")\n",
"\n",
"chat_message_history.add_user_message(\"Hello\")\n",
"chat_message_history.add_ai_message(\"Hi\")"
]
},
{
"cell_type": "code",
"execution_count": 2,
"id": "ca6dee29",
"id": "b476688cbb32ba90",
"metadata": {
"id": "8TpJZti99gxV"
"ExecuteTime": {
"end_time": "2023-08-28T10:04:38.929396Z",
"start_time": "2023-08-28T10:04:38.915727Z"
},
"collapsed": false,
"jupyter": {
"outputs_hidden": false
}
},
"outputs": [],
"outputs": [
{
"data": {
"text/plain": [
"[HumanMessage(content='Hello'), AIMessage(content='Hi')]"
]
},
"execution_count": 2,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"entity_store = SQLiteEntityStore()\n",
"llm = OpenAI(temperature=0)\n",
"memory = ConversationEntityMemory(llm=llm, entity_store=entity_store)\n",
"conversation = ConversationChain(\n",
" llm=llm,\n",
" prompt=ENTITY_MEMORY_CONVERSATION_TEMPLATE,\n",
" memory=memory,\n",
" verbose=True,\n",
")"
"chat_message_history.messages"
]
},
{
"cell_type": "markdown",
"id": "f9b4c3a0",
"metadata": {
"id": "HEAHG1L79ca1"
},
"id": "e400509a-1957-4d1d-bbd6-01e8dc3dccb3",
"metadata": {},
"source": [
"Notice the usage of `EntitySqliteStore` as parameter to `entity_store` on the `memory` property."
"## Chaining\n",
"\n",
"We can easily combine this message history class with [LCEL Runnables](/docs/expression_language/how_to/message_history)\n",
"\n",
"To do this we will want to use OpenAI, so we need to install that. We will also need to set the OPENAI_API_KEY environment variable to your OpenAI key.\n",
"\n",
"```bash\n",
"pip install -U langchain-openai\n",
"\n",
"export OPENAI_API_KEY='sk-xxxxxxx'\n",
"```"
]
},
{
"cell_type": "code",
"execution_count": 3,
"id": "297e78a6",
"metadata": {
"colab": {
"base_uri": "https://localhost:8080/",
"height": 437
},
"id": "BzXphJWf_TAZ",
"outputId": "de7fc966-e0fd-4daf-a9bd-4743455ea774"
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"\n",
"\n",
"\u001b[1m> Entering new ConversationChain chain...\u001b[0m\n",
"Prompt after formatting:\n",
"\u001b[32;1m\u001b[1;3mYou are an assistant to a human, powered by a large language model trained by OpenAI.\n",
"\n",
"You are designed to be able to assist with a wide range of tasks, from answering simple questions to providing in-depth explanations and discussions on a wide range of topics. As a language model, you are able to generate human-like text based on the input you receive, allowing you to engage in natural-sounding conversations and provide responses that are coherent and relevant to the topic at hand.\n",
"\n",
"You are constantly learning and improving, and your capabilities are constantly evolving. You are able to process and understand large amounts of text, and can use this knowledge to provide accurate and informative responses to a wide range of questions. You have access to some personalized information provided by the human in the Context section below. Additionally, you are able to generate your own text based on the input you receive, allowing you to engage in discussions and provide explanations and descriptions on a wide range of topics.\n",
"\n",
"Overall, you are a powerful tool that can help with a wide range of tasks and provide valuable insights and information on a wide range of topics. Whether the human needs help with a specific question or just wants to have a conversation about a particular topic, you are here to assist.\n",
"\n",
"Context:\n",
"{'Deven': 'Deven is working on a hackathon project with Sam.', 'Sam': 'Sam is working on a hackathon project with Deven.'}\n",
"\n",
"Current conversation:\n",
"\n",
"Last line:\n",
"Human: Deven & Sam are working on a hackathon project\n",
"You:\u001b[0m\n",
"\n",
"\u001b[1m> Finished chain.\u001b[0m\n"
]
},
{
"data": {
"text/plain": [
"' That sounds like a great project! What kind of project are they working on?'"
]
},
"execution_count": 3,
"metadata": {},
"output_type": "execute_result"
}
],
"id": "6558418b-0ece-4d01-9661-56d562d78f7a",
"metadata": {},
"outputs": [],
"source": [
"conversation.run(\"Deven & Sam are working on a hackathon project\")"
"from typing import Optional\n",
"\n",
"from langchain_core.prompts import ChatPromptTemplate, MessagesPlaceholder\n",
"from langchain_core.runnables.history import RunnableWithMessageHistory\n",
"from langchain_openai import ChatOpenAI"
]
},
{
"cell_type": "code",
"execution_count": 4,
"id": "7e71f1dc",
"metadata": {
"colab": {
"base_uri": "https://localhost:8080/",
"height": 35
},
"id": "YsFE3hBjC6gl",
"outputId": "56ab5ca9-e343-41b5-e69d-47541718a9b4"
},
"outputs": [
{
"data": {
"text/plain": [
"'Deven is working on a hackathon project with Sam.'"
]
},
"execution_count": 4,
"metadata": {},
"output_type": "execute_result"
}
],
"id": "82149122-61d3-490d-9bdb-bb98606e8ba1",
"metadata": {},
"outputs": [],
"source": [
"conversation.memory.entity_store.get(\"Deven\")"
"prompt = ChatPromptTemplate.from_messages(\n",
" [\n",
" (\"system\", \"You are a helpful assistant.\"),\n",
" MessagesPlaceholder(variable_name=\"history\"),\n",
" (\"human\", \"{question}\"),\n",
" ]\n",
")\n",
"\n",
"chain = prompt | ChatOpenAI()"
]
},
{
"cell_type": "code",
"execution_count": 5,
"id": "316f2e8d",
"id": "2df90853-b67c-490f-b7f8-b69d69270b9c",
"metadata": {},
"outputs": [],
"source": [
"chain_with_history = RunnableWithMessageHistory(\n",
" chain,\n",
" lambda session_id: SQLChatMessageHistory(\n",
" session_id=session_id, connection_string=\"sqlite:///sqlite.db\"\n",
" ),\n",
" input_messages_key=\"question\",\n",
" history_messages_key=\"history\",\n",
")"
]
},
{
"cell_type": "code",
"execution_count": 8,
"id": "0ce596b8-3b78-48fd-9f92-46dccbbfd58b",
"metadata": {},
"outputs": [],
"source": [
"# This is where we configure the session id\n",
"config = {\"configurable\": {\"session_id\": \"<SQL_SESSION_ID>\"}}"
]
},
{
"cell_type": "code",
"execution_count": 9,
"id": "38e1423b-ba86-4496-9151-25932fab1a8b",
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"'Sam is working on a hackathon project with Deven.'"
"AIMessage(content='Hello Bob! How can I assist you today?')"
]
},
"execution_count": 5,
"execution_count": 9,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"conversation.memory.entity_store.get(\"Sam\")"
"chain_with_history.invoke({\"question\": \"Hi! I'm bob\"}, config=config)"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "b85f8427",
"execution_count": 10,
"id": "2ee4ee62-a216-4fb1-bf33-57476a84cf16",
"metadata": {},
"outputs": [],
"source": []
"outputs": [
{
"data": {
"text/plain": [
"AIMessage(content='Your name is Bob! Is there anything specific you would like assistance with, Bob?')"
]
},
"execution_count": 10,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"chain_with_history.invoke({\"question\": \"Whats my name\"}, config=config)"
]
}
],
"metadata": {

View File

@@ -10,7 +10,6 @@
">[Streamlit](https://docs.streamlit.io/) is an open-source Python library that makes it easy to create and share beautiful, \n",
"custom web apps for machine learning and data science.\n",
"\n",
"\n",
"This notebook goes over how to store and use chat message history in a `Streamlit` app. `StreamlitChatMessageHistory` will store messages in\n",
"[Streamlit session state](https://docs.streamlit.io/library/api-reference/session-state)\n",
"at the specified `key=`. The default key is `\"langchain_messages\"`.\n",
@@ -20,6 +19,12 @@
"- For more on Streamlit check out their\n",
"[getting started documentation](https://docs.streamlit.io/library/get-started).\n",
"\n",
"The integration lives in the `langchain-community` package, so we need to install that. We also need to install `streamlit`.\n",
"\n",
"```\n",
"pip install -U langchain-community streamlit\n",
"```\n",
"\n",
"You can see the [full app example running here](https://langchain-st-memory.streamlit.app/), and more examples in\n",
"[github.com/langchain-ai/streamlit-agent](https://github.com/langchain-ai/streamlit-agent)."
]
@@ -31,7 +36,7 @@
"metadata": {},
"outputs": [],
"source": [
"from langchain.memory import StreamlitChatMessageHistory\n",
"from langchain_community.chat_message_histories import StreamlitChatMessageHistory\n",
"\n",
"history = StreamlitChatMessageHistory(key=\"chat_messages\")\n",
"\n",
@@ -54,7 +59,9 @@
"id": "b60dc735",
"metadata": {},
"source": [
"You can integrate `StreamlitChatMessageHistory` into `ConversationBufferMemory` and chains or agents as usual. The history will be persisted across re-runs of the Streamlit app within a given user session. A given `StreamlitChatMessageHistory` will NOT be persisted or shared across user sessions."
"We can easily combine this message history class with [LCEL Runnables](https://python.langchain.com/docs/expression_language/how_to/message_history).\n",
"\n",
"The history will be persisted across re-runs of the Streamlit app within a given user session. A given `StreamlitChatMessageHistory` will NOT be persisted or shared across user sessions."
]
},
{
@@ -64,13 +71,11 @@
"metadata": {},
"outputs": [],
"source": [
"from langchain.memory import ConversationBufferMemory\n",
"from langchain_community.chat_message_histories import StreamlitChatMessageHistory\n",
"\n",
"# Optionally, specify your own session_state key for storing messages\n",
"msgs = StreamlitChatMessageHistory(key=\"special_app_key\")\n",
"\n",
"memory = ConversationBufferMemory(memory_key=\"history\", chat_memory=msgs)\n",
"if len(msgs.messages) == 0:\n",
" msgs.add_ai_message(\"How can I help you?\")"
]
@@ -82,19 +87,34 @@
"metadata": {},
"outputs": [],
"source": [
"from langchain.chains import LLMChain\n",
"from langchain.prompts import PromptTemplate\n",
"from langchain_openai import OpenAI\n",
"from langchain_core.prompts import ChatPromptTemplate, MessagesPlaceholder\n",
"from langchain_core.runnables.history import RunnableWithMessageHistory\n",
"from langchain_openai import ChatOpenAI\n",
"\n",
"template = \"\"\"You are an AI chatbot having a conversation with a human.\n",
"prompt = ChatPromptTemplate.from_messages(\n",
" [\n",
" (\"system\", \"You are an AI chatbot having a conversation with a human.\"),\n",
" MessagesPlaceholder(variable_name=\"history\"),\n",
" (\"human\", \"{question}\"),\n",
" ]\n",
")\n",
"\n",
"{history}\n",
"Human: {human_input}\n",
"AI: \"\"\"\n",
"prompt = PromptTemplate(input_variables=[\"history\", \"human_input\"], template=template)\n",
"\n",
"# Add the memory to an LLMChain as usual\n",
"llm_chain = LLMChain(llm=OpenAI(), prompt=prompt, memory=memory)"
"chain = prompt | ChatOpenAI()"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "dac3d94f",
"metadata": {},
"outputs": [],
"source": [
"chain_with_history = RunnableWithMessageHistory(\n",
" chain,\n",
" lambda session_id: msgs, # Always return the instance created earlier\n",
" input_messages_key=\"question\",\n",
" history_messages_key=\"history\",\n",
")"
]
},
{
@@ -121,8 +141,9 @@
" st.chat_message(\"human\").write(prompt)\n",
"\n",
" # As usual, new messages are added to StreamlitChatMessageHistory when the Chain is called.\n",
" response = llm_chain.run(prompt)\n",
" st.chat_message(\"ai\").write(response)"
" config = {\"configurable\": {\"session_id\": \"any\"}}\n",
" response = chain_with_history.invoke({\"question\": prompt}, config)\n",
" st.chat_message(\"ai\").write(response.content)"
]
},
{

View File

@@ -186,7 +186,7 @@ from langchain_community.document_loaders import GoogleSpeechToTextLoader
### 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
> 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.
@@ -207,10 +207,14 @@ from langchain_community.vectorstores import MatchingEngine
> [Google BigQuery](https://cloud.google.com/bigquery),
> BigQuery is a serverless and cost-effective enterprise data warehouse in Google Cloud.
>
> Google BigQuery Vector Search
> Google BigQuery Vector Search
> BigQuery vector search lets you use GoogleSQL to do semantic search, using vector indexes for fast but approximate results, or using brute force for exact results.
> It can calculate Euclidean or Cosine distance. With LangChain, we default to use Euclidean distance.
> It can calculate Euclidean or Cosine distance. With LangChain, we default to use Euclidean distance.
> This is a private preview (experimental) feature. Please submit this
> [enrollment form](https://docs.google.com/forms/d/18yndSb4dTf2H0orqA9N7NAchQEDQekwWiD5jYfEkGWk/viewform?edit_requested=true)
> if you want to enroll BigQuery Vector Search Experimental.
We need to install several python packages.
@@ -228,7 +232,7 @@ from langchain.vectorstores import BigQueryVectorSearch
>[Google ScaNN](https://github.com/google-research/google-research/tree/master/scann)
> (Scalable Nearest Neighbors) is a python package.
>
>
>`ScaNN` is a method for efficient vector similarity search at scale.
>`ScaNN` includes search space pruning and quantization for Maximum Inner
@@ -285,9 +289,9 @@ 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
> allows enterprises to search, store, govern, and manage documents and their AI-extracted
> data and metadata in a single platform.
>
>
```python
from langchain.retrievers import GoogleDocumentAIWarehouseRetriever
@@ -304,9 +308,9 @@ documents = docai_wh_retriever.get_relevant_documents(
### Google Cloud Text-to-Speech
>[Google Cloud Text-to-Speech](https://cloud.google.com/text-to-speech) enables developers to
> synthesize natural-sounding speech with 100+ voices, available in multiple languages and variants.
> It applies DeepMinds groundbreaking research in WaveNet and Googles powerful neural networks
>[Google Cloud Text-to-Speech](https://cloud.google.com/text-to-speech) enables developers to
> synthesize natural-sounding speech with 100+ voices, available in multiple languages and variants.
> It applies DeepMinds groundbreaking research in WaveNet and Googles powerful neural networks
> to deliver the highest fidelity possible.
We need to install a python package.
@@ -354,7 +358,7 @@ from langchain.tools import GooglePlacesTool
### Google Search
- 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
- 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.
```python
@@ -444,12 +448,12 @@ from langchain_community.utilities.google_trends import GoogleTrendsAPIWrapper
### Google Document AI
>[Document AI](https://cloud.google.com/document-ai/docs/overview) is a `Google Cloud Platform`
> service that transforms unstructured data from documents into structured data, making it easier
>[Document AI](https://cloud.google.com/document-ai/docs/overview) is a `Google Cloud Platform`
> 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://`)
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://`)
and a processor name should look like `projects/PROJECT_NUMBER/locations/LOCATION/processors/PROCESSOR_ID`.
We can get it either programmatically or copy from the `Prediction endpoint` section of the `Processor details`
tab in the Google Cloud Console.
@@ -507,6 +511,23 @@ See a [usage example and authorization instructions](/docs/integrations/toolkits
from langchain_community.agent_toolkits import GmailToolkit
```
## Memory
### Cloud Firestore
> [`Cloud Firestore`](https://cloud.google.com/firestore) is a NoSQL document database built for automatic scaling, high performance, and ease of application development.
First, we need to install the python package.
```bash
pip install firebase-admin
```
See a [usage example and authorization instructions](/docs/integrations/memory/firestore_chat_message_history).
```python
from langchain_community.chat_message_histories.firestore import FirestoreChatMessageHistory
```
## Chat Loaders
@@ -560,7 +581,7 @@ from langchain_community.utilities import GoogleSerperAPIWrapper
### YouTube
>[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.

View File

@@ -10,7 +10,7 @@ All functionality related to `Microsoft Azure` and other `Microsoft` products.
>[Azure OpenAI](https://learn.microsoft.com/en-us/azure/cognitive-services/openai/) is an `Azure` service with powerful language models from `OpenAI` including the `GPT-3`, `Codex` and `Embeddings model` series for content generation, summarization, semantic search, and natural language to code translation.
```bash
pip install openai tiktoken
pip install langchain-openai
```
Set the environment variables to get access to the `Azure OpenAI` service.

View File

@@ -14,11 +14,12 @@ All functionality related to OpenAI
## Installation and Setup
- Install the LangChain partner package
Install the integration package with
```bash
pip install langchain-openai
```
- Get an OpenAI api key and set it as an environment variable (`OPENAI_API_KEY`)
Get an OpenAI api key and set it as an environment variable (`OPENAI_API_KEY`)
## LLM

View File

@@ -13,7 +13,7 @@ Activeloop Deep Lake supports SelfQuery Retrieval:
## More Resources
1. [Ultimate Guide to LangChain & Deep Lake: Build ChatGPT to Answer Questions on Your Financial Data](https://www.activeloop.ai/resources/ultimate-guide-to-lang-chain-deep-lake-build-chat-gpt-to-answer-questions-on-your-financial-data/)
2. [Twitter the-algorithm codebase analysis with Deep Lake](/docs/use_cases/question_answering/code/twitter-the-algorithm-analysis-deeplake)
2. [Twitter the-algorithm codebase analysis with Deep Lake](https://github.com/langchain-ai/langchain/blob/master/cookbook/twitter-the-algorithm-analysis-deeplake.ipynb)
3. Here is [whitepaper](https://www.deeplake.ai/whitepaper) and [academic paper](https://arxiv.org/pdf/2209.10785.pdf) for Deep Lake
4. Here is a set of additional resources available for review: [Deep Lake](https://github.com/activeloopai/deeplake), [Get started](https://docs.activeloop.ai/getting-started) and [Tutorials](https://docs.activeloop.ai/hub-tutorials)

View File

@@ -1,17 +1,34 @@
# Anyscale
This page covers how to use the Anyscale ecosystem within LangChain.
It is broken into two parts: installation and setup, and then references to specific Anyscale wrappers.
>[Anyscale](https://www.anyscale.com) is a platform to run, fine tune and scale LLMs via production-ready APIs.
> [Anyscale Endpoints](https://docs.anyscale.com/endpoints/overview) serve many open-source models in a cost-effective way.
`Anyscale` also provides [an example](https://docs.anyscale.com/endpoints/model-serving/examples/langchain-integration)
how to setup `LangChain` with `Anyscale` for advanced chat agents.
## Installation and Setup
- Get an Anyscale Service URL, route and API key and set them as environment variables (`ANYSCALE_SERVICE_URL`,`ANYSCALE_SERVICE_ROUTE`, `ANYSCALE_SERVICE_TOKEN`).
- Please see [the Anyscale docs](https://docs.anyscale.com/productionize/services-v2/get-started) for more details.
- Please see [the Anyscale docs](https://www.anyscale.com/get-started) for more details.
## Wrappers
We have to install the `openai` package:
### LLM
There exists an Anyscale LLM wrapper, which you can access with
```python
from langchain_community.llms import Anyscale
```bash
pip install openai
```
## LLM
See a [usage example](/docs/integrations/llms/anyscale).
```python
from langchain_community.llms.anyscale import Anyscale
```
## Chat Models
See a [usage example](/docs/integrations/chat/anyscale).
```python
from langchain_community.chat_models.anyscale import ChatAnyscale
```

View File

@@ -18,11 +18,11 @@ whether for semantic search or example selection.
from langchain_community.vectorstores import Chroma
```
For a more detailed walkthrough of the Chroma wrapper, see [this notebook](/docs/integrations/vectorstores/chroma_self_query)
For a more detailed walkthrough of the Chroma wrapper, see [this notebook](/docs/integrations/vectorstores/chroma)
## Retriever
See a [usage example](/docs/integrations/retrievers/self_query/chroma).
See a [usage example](/docs/integrations/retrievers/self_query/chroma_self_query).
```python
from langchain.retrievers import SelfQueryRetriever

View File

@@ -150,4 +150,4 @@ This command will initiate the execution of the `langchain_llm` task on the Flyt
The metrics will be displayed on the Flyte UI as follows:
![LangChain LLM](https://ik.imagekit.io/c8zl7irwkdda/Screenshot_2023-06-20_at_1.23.29_PM_MZYeG0dKa.png?updatedAt=1687247642993)
![Screenshot of Flyte Deck showing LangChain metrics and a dependency tree visualization.](https://ik.imagekit.io/c8zl7irwkdda/Screenshot_2023-06-20_at_1.23.29_PM_MZYeG0dKa.png?updatedAt=1687247642993 "Flyte Deck Metrics Display")

View File

@@ -6,7 +6,7 @@ This page covers how to use the [Helicone](https://helicone.ai) ecosystem within
Helicone is an [open-source](https://github.com/Helicone/helicone) observability platform that proxies your OpenAI traffic and provides you key insights into your spend, latency and usage.
![Helicone](/img/HeliconeDashboard.png)
![Screenshot of the Helicone dashboard showing average requests per day, response time, tokens per response, total cost, and a graph of requests over time.](/img/HeliconeDashboard.png "Helicone Dashboard")
## Quick start
@@ -18,7 +18,7 @@ export OPENAI_API_BASE="https://oai.hconeai.com/v1"
Now head over to [helicone.ai](https://helicone.ai/onboarding?step=2) to create your account, and add your OpenAI API key within our dashboard to view your logs.
![Helicone](/img/HeliconeKeys.png)
![Interface for entering and managing OpenAI API keys in the Helicone dashboard.](/img/HeliconeKeys.png "Helicone API Key Input")
## How to enable Helicone caching

View File

@@ -0,0 +1,25 @@
# Lantern
This page covers how to use the [Lantern](https://github.com/lanterndata/lantern) within LangChain
It is broken into two parts: setup, and then references to specific Lantern wrappers.
## Setup
1. The first step is to create a database with the `lantern` extension installed.
Follow the steps at [Lantern Installation Guide](https://github.com/lanterndata/lantern#-quick-install) to install the database and the extension. The docker image is the easiest way to get started.
## Wrappers
### VectorStore
There exists a wrapper around Postgres vector databases, allowing you to use it as a vectorstore,
whether for semantic search or example selection.
To import this vectorstore:
```python
from langchain_community.vectorstores import Lantern
```
### Usage
For a more detailed walkthrough of the Lantern Wrapper, see [this notebook](/docs/integrations/vectorstores/lantern)

View File

@@ -6,7 +6,7 @@ This page covers how to use [Metal](https://getmetal.io) within LangChain.
Metal is a managed retrieval & memory platform built for production. Easily index your data into `Metal` and run semantic search and retrieval on it.
![Metal](/img/MetalDash.png)
![Screenshot of the Metal dashboard showing the Browse Index feature with sample data.](/img/MetalDash.png "Metal Dashboard Interface")
## Quick start

View File

@@ -9,9 +9,7 @@
We need to install several python packages.
```bash
pip install openai
pip install psycopg2-binary
pip install tiktoken
```
## Vector Store

View File

@@ -66,7 +66,7 @@
"source": [
"## Document Compressor\n",
"\n",
"We can also use RAGatouille off-the-shelf as a reranker. This will allow us to use ColBERT to rerank retrieved results from any generic retriever. The benefits of this are that we can do this on top of any existing index, so that we don't need to create a new idex. We can do this by using the [document compressor](/docs/modules/data_connections/retrievers/contextual_compression) abstraction in LangChain."
"We can also use RAGatouille off-the-shelf as a reranker. This will allow us to use ColBERT to rerank retrieved results from any generic retriever. The benefits of this are that we can do this on top of any existing index, so that we don't need to create a new idex. We can do this by using the [document compressor](/docs/modules/data_connection/retrievers/contextual_compression) abstraction in LangChain."
]
},
{

View File

@@ -5,13 +5,15 @@
## Installation and Setup
You need to install `langchain-robocorp` python package, as well as the `robocorp-action-server` package to run the action server locally.
You need to install `langchain-robocorp` python package:
```bash
pip install langchain-robocorp robocorp-action-server
pip install langchain-robocorp
```
You will need a running instance of Action Server to communicate with from your agent application. You can bootstrap a new project using Action Server `new` command.
You will need a running instance of Action Server to communicate with from your agent application. See the [Robocorp Quickstart](https://github.com/robocorp/robocorp#quickstart) on how to setup Action Server and create your Actions.
You can bootstrap a new project using Action Server `new` command.
```bash
action-server new

View File

@@ -7,7 +7,7 @@
```bash
pip install tigrisdb openapi-schema-pydantic openai tiktoken
pip install tigrisdb openapi-schema-pydantic
```
## Vector Store

View File

@@ -10,7 +10,7 @@
```bash
pip install typesense openapi-schema-pydantic openai tiktoken
pip install typesense openapi-schema-pydantic
```
## Vector Store

View File

@@ -51,7 +51,7 @@
"cell_type": "markdown",
"metadata": {},
"source": [
"Also you'll need to create a [Activeloop]((https://activeloop.ai/)) account."
"Also you'll need to create a [Activeloop](https://activeloop.ai) account."
]
},
{

View File

@@ -18,6 +18,15 @@
"## Setup"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"%pip install --upgrade --quiet langchain langchain-openai"
]
},
{
"cell_type": "markdown",
"metadata": {},

View File

@@ -0,0 +1,322 @@
{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Astra DB\n",
"\n",
"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.\n",
"\n",
"In the walkthrough, we'll demo the `SelfQueryRetriever` with an `Astra DB` vector store."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Creating an Astra DB vector store\n",
"First we'll want to create an Astra DB VectorStore and seed it with some data. We've created a small demo set of documents that contain summaries of movies.\n",
"\n",
"NOTE: The self-query retriever requires you to have `lark` installed (`pip install lark`). We also need the `astrapy` package."
]
},
{
"cell_type": "code",
"execution_count": 5,
"metadata": {},
"outputs": [],
"source": [
"%pip install --upgrade --quiet lark astrapy langchain-openai"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"We want to use `OpenAIEmbeddings` so we have to get the OpenAI API Key."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"import os\n",
"from getpass import getpass\n",
"\n",
"from langchain_openai.embeddings import OpenAIEmbeddings\n",
"\n",
"os.environ[\"OPENAI_API_KEY\"] = getpass(\"OpenAI API Key:\")\n",
"\n",
"embeddings = OpenAIEmbeddings()"
]
},
{
"cell_type": "markdown",
"metadata": {
"collapsed": false,
"pycharm": {
"name": "#%% md\n"
}
},
"source": [
"Create the Astra DB VectorStore:\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,
"metadata": {},
"outputs": [],
"source": [
"ASTRA_DB_API_ENDPOINT = input(\"ASTRA_DB_API_ENDPOINT = \")\n",
"ASTRA_DB_APPLICATION_TOKEN = getpass(\"ASTRA_DB_APPLICATION_TOKEN = \")"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"from langchain.schema import Document\n",
"from langchain.vectorstores import AstraDB\n",
"\n",
"docs = [\n",
" Document(\n",
" page_content=\"A bunch of scientists bring back dinosaurs and mayhem breaks loose\",\n",
" metadata={\"year\": 1993, \"rating\": 7.7, \"genre\": \"science fiction\"},\n",
" ),\n",
" Document(\n",
" page_content=\"Leo DiCaprio gets lost in a dream within a dream within a dream within a ...\",\n",
" metadata={\"year\": 2010, \"director\": \"Christopher Nolan\", \"rating\": 8.2},\n",
" ),\n",
" Document(\n",
" page_content=\"A psychologist / detective gets lost in a series of dreams within dreams within dreams and Inception reused the idea\",\n",
" metadata={\"year\": 2006, \"director\": \"Satoshi Kon\", \"rating\": 8.6},\n",
" ),\n",
" Document(\n",
" page_content=\"A bunch of normal-sized women are supremely wholesome and some men pine after them\",\n",
" metadata={\"year\": 2019, \"director\": \"Greta Gerwig\", \"rating\": 8.3},\n",
" ),\n",
" Document(\n",
" page_content=\"Toys come alive and have a blast doing so\",\n",
" metadata={\"year\": 1995, \"genre\": \"animated\"},\n",
" ),\n",
" Document(\n",
" page_content=\"Three men walk into the Zone, three men walk out of the Zone\",\n",
" metadata={\n",
" \"year\": 1979,\n",
" \"director\": \"Andrei Tarkovsky\",\n",
" \"genre\": \"science fiction\",\n",
" \"rating\": 9.9,\n",
" },\n",
" ),\n",
"]\n",
"\n",
"vectorstore = AstraDB.from_documents(\n",
" docs,\n",
" embeddings,\n",
" collection_name=\"astra_self_query_demo\",\n",
" api_endpoint=ASTRA_DB_API_ENDPOINT,\n",
" token=ASTRA_DB_APPLICATION_TOKEN,\n",
")"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Creating our self-querying retriever\n",
"Now we can instantiate our retriever. To do this we'll need to provide some information upfront about the metadata fields that our documents support and a short description of the document contents."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"from langchain.chains.query_constructor.base import AttributeInfo\n",
"from langchain.llms import OpenAI\n",
"from langchain.retrievers.self_query.base import SelfQueryRetriever\n",
"\n",
"metadata_field_info = [\n",
" AttributeInfo(\n",
" name=\"genre\",\n",
" description=\"The genre of the movie\",\n",
" type=\"string or list[string]\",\n",
" ),\n",
" AttributeInfo(\n",
" name=\"year\",\n",
" description=\"The year the movie was released\",\n",
" type=\"integer\",\n",
" ),\n",
" AttributeInfo(\n",
" name=\"director\",\n",
" description=\"The name of the movie director\",\n",
" type=\"string\",\n",
" ),\n",
" AttributeInfo(\n",
" name=\"rating\", description=\"A 1-10 rating for the movie\", type=\"float\"\n",
" ),\n",
"]\n",
"document_content_description = \"Brief summary of a movie\"\n",
"llm = OpenAI(temperature=0)\n",
"\n",
"retriever = SelfQueryRetriever.from_llm(\n",
" llm, vectorstore, document_content_description, metadata_field_info, verbose=True\n",
")"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Testing it out\n",
"And now we can try actually using our retriever!"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"# This example only specifies a relevant query\n",
"retriever.get_relevant_documents(\"What are some movies about dinosaurs?\")"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"# This example specifies a filter\n",
"retriever.get_relevant_documents(\"I want to watch a movie rated higher than 8.5\")"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"# This example only specifies a query and a filter\n",
"retriever.get_relevant_documents(\"Has Greta Gerwig directed any movies about women\")"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"# This example specifies a composite filter\n",
"retriever.get_relevant_documents(\n",
" \"What's a highly rated (above 8.5), science fiction movie ?\"\n",
")"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"# This example specifies a query and composite filter\n",
"retriever.get_relevant_documents(\n",
" \"What's a movie about toys after 1990 but before 2005, and is animated\"\n",
")"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Filter k\n",
"\n",
"We can also use the self query retriever to specify `k`: the number of documents to fetch.\n",
"\n",
"We can do this by passing `enable_limit=True` to the constructor."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"retriever = SelfQueryRetriever.from_llm(\n",
" llm,\n",
" vectorstore,\n",
" document_content_description,\n",
" metadata_field_info,\n",
" verbose=True,\n",
" enable_limit=True,\n",
")"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"# This example only specifies a relevant query\n",
"retriever.get_relevant_documents(\"What are two movies about dinosaurs?\")"
]
},
{
"cell_type": "markdown",
"metadata": {
"collapsed": false
},
"source": [
"## Cleanup\n",
"\n",
"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,
"metadata": {
"collapsed": false
},
"outputs": [],
"source": [
"vectorstore.delete_collection()"
]
}
],
"metadata": {
"kernelspec": {
"display_name": ".venv",
"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.5"
}
},
"nbformat": 4,
"nbformat_minor": 2
}

View File

@@ -0,0 +1,240 @@
{
"cells": [
{
"cell_type": "raw",
"metadata": {},
"source": [
"---\n",
"sidebar_label: Astra DB\n",
"---"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Astra DB\n",
"\n",
"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.\n",
"\n",
"`AstraDBStore` and `AstraDBByteStore` need the `astrapy` package to be installed:"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"vscode": {
"languageId": "plaintext"
}
},
"outputs": [],
"source": [
"%pip install --upgrade --quiet astrapy"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"The Store takes the following parameters:\n",
"\n",
"* `api_endpoint`: Astra DB API endpoint. Looks like `https://01234567-89ab-cdef-0123-456789abcdef-us-east1.apps.astra.datastax.com`\n",
"* `token`: Astra DB token. Looks like `AstraCS:6gBhNmsk135....`\n",
"* `collection_name` : Astra DB collection name\n",
"* `namespace`: (Optional) Astra DB namespace"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## AstraDBStore\n",
"\n",
"The `AstraDBStore` is an implementation of `BaseStore` that stores everything in your DataStax Astra DB instance.\n",
"The store keys must be strings and will be mapped to the `_id` field of the Astra DB document.\n",
"The store values can be any object that can be serialized by `json.dumps`.\n",
"In the database, entries will have the form:\n",
"\n",
"```json\n",
"{\n",
" \"_id\": \"<key>\",\n",
" \"value\": <value>\n",
"}\n",
"```"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"from langchain_community.storage import AstraDBStore"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"from getpass import getpass\n",
"\n",
"ASTRA_DB_API_ENDPOINT = input(\"ASTRA_DB_API_ENDPOINT = \")\n",
"ASTRA_DB_APPLICATION_TOKEN = getpass(\"ASTRA_DB_APPLICATION_TOKEN = \")"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"store = AstraDBStore(\n",
" api_endpoint=ASTRA_DB_API_ENDPOINT,\n",
" token=ASTRA_DB_APPLICATION_TOKEN,\n",
" collection_name=\"my_store\",\n",
")"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"['v1', [0.1, 0.2, 0.3]]\n"
]
}
],
"source": [
"store.mset([(\"k1\", \"v1\"), (\"k2\", [0.1, 0.2, 0.3])])\n",
"print(store.mget([\"k1\", \"k2\"]))"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Usage with CacheBackedEmbeddings\n",
"\n",
"You may use the `AstraDBStore` in conjunction with a [`CacheBackedEmbeddings`](/docs/modules/data_connection/text_embedding/caching_embeddings) to cache the result of embeddings computations.\n",
"Note that `AstraDBStore` stores the embeddings as a list of floats without converting them first to bytes so we don't use `fromByteStore` there."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"from langchain.embeddings import CacheBackedEmbeddings, OpenAIEmbeddings\n",
"\n",
"embeddings = CacheBackedEmbeddings(\n",
" underlying_embeddings=OpenAIEmbeddings(), document_embedding_store=store\n",
")"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## AstraDBByteStore\n",
"\n",
"The `AstraDBByteStore` is an implementation of `ByteStore` that stores everything in your DataStax Astra DB instance.\n",
"The store keys must be strings and will be mapped to the `_id` field of the Astra DB document.\n",
"The store `bytes` values are converted to base64 strings for storage into Astra DB.\n",
"In the database, entries will have the form:\n",
"\n",
"```json\n",
"{\n",
" \"_id\": \"<key>\",\n",
" \"value\": \"bytes encoded in base 64\"\n",
"}\n",
"```"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"from langchain_community.storage import AstraDBByteStore"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"from getpass import getpass\n",
"\n",
"ASTRA_DB_API_ENDPOINT = input(\"ASTRA_DB_API_ENDPOINT = \")\n",
"ASTRA_DB_APPLICATION_TOKEN = getpass(\"ASTRA_DB_APPLICATION_TOKEN = \")"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"store = AstraDBByteStore(\n",
" api_endpoint=ASTRA_DB_API_ENDPOINT,\n",
" token=ASTRA_DB_APPLICATION_TOKEN,\n",
" collection_name=\"my_store\",\n",
")"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"[b'v1', b'v2']\n"
]
}
],
"source": [
"store.mset([(\"k1\", b\"v1\"), (\"k2\", b\"v2\")])\n",
"print(store.mget([\"k1\", \"k2\"]))"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": []
}
],
"metadata": {
"kernelspec": {
"display_name": ".venv",
"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.4"
}
},
"nbformat": 4,
"nbformat_minor": 2
}

View File

@@ -10,6 +10,51 @@
"which converts text into a vector form represented by numerical values, and is used in text retrieval, information recommendation, knowledge mining and other scenarios."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"**Deprecated Warning**\n",
"\n",
"We recommend users using `langchain_community.embeddings.ErnieEmbeddings` \n",
"to use `langchain_community.embeddings.QianfanEmbeddingsEndpoint` instead.\n",
"\n",
"documentation for `QianfanEmbeddingsEndpoint` is [here](./baidu_qianfan_endpoint).\n",
"\n",
"they are 2 why we recommend users to use `QianfanEmbeddingsEndpoint`:\n",
"\n",
"1. `QianfanEmbeddingsEndpoint` support more embedding model in the Qianfan platform.\n",
"2. `ErnieEmbeddings` is lack of maintenance and deprecated."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Some tips for migration:"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"from langchain_community.embeddings import QianfanEmbeddingsEndpoint\n",
"\n",
"embeddings = QianfanEmbeddingsEndpoint(\n",
" qianfan_ak=\"your qianfan ak\",\n",
" qianfan_sk=\"your qianfan sk\",\n",
")"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Usage"
]
},
{
"cell_type": "code",
"execution_count": null,

View File

@@ -194,6 +194,19 @@
"source": [
"In retrieval, relative distance matters. In the image above, you can see the difference in similarity scores between the \"relevant doc\" and \"simil stronger delta between the similar query and relevant doc on the latter case."
]
},
{
"cell_type": "markdown",
"id": "2e7857e5",
"metadata": {},
"source": [
"## Additional Configuraation\n",
"\n",
"You can pass the following parameters to ChatGoogleGenerativeAI in order to customize the SDK's behavior:\n",
"\n",
"- `client_options`: [Client Options](https://googleapis.dev/python/google-api-core/latest/client_options.html#module-google.api_core.client_options) to pass to the Google API Client, such as a custom `client_options[\"api_endpoint\"]`\n",
"- `transport`: The transport method to use, such as `rest`, `grpc`, or `grpc_asyncio`."
]
}
],
"metadata": {

View File

@@ -106,7 +106,7 @@
"metadata": {},
"outputs": [
{
"name": "stdin",
"name": "stdout",
"output_type": "stream",
"text": [
"Enter your HF Inference API Key:\n",
@@ -148,6 +148,75 @@
"query_result = embeddings.embed_query(text)\n",
"query_result[:3]"
]
},
{
"cell_type": "markdown",
"id": "19ef2d31",
"metadata": {},
"source": [
"## Hugging Face Hub\n",
"We can also generate embeddings locally via the Hugging Face Hub package, which requires us to install ``huggingface_hub ``"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "39e85945",
"metadata": {},
"outputs": [],
"source": [
"!pip install huggingface_hub"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "c78a2779",
"metadata": {},
"outputs": [],
"source": [
"from langchain_community.embeddings import HuggingFaceHubEmbeddings"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "116f3ce7",
"metadata": {},
"outputs": [],
"source": [
"embeddings = HuggingFaceHubEmbeddings()"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "d6f97ee9",
"metadata": {},
"outputs": [],
"source": [
"text = \"This is a test document.\""
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "fb6adc67",
"metadata": {},
"outputs": [],
"source": [
"query_result = embeddings.embed_query(text)"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "1f42c311",
"metadata": {},
"outputs": [],
"source": [
"query_result[:3]"
]
}
],
"metadata": {

View File

@@ -0,0 +1,103 @@
{
"cells": [
{
"cell_type": "markdown",
"id": "b14a24db",
"metadata": {},
"source": [
"# MistralAI\n",
"\n",
"This notebook explains how to use MistralAIEmbeddings, which is included in the langchain_mistralai package, to embed texts in langchain."
]
},
{
"cell_type": "code",
"execution_count": 1,
"id": "0ab948fc",
"metadata": {},
"outputs": [],
"source": [
"# pip install -U langchain-mistralai"
]
},
{
"cell_type": "markdown",
"id": "67c637ca",
"metadata": {},
"source": [
"## import the library"
]
},
{
"cell_type": "code",
"execution_count": 2,
"id": "5709b030",
"metadata": {},
"outputs": [],
"source": [
"from langchain_mistralai import MistralAIEmbeddings"
]
},
{
"cell_type": "code",
"execution_count": 3,
"id": "1756b1ba",
"metadata": {},
"outputs": [],
"source": [
"embedding = MistralAIEmbeddings(mistral_api_key=\"your-api-key\")"
]
},
{
"cell_type": "markdown",
"id": "4a2a098d",
"metadata": {},
"source": [
"# Using the Embedding Model\n",
"With `MistralAIEmbeddings`, you can directly use the default model 'mistral-embed', or set a different one if available."
]
},
{
"cell_type": "code",
"execution_count": 4,
"id": "584b9af5",
"metadata": {},
"outputs": [],
"source": [
"embedding.model = \"mistral-embed\" # or your preferred model if available"
]
},
{
"cell_type": "code",
"execution_count": 5,
"id": "be18b873",
"metadata": {},
"outputs": [],
"source": [
"res_query = embedding.embed_query(\"The test information\")\n",
"res_document = embedding.embed_documents([\"test1\", \"another test\"])"
]
}
],
"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.4"
}
},
"nbformat": 4,
"nbformat_minor": 5
}

View File

@@ -17,7 +17,7 @@
},
{
"cell_type": "code",
"execution_count": 1,
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
@@ -30,13 +30,18 @@
"source": [
"## Assign Environmental Variables\n",
"\n",
"The toolkit will read the AMADEUS_CLIENT_ID and AMADEUS_CLIENT_SECRET environmental variables to authenticate the user so you need to set them here. You will also need to set your OPENAI_API_KEY to use the agent later."
"The toolkit will read the AMADEUS_CLIENT_ID and AMADEUS_CLIENT_SECRET environmental variables to authenticate the user, so you need to set them here. "
]
},
{
"cell_type": "code",
"execution_count": 2,
"metadata": {},
"metadata": {
"ExecuteTime": {
"end_time": "2024-01-13T17:45:56.531388579Z",
"start_time": "2024-01-13T17:45:56.523533018Z"
}
},
"outputs": [],
"source": [
"# Set environmental variables here\n",
@@ -44,7 +49,6 @@
"\n",
"os.environ[\"AMADEUS_CLIENT_ID\"] = \"CLIENT_ID\"\n",
"os.environ[\"AMADEUS_CLIENT_SECRET\"] = \"CLIENT_SECRET\"\n",
"os.environ[\"OPENAI_API_KEY\"] = \"API_KEY\"\n",
"# os.environ[\"AMADEUS_HOSTNAME\"] = \"production\" or \"test\""
]
},
@@ -57,11 +61,39 @@
"To start, you need to create the toolkit, so you can access its tools later."
]
},
{
"cell_type": "markdown",
"metadata": {
"collapsed": false
},
"source": [
"By default, `AmadeusToolkit` uses `ChatOpenAI` to identify airports closest to a given location. To use it, just set `OPENAI_API_KEY`.\n"
]
},
{
"cell_type": "code",
"execution_count": 3,
"metadata": {
"tags": []
"collapsed": false,
"ExecuteTime": {
"end_time": "2024-01-13T17:45:56.557041160Z",
"start_time": "2024-01-13T17:45:56.530682481Z"
}
},
"outputs": [],
"source": [
"os.environ[\"OPENAI_API_KEY\"] = \"YOUR_OPENAI_KEY\""
]
},
{
"cell_type": "code",
"execution_count": 4,
"metadata": {
"tags": [],
"ExecuteTime": {
"end_time": "2024-01-13T17:45:58.431168124Z",
"start_time": "2024-01-13T17:45:56.536269739Z"
}
},
"outputs": [],
"source": [
@@ -71,6 +103,35 @@
"tools = toolkit.get_tools()"
]
},
{
"cell_type": "markdown",
"metadata": {
"collapsed": false
},
"source": [
"Alternatively, you can use any LLM supported by langchain, e.g. `HuggingFaceHub`. "
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": false
},
"outputs": [],
"source": [
"from langchain_community.llms import HuggingFaceHub\n",
"\n",
"os.environ[\"HUGGINGFACEHUB_API_TOKEN\"] = \"YOUR_HF_API_TOKEN\"\n",
"\n",
"llm = HuggingFaceHub(\n",
" repo_id=\"tiiuae/falcon-7b-instruct\",\n",
" model_kwargs={\"temperature\": 0.5, \"max_length\": 64},\n",
")\n",
"\n",
"toolkit_hf = AmadeusToolkit(llm=llm)"
]
},
{
"cell_type": "markdown",
"metadata": {},
@@ -78,91 +139,76 @@
"## Use Amadeus Toolkit within an Agent"
]
},
{
"cell_type": "code",
"execution_count": 4,
"metadata": {
"tags": []
},
"outputs": [],
"source": [
"from langchain.agents import AgentType, initialize_agent\n",
"from langchain_openai import OpenAI"
]
},
{
"cell_type": "code",
"execution_count": 5,
"metadata": {
"tags": []
},
"outputs": [],
"source": [
"llm = OpenAI(temperature=0)\n",
"agent = initialize_agent(\n",
" tools=tools,\n",
" llm=llm,\n",
" verbose=False,\n",
" agent=AgentType.STRUCTURED_CHAT_ZERO_SHOT_REACT_DESCRIPTION,\n",
")"
]
},
{
"cell_type": "code",
"execution_count": 6,
"metadata": {
"tags": []
},
"outputs": [
{
"data": {
"text/plain": [
"'The closest airport to Cali, Colombia is Alfonso Bonilla Aragón International Airport (CLO).'"
]
},
"execution_count": 6,
"metadata": {},
"output_type": "execute_result"
"tags": [],
"ExecuteTime": {
"end_time": "2024-01-13T17:46:00.148691365Z",
"start_time": "2024-01-13T17:45:59.317173243Z"
}
],
},
"outputs": [],
"source": [
"agent.run(\"What is the name of the airport in Cali, Colombia?\")"
"from langchain import hub\n",
"from langchain.agents import AgentExecutor, create_react_agent\n",
"from langchain_openai import ChatOpenAI"
]
},
{
"cell_type": "code",
"execution_count": 7,
"metadata": {
"tags": []
},
"outputs": [
{
"data": {
"text/plain": [
"'The cheapest flight on August 23, 2023 leaving Dallas, Texas before noon to Lincoln, Nebraska has a departure time of 16:42 and a total price of 276.08 EURO.'"
]
},
"execution_count": 7,
"metadata": {},
"output_type": "execute_result"
"tags": [],
"ExecuteTime": {
"end_time": "2024-01-13T17:46:01.270044101Z",
"start_time": "2024-01-13T17:46:00.148988945Z"
}
],
},
"outputs": [],
"source": [
"agent.run(\n",
" \"What is the departure time of the cheapest flight on August 23, 2023 leaving Dallas, Texas before noon to Lincoln, Nebraska?\"\n",
"llm = ChatOpenAI(temperature=0)\n",
"\n",
"prompt = hub.pull(\"hwchase17/react\")\n",
"agent = create_react_agent(llm, tools, prompt)\n",
"\n",
"agent_executor = AgentExecutor(\n",
" agent=agent,\n",
" tools=tools,\n",
" verbose=True,\n",
")"
]
},
{
"cell_type": "code",
"execution_count": 8,
"metadata": {},
"metadata": {
"collapsed": false,
"ExecuteTime": {
"end_time": "2024-01-13T17:46:06.176227412Z",
"start_time": "2024-01-13T17:46:01.272468682Z"
}
},
"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 use the closest_airport tool to find the airport in Cali, Colombia.\n",
"Action: closest_airport\n",
"Action Input: location= \"Cali, Colombia\"\u001B[0m\u001B[36;1m\u001B[1;3mcontent='{\\n \"iataCode\": \"CLO\"\\n}'\u001B[0m\u001B[32;1m\u001B[1;3mThe airport in Cali, Colombia is called CLO.\n",
"Final Answer: CLO\u001B[0m\n",
"\n",
"\u001B[1m> Finished chain.\u001B[0m\n"
]
},
{
"data": {
"text/plain": [
"'The earliest flight on August 23, 2023 leaving Dallas, Texas to Lincoln, Nebraska lands in Lincoln, Nebraska at 16:07.'"
]
"text/plain": "{'input': 'What is the name of the airport in Cali, Colombia?',\n 'output': 'CLO'}"
},
"execution_count": 8,
"metadata": {},
@@ -170,52 +216,67 @@
}
],
"source": [
"agent.run(\n",
" \"At what time does earliest flight on August 23, 2023 leaving Dallas, Texas to Lincoln, Nebraska land in Nebraska?\"\n",
"agent_executor.invoke({\"input\": \"What is the name of the airport in Cali, Colombia?\"})"
]
},
{
"cell_type": "markdown",
"metadata": {
"collapsed": false
},
"source": []
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"tags": []
},
"outputs": [],
"source": [
"agent_executor.invoke(\n",
" {\n",
" \"input\": \"What is the departure time of the cheapest flight on August 23, 2023 leaving Dallas, Texas before noon to Lincoln, Nebraska?\"\n",
" }\n",
")"
]
},
{
"cell_type": "code",
"execution_count": 9,
"execution_count": null,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"'The cheapest flight between Portland, Oregon to Dallas, TX on October 3, 2023 is a Spirit Airlines flight with a total price of 84.02 EURO and a total travel time of 8 hours and 43 minutes.'"
]
},
"execution_count": 9,
"metadata": {},
"output_type": "execute_result"
}
],
"outputs": [],
"source": [
"agent.run(\n",
" \"What is the full travel time for the cheapest flight between Portland, Oregon to Dallas, TX on October 3, 2023?\"\n",
"agent_executor.invoke(\n",
" {\n",
" \"input\": \"At what time does earliest flight on August 23, 2023 leaving Dallas, Texas to Lincoln, Nebraska land in Nebraska?\"\n",
" }\n",
")"
]
},
{
"cell_type": "code",
"execution_count": 10,
"execution_count": null,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"'Dear Paul,\\n\\nI am writing to request that you book the earliest flight from DFW to DCA on Aug 28, 2023. The flight details are as follows:\\n\\nFlight 1: DFW to ATL, departing at 7:15 AM, arriving at 10:25 AM, flight number 983, carrier Delta Air Lines\\nFlight 2: ATL to DCA, departing at 12:15 PM, arriving at 2:02 PM, flight number 759, carrier Delta Air Lines\\n\\nThank you for your help.\\n\\nSincerely,\\nSantiago'"
]
},
"execution_count": 10,
"metadata": {},
"output_type": "execute_result"
}
],
"outputs": [],
"source": [
"agent.run(\n",
" \"Please draft a concise email from Santiago to Paul, Santiago's travel agent, asking him to book the earliest flight from DFW to DCA on Aug 28, 2023. Include all flight details in the email.\"\n",
"agent_executor.invoke(\n",
" {\n",
" \"input\": \"What is the full travel time for the cheapest flight between Portland, Oregon to Dallas, TX on October 3, 2023?\"\n",
" }\n",
")"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"agent_executor.invoke(\n",
" {\n",
" \"input\": \"Please draft a concise email from Santiago to Paul, Santiago's travel agent, asking him to book the earliest flight from DFW to DCA on Aug 28, 2023. Include all flight details in the email.\"\n",
" }\n",
")"
]
}

View File

@@ -5,16 +5,25 @@
"metadata": {},
"source": [
"# MultiOn\n",
" \n",
"[MultiON](https://www.multion.ai/blog/multion-building-a-brighter-future-for-humanity-with-ai-agents) has built an AI Agent that can interact with a broad array of web services and applications. \n",
"\n",
"This notebook walks you through connecting LangChain to the `MultiOn` Client in your browser\n",
"This notebook walks you through connecting LangChain to the `MultiOn` Client in your browser. \n",
"\n",
"To use this toolkit, you will need to add `MultiOn Extension` to your browser as explained in the [MultiOn for Chrome](https://multion.notion.site/Download-MultiOn-ddddcfe719f94ab182107ca2612c07a5)."
"This enables custom agentic workflow that utilize the power of MultiON agents.\n",
" \n",
"To use this toolkit, you will need to add `MultiOn Extension` to your browser: \n",
"\n",
"* Create a [MultiON account](https://app.multion.ai/login?callbackUrl=%2Fprofile). \n",
"* Add [MultiOn extension for Chrome](https://multion.notion.site/Download-MultiOn-ddddcfe719f94ab182107ca2612c07a5)."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"metadata": {
"scrolled": true
},
"outputs": [],
"source": [
"%pip install --upgrade --quiet multion langchain -q"
@@ -22,22 +31,43 @@
},
{
"cell_type": "code",
"execution_count": null,
"execution_count": 37,
"metadata": {},
"outputs": [],
"outputs": [
{
"data": {
"text/plain": [
"MultionToolkit()"
]
},
"execution_count": 37,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"from langchain_community.agent_toolkits import MultionToolkit\n",
"\n",
"toolkit = MultionToolkit()\n",
"\n",
"toolkit"
]
},
{
"cell_type": "code",
"execution_count": null,
"execution_count": 38,
"metadata": {},
"outputs": [],
"outputs": [
{
"data": {
"text/plain": [
"[MultionCreateSession(), MultionUpdateSession(), MultionCloseSession()]"
]
},
"execution_count": 38,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"tools = toolkit.get_tools()\n",
"tools"
@@ -49,14 +79,24 @@
"source": [
"## MultiOn Setup\n",
"\n",
"Once you have created an account, create an API key at https://app.multion.ai/. \n",
"\n",
"Login to establish connection with your extension."
]
},
{
"cell_type": "code",
"execution_count": null,
"execution_count": 39,
"metadata": {},
"outputs": [],
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Logged in.\n"
]
}
],
"source": [
"# Authorize connection to your Browser extention\n",
"import multion\n",
@@ -68,42 +108,98 @@
"cell_type": "markdown",
"metadata": {},
"source": [
"## Use Multion Toolkit within an Agent"
"## Use Multion Toolkit within an Agent\n",
"\n",
"This will use MultiON chrome extension to perform the desired actions.\n",
"\n",
"We can run the below, and view the [trace](https://smith.langchain.com/public/34aaf36d-204a-4ce3-a54e-4a0976f09670/r) to see:\n",
"\n",
"* The agent uses the `create_multion_session` tool\n",
"* It then uses MultiON to execute the query"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"tags": []
},
"execution_count": 40,
"metadata": {},
"outputs": [],
"source": [
"from langchain.agents import AgentType, initialize_agent\n",
"from langchain_openai import OpenAI\n",
"\n",
"llm = OpenAI(temperature=0)\n",
"from langchain_community.agent_toolkits import MultionToolkit\n",
"\n",
"toolkit = MultionToolkit()\n",
"tools = toolkit.get_tools()\n",
"agent = initialize_agent(\n",
"from langchain import hub\n",
"from langchain.agents import AgentExecutor, create_openai_functions_agent\n",
"from langchain_openai import ChatOpenAI"
]
},
{
"cell_type": "code",
"execution_count": 41,
"metadata": {},
"outputs": [],
"source": [
"# Prompt\n",
"instructions = \"\"\"You are an assistant.\"\"\"\n",
"base_prompt = hub.pull(\"langchain-ai/openai-functions-template\")\n",
"prompt = base_prompt.partial(instructions=instructions)"
]
},
{
"cell_type": "code",
"execution_count": 32,
"metadata": {},
"outputs": [],
"source": [
"# LLM\n",
"llm = ChatOpenAI(temperature=0)"
]
},
{
"cell_type": "code",
"execution_count": 42,
"metadata": {},
"outputs": [],
"source": [
"# Agent\n",
"agent = create_openai_functions_agent(llm, toolkit.get_tools(), prompt)\n",
"agent_executor = AgentExecutor(\n",
" agent=agent,\n",
" tools=toolkit.get_tools(),\n",
" llm=llm,\n",
" agent=AgentType.STRUCTURED_CHAT_ZERO_SHOT_REACT_DESCRIPTION,\n",
" verbose=True,\n",
" verbose=False,\n",
")"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"tags": []
},
"outputs": [],
"execution_count": 46,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"WARNING: 'new_session' is deprecated and will be removed in a future version. Use 'create_session' instead.\n",
"WARNING: 'update_session' is deprecated and will be removed in a future version. Use 'step_session' instead.\n",
"WARNING: 'update_session' is deprecated and will be removed in a future version. Use 'step_session' instead.\n",
"WARNING: 'update_session' is deprecated and will be removed in a future version. Use 'step_session' instead.\n",
"WARNING: 'update_session' is deprecated and will be removed in a future version. Use 'step_session' instead.\n"
]
},
{
"data": {
"text/plain": [
"{'input': 'Use multion to how AlphaCodium works, a recently released code language model.',\n",
" 'output': 'AlphaCodium is a recently released code language model that is designed to assist developers in writing code more efficiently. It is based on advanced machine learning techniques and natural language processing. AlphaCodium can understand and generate code in multiple programming languages, making it a versatile tool for developers.\\n\\nThe model is trained on a large dataset of code snippets and programming examples, allowing it to learn patterns and best practices in coding. It can provide suggestions and auto-complete code based on the context and the desired outcome.\\n\\nAlphaCodium also has the ability to analyze code and identify potential errors or bugs. It can offer recommendations for improving code quality and performance.\\n\\nOverall, AlphaCodium aims to enhance the coding experience by providing intelligent assistance and reducing the time and effort required to write high-quality code.\\n\\nFor more detailed information, you can visit the official AlphaCodium website or refer to the documentation and resources available online.\\n\\nI hope this helps! Let me know if you have any other questions.'}"
]
},
"execution_count": 46,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"agent.run(\"Tweet 'Hi from MultiOn'\")"
"agent_executor.invoke(\n",
" {\n",
" \"input\": \"Use multion to explain how AlphaCodium works, a recently released code language model.\"\n",
" }\n",
")"
]
}
],
@@ -123,7 +219,7 @@
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.10.12"
"version": "3.9.16"
}
},
"nbformat": 4,

View File

@@ -7,9 +7,13 @@
"source": [
"# Robocorp\n",
"\n",
"This notebook covers how to get started with [Robocorp Action Server](https://github.com/robocorp/robo/tree/master/action_server/docs) action toolkit and LangChain.\n",
"This notebook covers how to get started with [Robocorp Action Server](https://github.com/robocorp/robocorp) action toolkit and LangChain.\n",
"\n",
"## Installation"
"## Installation\n",
"\n",
"First, see the [Robocorp Quickstart](https://github.com/robocorp/robocorp#quickstart) on how to setup Action Server and create your Actions.\n",
"\n",
"In your LangChain application, install the `langchain-robocorp` package: "
]
},
{
@@ -19,24 +23,8 @@
"metadata": {},
"outputs": [],
"source": [
"# Install package and Action Server\n",
"%pip install --upgrade --quiet langchain-robocorp robocorp-action-server"
]
},
{
"cell_type": "markdown",
"id": "8e2ca5c5",
"metadata": {},
"source": [
"## Action Server setup\n",
"\n",
"You will need a running instance of Action Server to communicate with from your agent application. You can bootstrap a new project using Action Server `new` command.\n",
"\n",
"```bash\n",
"!action-server new\n",
"cd ./your-project-name\n",
"action-server start\n",
"```\n"
"# Install package\n",
"%pip install --upgrade --quiet langchain-robocorp"
]
},
{

View File

@@ -0,0 +1,112 @@
{
"cells": [
{
"cell_type": "markdown",
"id": "245a954a",
"metadata": {
"id": "245a954a"
},
"source": [
"# Polygon Stock Market API\n",
"\n",
">[Polygon](https://polygon.io/) The Polygon.io Stocks API provides REST endpoints that let you query the latest market data from all US stock exchanges.\n",
"\n",
"Use the ``PolygonAPIWrapper`` to get stock market data like the latest quote for a ticker."
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "34bb5968",
"metadata": {
"id": "34bb5968",
"is_executing": true
},
"outputs": [],
"source": [
"import getpass\n",
"import os\n",
"\n",
"os.environ[\"POLYGON_API_KEY\"] = getpass.getpass()"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "ac4910f8",
"metadata": {
"id": "ac4910f8",
"is_executing": true
},
"outputs": [],
"source": [
"from langchain_community.utilities.polygon import PolygonAPIWrapper"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "84b8f773",
"metadata": {
"id": "84b8f773"
},
"outputs": [],
"source": [
"polygon = PolygonAPIWrapper()"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "068991a6",
"metadata": {
"id": "068991a6",
"outputId": "c5cdc6ec-03cf-4084-cc6f-6ae792d91d39"
},
"outputs": [
{
"data": {
"text/plain": [
"{'results': {'P': 185.86, 'S': 1, 'T': 'AAPL', 'X': 11, 'i': [604], 'p': 185.81, 'q': 106551669, 's': 2, 't': 1705098436014023700, 'x': 12, 'y': 1705098436014009300, 'z': 3}}"
]
},
"execution_count": 1,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"polygon.run(\"get_last_quote\", \"AAPL\")"
]
}
],
"metadata": {
"colab": {
"provenance": []
},
"kernelspec": {
"name": "venv",
"language": "python",
"display_name": "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"
},
"vscode": {
"interpreter": {
"hash": "53f3bc57609c7a84333bb558594977aa5b4026b1d6070b93987956689e367341"
}
}
},
"nbformat": 4,
"nbformat_minor": 5
}

View File

@@ -113,10 +113,63 @@
"requests.get(\"https://www.google.com\")"
]
},
{
"cell_type": "markdown",
"id": "4b0bf1d0",
"metadata": {},
"source": [
"If you need the output to be decoded from JSON, you can use the ``JsonRequestsWrapper``."
]
},
{
"cell_type": "code",
"execution_count": 1,
"id": "3f27ee3d",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"\n",
"\n",
"Type - <class 'dict'>\n",
"\n",
"Content: \n",
"```\n",
"{'count': 5707, 'name': 'jackson', 'age': 38}\n",
"```\n",
"\n",
"\n"
]
}
],
"source": [
"from langchain_community.utilities.requests import JsonRequestsWrapper\n",
"\n",
"requests = JsonRequestsWrapper()\n",
"\n",
"\n",
"rval = requests.get(\"https://api.agify.io/?name=jackson\")\n",
"\n",
"print(\n",
" f\"\"\"\n",
"\n",
"Type - {type(rval)}\n",
"\n",
"Content: \n",
"```\n",
"{rval}\n",
"```\n",
"\n",
"\"\"\"\n",
")"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "3f27ee3d",
"id": "52a1aa15",
"metadata": {},
"outputs": [],
"source": []
@@ -138,7 +191,7 @@
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.11.2"
"version": "3.10.13"
}
},
"nbformat": 4,

View File

@@ -132,7 +132,7 @@
"source": [
"from langchain.text_splitter import CharacterTextSplitter\n",
"from langchain_community.document_loaders import TextLoader\n",
"from langchain_community.vectorstores.azure_cosmos_db_vector_search import (\n",
"from langchain_community.vectorstores.azure_cosmos_db import (\n",
" AzureCosmosDBVectorSearch,\n",
" CosmosDBSimilarityType,\n",
")\n",

View File

@@ -14,6 +14,15 @@
"This tutorial illustrates how to work with an end-to-end data and embedding management system in LangChain, and provide scalable semantic search in BigQuery."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"This is a **private preview (experimental)** feature. Please submit this\n",
"[enrollment form](https://docs.google.com/forms/d/18yndSb4dTf2H0orqA9N7NAchQEDQekwWiD5jYfEkGWk/viewform?edit_requested=true)\n",
"if you want to enroll BigQuery Vector Search Experimental."
]
},
{
"cell_type": "markdown",
"metadata": {
@@ -324,6 +333,24 @@
"docs = store.similarity_search_by_vector(query_vector, filter={\"len\": 6})\n",
"print(docs)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Explore job satistics with BigQuery Job Id"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"job_id = \"\" # @param {type:\"string\"}\n",
"# Debug and explore the job statistics with a BigQuery Job id.\n",
"store.explore_job_stats(job_id)"
]
}
],
"metadata": {

View File

@@ -75,7 +75,7 @@
" )\n",
"```\n",
"### Authentication\n",
"For production, we recommend you run with security enabled. To connect with login credentials, you can use the parameters `api_key` or `es_user` and `es_password`.\n",
"For production, we recommend you run with security enabled. To connect with login credentials, you can use the parameters `es_api_key` or `es_user` and `es_password`.\n",
"\n",
"Example:\n",
"```python\n",

View File

@@ -0,0 +1,659 @@
{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Lantern\n",
"\n",
">[Lantern](https://github.com/lanterndata/lantern) is an open-source vector similarity search for `Postgres`\n",
"\n",
"It supports:\n",
"- Exact and approximate nearest neighbor search\n",
"- L2 squared distance, hamming distance, and cosine distance\n",
"\n",
"This notebook shows how to use the Postgres vector database (`Lantern`)."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"See the [installation instruction](https://github.com/lanterndata/lantern#-quick-install)."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"We want to use `OpenAIEmbeddings` so we have to get the OpenAI API Key."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Pip install necessary package\n",
"!pip install openai\n",
"!pip install psycopg2-binary\n",
"!pip install tiktoken"
]
},
{
"cell_type": "code",
"execution_count": 1,
"metadata": {
"ExecuteTime": {
"end_time": "2023-09-09T08:02:16.802456Z",
"start_time": "2023-09-09T08:02:07.065604Z"
}
},
"outputs": [
{
"name": "stdin",
"output_type": "stream",
"text": [
"OpenAI API Key: ········\n"
]
}
],
"source": [
"import getpass\n",
"import os\n",
"\n",
"os.environ[\"OPENAI_API_KEY\"] = getpass.getpass(\"OpenAI API Key:\")"
]
},
{
"cell_type": "code",
"execution_count": 2,
"metadata": {
"ExecuteTime": {
"end_time": "2023-09-09T08:02:19.742896Z",
"start_time": "2023-09-09T08:02:19.732527Z"
},
"tags": []
},
"outputs": [
{
"data": {
"text/plain": [
"False"
]
},
"execution_count": 2,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"## Loading Environment Variables\n",
"from typing import List, Tuple\n",
"\n",
"from dotenv import load_dotenv\n",
"\n",
"load_dotenv()"
]
},
{
"cell_type": "code",
"execution_count": 5,
"metadata": {
"ExecuteTime": {
"end_time": "2023-09-09T08:02:23.144824Z",
"start_time": "2023-09-09T08:02:22.047801Z"
},
"tags": []
},
"outputs": [],
"source": [
"from langchain.text_splitter import CharacterTextSplitter\n",
"from langchain_community.document_loaders import TextLoader\n",
"from langchain_community.embeddings import OpenAIEmbeddings\n",
"from langchain_community.vectorstores import Lantern\n",
"from langchain_core.documents import Document"
]
},
{
"cell_type": "code",
"execution_count": 6,
"metadata": {
"ExecuteTime": {
"end_time": "2023-09-09T08:02:25.452472Z",
"start_time": "2023-09-09T08:02:25.441563Z"
}
},
"outputs": [],
"source": [
"loader = TextLoader(\"../../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": 8,
"metadata": {
"ExecuteTime": {
"end_time": "2023-09-09T08:02:28.174088Z",
"start_time": "2023-09-09T08:02:28.162698Z"
}
},
"outputs": [
{
"name": "stdin",
"output_type": "stream",
"text": [
"DB Connection String: ········\n"
]
}
],
"source": [
"# Lantern needs the connection string to the database.\n",
"# Example postgresql://postgres:postgres@localhost:5432/postgres\n",
"CONNECTION_STRING = getpass.getpass(\"DB Connection String:\")\n",
"\n",
"# # Alternatively, you can create it from environment variables.\n",
"# import os\n",
"\n",
"# CONNECTION_STRING = Lantern.connection_string_from_db_params(\n",
"# driver=os.environ.get(\"LANTERN_DRIVER\", \"psycopg2\"),\n",
"# host=os.environ.get(\"LANTERN_HOST\", \"localhost\"),\n",
"# port=int(os.environ.get(\"LANTERN_PORT\", \"5432\")),\n",
"# database=os.environ.get(\"LANTERN_DATABASE\", \"postgres\"),\n",
"# user=os.environ.get(\"LANTERN_USER\", \"postgres\"),\n",
"# password=os.environ.get(\"LANTERN_PASSWORD\", \"postgres\"),\n",
"# )\n",
"\n",
"# or you can pass it via `LANTERN_CONNECTION_STRING` env variable"
]
},
{
"cell_type": "markdown",
"metadata": {
"collapsed": false,
"jupyter": {
"outputs_hidden": false
}
},
"source": [
"## Similarity Search with Cosine Distance (Default)"
]
},
{
"cell_type": "code",
"execution_count": 10,
"metadata": {
"ExecuteTime": {
"end_time": "2023-09-09T08:04:16.696625Z",
"start_time": "2023-09-09T08:02:31.817790Z"
}
},
"outputs": [],
"source": [
"# The Lantern Module will try to create a table with the name of the collection.\n",
"# So, make sure that the collection name is unique and the user has the permission to create a table.\n",
"\n",
"COLLECTION_NAME = \"state_of_the_union_test\"\n",
"\n",
"db = Lantern.from_documents(\n",
" embedding=embeddings,\n",
" documents=docs,\n",
" collection_name=COLLECTION_NAME,\n",
" connection_string=CONNECTION_STRING,\n",
" pre_delete_collection=True,\n",
")"
]
},
{
"cell_type": "code",
"execution_count": 11,
"metadata": {
"ExecuteTime": {
"end_time": "2023-09-09T08:05:11.104135Z",
"start_time": "2023-09-09T08:05:10.548998Z"
}
},
"outputs": [],
"source": [
"query = \"What did the president say about Ketanji Brown Jackson\"\n",
"docs_with_score = db.similarity_search_with_score(query)"
]
},
{
"cell_type": "code",
"execution_count": 12,
"metadata": {
"ExecuteTime": {
"end_time": "2023-09-09T08:05:13.532334Z",
"start_time": "2023-09-09T08:05:13.523191Z"
}
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"--------------------------------------------------------------------------------\n",
"Score: 0.18440479\n",
"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",
"--------------------------------------------------------------------------------\n",
"--------------------------------------------------------------------------------\n",
"Score: 0.21727282\n",
"A former top litigator in private practice. A former federal public defender. And from a family of public school educators and police officers. A consensus builder. Since shes been nominated, shes received a broad range of support—from the Fraternal Order of Police to former judges appointed by Democrats and Republicans. \n",
"\n",
"And if we are to advance liberty and justice, we need to secure the Border and fix the immigration system. \n",
"\n",
"We can do both. At our border, weve installed new technology like cutting-edge scanners to better detect drug smuggling. \n",
"\n",
"Weve set up joint patrols with Mexico and Guatemala to catch more human traffickers. \n",
"\n",
"Were putting in place dedicated immigration judges so families fleeing persecution and violence can have their cases heard faster. \n",
"\n",
"Were securing commitments and supporting partners in South and Central America to host more refugees and secure their own borders.\n",
"--------------------------------------------------------------------------------\n",
"--------------------------------------------------------------------------------\n",
"Score: 0.22621095\n",
"And for our LGBTQ+ Americans, lets finally get the bipartisan Equality Act to my desk. The onslaught of state laws targeting transgender Americans and their families is wrong. \n",
"\n",
"As I said last year, especially to our younger transgender Americans, I will always have your back as your President, so you can be yourself and reach your God-given potential. \n",
"\n",
"While it often appears that we never agree, that isnt true. I signed 80 bipartisan bills into law last year. From preventing government shutdowns to protecting Asian-Americans from still-too-common hate crimes to reforming military justice. \n",
"\n",
"And soon, well strengthen the Violence Against Women Act that I first wrote three decades ago. It is important for us to show the nation that we can come together and do big things. \n",
"\n",
"So tonight Im offering a Unity Agenda for the Nation. Four big things we can do together. \n",
"\n",
"First, beat the opioid epidemic.\n",
"--------------------------------------------------------------------------------\n",
"--------------------------------------------------------------------------------\n",
"Score: 0.22654456\n",
"Tonight, Im announcing a crackdown on these companies overcharging American businesses and consumers. \n",
"\n",
"And as Wall Street firms take over more nursing homes, quality in those homes has gone down and costs have gone up. \n",
"\n",
"That ends on my watch. \n",
"\n",
"Medicare is going to set higher standards for nursing homes and make sure your loved ones get the care they deserve and expect. \n",
"\n",
"Well also cut costs and keep the economy going strong by giving workers a fair shot, provide more training and apprenticeships, hire them based on their skills not degrees. \n",
"\n",
"Lets pass the Paycheck Fairness Act and paid leave. \n",
"\n",
"Raise the minimum wage to $15 an hour and extend the Child Tax Credit, so no one has to raise a family in poverty. \n",
"\n",
"Lets increase Pell Grants and increase our historic support of HBCUs, and invest in what Jill—our First Lady who teaches full-time—calls Americas best-kept secret: community colleges.\n",
"--------------------------------------------------------------------------------\n"
]
}
],
"source": [
"for doc, score in docs_with_score:\n",
" print(\"-\" * 80)\n",
" print(\"Score: \", score)\n",
" print(doc.page_content)\n",
" print(\"-\" * 80)"
]
},
{
"cell_type": "markdown",
"metadata": {
"collapsed": false,
"jupyter": {
"outputs_hidden": false
}
},
"source": [
"## Maximal Marginal Relevance Search (MMR)\n",
"Maximal marginal relevance optimizes for similarity to query AND diversity among selected documents."
]
},
{
"cell_type": "code",
"execution_count": 13,
"metadata": {
"ExecuteTime": {
"end_time": "2023-09-09T08:05:23.276819Z",
"start_time": "2023-09-09T08:05:21.972256Z"
},
"collapsed": false,
"jupyter": {
"outputs_hidden": false
}
},
"outputs": [],
"source": [
"docs_with_score = db.max_marginal_relevance_search_with_score(query)"
]
},
{
"cell_type": "code",
"execution_count": 14,
"metadata": {
"ExecuteTime": {
"end_time": "2023-09-09T08:05:27.478580Z",
"start_time": "2023-09-09T08:05:27.470138Z"
},
"collapsed": false,
"jupyter": {
"outputs_hidden": false
}
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"--------------------------------------------------------------------------------\n",
"Score: 0.18440479\n",
"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",
"--------------------------------------------------------------------------------\n",
"--------------------------------------------------------------------------------\n",
"Score: 0.23515457\n",
"We cant change how divided weve been. But we can change how we move forward—on COVID-19 and other issues we must face together. \n",
"\n",
"I recently visited the New York City Police Department days after the funerals of Officer Wilbert Mora and his partner, Officer Jason Rivera. \n",
"\n",
"They were responding to a 9-1-1 call when a man shot and killed them with a stolen gun. \n",
"\n",
"Officer Mora was 27 years old. \n",
"\n",
"Officer Rivera was 22. \n",
"\n",
"Both Dominican Americans whod grown up on the same streets they later chose to patrol as police officers. \n",
"\n",
"I spoke with their families and told them that we are forever in debt for their sacrifice, and we will carry on their mission to restore the trust and safety every community deserves. \n",
"\n",
"Ive worked on these issues a long time. \n",
"\n",
"I know what works: Investing in crime prevention and community police officers wholl walk the beat, wholl know the neighborhood, and who can restore trust and safety.\n",
"--------------------------------------------------------------------------------\n",
"--------------------------------------------------------------------------------\n",
"Score: 0.24478757\n",
"One was stationed at bases and breathing in toxic smoke from “burn pits” that incinerated wastes of war—medical and hazard material, jet fuel, and more. \n",
"\n",
"When they came home, many of the worlds fittest and best trained warriors were never the same. \n",
"\n",
"Headaches. Numbness. Dizziness. \n",
"\n",
"A cancer that would put them in a flag-draped coffin. \n",
"\n",
"I know. \n",
"\n",
"One of those soldiers was my son Major Beau Biden. \n",
"\n",
"We dont know for sure if a burn pit was the cause of his brain cancer, or the diseases of so many of our troops. \n",
"\n",
"But Im committed to finding out everything we can. \n",
"\n",
"Committed to military families like Danielle Robinson from Ohio. \n",
"\n",
"The widow of Sergeant First Class Heath Robinson. \n",
"\n",
"He was born a soldier. Army National Guard. Combat medic in Kosovo and Iraq. \n",
"\n",
"Stationed near Baghdad, just yards from burn pits the size of football fields. \n",
"\n",
"Heaths widow Danielle is here with us tonight. They loved going to Ohio State football games. He loved building Legos with their daughter.\n",
"--------------------------------------------------------------------------------\n",
"--------------------------------------------------------------------------------\n",
"Score: 0.25137997\n",
"And Im taking robust action to make sure the pain of our sanctions is targeted at Russias economy. And I will use every tool at our disposal to protect American businesses and consumers. \n",
"\n",
"Tonight, I can announce that the United States has worked with 30 other countries to release 60 Million barrels of oil from reserves around the world. \n",
"\n",
"America will lead that effort, releasing 30 Million barrels from our own Strategic Petroleum Reserve. And we stand ready to do more if necessary, unified with our allies. \n",
"\n",
"These steps will help blunt gas prices here at home. And I know the news about whats happening can seem alarming. \n",
"\n",
"But I want you to know that we are going to be okay. \n",
"\n",
"When the history of this era is written Putins war on Ukraine will have left Russia weaker and the rest of the world stronger. \n",
"\n",
"While it shouldnt have taken something so terrible for people around the world to see whats at stake now everyone sees it clearly.\n",
"--------------------------------------------------------------------------------\n"
]
}
],
"source": [
"for doc, score in docs_with_score:\n",
" print(\"-\" * 80)\n",
" print(\"Score: \", score)\n",
" print(doc.page_content)\n",
" print(\"-\" * 80)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Working with vectorstore\n",
"\n",
"Above, we created a vectorstore from scratch. However, often times we want to work with an existing vectorstore.\n",
"In order to do that, we can initialize it directly."
]
},
{
"cell_type": "code",
"execution_count": 15,
"metadata": {},
"outputs": [],
"source": [
"store = Lantern(\n",
" collection_name=COLLECTION_NAME,\n",
" connection_string=CONNECTION_STRING,\n",
" embedding_function=embeddings,\n",
")"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Add documents\n",
"We can add documents to the existing vectorstore."
]
},
{
"cell_type": "code",
"execution_count": 16,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"['f8164598-aa28-11ee-a037-acde48001122']"
]
},
"execution_count": 16,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"store.add_documents([Document(page_content=\"foo\")])"
]
},
{
"cell_type": "code",
"execution_count": 17,
"metadata": {},
"outputs": [],
"source": [
"docs_with_score = db.similarity_search_with_score(\"foo\")"
]
},
{
"cell_type": "code",
"execution_count": 18,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"(Document(page_content='foo'), -1.1920929e-07)"
]
},
"execution_count": 18,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"docs_with_score[0]"
]
},
{
"cell_type": "code",
"execution_count": 19,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"(Document(page_content='And lets pass the PRO Act when a majority of workers want to form a union—they shouldnt be stopped. \\n\\nWhen we invest in our workers, when we build the economy from the bottom up and the middle out together, we can do something we havent done in a long time: build a better America. \\n\\nFor more than two years, COVID-19 has impacted every decision in our lives and the life of the nation. \\n\\nAnd I know youre tired, frustrated, and exhausted. \\n\\nBut I also know this. \\n\\nBecause of the progress weve made, because of your resilience and the tools we have, tonight I can say \\nwe are moving forward safely, back to more normal routines. \\n\\nWeve reached a new moment in the fight against COVID-19, with severe cases down to a level not seen since last July. \\n\\nJust a few days ago, the Centers for Disease Control and Prevention—the CDC—issued new mask guidelines. \\n\\nUnder these new guidelines, most Americans in most of the country can now be mask free.', metadata={'source': '../../modules/state_of_the_union.txt'}),\n",
" 0.24038416)"
]
},
"execution_count": 19,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"docs_with_score[1]"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Overriding a vectorstore\n",
"\n",
"If you have an existing collection, you override it by doing `from_documents` and setting `pre_delete_collection` = True \n",
"This will delete the collection before re-populating it"
]
},
{
"cell_type": "code",
"execution_count": 20,
"metadata": {},
"outputs": [],
"source": [
"db = Lantern.from_documents(\n",
" documents=docs,\n",
" embedding=embeddings,\n",
" collection_name=COLLECTION_NAME,\n",
" connection_string=CONNECTION_STRING,\n",
" pre_delete_collection=True,\n",
")"
]
},
{
"cell_type": "code",
"execution_count": 21,
"metadata": {},
"outputs": [],
"source": [
"docs_with_score = db.similarity_search_with_score(\"foo\")"
]
},
{
"cell_type": "code",
"execution_count": 22,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"(Document(page_content='And lets pass the PRO Act when a majority of workers want to form a union—they shouldnt be stopped. \\n\\nWhen we invest in our workers, when we build the economy from the bottom up and the middle out together, we can do something we havent done in a long time: build a better America. \\n\\nFor more than two years, COVID-19 has impacted every decision in our lives and the life of the nation. \\n\\nAnd I know youre tired, frustrated, and exhausted. \\n\\nBut I also know this. \\n\\nBecause of the progress weve made, because of your resilience and the tools we have, tonight I can say \\nwe are moving forward safely, back to more normal routines. \\n\\nWeve reached a new moment in the fight against COVID-19, with severe cases down to a level not seen since last July. \\n\\nJust a few days ago, the Centers for Disease Control and Prevention—the CDC—issued new mask guidelines. \\n\\nUnder these new guidelines, most Americans in most of the country can now be mask free.', metadata={'source': '../../modules/state_of_the_union.txt'}),\n",
" 0.2403456)"
]
},
"execution_count": 22,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"docs_with_score[0]"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Using a VectorStore as a Retriever"
]
},
{
"cell_type": "code",
"execution_count": 23,
"metadata": {},
"outputs": [],
"source": [
"retriever = store.as_retriever()"
]
},
{
"cell_type": "code",
"execution_count": 24,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"tags=['Lantern', 'OpenAIEmbeddings'] vectorstore=<langchain_community.vectorstores.lantern.Lantern object at 0x11d02f9d0>\n"
]
}
],
"source": [
"print(retriever)"
]
},
{
"cell_type": "code",
"execution_count": null,
"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.6"
}
},
"nbformat": 4,
"nbformat_minor": 4
}

View File

@@ -6,7 +6,7 @@
"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."
"This notebook shows how to use functionality related to the Postgres vector database ([pgvecto.rs](https://github.com/tensorchord/pgvecto.rs))."
]
},
{
@@ -15,10 +15,7 @@
"metadata": {},
"outputs": [],
"source": [
"## Loading Environment Variables\n",
"from dotenv import load_dotenv\n",
"\n",
"load_dotenv()"
"%pip install \"pgvecto_rs[sdk]\""
]
},
{
@@ -32,8 +29,8 @@
"from langchain.docstore.document import Document\n",
"from langchain.text_splitter import CharacterTextSplitter\n",
"from langchain_community.document_loaders import TextLoader\n",
"from langchain_community.vectorstores.pgvecto_rs import PGVecto_rs\n",
"from langchain_openai import OpenAIEmbeddings"
"from langchain_community.embeddings.fake import FakeEmbeddings\n",
"from langchain_community.vectorstores.pgvecto_rs import PGVecto_rs"
]
},
{
@@ -42,12 +39,12 @@
"metadata": {},
"outputs": [],
"source": [
"loader = TextLoader(\"../../../state_of_the_union.txt\")\n",
"loader = TextLoader(\"../../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()"
"embeddings = FakeEmbeddings(size=3)"
]
},
{
@@ -176,7 +173,17 @@
"outputs": [],
"source": [
"query = \"What did the president say about Ketanji Brown Jackson\"\n",
"docs: List[Document] = db1.similarity_search(query, k=4)"
"docs: List[Document] = db1.similarity_search(query, k=4)\n",
"for doc in docs:\n",
" print(doc.page_content)\n",
" print(\"======================\")"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Similarity Search with Filter"
]
},
{
@@ -185,6 +192,36 @@
"metadata": {},
"outputs": [],
"source": [
"from pgvecto_rs.sdk.filters import meta_contains\n",
"\n",
"query = \"What did the president say about Ketanji Brown Jackson\"\n",
"docs: List[Document] = db1.similarity_search(\n",
" query, k=4, filter=meta_contains({\"source\": \"../../modules/state_of_the_union.txt\"})\n",
")\n",
"\n",
"for doc in docs:\n",
" print(doc.page_content)\n",
" print(\"======================\")"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Or:"
]
},
{
"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(\n",
" query, k=4, filter={\"source\": \"../../modules/state_of_the_union.txt\"}\n",
")\n",
"\n",
"for doc in docs:\n",
" print(doc.page_content)\n",
" print(\"======================\")"
@@ -207,7 +244,7 @@
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.11.3"
"version": "3.11.6"
}
},
"nbformat": 4,

View File

@@ -40,7 +40,7 @@
},
"outputs": [],
"source": [
"%pip install --upgrade --quiet surrealdb langchain langchain-community"
"# %pip install --upgrade --quiet surrealdb langchain langchain-community"
]
},
{
@@ -54,6 +54,19 @@
{
"cell_type": "code",
"execution_count": 1,
"id": "1c2d942d-5d90-4f9f-af96-dff976e4510f",
"metadata": {},
"outputs": [],
"source": [
"# add this import for running in jupyter notebook\n",
"import nest_asyncio\n",
"\n",
"nest_asyncio.apply()"
]
},
{
"cell_type": "code",
"execution_count": 2,
"id": "e49be085-ddf1-4028-8c0c-97836ce4a873",
"metadata": {
"tags": []
@@ -68,7 +81,7 @@
},
{
"cell_type": "code",
"execution_count": 2,
"execution_count": 3,
"id": "38222aee-adc5-44c2-913c-97977b394cf5",
"metadata": {
"tags": []
@@ -92,28 +105,28 @@
},
{
"cell_type": "code",
"execution_count": 3,
"execution_count": 4,
"id": "ff9d0304-1e11-4db2-9454-1350db7907e6",
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"['documents:th7j29cjsx6495wluo7e',\n",
" 'documents:qkqhhjnl7ahbhr07euky',\n",
" 'documents:8kd6xw8o7y0l171iqry0',\n",
" 'documents:33ejf42dlkmavol9si74',\n",
" 'documents:f7y4dbs7eitqz58xt1p5']"
"['documents:38hz49bv1p58f5lrvrdc',\n",
" 'documents:niayw63vzwm2vcbh6w2s',\n",
" 'documents:it1fa3ktplbuye43n0ch',\n",
" 'documents:il8f7vgbbp9tywmsn98c',\n",
" 'documents:vza4c6cqje0avqd58gal']"
]
},
"execution_count": 3,
"execution_count": 4,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"db = SurrealDBStore(\n",
" dburl=\"http://localhost:8000/rpc\", # url for the hosted SurrealDB database\n",
" dburl=\"ws://localhost:8000/rpc\", # url for the hosted SurrealDB database\n",
" embedding_function=embeddings,\n",
" db_user=\"root\", # SurrealDB credentials if needed: db username\n",
" db_pass=\"root\", # SurrealDB credentials if needed: db password\n",
@@ -145,7 +158,7 @@
},
{
"cell_type": "code",
"execution_count": 4,
"execution_count": 5,
"id": "73d66563-4e1f-4edf-9e95-5fc9adcfa2cb",
"metadata": {},
"outputs": [],
@@ -153,7 +166,7 @@
"await db.adelete()\n",
"\n",
"db = await SurrealDBStore.afrom_documents(\n",
" dburl=\"http://localhost:8000/rpc\", # url for the hosted SurrealDB database\n",
" dburl=\"ws://localhost:8000/rpc\", # url for the hosted SurrealDB database\n",
" embedding=embeddings,\n",
" documents=docs,\n",
" db_user=\"root\", # SurrealDB credentials if needed: db username\n",
@@ -174,7 +187,7 @@
},
{
"cell_type": "code",
"execution_count": 5,
"execution_count": 6,
"id": "aa28a7f8-41d0-4299-84eb-91d1576e8a63",
"metadata": {
"tags": []
@@ -187,7 +200,7 @@
},
{
"cell_type": "code",
"execution_count": 6,
"execution_count": 7,
"id": "1eb16d2a-b466-456a-b412-5e74bb8523dd",
"metadata": {
"tags": []
@@ -229,7 +242,7 @@
},
{
"cell_type": "code",
"execution_count": 7,
"execution_count": 8,
"id": "8e9eef05-1516-469a-ad36-880c69aef7a9",
"metadata": {
"tags": []
@@ -241,7 +254,7 @@
},
{
"cell_type": "code",
"execution_count": 8,
"execution_count": 9,
"id": "bd5fb0e4-2a94-4bb4-af8a-27327ecb1a7f",
"metadata": {
"tags": []
@@ -250,11 +263,11 @@
{
"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={'id': 'documents:639m99rzwqlm9imcwg13'}),\n",
" 0.39839545290036454)"
"(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={'id': 'documents:slgdlhjkfknhqo15xz0w', 'source': '../../modules/state_of_the_union.txt'}),\n",
" 0.39839531721941895)"
]
},
"execution_count": 8,
"execution_count": 9,
"metadata": {},
"output_type": "execute_result"
}
@@ -280,7 +293,7 @@
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.9.1"
"version": "3.10.12"
}
},
"nbformat": 4,

View File

@@ -0,0 +1,248 @@
{
"cells": [
{
"cell_type": "markdown",
"id": "96ff9e912bfe9d8",
"metadata": {
"collapsed": false
},
"source": [
"# viking DB\n",
"\n",
">[viking DB](https://www.volcengine.com/docs/6459/1163946) is a database that stores, indexes, and manages massive embedding vectors generated by deep neural networks and other machine learning (ML) models.\n",
"\n",
"This notebook shows how to use functionality related to the VikingDB vector database.\n",
"\n",
"To run, you should have a [viking DB instance up and running](https://www.volcengine.com/docs/6459/1165058).\n",
"\n",
"\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "dd771e02d8a93a0",
"metadata": {
"collapsed": false
},
"outputs": [],
"source": [
"!pip install --upgrade volcengine"
]
},
{
"cell_type": "markdown",
"id": "12719205caed0d18",
"metadata": {
"collapsed": false
},
"source": [
"We want to use VikingDBEmbeddings so we have to get the VikingDB API Key."
]
},
{
"cell_type": "code",
"execution_count": 2,
"id": "fbfb32665b4a3640",
"metadata": {
"ExecuteTime": {
"end_time": "2023-12-21T09:53:24.186916Z",
"start_time": "2023-12-21T09:53:24.179524Z"
},
"collapsed": false
},
"outputs": [],
"source": [
"import getpass\n",
"import os\n",
"\n",
"os.environ[\"OPENAI_API_KEY\"] = getpass.getpass(\"OpenAI API Key:\")"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "d8c983d329237fa4",
"metadata": {
"collapsed": false
},
"outputs": [],
"source": [
"from langchain.document_loaders import TextLoader\n",
"from langchain.text_splitter import RecursiveCharacterTextSplitter\n",
"from langchain.vectorstores.vikingdb import VikingDB, VikingDBConfig\n",
"from langchain_openai import OpenAIEmbeddings"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "1a4aea2eaeb2261",
"metadata": {
"collapsed": false
},
"outputs": [],
"source": [
"loader = TextLoader(\"./test.txt\")\n",
"documents = loader.load()\n",
"text_splitter = RecursiveCharacterTextSplitter(chunk_size=10, chunk_overlap=0)\n",
"docs = text_splitter.split_documents(documents)\n",
"\n",
"embeddings = OpenAIEmbeddings()"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "bfd593f3deabfaf8",
"metadata": {
"collapsed": false
},
"outputs": [],
"source": [
"db = VikingDB.from_documents(\n",
" docs,\n",
" embeddings,\n",
" connection_args=VikingDBConfig(\n",
" host=\"host\", region=\"region\", ak=\"ak\", sk=\"sk\", scheme=\"http\"\n",
" ),\n",
" drop_old=True,\n",
")"
]
},
{
"cell_type": "code",
"execution_count": 6,
"id": "50e6ee12ca7eec39",
"metadata": {
"ExecuteTime": {
"end_time": "2023-12-21T10:01:47.355894Z",
"start_time": "2023-12-21T10:01:47.334789Z"
},
"collapsed": false
},
"outputs": [],
"source": [
"query = \"What did the president say about Ketanji Brown Jackson\"\n",
"docs = db.similarity_search(query)"
]
},
{
"cell_type": "code",
"execution_count": 6,
"id": "b6b81f5995c79ef0",
"metadata": {
"ExecuteTime": {
"end_time": "2023-12-21T10:01:47.771478Z",
"start_time": "2023-12-21T10:01:47.731485Z"
},
"collapsed": false
},
"outputs": [],
"source": [
"docs[0].page_content"
]
},
{
"cell_type": "markdown",
"id": "a2d932c1290478ee",
"metadata": {
"collapsed": false
},
"source": [
"### Compartmentalize the data with viking DB Collections\n",
"\n",
"You can store different unrelated documents in different collections within same viking DB instance to maintain the context"
]
},
{
"cell_type": "markdown",
"id": "907de4eb10626d2a",
"metadata": {
"collapsed": false
},
"source": [
"Here's how you can create a new collection"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "4f5a59ba40f7985f",
"metadata": {
"collapsed": false
},
"outputs": [],
"source": [
"db = VikingDB.from_documents(\n",
" docs,\n",
" embeddings,\n",
" connection_args=VikingDBConfig(\n",
" host=\"host\", region=\"region\", ak=\"ak\", sk=\"sk\", scheme=\"http\"\n",
" ),\n",
" collection_name=\"collection_1\",\n",
" drop_old=True,\n",
")"
]
},
{
"cell_type": "markdown",
"id": "7c8eada37b17d992",
"metadata": {
"collapsed": false
},
"source": [
"And here is how you retrieve that stored collection"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "883ec678d47c9adc",
"metadata": {
"collapsed": false
},
"outputs": [],
"source": [
"db = VikingDB.from_documents(\n",
" embeddings,\n",
" connection_args=VikingDBConfig(\n",
" host=\"host\", region=\"region\", ak=\"ak\", sk=\"sk\", scheme=\"http\"\n",
" ),\n",
" collection_name=\"collection_1\",\n",
")"
]
},
{
"cell_type": "markdown",
"id": "2f0be30cfe70083d",
"metadata": {
"collapsed": false
},
"source": [
"After retreival you can go on querying it as usual."
]
}
],
"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

@@ -30,12 +30,12 @@ Whether this agent requires the model to support any additional parameters. Some
Our commentary on when you should consider using this agent type.
| Agent Type | Intended Model Type | Supports Chat History | Supports Multi-Input Tools | Supports Parallel Function Calling | Required Model Params | When to Use |
|--------------------------------------------|---------------------|-----------------------|----------------------------|-------------------------------------|----------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------|
| [OpenAI Tools](./openai_tools) | Chat | ✅ | ✅ | ✅ | `tools` | If you are using a recent OpenAI model (`1106` onwards) |
| [OpenAI Functions](./openai_functions_agent)| Chat | ✅ | ✅ | | `functions` | If you are using an OpenAI model, or an open-source model that has been finetuned for function calling and exposes the same `functions` parameters as OpenAI |
| [XML](./xml_agent) | LLM | ✅ | | | | If you are using Anthropic models, or other models good at XML |
| [Structured Chat](./structured_chat) | Chat | ✅ | ✅ | | | If you need to support tools with multiple inputs |
| [JSON Chat](./json_agent) | Chat | ✅ | | | | If you are using a model good at JSON |
| [ReAct](./react) | LLM | ✅ | | | | If you are using a simple model |
| [Self Ask With Search](./self_ask_with_search)| LLM | | | | | If you are using a simple model and only have one search tool |
| Agent Type | Intended Model Type | Supports Chat History | Supports Multi-Input Tools | Supports Parallel Function Calling | Required Model Params | When to Use | API |
|--------------------------------------------|---------------------|-----------------------|----------------------------|-------------------------------------|----------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------|---------------------|
| [OpenAI Tools](./openai_tools) | Chat | ✅ | ✅ | ✅ | `tools` | If you are using a recent OpenAI model (`1106` onwards) | [Ref](https://api.python.langchain.com/en/latest/agents/langchain.agents.openai_tools.base.create_openai_tools_agent.html) |
| [OpenAI Functions](./openai_functions_agent)| Chat | ✅ | ✅ | | `functions` | If you are using an OpenAI model, or an open-source model that has been finetuned for function calling and exposes the same `functions` parameters as OpenAI | [Ref](https://api.python.langchain.com/en/latest/agents/langchain.agents.openai_functions_agent.base.create_openai_functions_agent.html) |
| [XML](./xml_agent) | LLM | ✅ | | | | If you are using Anthropic models, or other models good at XML | [Ref](https://api.python.langchain.com/en/latest/agents/langchain.agents.xml.base.create_xml_agent.html) |
| [Structured Chat](./structured_chat) | Chat | ✅ | ✅ | | | If you need to support tools with multiple inputs | [Ref](https://api.python.langchain.com/en/latest/agents/langchain.agents.structured_chat.base.create_structured_chat_agent.html) |
| [JSON Chat](./json_agent) | Chat | ✅ | | | | If you are using a model good at JSON | [Ref](https://api.python.langchain.com/en/latest/agents/langchain.agents.json_chat.base.create_json_chat_agent.html) |
| [ReAct](./react) | LLM | ✅ | | | | If you are using a simple model | [Ref](https://api.python.langchain.com/en/latest/agents/langchain.agents.react.agent.create_react_agent.html) |
| [Self Ask With Search](./self_ask_with_search)| LLM | | | | | If you are using a simple model and only have one search tool | [Ref](https://api.python.langchain.com/en/latest/agents/langchain.agents.self_ask_with_search.base.create_self_ask_with_search_agent.html) |

View File

@@ -19,9 +19,27 @@
"\n",
"Certain OpenAI models (like gpt-3.5-turbo-0613 and gpt-4-0613) have been fine-tuned to detect when a function should be called and respond with the inputs that should be passed to the function. In an API call, you can describe functions and have the model intelligently choose to output a JSON object containing arguments to call those functions. The goal of the OpenAI Function APIs is to more reliably return valid and useful function calls than a generic text completion or chat API.\n",
"\n",
"A number of open source models have adopted the same format for function calls and have also fine-tuned the model to detect when a function should be called.\n",
"\n",
"The OpenAI Functions Agent is designed to work with these models.\n",
"\n",
"Install `openai`, `tavily-python` packages which are required as the LangChain packages call them internally."
"Install `openai`, `tavily-python` packages which are required as the LangChain packages call them internally.\n",
"\n",
"\n",
":::info\n",
"\n",
"OpenAI API has deprecated `functions` in favor of `tools`. The difference between the two is that the `tools` API allows the model to request that multiple functions be invoked at once, which can reduce response times in some architectures. It's recommended to use the tools agent for OpenAI models.\n",
"\n",
"See the following links for more information:\n",
"\n",
"[OpenAI chat create](https://platform.openai.com/docs/api-reference/chat/create)\n",
"\n",
"[OpenAI function calling](https://platform.openai.com/docs/guides/function-calling)\n",
":::\n",
"\n",
":::tip\n",
"The `functions` format remains relevant for open source models and providers that have adopted it, and this agent is expected to work for such models.\n",
":::\n"
]
},
{
@@ -260,7 +278,7 @@
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.10.1"
"version": "3.11.4"
}
},
"nbformat": 4,

View File

@@ -17,7 +17,7 @@
"source": [
"# Structured chat\n",
"\n",
"The structured chat agent is capable of using multi-input tools.\n"
"The structured chat agent is capable of using multi-input tools."
]
},
{
@@ -237,7 +237,7 @@
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.10.1"
"version": "3.11.4"
}
},
"nbformat": 4,

View File

@@ -17,7 +17,14 @@
"source": [
"# XML Agent\n",
"\n",
"Some language models (like Anthropic's Claude) are particularly good at reasoning/writing XML. This goes over how to use an agent that uses XML when prompting. "
"Some language models (like Anthropic's Claude) are particularly good at reasoning/writing XML. This goes over how to use an agent that uses XML when prompting. \n",
"\n",
":::tip\n",
"\n",
"* Use with regular LLMs, not with chat models.\n",
"* Use only with unstructured tools; i.e., tools that accept a single string input.\n",
"* See [AgentTypes](/docs/moduels/agents/agent_types/) documentation for more agent types.\n",
":::"
]
},
{
@@ -217,7 +224,7 @@
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.10.1"
"version": "3.11.4"
}
},
"nbformat": 4,

View File

@@ -233,12 +233,7 @@
"\n",
"In addition to streaming the final result, you can also stream tokens. This will require slightly more complicated parsing of the logs\n",
"\n",
"\n",
"::: {.callout-warning}\n",
"For versions of langchain prior to and include 0.1.0, please set `streaming=True`, on the LLM.\n",
"\n",
"llm = ChatOpenAI(model=\"gpt-3.5-turbo\", temperature=0, streaming=True)\n",
":::"
"You will also need to make sure you set the LLM to be streaming"
]
},
{
@@ -1104,7 +1099,7 @@
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.11.4"
"version": "3.10.1"
}
},
"nbformat": 4,

View File

@@ -0,0 +1,350 @@
{
"cells": [
{
"cell_type": "markdown",
"id": "b69e747b-4e79-4caf-8f8b-c6e70275a31d",
"metadata": {},
"source": [
"# Event Streaming\n",
"\n",
"**NEW** This is a new API only works with recent versions of langchain-core!\n",
"\n",
"In this notebook, we'll see how to use `astream_events` to stream **token by token** from LLM calls used within the tools invoked by the agent. \n",
"\n",
"We will **only** stream tokens from LLMs used within tools and from no other LLMs (just to show that we can)! \n",
"\n",
"Feel free to adapt this example to the needs of your application.\n",
"\n",
"Our agent will use the OpenAI tools API for tool invocation, and we'll provide the agent with two tools:\n",
"\n",
"1. `where_cat_is_hiding`: A tool that uses an LLM to tell us where the cat is hiding\n",
"2. `tell_me_a_joke_about`: A tool that can use an LLM to tell a joke about the given topic\n",
"\n",
"\n",
"## ⚠️ Beta API ⚠️ ##\n",
"\n",
"Event Streaming is a **beta** API, and may change a bit based on feedback.\n",
"\n",
"Keep in mind the following constraints (repeated in tools section):\n",
"\n",
"* streaming only works properly if using `async`\n",
"* propagate callbacks if definning custom functions / runnables\n",
"* If creating a tool that uses an LLM, make sure to use `.astream()` on the LLM rather than `.ainvoke` to ask the LLM to stream tokens.\n",
"\n",
"## Event Hooks Reference\n",
"\n",
"\n",
"Here is a reference table that shows some events that might be emitted by the various Runnable objects.\n",
"Definitions for some of the Runnable are included after the table.\n",
"\n",
"⚠️ When streaming the inputs for the runnable will not be available until the input stream has been entirely consumed This means that the inputs will be available at for the corresponding `end` hook rather than `start` event.\n",
"\n",
"\n",
"| event | name | chunk | input | output |\n",
"|----------------------|------------------|---------------------------------|-----------------------------------------------|-------------------------------------------------|\n",
"| on_chat_model_start | [model name] | | {\"messages\": [[SystemMessage, HumanMessage]]} | |\n",
"| on_chat_model_stream | [model name] | AIMessageChunk(content=\"hello\") | | |\n",
"| on_chat_model_end | [model name] | | {\"messages\": [[SystemMessage, HumanMessage]]} | {\"generations\": [...], \"llm_output\": None, ...} |\n",
"| on_llm_start | [model name] | | {'input': 'hello'} | |\n",
"| on_llm_stream | [model name] | 'Hello' | | |\n",
"| on_llm_end | [model name] | | 'Hello human!' |\n",
"| on_chain_start | format_docs | | | |\n",
"| on_chain_stream | format_docs | \"hello world!, goodbye world!\" | | |\n",
"| on_chain_end | format_docs | | [Document(...)] | \"hello world!, goodbye world!\" |\n",
"| on_tool_start | some_tool | | {\"x\": 1, \"y\": \"2\"} | |\n",
"| on_tool_stream | some_tool | {\"x\": 1, \"y\": \"2\"} | | |\n",
"| on_tool_end | some_tool | | | {\"x\": 1, \"y\": \"2\"} |\n",
"| on_retriever_start | [retriever name] | | {\"query\": \"hello\"} | |\n",
"| on_retriever_chunk | [retriever name] | {documents: [...]} | | |\n",
"| on_retriever_end | [retriever name] | | {\"query\": \"hello\"} | {documents: [...]} |\n",
"| on_prompt_start | [template_name] | | {\"question\": \"hello\"} | |\n",
"| on_prompt_end | [template_name] | | {\"question\": \"hello\"} | ChatPromptValue(messages: [SystemMessage, ...]) |\n",
"\n",
"\n",
"Here are declarations associated with the events shown above:\n",
"\n",
"`format_docs`:\n",
"\n",
"```python\n",
"def format_docs(docs: List[Document]) -> str:\n",
" '''Format the docs.'''\n",
" return \", \".join([doc.page_content for doc in docs])\n",
"\n",
"format_docs = RunnableLambda(format_docs)\n",
"```\n",
"\n",
"`some_tool`:\n",
"\n",
"```python\n",
"@tool\n",
"def some_tool(x: int, y: str) -> dict:\n",
" '''Some_tool.'''\n",
" return {\"x\": x, \"y\": y}\n",
"```\n",
"\n",
"`prompt`:\n",
"\n",
"```python\n",
"template = ChatPromptTemplate.from_messages(\n",
" [(\"system\", \"You are Cat Agent 007\"), (\"human\", \"{question}\")]\n",
").with_config({\"run_name\": \"my_template\", \"tags\": [\"my_template\"]})\n",
"```\n",
"\n"
]
},
{
"cell_type": "code",
"execution_count": 6,
"id": "29205bef-2288-48e9-9067-f19072277a97",
"metadata": {
"tags": []
},
"outputs": [],
"source": [
"from langchain import hub\n",
"from langchain.agents import AgentExecutor, create_openai_tools_agent\n",
"from langchain.tools import tool\n",
"from langchain_core.callbacks import Callbacks\n",
"from langchain_core.prompts import ChatPromptTemplate\n",
"from langchain_openai import ChatOpenAI"
]
},
{
"cell_type": "markdown",
"id": "d6b0fafa-ce3b-489b-bf1d-d37b87f4819e",
"metadata": {},
"source": [
"## Create the model\n",
"\n",
"**Attention** For older versions of langchain, we must set `streaming=True`"
]
},
{
"cell_type": "code",
"execution_count": 7,
"id": "fa3c3761-a1cd-4118-8559-ea4d8857d394",
"metadata": {
"tags": []
},
"outputs": [],
"source": [
"model = ChatOpenAI(temperature=0, streaming=True)"
]
},
{
"cell_type": "markdown",
"id": "b76e1a3b-2983-42d9-ac12-4a0f32cd4a24",
"metadata": {},
"source": [
"## Tools\n",
"\n",
"We define two tools that rely on a chat model to generate output!\n",
"\n",
"Please note a few different things:\n",
"\n",
"1. The tools are **async**\n",
"1. The model is invoked using **.astream()** to force the output to stream\n",
"1. For older langchain versions you should set `streaming=True` on the model!\n",
"1. We attach tags to the model so that we can filter on said tags in our callback handler\n",
"1. The tools accept callbacks and propagate them to the model as a runtime argument"
]
},
{
"cell_type": "code",
"execution_count": 8,
"id": "c767f760-fe52-47e5-9c2a-622f03507aaf",
"metadata": {
"tags": []
},
"outputs": [],
"source": [
"@tool\n",
"async def where_cat_is_hiding(callbacks: Callbacks) -> str: # <--- Accept callbacks\n",
" \"\"\"Where is the cat hiding right now?\"\"\"\n",
" chunks = [\n",
" chunk\n",
" async for chunk in model.astream(\n",
" \"Give one up to three word answer about where the cat might be hiding in the house right now.\",\n",
" {\n",
" \"tags\": [\"tool_llm\"],\n",
" \"callbacks\": callbacks,\n",
" }, # <--- Propagate callbacks and assign a tag to this model\n",
" )\n",
" ]\n",
" return \"\".join(chunk.content for chunk in chunks)\n",
"\n",
"\n",
"@tool\n",
"async def tell_me_a_joke_about(\n",
" topic: str, callbacks: Callbacks\n",
") -> str: # <--- Accept callbacks\n",
" \"\"\"Tell a joke about a given topic.\"\"\"\n",
" template = ChatPromptTemplate.from_messages(\n",
" [\n",
" (\"system\", \"You are Cat Agent 007. You are funny and know many jokes.\"),\n",
" (\"human\", \"Tell me a long joke about {topic}\"),\n",
" ]\n",
" )\n",
" chain = template | model.with_config({\"tags\": [\"tool_llm\"]})\n",
" chunks = [\n",
" chunk\n",
" async for chunk in chain.astream({\"topic\": topic}, {\"callbacks\": callbacks})\n",
" ]\n",
" return \"\".join(chunk.content for chunk in chunks)"
]
},
{
"cell_type": "markdown",
"id": "cba476f8-29da-4c2c-9134-186871caf7ae",
"metadata": {},
"source": [
"## Initialize the Agent"
]
},
{
"cell_type": "code",
"execution_count": 9,
"id": "0bab4488-bf4c-461f-b41e-5e60310fe0f2",
"metadata": {
"tags": []
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"input_variables=['agent_scratchpad', 'input'] input_types={'chat_history': typing.List[typing.Union[langchain_core.messages.ai.AIMessage, langchain_core.messages.human.HumanMessage, langchain_core.messages.chat.ChatMessage, langchain_core.messages.system.SystemMessage, langchain_core.messages.function.FunctionMessage, langchain_core.messages.tool.ToolMessage]], 'agent_scratchpad': typing.List[typing.Union[langchain_core.messages.ai.AIMessage, langchain_core.messages.human.HumanMessage, langchain_core.messages.chat.ChatMessage, langchain_core.messages.system.SystemMessage, langchain_core.messages.function.FunctionMessage, langchain_core.messages.tool.ToolMessage]]} messages=[SystemMessagePromptTemplate(prompt=PromptTemplate(input_variables=[], template='You are a helpful assistant')), MessagesPlaceholder(variable_name='chat_history', optional=True), HumanMessagePromptTemplate(prompt=PromptTemplate(input_variables=['input'], template='{input}')), MessagesPlaceholder(variable_name='agent_scratchpad')]\n",
"[SystemMessagePromptTemplate(prompt=PromptTemplate(input_variables=[], template='You are a helpful assistant')), MessagesPlaceholder(variable_name='chat_history', optional=True), HumanMessagePromptTemplate(prompt=PromptTemplate(input_variables=['input'], template='{input}')), MessagesPlaceholder(variable_name='agent_scratchpad')]\n"
]
}
],
"source": [
"# Get the prompt to use - you can modify this!\n",
"prompt = hub.pull(\"hwchase17/openai-tools-agent\")\n",
"print(prompt)\n",
"print(prompt.messages)"
]
},
{
"cell_type": "code",
"execution_count": 10,
"id": "1762f4e1-402a-4bfb-af26-eb5b7b8f56bd",
"metadata": {
"tags": []
},
"outputs": [],
"source": [
"tools = [tell_me_a_joke_about, where_cat_is_hiding]\n",
"agent = create_openai_tools_agent(model.with_config({\"tags\": [\"agent\"]}), tools, prompt)\n",
"executor = AgentExecutor(agent=agent, tools=tools)"
]
},
{
"cell_type": "markdown",
"id": "841271d7-1de1-41a9-9387-bb04368537f1",
"metadata": {},
"source": [
"## Stream the output\n",
"\n",
"The streamed output is shown with a `|` as the delimiter between tokens. "
]
},
{
"cell_type": "code",
"execution_count": 11,
"id": "a5d94bd8-4a55-4527-b21a-4245a38c7c26",
"metadata": {
"tags": []
},
"outputs": [
{
"name": "stderr",
"output_type": "stream",
"text": [
"/home/eugene/src/langchain/libs/core/langchain_core/_api/beta_decorator.py:86: LangChainBetaWarning: This API is in beta and may change in the future.\n",
" warn_beta(\n"
]
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"--\n",
"Starting tool: where_cat_is_hiding with inputs: {}\n",
"\n",
"\n",
"|Under| the| bed|.||\n",
"\n",
"Ended tool: where_cat_is_hiding\n",
"--\n",
"Starting tool: tell_me_a_joke_about with inputs: {'topic': 'under the bed'}\n",
"\n",
"\n",
"|Sure|,| here|'s| a| long| joke| about| what|'s| hiding| under| the| bed|:\n",
"\n",
"|Once| upon| a| time|,| there| was| a| mis|chie|vous| little| boy| named| Tim|my|.| Tim|my| had| always| been| afraid| of| what| might| be| lurking| under| his| bed| at| night|.| Every| evening|,| he| would| ti|pt|oe| into| his| room|,| turn| off| the| lights|,| and| then| make| a| daring| leap| onto| his| bed|,| ensuring| that| nothing| could| grab| his| ankles|.\n",
"\n",
"|One| night|,| Tim|my|'s| parents| decided| to| play| a| prank| on| him|.| They| hid| a| remote|-controlled| toy| monster| under| his| bed|,| complete| with| glowing| eyes| and| a| grow|ling| sound| effect|.| As| Tim|my| settled| into| bed|,| his| parents| quietly| sn|uck| into| his| room|,| ready| to| give| him| the| scare| of| a| lifetime|.\n",
"\n",
"|Just| as| Tim|my| was| about| to| drift| off| to| sleep|,| he| heard| a| faint| grow|l| coming| from| under| his| bed|.| His| eyes| widened| with| fear|,| and| his| heart| started| racing|.| He| must|ered| up| the| courage| to| peek| under| the| bed|,| and| to| his| surprise|,| he| saw| a| pair| of| glowing| eyes| staring| back| at| him|.\n",
"\n",
"|Terr|ified|,| Tim|my| jumped| out| of| bed| and| ran| to| his| parents|,| screaming|,| \"|There|'s| a| monster| under| my| bed|!| Help|!\"\n",
"\n",
"|His| parents|,| trying| to| st|ifle| their| laughter|,| rushed| into| his| room|.| They| pretended| to| be| just| as| scared| as| Tim|my|,| and| together|,| they| brav|ely| approached| the| bed|.| Tim|my|'s| dad| grabbed| a| bro|om|stick|,| ready| to| defend| his| family| against| the| imaginary| monster|.\n",
"\n",
"|As| they| got| closer|,| the| \"|monster|\"| under| the| bed| started| to| move|.| Tim|my|'s| mom|,| unable| to| contain| her| laughter| any| longer|,| pressed| a| button| on| the| remote| control|,| causing| the| toy| monster| to| sc|urry| out| from| under| the| bed|.| Tim|my|'s| fear| quickly| turned| into| confusion|,| and| then| into| laughter| as| he| realized| it| was| all| just| a| prank|.\n",
"\n",
"|From| that| day| forward|,| Tim|my| learned| that| sometimes| the| things| we| fear| the| most| are| just| fig|ments| of| our| imagination|.| And| as| for| what|'s| hiding| under| his| bed|?| Well|,| it|'s| just| dust| b|unn|ies| and| the| occasional| missing| sock|.| Nothing| to| be| afraid| of|!\n",
"\n",
"|Remember|,| laughter| is| the| best| monster| repell|ent|!||\n",
"\n",
"Ended tool: tell_me_a_joke_about\n"
]
}
],
"source": [
"async for event in executor.astream_events(\n",
" {\"input\": \"where is the cat hiding? Tell me a joke about that location?\"},\n",
" include_tags=[\"tool_llm\"],\n",
" include_types=[\"tool\"],\n",
"):\n",
" hook = event[\"event\"]\n",
" if hook == \"on_chat_model_stream\":\n",
" print(event[\"data\"][\"chunk\"].content, end=\"|\")\n",
" elif hook in {\"on_chat_model_start\", \"on_chat_model_end\"}:\n",
" print()\n",
" print()\n",
" elif hook == \"on_tool_start\":\n",
" print(\"--\")\n",
" print(\n",
" f\"Starting tool: {event['name']} with inputs: {event['data'].get('input')}\"\n",
" )\n",
" elif hook == \"on_tool_end\":\n",
" print(f\"Ended tool: {event['name']}\")\n",
" else:\n",
" pass"
]
}
],
"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.4"
}
},
"nbformat": 4,
"nbformat_minor": 5
}

View File

@@ -1,6 +0,0 @@
# Callbacks for custom chains
When you create a custom chain you can easily set it up to use the same callback system as all the built-in chains.
`_call`, `_generate`, `_run`, and equivalent async methods on Chains / LLMs / Chat Models / Agents / Tools now receive a 2nd argument called `run_manager` which is bound to that run, and contains the logging methods that can be used by that object (i.e. `on_llm_new_token`). This is useful when constructing a custom chain. See this guide for more information on how to [create custom chains and use callbacks inside them](/docs/modules/chains/how_to/custom_chain).

View File

@@ -419,6 +419,105 @@
"print(texts[0])"
]
},
{
"cell_type": "markdown",
"id": "98a3f975",
"metadata": {},
"source": [
"## KoNLPY\n",
"> [KoNLPy: Korean NLP in Python](https://konlpy.org/en/latest/) is is a Python package for natural language processing (NLP) of the Korean language.\n",
"\n",
"Token splitting involves the segmentation of text into smaller, more manageable units called tokens. These tokens are often words, phrases, symbols, or other meaningful elements crucial for further processing and analysis. In languages like English, token splitting typically involves separating words by spaces and punctuation marks. The effectiveness of token splitting largely depends on the tokenizer's understanding of the language structure, ensuring the generation of meaningful tokens. Since tokenizers designed for the English language are not equipped to understand the unique semantic structures of other languages, such as Korean, they cannot be effectively used for Korean language processing.\n",
"\n",
"### Token splitting for Korean with KoNLPy's Kkma Analyzer\n",
"In case of Korean text, KoNLPY includes at morphological analyzer called `Kkma` (Korean Knowledge Morpheme Analyzer). `Kkma` provides detailed morphological analysis of Korean text. It breaks down sentences into words and words into their respective morphemes, identifying parts of speech for each token. It can segment a block of text into individual sentences, which is particularly useful for processing long texts.\n",
"\n",
"### Usage Considerations\n",
"While `Kkma` is renowned for its detailed analysis, it is important to note that this precision may impact processing speed. Thus, `Kkma` is best suited for applications where analytical depth is prioritized over rapid text processing."
]
},
{
"cell_type": "code",
"execution_count": 28,
"id": "88ec8f2f",
"metadata": {},
"outputs": [],
"source": [
"# pip install konlpy"
]
},
{
"cell_type": "code",
"execution_count": 23,
"id": "ddfba6cf",
"metadata": {},
"outputs": [],
"source": [
"# This is a long Korean document that we want to split up into its component sentences.\n",
"with open(\"./your_korean_doc.txt\") as f:\n",
" korean_document = f.read()"
]
},
{
"cell_type": "code",
"execution_count": 24,
"id": "225dfc5c",
"metadata": {},
"outputs": [],
"source": [
"from langchain.text_splitter import KonlpyTextSplitter\n",
"\n",
"text_splitter = KonlpyTextSplitter()"
]
},
{
"cell_type": "code",
"execution_count": 37,
"id": "cf156711",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"춘향전 옛날에 남원에 이 도령이라는 벼슬아치 아들이 있었다.\n",
"\n",
"그의 외모는 빛나는 달처럼 잘생겼고, 그의 학식과 기예는 남보다 뛰어났다.\n",
"\n",
"한편, 이 마을에는 춘향이라는 절세 가인이 살고 있었다.\n",
"\n",
"춘 향의 아름다움은 꽃과 같아 마을 사람들 로부터 많은 사랑을 받았다.\n",
"\n",
"어느 봄날, 도령은 친구들과 놀러 나갔다가 춘 향을 만 나 첫 눈에 반하고 말았다.\n",
"\n",
"두 사람은 서로 사랑하게 되었고, 이내 비밀스러운 사랑의 맹세를 나누었다.\n",
"\n",
"하지만 좋은 날들은 오래가지 않았다.\n",
"\n",
"도령의 아버지가 다른 곳으로 전근을 가게 되어 도령도 떠나 야만 했다.\n",
"\n",
"이별의 아픔 속에서도, 두 사람은 재회를 기약하며 서로를 믿고 기다리기로 했다.\n",
"\n",
"그러나 새로 부임한 관아의 사또가 춘 향의 아름다움에 욕심을 내 어 그녀에게 강요를 시작했다.\n",
"\n",
"춘 향 은 도령에 대한 자신의 사랑을 지키기 위해, 사또의 요구를 단호히 거절했다.\n",
"\n",
"이에 분노한 사또는 춘 향을 감옥에 가두고 혹독한 형벌을 내렸다.\n",
"\n",
"이야기는 이 도령이 고위 관직에 오른 후, 춘 향을 구해 내는 것으로 끝난다.\n",
"\n",
"두 사람은 오랜 시련 끝에 다시 만나게 되고, 그들의 사랑은 온 세상에 전해 지며 후세에까지 이어진다.\n",
"\n",
"- 춘향전 (The Tale of Chunhyang)\n"
]
}
],
"source": [
"texts = text_splitter.split_text(korean_document)\n",
"# The sentences are split with \"\\n\\n\" characters.\n",
"print(texts[0])"
]
},
{
"cell_type": "markdown",
"id": "13dc0983",
@@ -521,7 +620,7 @@
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.10.1"
"version": "3.10.12"
},
"vscode": {
"interpreter": {

View File

@@ -14,7 +14,7 @@ This section of the documentation covers everything related to the *retrieval* s
Although this sounds simple, it can be subtly complex.
This encompasses several key modules.
![data_connection_diagram](/img/data_connection.jpg)
![Illustrative diagram showing the data connection process with steps: Source, Load, Transform, Embed, Store, and Retrieve.](/img/data_connection.jpg "Data Connection Process Diagram")
**[Document loaders](/docs/modules/data_connection/document_loaders/)**

View File

@@ -24,7 +24,7 @@
},
{
"cell_type": "code",
"execution_count": 5,
"execution_count": 1,
"metadata": {},
"outputs": [],
"source": [
@@ -35,22 +35,31 @@
},
{
"cell_type": "code",
"execution_count": 6,
"execution_count": 14,
"metadata": {},
"outputs": [],
"source": [
"doc_list = [\n",
"doc_list_1 = [\n",
" \"I like apples\",\n",
" \"I like oranges\",\n",
" \"Apples and oranges are fruits\",\n",
"]\n",
"\n",
"# initialize the bm25 retriever and faiss retriever\n",
"bm25_retriever = BM25Retriever.from_texts(doc_list)\n",
"bm25_retriever = BM25Retriever.from_texts(\n",
" doc_list_1, metadatas=[{\"source\": 1}] * len(doc_list_1)\n",
")\n",
"bm25_retriever.k = 2\n",
"\n",
"doc_list_2 = [\n",
" \"You like apples\",\n",
" \"You like oranges\",\n",
"]\n",
"\n",
"embedding = OpenAIEmbeddings()\n",
"faiss_vectorstore = FAISS.from_texts(doc_list, embedding)\n",
"faiss_vectorstore = FAISS.from_texts(\n",
" doc_list_2, embedding, metadatas=[{\"source\": 2}] * len(doc_list_2)\n",
")\n",
"faiss_retriever = faiss_vectorstore.as_retriever(search_kwargs={\"k\": 2})\n",
"\n",
"# initialize the ensemble retriever\n",
@@ -61,26 +70,92 @@
},
{
"cell_type": "code",
"execution_count": 7,
"execution_count": 15,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"[Document(page_content='I like apples'),\n",
" Document(page_content='Apples and oranges are fruits')]"
"[Document(page_content='You like apples', metadata={'source': 2}),\n",
" Document(page_content='I like apples', metadata={'source': 1}),\n",
" Document(page_content='You like oranges', metadata={'source': 2}),\n",
" Document(page_content='Apples and oranges are fruits', metadata={'source': 1})]"
]
},
"execution_count": 7,
"execution_count": 15,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"docs = ensemble_retriever.get_relevant_documents(\"apples\")\n",
"docs = ensemble_retriever.invoke(\"apples\")\n",
"docs"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Runtime Configuration\n",
"\n",
"We can also configure the retrievers at runtime. In order to do this, we need to mark the fields as configurable"
]
},
{
"cell_type": "code",
"execution_count": 16,
"metadata": {},
"outputs": [],
"source": [
"from langchain_core.runnables import ConfigurableField"
]
},
{
"cell_type": "code",
"execution_count": 17,
"metadata": {},
"outputs": [],
"source": [
"faiss_retriever = faiss_vectorstore.as_retriever(\n",
" search_kwargs={\"k\": 2}\n",
").configurable_fields(\n",
" search_kwargs=ConfigurableField(\n",
" id=\"search_kwargs_faiss\",\n",
" name=\"Search Kwargs\",\n",
" description=\"The search kwargs to use\",\n",
" )\n",
")"
]
},
{
"cell_type": "code",
"execution_count": 18,
"metadata": {},
"outputs": [],
"source": [
"ensemble_retriever = EnsembleRetriever(\n",
" retrievers=[bm25_retriever, faiss_retriever], weights=[0.5, 0.5]\n",
")"
]
},
{
"cell_type": "code",
"execution_count": 19,
"metadata": {},
"outputs": [],
"source": [
"config = {\"configurable\": {\"search_kwargs_faiss\": {\"k\": 1}}}\n",
"docs = ensemble_retriever.invoke(\"apples\", config=config)\n",
"docs"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Notice that this only returns one source from the FAISS retriever, because we pass in the relevant configuration at run time"
]
},
{
"cell_type": "code",
"execution_count": null,

View File

@@ -15,7 +15,7 @@
"\n",
"A self-querying retriever is one that, as the name suggests, has the ability to query itself. Specifically, given any natural language query, the retriever uses a query-constructing LLM chain to write a structured query and then applies that structured query to its underlying VectorStore. This allows the retriever to not only use the user-input query for semantic similarity comparison with the contents of stored documents but to also extract filters from the user query on the metadata of stored documents and to execute those filters.\n",
"\n",
"![](https://drive.google.com/uc?id=1OQUN-0MJcDUxmPXofgS7MqReEs720pqS)\n",
"![](../../../../static/img/self_querying.jpg)\n",
"\n",
"## Get started\n",
"For demonstration purposes we'll use a `Chroma` vector store. We've created a small demo set of documents that contain summaries of movies.\n",
@@ -561,7 +561,7 @@
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.10.1"
"version": "3.9.1"
}
},
"nbformat": 4,

View File

@@ -17,10 +17,10 @@ The base Embeddings class in LangChain provides two methods: one for embedding d
### Setup
To start we'll need to install the OpenAI Python package:
To start we'll need to install the OpenAI partner package:
```bash
pip install openai
pip install langchain-openai
```
Accessing the API requires an API key, which you can get by creating an account and heading [here](https://platform.openai.com/account/api-keys). Once we have a key we'll want to set it as an environment variable by running:

View File

@@ -12,7 +12,7 @@ vectors, and then at query time to embed the unstructured query and retrieve the
'most similar' to the embedded query. A vector store takes care of storing embedded data and performing vector search
for you.
![vector store diagram](/img/vector_stores.jpg)
![Diagram illustrating the process of vector stores: 1. Load source data, 2. Query vector store, 3. Retrieve 'most similar' results.](/img/vector_stores.jpg "Vector Store Process Diagram")
## Get started

View File

@@ -36,7 +36,7 @@ A chain will interact with its memory system twice in a given run.
1. AFTER receiving the initial user inputs but BEFORE executing the core logic, a chain will READ from its memory system and augment the user inputs.
2. AFTER executing the core logic but BEFORE returning the answer, a chain will WRITE the inputs and outputs of the current run to memory, so that they can be referred to in future runs.
![memory-diagram](/img/memory_diagram.png)
![Diagram illustrating the READ and WRITE operations of a memory system in a conversational interface.](/img/memory_diagram.png "Memory System Diagram")
## Building memory into a system

View File

@@ -1,5 +1,5 @@
---
sidebar_position: 2
sidebar_position: 3
---
# Chat Models

View File

@@ -24,10 +24,10 @@
"\n",
"## Setup\n",
"\n",
"For this example we'll need to install the OpenAI Python package:\n",
"For this example we'll need to install the OpenAI partner package:\n",
"\n",
"```bash\n",
"pip install openai\n",
"pip install langchain-openai\n",
"```\n",
"\n",
"Accessing the API requires an API key, which you can get by creating an account and heading [here](https://platform.openai.com/account/api-keys). Once we have a key we'll want to set it as an environment variable by running:\n",

View File

@@ -1,5 +1,5 @@
---
sidebar_position: 0
sidebar_position: 1
---
# Concepts

View File

@@ -9,7 +9,7 @@ sidebar_class_name: hidden
The core element of any language model application is...the model. LangChain gives you the building blocks to interface with any language model.
![model_io_diagram](/img/model_io.jpg)
![Flowchart illustrating the Model I/O process with steps Format, Predict, and Parse, showing the transformation from input variables to structured output.](/img/model_io.jpg "Model Input/Output Process Diagram")
## [Conceptual Guide](/docs/modules/model_io/concepts)

View File

@@ -1,5 +1,5 @@
---
sidebar_position: 1
sidebar_position: 4
---
# LLMs

View File

@@ -1,5 +1,5 @@
---
sidebar_position: 4
sidebar_position: 5
hide_table_of_contents: true
---
# Output Parsers

View File

@@ -1,5 +1,5 @@
---
sidebar_position: 0
sidebar_position: 2
---
# Prompts

View File

@@ -16,10 +16,10 @@ import CodeBlock from "@theme/CodeBlock";
<Tabs>
<TabItem value="openai" label="OpenAI" default>
First we'll need to install their Python package:
First we'll need to install their partner package:
```shell
pip install openai
pip install langchain-openai
```
Accessing the API requires an API key, which you can get by creating an account and heading [here](https://platform.openai.com/account/api-keys). Once we have a key we'll want to set it as an environment variable by running:

View File

@@ -0,0 +1,151 @@
{
"cells": [
{
"cell_type": "markdown",
"id": "5fbab4e7-2c5e-4682-8c97-bfada89d206f",
"metadata": {},
"source": [
"# Classification"
]
},
{
"cell_type": "markdown",
"id": "0e135e18-f9b5-41d9-971d-f1c57a76add4",
"metadata": {},
"source": [
"## Direct prompting"
]
},
{
"cell_type": "markdown",
"id": "cf9d74f6-f18c-4ceb-a21b-ef101a758816",
"metadata": {},
"source": [
"## Function-calling"
]
},
{
"cell_type": "markdown",
"id": "81b3dd6a-c648-4930-98f3-733f0f0e5af7",
"metadata": {},
"source": [
"## Logprobs"
]
},
{
"cell_type": "code",
"execution_count": 1,
"id": "edd66c98-1146-4f34-8828-433553f55ab0",
"metadata": {},
"outputs": [],
"source": [
"from langchain_openai import ChatOpenAI"
]
},
{
"cell_type": "code",
"execution_count": 4,
"id": "2e9f633e-5d2c-41dd-a1d1-f4b0230facca",
"metadata": {},
"outputs": [],
"source": [
"from langchain.chains.classification import create_openai_logprobs_classification_chain"
]
},
{
"cell_type": "code",
"execution_count": 5,
"id": "107020bc-fadd-49ad-aa30-c5bee19d8f63",
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"{'classification': 'D', 'confidence': 0.9996887772698445}"
]
},
"execution_count": 5,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"llm = ChatOpenAI(model=\"gpt-3.5-turbo\", temperature=0)\n",
"classes = {\"C\": \"The input is about cats\", \"D\": \"The input is about dogs\"}\n",
"chain = create_openai_logprobs_classification_chain(llm, classes)\n",
"chain.invoke({\"input\": \"I really love my golden retriever\"})"
]
},
{
"cell_type": "code",
"execution_count": 6,
"id": "c829152c-e113-4ae4-a628-10fc235c5bba",
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"{'classification': 'C', 'confidence': 0.9997948118239739}"
]
},
"execution_count": 6,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"chain.invoke({\"input\": \"Aren't siamese just the best\"})"
]
},
{
"cell_type": "code",
"execution_count": 7,
"id": "88bd9984-a050-4a1b-9707-b8f0994bd5b7",
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"{'classification': 'C', 'confidence': 0.677221622476509}"
]
},
"execution_count": 7,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"chain.invoke({\"input\": \"They scratched up everything\"})"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "246e36e0-3ca7-47e7-a46d-de9f1ea33c87",
"metadata": {},
"outputs": [],
"source": []
}
],
"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,289 @@
{
"cells": [
{
"cell_type": "raw",
"id": "7b68af90-bfab-4407-93b6-d084cf948b4b",
"metadata": {},
"source": [
"---\n",
"sidebar_position: 1\n",
"---"
]
},
{
"cell_type": "markdown",
"id": "1925a807-fa01-44bc-8a03-d9907311c7f9",
"metadata": {
"jp-MarkdownHeadingCollapsed": true
},
"source": [
"## Agents\n",
"\n",
"Chains are great when we know the specific sequence of tool usage needed for any user input. But for certain use cases, how many times we use tools depends on the input. In these cases, we want to let the model itself decide how many times to use tools and in what order. [Agents](/docs/modules/agents/) let us do just this.\n",
"\n",
"LangChain comes with a number of built-in agents that are optimized for different use cases. Read about all the [agent types here](/docs/modules/agents/agent_types/).\n",
"\n",
"As an example, let's try out the OpenAI tools agent, which makes use of the new OpenAI tool-calling API (this is only available in the latest OpenAI models, and differs from function-calling in that the model can return multiple function invocations at once).\n",
"\n",
"![agent](../../../static/img/tool_agent.svg)"
]
},
{
"cell_type": "markdown",
"id": "c224a321-2f5a-410c-b466-a10d0199bad8",
"metadata": {},
"source": [
"## Setup\n",
"\n",
"We'll need to install the following packages:"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "f6303995-a8f7-4504-8b29-e227683f375e",
"metadata": {},
"outputs": [],
"source": [
"%pip install --upgrade --quiet langchain langchain-openai"
]
},
{
"cell_type": "markdown",
"id": "a33915ce-00c5-4379-8a83-c0053e471cdb",
"metadata": {},
"source": [
"And set these environment variables:"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "54667a49-c226-486d-a887-33120c90cc91",
"metadata": {},
"outputs": [],
"source": [
"import getpass\n",
"import os\n",
"\n",
"os.environ[\"OPENAI_API_KEY\"] = getpass.getpass()\n",
"\n",
"# If you'd like to use LangSmith, uncomment the below\n",
"# os.environ[\"LANGCHAIN_TRACING_V2\"] = \"true\"\n",
"# os.environ[\"LANGCHAIN_API_KEY\"] = getpass.getpass()"
]
},
{
"cell_type": "markdown",
"id": "aaaad3ad-085b-494e-84aa-9cb3e983c80b",
"metadata": {},
"source": [
"## Create tools\n",
"\n",
"First, we need to create some tool to call. For this example, we will create custom tools from functions. For more information on creating custom tools, please see [this guide](/docs/modules/agents/tools/)."
]
},
{
"cell_type": "code",
"execution_count": 1,
"id": "1c44ba79-6ab2-4d55-8247-82fca4d9b70c",
"metadata": {},
"outputs": [],
"source": [
"from langchain_core.tools import tool\n",
"\n",
"\n",
"@tool\n",
"def multiply(first_int: int, second_int: int) -> int:\n",
" \"\"\"Multiply two integers together.\"\"\"\n",
" return first_int * second_int\n",
"\n",
"\n",
"@tool\n",
"def add(first_int: int, second_int: int) -> int:\n",
" \"Add two integers.\"\n",
" return first_int + second_int\n",
"\n",
"\n",
"@tool\n",
"def exponentiate(base: int, exponent: int) -> int:\n",
" \"Exponentiate the base to the exponent power.\"\n",
" return base**exponent\n",
"\n",
"\n",
"tools = [multiply, add, exponentiate]"
]
},
{
"cell_type": "markdown",
"id": "a3d0c8ca-72bd-4187-b1e6-f5eef92eeb52",
"metadata": {},
"source": [
"## Create prompt"
]
},
{
"cell_type": "code",
"execution_count": 1,
"id": "e27a4e1a-938b-4b60-8e32-25e4ee530274",
"metadata": {},
"outputs": [],
"source": [
"from langchain import hub\n",
"from langchain.agents import AgentExecutor, create_openai_tools_agent\n",
"from langchain_openai import ChatOpenAI"
]
},
{
"cell_type": "code",
"execution_count": 2,
"id": "bcc9536e-0328-4e29-9d3d-133f3e63e589",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"================================\u001b[1m System Message \u001b[0m================================\n",
"\n",
"You are a helpful assistant\n",
"\n",
"=============================\u001b[1m Messages Placeholder \u001b[0m=============================\n",
"\n",
"\u001b[33;1m\u001b[1;3m{chat_history}\u001b[0m\n",
"\n",
"================================\u001b[1m Human Message \u001b[0m=================================\n",
"\n",
"\u001b[33;1m\u001b[1;3m{input}\u001b[0m\n",
"\n",
"=============================\u001b[1m Messages Placeholder \u001b[0m=============================\n",
"\n",
"\u001b[33;1m\u001b[1;3m{agent_scratchpad}\u001b[0m\n"
]
}
],
"source": [
"# Get the prompt to use - you can modify this!\n",
"prompt = hub.pull(\"hwchase17/openai-tools-agent\")\n",
"prompt.pretty_print()"
]
},
{
"cell_type": "markdown",
"id": "85e9875a-d8d4-4712-b3f0-b513c684451b",
"metadata": {},
"source": [
"## Create agent"
]
},
{
"cell_type": "code",
"execution_count": 4,
"id": "a1c5319d-6609-449d-8dd0-127e9a600656",
"metadata": {},
"outputs": [],
"source": [
"# Choose the LLM that will drive the agent\n",
"# Only certain models support this\n",
"model = ChatOpenAI(model=\"gpt-3.5-turbo-1106\", temperature=0)\n",
"\n",
"# Construct the OpenAI Tools agent\n",
"agent = create_openai_tools_agent(model, tools, prompt)"
]
},
{
"cell_type": "code",
"execution_count": 5,
"id": "c86bfe50-c5b3-49ed-86c8-1fe8dcd0c83a",
"metadata": {},
"outputs": [],
"source": [
"# Create an agent executor by passing in the agent and tools\n",
"agent_executor = AgentExecutor(agent=agent, tools=tools, verbose=True)"
]
},
{
"cell_type": "markdown",
"id": "448d5ef2-9820-44d0-96d3-ff1d648e4b01",
"metadata": {},
"source": [
"## Invoke agent"
]
},
{
"cell_type": "code",
"execution_count": 6,
"id": "c098f8df-fd7f-4c13-963a-8e34194d3f84",
"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: `exponentiate` with `{'base': 3, 'exponent': 5}`\n",
"\n",
"\n",
"\u001b[0m\u001b[38;5;200m\u001b[1;3m243\u001b[0m\u001b[32;1m\u001b[1;3m\n",
"Invoking: `add` with `{'first_int': 12, 'second_int': 3}`\n",
"\n",
"\n",
"\u001b[0m\u001b[33;1m\u001b[1;3m15\u001b[0m\u001b[32;1m\u001b[1;3m\n",
"Invoking: `multiply` with `{'first_int': 243, 'second_int': 15}`\n",
"\n",
"\n",
"\u001b[0m\u001b[36;1m\u001b[1;3m3645\u001b[0m\u001b[32;1m\u001b[1;3m\n",
"Invoking: `exponentiate` with `{'base': 3645, 'exponent': 2}`\n",
"\n",
"\n",
"\u001b[0m\u001b[38;5;200m\u001b[1;3m13286025\u001b[0m\u001b[32;1m\u001b[1;3mThe result of raising 3 to the fifth power and multiplying that by the sum of twelve and three, then squaring the whole result is 13,286,025.\u001b[0m\n",
"\n",
"\u001b[1m> Finished chain.\u001b[0m\n"
]
},
{
"data": {
"text/plain": [
"{'input': 'Take 3 to the fifth power and multiply that by the sum of twelve and three, then square the whole result',\n",
" 'output': 'The result of raising 3 to the fifth power and multiplying that by the sum of twelve and three, then squaring the whole result is 13,286,025.'}"
]
},
"execution_count": 6,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"agent_executor.invoke(\n",
" {\n",
" \"input\": \"Take 3 to the fifth power and multiply that by the sum of twelve and three, then square the whole result\"\n",
" }\n",
")"
]
}
],
"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,274 @@
{
"cells": [
{
"cell_type": "markdown",
"id": "b09b745d-f006-4ecc-8772-afa266c43605",
"metadata": {},
"source": [
"# Human-in-the-loop\n",
"\n",
"There are certain tools that we don't trust a model to execute on its own. One thing we can do in such situations is require human approval before the tool is invoked."
]
},
{
"cell_type": "markdown",
"id": "09178c30-a633-4d7b-88ea-092316f14b6f",
"metadata": {},
"source": [
"## Setup\n",
"\n",
"We'll need to install the following packages:"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "e44bec05-9aa4-47b1-a660-c0a183533598",
"metadata": {},
"outputs": [],
"source": [
"%pip install --upgrade --quiet langchain langchain-openai"
]
},
{
"cell_type": "markdown",
"id": "f09629b6-7f62-4879-a791-464739ca6b6b",
"metadata": {},
"source": [
"And set these environment variables:"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "2bed0ccf-20cc-4fd3-9947-55471dd8c4da",
"metadata": {},
"outputs": [],
"source": [
"import getpass\n",
"import os\n",
"\n",
"os.environ[\"OPENAI_API_KEY\"] = getpass.getpass()\n",
"\n",
"# If you'd like to use LangSmith, uncomment the below:\n",
"# os.environ[\"LANGCHAIN_TRACING_V2\"] = \"true\"\n",
"# os.environ[\"LANGCHAIN_API_KEY\"] = getpass.getpass()"
]
},
{
"cell_type": "markdown",
"id": "43721981-4595-4721-bea0-5c67696426d3",
"metadata": {},
"source": [
"## Chain\n",
"\n",
"Suppose we have the following (dummy) tools and tool-calling chain:"
]
},
{
"cell_type": "code",
"execution_count": 25,
"id": "0221fdfd-2a18-4449-a123-e6b0b15bb3d9",
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"[{'type': 'count_emails', 'args': {'last_n_days': 5}, 'output': 10}]"
]
},
"execution_count": 25,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"from operator import itemgetter\n",
"\n",
"from langchain.output_parsers import JsonOutputToolsParser\n",
"from langchain_community.tools.convert_to_openai import format_tool_to_openai_tool\n",
"from langchain_core.runnables import Runnable, RunnableLambda, RunnablePassthrough\n",
"from langchain_core.tools import tool\n",
"from langchain_openai import ChatOpenAI\n",
"\n",
"\n",
"@tool\n",
"def count_emails(last_n_days: int) -> int:\n",
" \"\"\"Multiply two integers together.\"\"\"\n",
" return last_n_days * 2\n",
"\n",
"\n",
"@tool\n",
"def send_email(message: str, recipient: str) -> str:\n",
" \"Add two integers.\"\n",
" return f\"Successfully sent email to {recipient}.\"\n",
"\n",
"\n",
"tools = [count_emails, send_email]\n",
"model = ChatOpenAI(model=\"gpt-3.5-turbo\", temperature=0).bind(\n",
" tools=[format_tool_to_openai_tool(t) for t in tools]\n",
")\n",
"\n",
"\n",
"def call_tool(tool_invocation: dict) -> Runnable:\n",
" \"\"\"Function for dynamically constructing the end of the chain based on the model-selected tool.\"\"\"\n",
" tool_map = {tool.name: tool for tool in tools}\n",
" tool = tool_map[tool_invocation[\"type\"]]\n",
" return RunnablePassthrough.assign(output=itemgetter(\"args\") | tool)\n",
"\n",
"\n",
"# .map() allows us to apply a function to a list of inputs.\n",
"call_tool_list = RunnableLambda(call_tool).map()\n",
"chain = model | JsonOutputToolsParser() | call_tool_list\n",
"chain.invoke(\"how many emails did i get in the last 5 days?\")"
]
},
{
"cell_type": "markdown",
"id": "258c1c7b-a765-4558-93fe-d0defbc29223",
"metadata": {},
"source": [
"## Adding human approval\n",
"\n",
"We can add a simple human approval step to our tool_chain function:"
]
},
{
"cell_type": "code",
"execution_count": 30,
"id": "341fb055-0315-47bc-8f72-ed6103d2981f",
"metadata": {},
"outputs": [],
"source": [
"import json\n",
"\n",
"\n",
"def human_approval(tool_invocations: list) -> Runnable:\n",
" tool_strs = \"\\n\\n\".join(\n",
" json.dumps(tool_call, indent=2) for tool_call in tool_invocations\n",
" )\n",
" msg = (\n",
" f\"Do you approve of the following tool invocations\\n\\n{tool_strs}\\n\\n\"\n",
" \"Anything except 'Y'/'Yes' (case-insensitive) will be treated as a no.\"\n",
" )\n",
" resp = input(msg)\n",
" if resp.lower() not in (\"yes\", \"y\"):\n",
" raise ValueError(f\"Tool invocations not approved:\\n\\n{tool_strs}\")\n",
" return tool_invocations"
]
},
{
"cell_type": "code",
"execution_count": 31,
"id": "25dca07b-56ca-4b94-9955-d4f3e9895e03",
"metadata": {},
"outputs": [
{
"name": "stdin",
"output_type": "stream",
"text": [
"Do you approve of the following tool invocations\n",
"\n",
"{\n",
" \"type\": \"count_emails\",\n",
" \"args\": {\n",
" \"last_n_days\": 5\n",
" }\n",
"}\n",
"\n",
"Anything except 'Y'/'Yes' (case-insensitive) will be treated as a no. y\n"
]
},
{
"data": {
"text/plain": [
"[{'type': 'count_emails', 'args': {'last_n_days': 5}, 'output': 10}]"
]
},
"execution_count": 31,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"chain = model | JsonOutputToolsParser() | human_approval | call_tool_list\n",
"chain.invoke(\"how many emails did i get in the last 5 days?\")"
]
},
{
"cell_type": "code",
"execution_count": 32,
"id": "f558f2cd-847b-4ef9-a770-3961082b540c",
"metadata": {},
"outputs": [
{
"name": "stdin",
"output_type": "stream",
"text": [
"Do you approve of the following tool invocations\n",
"\n",
"{\n",
" \"type\": \"send_email\",\n",
" \"args\": {\n",
" \"message\": \"What's up homie\",\n",
" \"recipient\": \"sally@gmail.com\"\n",
" }\n",
"}\n",
"\n",
"Anything except 'Y'/'Yes' (case-insensitive) will be treated as a no. no\n"
]
},
{
"ename": "ValueError",
"evalue": "Tool invocations not approved:\n\n{\n \"type\": \"send_email\",\n \"args\": {\n \"message\": \"What's up homie\",\n \"recipient\": \"sally@gmail.com\"\n }\n}",
"output_type": "error",
"traceback": [
"\u001b[0;31m---------------------------------------------------------------------------\u001b[0m",
"\u001b[0;31mValueError\u001b[0m Traceback (most recent call last)",
"Cell \u001b[0;32mIn[32], line 1\u001b[0m\n\u001b[0;32m----> 1\u001b[0m \u001b[43mchain\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43minvoke\u001b[49m\u001b[43m(\u001b[49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[38;5;124;43mSend sally@gmail.com an email saying \u001b[39;49m\u001b[38;5;124;43m'\u001b[39;49m\u001b[38;5;124;43mWhat\u001b[39;49m\u001b[38;5;124;43m'\u001b[39;49m\u001b[38;5;124;43ms up homie\u001b[39;49m\u001b[38;5;124;43m'\u001b[39;49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[43m)\u001b[49m\n",
"File \u001b[0;32m~/langchain/libs/core/langchain_core/runnables/base.py:1774\u001b[0m, in \u001b[0;36mRunnableSequence.invoke\u001b[0;34m(self, input, config)\u001b[0m\n\u001b[1;32m 1772\u001b[0m \u001b[38;5;28;01mtry\u001b[39;00m:\n\u001b[1;32m 1773\u001b[0m \u001b[38;5;28;01mfor\u001b[39;00m i, step \u001b[38;5;129;01min\u001b[39;00m \u001b[38;5;28menumerate\u001b[39m(\u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39msteps):\n\u001b[0;32m-> 1774\u001b[0m \u001b[38;5;28minput\u001b[39m \u001b[38;5;241m=\u001b[39m \u001b[43mstep\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43minvoke\u001b[49m\u001b[43m(\u001b[49m\n\u001b[1;32m 1775\u001b[0m \u001b[43m \u001b[49m\u001b[38;5;28;43minput\u001b[39;49m\u001b[43m,\u001b[49m\n\u001b[1;32m 1776\u001b[0m \u001b[43m \u001b[49m\u001b[38;5;66;43;03m# mark each step as a child run\u001b[39;49;00m\n\u001b[1;32m 1777\u001b[0m \u001b[43m \u001b[49m\u001b[43mpatch_config\u001b[49m\u001b[43m(\u001b[49m\n\u001b[1;32m 1778\u001b[0m \u001b[43m \u001b[49m\u001b[43mconfig\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mcallbacks\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mrun_manager\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mget_child\u001b[49m\u001b[43m(\u001b[49m\u001b[38;5;124;43mf\u001b[39;49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[38;5;124;43mseq:step:\u001b[39;49m\u001b[38;5;132;43;01m{\u001b[39;49;00m\u001b[43mi\u001b[49m\u001b[38;5;241;43m+\u001b[39;49m\u001b[38;5;241;43m1\u001b[39;49m\u001b[38;5;132;43;01m}\u001b[39;49;00m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[43m)\u001b[49m\n\u001b[1;32m 1779\u001b[0m \u001b[43m \u001b[49m\u001b[43m)\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m 1780\u001b[0m \u001b[43m \u001b[49m\u001b[43m)\u001b[49m\n\u001b[1;32m 1781\u001b[0m \u001b[38;5;66;03m# finish the root run\u001b[39;00m\n\u001b[1;32m 1782\u001b[0m \u001b[38;5;28;01mexcept\u001b[39;00m \u001b[38;5;167;01mBaseException\u001b[39;00m \u001b[38;5;28;01mas\u001b[39;00m e:\n",
"File \u001b[0;32m~/langchain/libs/core/langchain_core/runnables/base.py:3074\u001b[0m, in \u001b[0;36mRunnableLambda.invoke\u001b[0;34m(self, input, config, **kwargs)\u001b[0m\n\u001b[1;32m 3072\u001b[0m \u001b[38;5;250m\u001b[39m\u001b[38;5;124;03m\"\"\"Invoke this runnable synchronously.\"\"\"\u001b[39;00m\n\u001b[1;32m 3073\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;28mhasattr\u001b[39m(\u001b[38;5;28mself\u001b[39m, \u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mfunc\u001b[39m\u001b[38;5;124m\"\u001b[39m):\n\u001b[0;32m-> 3074\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43m_call_with_config\u001b[49m\u001b[43m(\u001b[49m\n\u001b[1;32m 3075\u001b[0m \u001b[43m \u001b[49m\u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43m_invoke\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m 3076\u001b[0m \u001b[43m \u001b[49m\u001b[38;5;28;43minput\u001b[39;49m\u001b[43m,\u001b[49m\n\u001b[1;32m 3077\u001b[0m \u001b[43m \u001b[49m\u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43m_config\u001b[49m\u001b[43m(\u001b[49m\u001b[43mconfig\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mfunc\u001b[49m\u001b[43m)\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m 3078\u001b[0m \u001b[43m \u001b[49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[43mkwargs\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m 3079\u001b[0m \u001b[43m \u001b[49m\u001b[43m)\u001b[49m\n\u001b[1;32m 3080\u001b[0m \u001b[38;5;28;01melse\u001b[39;00m:\n\u001b[1;32m 3081\u001b[0m \u001b[38;5;28;01mraise\u001b[39;00m \u001b[38;5;167;01mTypeError\u001b[39;00m(\n\u001b[1;32m 3082\u001b[0m \u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mCannot invoke a coroutine function synchronously.\u001b[39m\u001b[38;5;124m\"\u001b[39m\n\u001b[1;32m 3083\u001b[0m \u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mUse `ainvoke` instead.\u001b[39m\u001b[38;5;124m\"\u001b[39m\n\u001b[1;32m 3084\u001b[0m )\n",
"File \u001b[0;32m~/langchain/libs/core/langchain_core/runnables/base.py:975\u001b[0m, in \u001b[0;36mRunnable._call_with_config\u001b[0;34m(self, func, input, config, run_type, **kwargs)\u001b[0m\n\u001b[1;32m 971\u001b[0m context \u001b[38;5;241m=\u001b[39m copy_context()\n\u001b[1;32m 972\u001b[0m context\u001b[38;5;241m.\u001b[39mrun(var_child_runnable_config\u001b[38;5;241m.\u001b[39mset, child_config)\n\u001b[1;32m 973\u001b[0m output \u001b[38;5;241m=\u001b[39m cast(\n\u001b[1;32m 974\u001b[0m Output,\n\u001b[0;32m--> 975\u001b[0m \u001b[43mcontext\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mrun\u001b[49m\u001b[43m(\u001b[49m\n\u001b[1;32m 976\u001b[0m \u001b[43m \u001b[49m\u001b[43mcall_func_with_variable_args\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m 977\u001b[0m \u001b[43m \u001b[49m\u001b[43mfunc\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;66;43;03m# type: ignore[arg-type]\u001b[39;49;00m\n\u001b[1;32m 978\u001b[0m \u001b[43m \u001b[49m\u001b[38;5;28;43minput\u001b[39;49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;66;43;03m# type: ignore[arg-type]\u001b[39;49;00m\n\u001b[1;32m 979\u001b[0m \u001b[43m \u001b[49m\u001b[43mconfig\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m 980\u001b[0m \u001b[43m \u001b[49m\u001b[43mrun_manager\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m 981\u001b[0m \u001b[43m \u001b[49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[43mkwargs\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m 982\u001b[0m \u001b[43m \u001b[49m\u001b[43m)\u001b[49m,\n\u001b[1;32m 983\u001b[0m )\n\u001b[1;32m 984\u001b[0m \u001b[38;5;28;01mexcept\u001b[39;00m \u001b[38;5;167;01mBaseException\u001b[39;00m \u001b[38;5;28;01mas\u001b[39;00m e:\n\u001b[1;32m 985\u001b[0m run_manager\u001b[38;5;241m.\u001b[39mon_chain_error(e)\n",
"File \u001b[0;32m~/langchain/libs/core/langchain_core/runnables/config.py:323\u001b[0m, in \u001b[0;36mcall_func_with_variable_args\u001b[0;34m(func, input, config, run_manager, **kwargs)\u001b[0m\n\u001b[1;32m 321\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m run_manager \u001b[38;5;129;01mis\u001b[39;00m \u001b[38;5;129;01mnot\u001b[39;00m \u001b[38;5;28;01mNone\u001b[39;00m \u001b[38;5;129;01mand\u001b[39;00m accepts_run_manager(func):\n\u001b[1;32m 322\u001b[0m kwargs[\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mrun_manager\u001b[39m\u001b[38;5;124m\"\u001b[39m] \u001b[38;5;241m=\u001b[39m run_manager\n\u001b[0;32m--> 323\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[43mfunc\u001b[49m\u001b[43m(\u001b[49m\u001b[38;5;28;43minput\u001b[39;49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[43mkwargs\u001b[49m\u001b[43m)\u001b[49m\n",
"File \u001b[0;32m~/langchain/libs/core/langchain_core/runnables/base.py:2950\u001b[0m, in \u001b[0;36mRunnableLambda._invoke\u001b[0;34m(self, input, run_manager, config, **kwargs)\u001b[0m\n\u001b[1;32m 2948\u001b[0m output \u001b[38;5;241m=\u001b[39m chunk\n\u001b[1;32m 2949\u001b[0m \u001b[38;5;28;01melse\u001b[39;00m:\n\u001b[0;32m-> 2950\u001b[0m output \u001b[38;5;241m=\u001b[39m \u001b[43mcall_func_with_variable_args\u001b[49m\u001b[43m(\u001b[49m\n\u001b[1;32m 2951\u001b[0m \u001b[43m \u001b[49m\u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mfunc\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;28;43minput\u001b[39;49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mconfig\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mrun_manager\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[43mkwargs\u001b[49m\n\u001b[1;32m 2952\u001b[0m \u001b[43m \u001b[49m\u001b[43m)\u001b[49m\n\u001b[1;32m 2953\u001b[0m \u001b[38;5;66;03m# If the output is a runnable, invoke it\u001b[39;00m\n\u001b[1;32m 2954\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;28misinstance\u001b[39m(output, Runnable):\n",
"File \u001b[0;32m~/langchain/libs/core/langchain_core/runnables/config.py:323\u001b[0m, in \u001b[0;36mcall_func_with_variable_args\u001b[0;34m(func, input, config, run_manager, **kwargs)\u001b[0m\n\u001b[1;32m 321\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m run_manager \u001b[38;5;129;01mis\u001b[39;00m \u001b[38;5;129;01mnot\u001b[39;00m \u001b[38;5;28;01mNone\u001b[39;00m \u001b[38;5;129;01mand\u001b[39;00m accepts_run_manager(func):\n\u001b[1;32m 322\u001b[0m kwargs[\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mrun_manager\u001b[39m\u001b[38;5;124m\"\u001b[39m] \u001b[38;5;241m=\u001b[39m run_manager\n\u001b[0;32m--> 323\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[43mfunc\u001b[49m\u001b[43m(\u001b[49m\u001b[38;5;28;43minput\u001b[39;49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[43mkwargs\u001b[49m\u001b[43m)\u001b[49m\n",
"Cell \u001b[0;32mIn[30], line 11\u001b[0m, in \u001b[0;36mhuman_approval\u001b[0;34m(tool_invocations)\u001b[0m\n\u001b[1;32m 9\u001b[0m resp \u001b[38;5;241m=\u001b[39m \u001b[38;5;28minput\u001b[39m(msg)\n\u001b[1;32m 10\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;129;01mnot\u001b[39;00m resp\u001b[38;5;241m.\u001b[39mlower() \u001b[38;5;129;01min\u001b[39;00m (\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124myes\u001b[39m\u001b[38;5;124m\"\u001b[39m, \u001b[38;5;124m\"\u001b[39m\u001b[38;5;124my\u001b[39m\u001b[38;5;124m\"\u001b[39m):\n\u001b[0;32m---> 11\u001b[0m \u001b[38;5;28;01mraise\u001b[39;00m \u001b[38;5;167;01mValueError\u001b[39;00m(\u001b[38;5;124mf\u001b[39m\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mTool invocations not approved:\u001b[39m\u001b[38;5;130;01m\\n\u001b[39;00m\u001b[38;5;130;01m\\n\u001b[39;00m\u001b[38;5;132;01m{\u001b[39;00mtool_strs\u001b[38;5;132;01m}\u001b[39;00m\u001b[38;5;124m\"\u001b[39m)\n\u001b[1;32m 12\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m tool_invocations\n",
"\u001b[0;31mValueError\u001b[0m: Tool invocations not approved:\n\n{\n \"type\": \"send_email\",\n \"args\": {\n \"message\": \"What's up homie\",\n \"recipient\": \"sally@gmail.com\"\n }\n}"
]
}
],
"source": [
"chain.invoke(\"Send sally@gmail.com an email saying 'What's up homie'\")"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "e938d8f1-df93-4726-a465-78e596312246",
"metadata": {},
"outputs": [],
"source": []
}
],
"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,61 @@
{
"cells": [
{
"cell_type": "raw",
"id": "451cda29-bed0-4558-9ed7-099bdd12ad60",
"metadata": {},
"source": [
"---\n",
"sidebar_position: 0.9\n",
"---"
]
},
{
"cell_type": "markdown",
"id": "14b94240",
"metadata": {},
"source": [
"# Tool use\n",
"\n",
"An exciting use case for LLMs is building natural language interfaces for other \"tools\", whether those are APIs, functions, databases, etc. LangChain is great for building such interfaces because it has:\n",
"\n",
"- Good model output parsing, which makes it easy to extract JSON, XML, OpenAI function-calls, etc. from model outputs.\n",
"- A large collection of built-in [Tools](/docs/integrations/tools).\n",
"- Provides a lot of flexibility in how you call these tools.\n",
"\n",
"There are two main ways to use tools: [chains](/docs/modules/chains) and [agents](/docs/modules/agents/). \n",
"\n",
"Chains lets you create a pre-defined sequence of tool usage(s). \n",
"\n",
"![chain](../../../static/img/tool_chain.svg)\n",
"\n",
"Agents let the model use tools in a loop, so that it can decide how many times to use tools.\n",
"\n",
"![agent](../../../static/img/tool_agent.svg)\n",
"\n",
"To get started with both approaches, head to the [Quickstart](/docs/use_cases/tool_use/quickstart) page."
]
}
],
"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,259 @@
{
"cells": [
{
"cell_type": "raw",
"id": "1ea1fe24-fe1e-463b-a52c-79f0ef02328e",
"metadata": {},
"source": [
"---\n",
"sidebar_position: 2\n",
"---"
]
},
{
"cell_type": "markdown",
"id": "95982bf1-7d9d-4dd6-a4ad-9de0719fe17f",
"metadata": {},
"source": [
"# Choosing between multiple tools\n",
"\n",
"In our [Quickstart](/docs/use_cases/tool_use/quickstart) we went over how to build a Chain that calls a single `multiply` tool. Now let's take a look at how we might augment this chain so that it can pick from a number of tools to call. We'll focus on Chains since [Agents](/docs/use_cases/tool_use/agents) can route between multiple tools by default."
]
},
{
"cell_type": "markdown",
"id": "3fafec38-443a-42ad-a913-5be7667e3734",
"metadata": {},
"source": [
"## Setup\n",
"\n",
"We'll need to install the following packages for this guide:"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "78411bf1-0117-4f33-a3d7-f3d77a97bb78",
"metadata": {},
"outputs": [],
"source": [
"%pip install --upgrade --quiet langchain langchain-openai"
]
},
{
"cell_type": "markdown",
"id": "59d08fd0-ddd9-4c74-bcea-a5ca3a86e542",
"metadata": {},
"source": [
"And set these environment variables:"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "4185e74b-0500-4cad-ace0-bac37de466ac",
"metadata": {},
"outputs": [],
"source": [
"import getpass\n",
"import os\n",
"\n",
"os.environ[\"OPENAI_API_KEY\"] = getpass.getpass()\n",
"\n",
"# If you'd like to use LangSmith, uncomment the below\n",
"# os.environ[\"LANGCHAIN_TRACING_V2\"] = \"true\"\n",
"# os.environ[\"LANGCHAIN_API_KEY\"] = getpass.getpass()"
]
},
{
"cell_type": "markdown",
"id": "d28159f5-b7d0-4385-aa44-4cd1b64507bb",
"metadata": {},
"source": [
"## Tools\n",
"\n",
"Recall we already had a `multiply` tool:"
]
},
{
"cell_type": "code",
"execution_count": 3,
"id": "e13ec98c-8521-4d63-b521-caf92da87b70",
"metadata": {},
"outputs": [],
"source": [
"from langchain_core.tools import tool\n",
"\n",
"\n",
"@tool\n",
"def multiply(first_int: int, second_int: int) -> int:\n",
" \"\"\"Multiply two integers together.\"\"\"\n",
" return first_int * second_int"
]
},
{
"cell_type": "markdown",
"id": "3de233af-b3bd-4f0c-8b1a-83527143a8db",
"metadata": {},
"source": [
"And now we can add to it a `exponentiate` and `add` tool:"
]
},
{
"cell_type": "code",
"execution_count": 4,
"id": "e93661cd-a2ba-4ada-91ad-baf1b60879ec",
"metadata": {},
"outputs": [],
"source": [
"@tool\n",
"def add(first_int: int, second_int: int) -> int:\n",
" \"Add two integers.\"\n",
" return first_int + second_int\n",
"\n",
"\n",
"@tool\n",
"def exponentiate(base: int, exponent: int) -> int:\n",
" \"Exponentiate the base to the exponent power.\"\n",
" return base**exponent"
]
},
{
"cell_type": "markdown",
"id": "bbea4555-ed10-4a18-b802-e9a3071f132b",
"metadata": {},
"source": [
"The main difference between using one Tool and many, is that in the case of many we can't be sure which Tool the model will invoke. So we cannot hardcode, like we did in the [Quickstart](/docs/use_cases/tool_use/quickstart), a specific tool into our chain. Instead we'll add `call_tool_list`, a `RunnableLambda` that takes the `JsonOutputToolsParser` output and actually builds the end of the chain based on it, meaning it appends the Tools that were envoked to the end of the chain at runtime. We can do this because LCEL has the cool property that in any Runnable (the core building block of LCEL) sequence, if one component returns more Runnables, those are run as part of the chain."
]
},
{
"cell_type": "code",
"execution_count": 13,
"id": "c35359ae-a740-48c5-b5e7-1a377fb25aa2",
"metadata": {},
"outputs": [],
"source": [
"from operator import itemgetter\n",
"from typing import Union\n",
"\n",
"from langchain.output_parsers import JsonOutputToolsParser\n",
"from langchain_community.tools.convert_to_openai import (\n",
" format_tool_to_openai_tool,\n",
")\n",
"from langchain_core.runnables import (\n",
" Runnable,\n",
" RunnableLambda,\n",
" RunnableMap,\n",
" RunnablePassthrough,\n",
")\n",
"from langchain_openai import ChatOpenAI\n",
"\n",
"model = ChatOpenAI(model=\"gpt-3.5-turbo\")\n",
"tools = [multiply, exponentiate, add]\n",
"model_with_tools = model.bind(tools=[format_tool_to_openai_tool(t) for t in tools])\n",
"tool_map = {tool.name: tool for tool in tools}\n",
"\n",
"\n",
"def call_tool(tool_invocation: dict) -> Union[str, Runnable]:\n",
" \"\"\"Function for dynamically constructing the end of the chain based on the model-selected tool.\"\"\"\n",
" tool = tool_map[tool_invocation[\"type\"]]\n",
" return RunnablePassthrough.assign(output=itemgetter(\"args\") | tool)\n",
"\n",
"\n",
"# .map() allows us to apply a function to a list of inputs.\n",
"call_tool_list = RunnableLambda(call_tool).map()\n",
"chain = model_with_tools | JsonOutputToolsParser() | call_tool_list"
]
},
{
"cell_type": "code",
"execution_count": 14,
"id": "ea6dbb32-ec9b-4c70-a90f-a2db93978cf1",
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"[{'type': 'multiply',\n",
" 'args': {'first_int': 23, 'second_int': 7},\n",
" 'output': 161}]"
]
},
"execution_count": 14,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"chain.invoke(\"What's 23 times 7\")"
]
},
{
"cell_type": "code",
"execution_count": 15,
"id": "b1c6c0f8-6d04-40d4-a40e-8719ca7b27c2",
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"[{'type': 'add',\n",
" 'args': {'first_int': 1000000, 'second_int': 1000000000},\n",
" 'output': 1001000000}]"
]
},
"execution_count": 15,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"chain.invoke(\"add a million plus a billion\")"
]
},
{
"cell_type": "code",
"execution_count": 16,
"id": "ce76f299-1a4d-421c-afa4-a6346e34285c",
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"[{'type': 'exponentiate',\n",
" 'args': {'base': 37, 'exponent': 3},\n",
" 'output': 50653}]"
]
},
"execution_count": 16,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"chain.invoke(\"cube thirty-seven\")"
]
}
],
"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
}

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