mirror of
https://github.com/hwchase17/langchain.git
synced 2026-02-04 08:10:25 +00:00
Compare commits
414 Commits
harrison/n
...
wip-v1.0
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
80a091b9fc | ||
|
|
d7cce2f469 | ||
|
|
2b0c1da2cb | ||
|
|
b2188aeb7b | ||
|
|
bea249beff | ||
|
|
2d29959386 | ||
|
|
48b77752d0 | ||
|
|
6f2d16e6be | ||
|
|
a9eda18e1e | ||
|
|
a89c549cb0 | ||
|
|
a336afaecd | ||
|
|
bb9b802cda | ||
|
|
4ff83e92c1 | ||
|
|
738dc79959 | ||
|
|
9ad7f7a0cc | ||
|
|
af07949d13 | ||
|
|
a10e880c00 | ||
|
|
7b5e839be3 | ||
|
|
fa0955ccb1 | ||
|
|
e02acdfe60 | ||
|
|
740842485c | ||
|
|
08bb74f148 | ||
|
|
7d78ed9b53 | ||
|
|
7ccff656eb | ||
|
|
002d623f2d | ||
|
|
34f8031bd9 | ||
|
|
87e1bbf3b1 | ||
|
|
e8f76e506f | ||
|
|
a541b5bee1 | ||
|
|
3e970506ba | ||
|
|
d1b0196faa | ||
|
|
aac69839a9 | ||
|
|
64141072a3 | ||
|
|
c49d470e13 | ||
|
|
208e8e8f07 | ||
|
|
0795be2a04 | ||
|
|
06301c701e | ||
|
|
9c97597175 | ||
|
|
b7223f45cc | ||
|
|
8ba8a5e301 | ||
|
|
16a2d9759b | ||
|
|
0e404adc60 | ||
|
|
ffaedf7cfc | ||
|
|
b6ecc0b040 | ||
|
|
4d581000ad | ||
|
|
06ddc57c7a | ||
|
|
49704ffc19 | ||
|
|
eed0f6c289 | ||
|
|
8926986483 | ||
|
|
729637a347 | ||
|
|
3325196be1 | ||
|
|
f402fdcea3 | ||
|
|
ca9217c02d | ||
|
|
f9bae40475 | ||
|
|
7f757cf37d | ||
|
|
c20bd07f16 | ||
|
|
839a18e112 | ||
|
|
33a6def762 | ||
|
|
c456c8ae51 | ||
|
|
8f60946d5a | ||
|
|
790c4a8e43 | ||
|
|
b83d45bff7 | ||
|
|
ba663defc2 | ||
|
|
0633974eb0 | ||
|
|
4d39cf39ff | ||
|
|
77e52a6c9c | ||
|
|
2af1cb6ca3 | ||
|
|
54f3a6d9cf | ||
|
|
54ea62050b | ||
|
|
87e5be1097 | ||
|
|
fcd8fdd748 | ||
|
|
370010d195 | ||
|
|
986302322f | ||
|
|
adc941d1dc | ||
|
|
d15514d571 | ||
|
|
a5137b0a3e | ||
|
|
5bea28393d | ||
|
|
c3fed20940 | ||
|
|
6d418ba983 | ||
|
|
12daba63ff | ||
|
|
eaf8dce7c2 | ||
|
|
ee94f9567a | ||
|
|
f82de1a8d7 | ||
|
|
f3f5b93be6 | ||
|
|
e3efd1e891 | ||
|
|
d6769cf032 | ||
|
|
00565d7bf6 | ||
|
|
7ab2e0dd3b | ||
|
|
81319ad3f0 | ||
|
|
e3f3c13b75 | ||
|
|
c30844fce4 | ||
|
|
c9eb3bdb2d | ||
|
|
e97baeb9a6 | ||
|
|
3a6046b157 | ||
|
|
8fdc619f75 | ||
|
|
729bfe8369 | ||
|
|
9b624a79b2 | ||
|
|
c60c5a91cb | ||
|
|
d9e0c212e0 | ||
|
|
2f93566c87 | ||
|
|
db8c2d3bae | ||
|
|
f015526e42 | ||
|
|
57d931532f | ||
|
|
3515a54c10 | ||
|
|
50012d95e2 | ||
|
|
33f06875cb | ||
|
|
e5730307e7 | ||
|
|
ccfdce64d3 | ||
|
|
4ca523a9d6 | ||
|
|
4783a9c18e | ||
|
|
ee4d84de7c | ||
|
|
092dd5e174 | ||
|
|
a4e1a54393 | ||
|
|
dd81e1c3fb | ||
|
|
135a5b97e6 | ||
|
|
b92b394804 | ||
|
|
083bb3cdd7 | ||
|
|
2e9291cdd7 | ||
|
|
4f8a76b571 | ||
|
|
05ba941230 | ||
|
|
ae4976896e | ||
|
|
e7cdaad58f | ||
|
|
504ef96500 | ||
|
|
d99a02bb27 | ||
|
|
793de80429 | ||
|
|
7d4e9d8cda | ||
|
|
54dca494cf | ||
|
|
7b30e58386 | ||
|
|
e62b541dfd | ||
|
|
8699980d09 | ||
|
|
79e536b0d6 | ||
|
|
b5720ff17a | ||
|
|
48b05224ad | ||
|
|
89079ad411 | ||
|
|
2c95586f2a | ||
|
|
36f8c7335c | ||
|
|
f6cf4fcd6e | ||
|
|
9c1285cf5b | ||
|
|
c3be45bf14 | ||
|
|
cfa9973828 | ||
|
|
8f488d62b2 | ||
|
|
cdae9e4942 | ||
|
|
e75878bfa2 | ||
|
|
7ddc798f95 | ||
|
|
6081ba9184 | ||
|
|
0cc6f8bb58 | ||
|
|
7dcf6a515e | ||
|
|
043a7560a5 | ||
|
|
6c90ba1f05 | ||
|
|
ea3b9695e6 | ||
|
|
5b418d3f26 | ||
|
|
6b4054c795 | ||
|
|
30fde5af38 | ||
|
|
781db9d892 | ||
|
|
f2b0afd0b7 | ||
|
|
c3654202a3 | ||
|
|
fa4c302463 | ||
|
|
4d118777bc | ||
|
|
b215ed5642 | ||
|
|
c891a51608 | ||
|
|
82650ea7f1 | ||
|
|
13964efccf | ||
|
|
f247270111 | ||
|
|
8be4adccd1 | ||
|
|
b6bd507198 | ||
|
|
f158cea1e8 | ||
|
|
3e0d7512ef | ||
|
|
53ed770849 | ||
|
|
e2050e24ef | ||
|
|
90280d1f58 | ||
|
|
ee340e0a3b | ||
|
|
d5ba5d3511 | ||
|
|
76d0758007 | ||
|
|
8b3f74012c | ||
|
|
59bb8bffd1 | ||
|
|
16ec9bc535 | ||
|
|
fda8a71e19 | ||
|
|
8f23bd109b | ||
|
|
ff632c1028 | ||
|
|
3f71efc93c | ||
|
|
cb3b5bf69b | ||
|
|
1c8a01ed03 | ||
|
|
25333d3b45 | ||
|
|
54a9556f5c | ||
|
|
42830208f3 | ||
|
|
66041a2778 | ||
|
|
ab1b822523 | ||
|
|
543d90e108 | ||
|
|
f8640630d8 | ||
|
|
653dc77c7e | ||
|
|
f9605c7438 | ||
|
|
ebd6f7d8a3 | ||
|
|
f6ab75ba8b | ||
|
|
e63c1d7171 | ||
|
|
b6af0d228c | ||
|
|
5800721fd4 | ||
|
|
ebfb938a68 | ||
|
|
1a3e9e06ee | ||
|
|
8180020b93 | ||
|
|
435194acf6 | ||
|
|
c7ebbe5c8a | ||
|
|
244c699551 | ||
|
|
369858de19 | ||
|
|
76dfb7fbe8 | ||
|
|
f25133c523 | ||
|
|
fc7a07d6f1 | ||
|
|
e8ff6f4db6 | ||
|
|
4ebce80fbb | ||
|
|
8670b24c8e | ||
|
|
8d60ddba3a | ||
|
|
9f6431924f | ||
|
|
569a3d9602 | ||
|
|
8ef4df903f | ||
|
|
b944bbc766 | ||
|
|
0be7515abc | ||
|
|
cc9a97a477 | ||
|
|
ee17adb022 | ||
|
|
6a43f140bc | ||
|
|
4619a2727f | ||
|
|
6487a7e2e5 | ||
|
|
406ebc9141 | ||
|
|
e6b5ff213a | ||
|
|
03f0ebd93e | ||
|
|
c9eed530ce | ||
|
|
e6c38a043f | ||
|
|
dc47c2c598 | ||
|
|
3420ca1da2 | ||
|
|
f11dd177e9 | ||
|
|
d5a4abf960 | ||
|
|
b1497bcea1 | ||
|
|
b88115f6fc | ||
|
|
84f9824cc9 | ||
|
|
0814bfe5ed | ||
|
|
cbaf97ada4 | ||
|
|
dc2da95ac0 | ||
|
|
9e78ff19ab | ||
|
|
67aa37b144 | ||
|
|
649d8a8223 | ||
|
|
9f14714367 | ||
|
|
338d3d2795 | ||
|
|
31f641a11f | ||
|
|
91286b0b27 | ||
|
|
bea72bac3e | ||
|
|
7cc9312979 | ||
|
|
387d0f4edf | ||
|
|
207ea46813 | ||
|
|
15d558ff16 | ||
|
|
9cc85387d1 | ||
|
|
7e5180e2fa | ||
|
|
bbb1b9085d | ||
|
|
ff9f17bc66 | ||
|
|
b1f08467cd | ||
|
|
2903e08311 | ||
|
|
115e20a0bc | ||
|
|
0ea945d291 | ||
|
|
5795ec3c4d | ||
|
|
bd765753ca | ||
|
|
5fd7962a78 | ||
|
|
c68796579e | ||
|
|
255ad31955 | ||
|
|
00e992a780 | ||
|
|
83d938593b | ||
|
|
38afeddcb6 | ||
|
|
fca1aaa9b5 | ||
|
|
af17774186 | ||
|
|
d72da29c0b | ||
|
|
653b0908af | ||
|
|
eb77da7de5 | ||
|
|
9c93439a01 | ||
|
|
64fe1e9a80 | ||
|
|
e4a90490c3 | ||
|
|
80776b80f0 | ||
|
|
2c2bab93fc | ||
|
|
221c96e7b4 | ||
|
|
3ef1165c0c | ||
|
|
364465bd11 | ||
|
|
ffee5155b4 | ||
|
|
5ef7d42bf6 | ||
|
|
750a3ffda6 | ||
|
|
7b874da9b2 | ||
|
|
8b1e25461b | ||
|
|
ced9fc270f | ||
|
|
8e213c9f1a | ||
|
|
311aa94d69 | ||
|
|
a8828b1bda | ||
|
|
7a158c7f1c | ||
|
|
cb8598b828 | ||
|
|
25c34bd9b2 | ||
|
|
38001699d5 | ||
|
|
3da0377c02 | ||
|
|
0abf82a45a | ||
|
|
2fed177d0b | ||
|
|
fded6c6b13 | ||
|
|
9c7d262ff4 | ||
|
|
67e651b592 | ||
|
|
f08dfb6f49 | ||
|
|
450870c9ac | ||
|
|
10dfeea110 | ||
|
|
34ecb92178 | ||
|
|
49b3918c26 | ||
|
|
12921a94c5 | ||
|
|
181bb91ce0 | ||
|
|
b274416441 | ||
|
|
544b08d610 | ||
|
|
389a781aa0 | ||
|
|
443f0ccb0e | ||
|
|
00e547c311 | ||
|
|
a48ace52ad | ||
|
|
d464d3089b | ||
|
|
f1d44d0f9d | ||
|
|
20979d525c | ||
|
|
a35ee49f37 | ||
|
|
352ff363ca | ||
|
|
256a0b5f2f | ||
|
|
937087a29c | ||
|
|
08bf4c321f | ||
|
|
4c6af2d1b2 | ||
|
|
ee268db1c5 | ||
|
|
dcc517b187 | ||
|
|
c124e67325 | ||
|
|
699a5d06d1 | ||
|
|
00f699c60d | ||
|
|
e36e25fe2f | ||
|
|
cc3b5afe52 | ||
|
|
428c2ee6c5 | ||
|
|
714f74a847 | ||
|
|
c3b28c769a | ||
|
|
017348b27c | ||
|
|
1e101ae9a2 | ||
|
|
fe6c415c9f | ||
|
|
188c0154b3 | ||
|
|
3c189f0393 | ||
|
|
54c2419a4e | ||
|
|
35e9d36b0e | ||
|
|
8b90eae455 | ||
|
|
05d14775f2 | ||
|
|
33c7f230e0 | ||
|
|
97dd7628d2 | ||
|
|
f5bd00d1f1 | ||
|
|
3486d6c74d | ||
|
|
8509efa6ad | ||
|
|
b1a105f85f | ||
|
|
9e54c5fa7f | ||
|
|
0b8817c900 | ||
|
|
390606c155 | ||
|
|
cc98fb9bee | ||
|
|
16420cad71 | ||
|
|
01fdeede50 | ||
|
|
f4e83e0ad8 | ||
|
|
4024d47412 | ||
|
|
083fbfb0d1 | ||
|
|
f589168411 | ||
|
|
5840dad40b | ||
|
|
e3b6c9bb66 | ||
|
|
c672590f42 | ||
|
|
323729915a | ||
|
|
0c3e8ccd0e | ||
|
|
20401df25d | ||
|
|
e0aaaccb61 | ||
|
|
9368ce6b07 | ||
|
|
f8bcc98362 | ||
|
|
d8d93882f9 | ||
|
|
228fbac3a6 | ||
|
|
6ea06ca972 | ||
|
|
5b0a55ad35 | ||
|
|
6e2f46d04c | ||
|
|
5bf0b218c8 | ||
|
|
4e39c164bb | ||
|
|
0b3af47335 | ||
|
|
bc91a4811c | ||
|
|
f98f7359d3 | ||
|
|
50b48fa1ff | ||
|
|
a54f4385f8 | ||
|
|
98e4e7d043 | ||
|
|
2cf5c52c13 | ||
|
|
bf41a75073 | ||
|
|
e15c41233d | ||
|
|
25d5db88d5 | ||
|
|
1237f94633 | ||
|
|
5c8837ea5a | ||
|
|
820e355f53 | ||
|
|
9a3ba71636 | ||
|
|
00def6da72 | ||
|
|
4f8cced3b6 | ||
|
|
365d7c414b | ||
|
|
a4874123a0 | ||
|
|
a5f92fdd9a | ||
|
|
431e6d6211 | ||
|
|
0f1afa178e | ||
|
|
830d1a207c | ||
|
|
b494a3c57b | ||
|
|
f088fac492 | ||
|
|
925ad65df9 | ||
|
|
e09d90b627 | ||
|
|
ddde1eff68 | ||
|
|
9b576440ed | ||
|
|
a80fa1b25f | ||
|
|
72b66fcca5 | ||
|
|
a47d993ddd | ||
|
|
cb4705dfc0 | ||
|
|
9a9263a2dd | ||
|
|
e4b69db4cf | ||
|
|
242881562b | ||
|
|
a2322f68ba | ||
|
|
7e9ae5df60 | ||
|
|
7a108618ae | ||
|
|
6f058e7b9b | ||
|
|
dbc5a3b718 | ||
|
|
f0f1e28473 | ||
|
|
8bd2403518 | ||
|
|
4dd9110424 | ||
|
|
174e685139 | ||
|
|
9721684501 | ||
|
|
a4e135b508 |
6
.github/CONTRIBUTING.md
vendored
6
.github/CONTRIBUTING.md
vendored
@@ -3,8 +3,4 @@
|
||||
Hi there! Thank you for even being interested in contributing to LangChain.
|
||||
As an open-source project in a rapidly developing field, we are extremely open to contributions, whether they involve new features, improved infrastructure, better documentation, or bug fixes.
|
||||
|
||||
To learn how to contribute to LangChain, please follow the [contribution guide here](https://python.langchain.com/docs/contributing/).
|
||||
|
||||
## New features
|
||||
|
||||
For new features, please start a new [discussion on our forum](https://forum.langchain.com/), where the maintainers will help with scoping out the necessary changes.
|
||||
To learn how to contribute to LangChain, please follow the [contribution guide here](https://docs.langchain.com/oss/python/contributing).
|
||||
|
||||
9
.github/ISSUE_TEMPLATE/bug-report.yml
vendored
9
.github/ISSUE_TEMPLATE/bug-report.yml
vendored
@@ -1,6 +1,7 @@
|
||||
name: "\U0001F41B Bug Report"
|
||||
description: Report a bug in LangChain. To report a security issue, please instead use the security option below. For questions, please use the LangChain forum.
|
||||
labels: ["bug"]
|
||||
type: bug
|
||||
body:
|
||||
- type: markdown
|
||||
attributes:
|
||||
@@ -13,9 +14,7 @@ body:
|
||||
if there's another way to solve your problem:
|
||||
|
||||
* [LangChain Forum](https://forum.langchain.com/),
|
||||
* [LangChain Github Issues](https://github.com/langchain-ai/langchain/issues?q=is%3Aissue),
|
||||
* [LangChain documentation with the integrated search](https://python.langchain.com/docs/get_started/introduction),
|
||||
* [LangChain how-to guides](https://python.langchain.com/docs/how_to/),
|
||||
* [LangChain documentation with the integrated search](https://docs.langchain.com/oss/python/langchain/overview),
|
||||
* [API Reference](https://python.langchain.com/api_reference/),
|
||||
* [LangChain ChatBot](https://chat.langchain.com/)
|
||||
* [GitHub search](https://github.com/langchain-ai/langchain),
|
||||
@@ -25,7 +24,7 @@ body:
|
||||
label: Checked other resources
|
||||
description: Please confirm and check all the following options.
|
||||
options:
|
||||
- label: This is a bug, not a usage question. For questions, please use the LangChain Forum (https://forum.langchain.com/).
|
||||
- label: This is a bug, not a usage question.
|
||||
required: true
|
||||
- label: I added a clear and descriptive title that summarizes this issue.
|
||||
required: true
|
||||
@@ -35,6 +34,8 @@ body:
|
||||
required: true
|
||||
- label: The bug is not resolved by updating to the latest stable version of LangChain (or the specific integration package).
|
||||
required: true
|
||||
- label: This is not related to the langchain-community package.
|
||||
required: true
|
||||
- label: I read what a minimal reproducible example is (https://stackoverflow.com/help/minimal-reproducible-example).
|
||||
required: true
|
||||
- label: I posted a self-contained, minimal, reproducible example. A maintainer can copy it and run it AS IS.
|
||||
|
||||
9
.github/ISSUE_TEMPLATE/config.yml
vendored
9
.github/ISSUE_TEMPLATE/config.yml
vendored
@@ -1,6 +1,9 @@
|
||||
blank_issues_enabled: false
|
||||
version: 2.1
|
||||
contact_links:
|
||||
- name: LangChain Forum
|
||||
url: https://forum.langchain.com/
|
||||
about: General community discussions, support, and feature requests
|
||||
- name: 📚 Documentation
|
||||
url: https://github.com/langchain-ai/docs/issues/new?template=langchain.yml
|
||||
about: Report an issue related to the LangChain documentation
|
||||
- name: 💬 LangChain Forum
|
||||
url: https://forum.langchain.com/
|
||||
about: General community discussions and support
|
||||
|
||||
59
.github/ISSUE_TEMPLATE/documentation.yml
vendored
59
.github/ISSUE_TEMPLATE/documentation.yml
vendored
@@ -1,59 +0,0 @@
|
||||
name: Documentation
|
||||
description: Report an issue related to the LangChain documentation.
|
||||
title: "docs: <Please write a comprehensive title after the 'docs: ' prefix>"
|
||||
labels: [documentation]
|
||||
|
||||
body:
|
||||
- type: markdown
|
||||
attributes:
|
||||
value: |
|
||||
Thank you for taking the time to report an issue in the documentation.
|
||||
|
||||
Only report issues with documentation here, explain if there are
|
||||
any missing topics or if you found a mistake in the documentation.
|
||||
|
||||
Do **NOT** use this to ask usage questions or reporting issues with your code.
|
||||
|
||||
If you have usage questions or need help solving some problem,
|
||||
please use the [LangChain Forum](https://forum.langchain.com/).
|
||||
|
||||
If you're in the wrong place, here are some helpful links to find a better
|
||||
place to ask your question:
|
||||
|
||||
* [LangChain Forum](https://forum.langchain.com/),
|
||||
* [LangChain Github Issues](https://github.com/langchain-ai/langchain/issues?q=is%3Aissue),
|
||||
* [LangChain documentation with the integrated search](https://python.langchain.com/docs/get_started/introduction),
|
||||
* [LangChain how-to guides](https://python.langchain.com/docs/how_to/),
|
||||
* [API Reference](https://python.langchain.com/api_reference/),
|
||||
* [LangChain ChatBot](https://chat.langchain.com/)
|
||||
* [GitHub search](https://github.com/langchain-ai/langchain),
|
||||
- type: input
|
||||
id: url
|
||||
attributes:
|
||||
label: URL
|
||||
description: URL to documentation
|
||||
validations:
|
||||
required: false
|
||||
- type: checkboxes
|
||||
id: checks
|
||||
attributes:
|
||||
label: Checklist
|
||||
description: Please confirm and check all the following options.
|
||||
options:
|
||||
- label: I added a very descriptive title to this issue.
|
||||
required: true
|
||||
- label: I included a link to the documentation page I am referring to (if applicable).
|
||||
required: true
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: "Issue with current documentation:"
|
||||
description: >
|
||||
Please make sure to leave a reference to the document/code you're
|
||||
referring to. Feel free to include names of classes, functions, methods
|
||||
or concepts you'd like to see documented more.
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: "Idea or request for content:"
|
||||
description: >
|
||||
Please describe as clearly as possible what topics you think are missing
|
||||
from the current documentation.
|
||||
118
.github/ISSUE_TEMPLATE/feature-request.yml
vendored
Normal file
118
.github/ISSUE_TEMPLATE/feature-request.yml
vendored
Normal file
@@ -0,0 +1,118 @@
|
||||
name: "✨ Feature Request"
|
||||
description: Request a new feature or enhancement for LangChain. For questions, please use the LangChain forum.
|
||||
labels: ["feature request"]
|
||||
type: feature
|
||||
body:
|
||||
- type: markdown
|
||||
attributes:
|
||||
value: |
|
||||
Thank you for taking the time to request a new feature.
|
||||
|
||||
Use this to request NEW FEATURES or ENHANCEMENTS in LangChain. For bug reports, please use the bug report template. For usage questions and general design questions, please use the [LangChain Forum](https://forum.langchain.com/).
|
||||
|
||||
Relevant links to check before filing a feature request to see if your request has already been made or
|
||||
if there's another way to achieve what you want:
|
||||
|
||||
* [LangChain Forum](https://forum.langchain.com/),
|
||||
* [LangChain documentation with the integrated search](https://docs.langchain.com/oss/python/langchain/overview),
|
||||
* [API Reference](https://python.langchain.com/api_reference/),
|
||||
* [LangChain ChatBot](https://chat.langchain.com/)
|
||||
* [GitHub search](https://github.com/langchain-ai/langchain),
|
||||
- type: checkboxes
|
||||
id: checks
|
||||
attributes:
|
||||
label: Checked other resources
|
||||
description: Please confirm and check all the following options.
|
||||
options:
|
||||
- label: This is a feature request, not a bug report or usage question.
|
||||
required: true
|
||||
- label: I added a clear and descriptive title that summarizes the feature request.
|
||||
required: true
|
||||
- label: I used the GitHub search to find a similar feature request and didn't find it.
|
||||
required: true
|
||||
- label: I checked the LangChain documentation and API reference to see if this feature already exists.
|
||||
required: true
|
||||
- label: This is not related to the langchain-community package.
|
||||
required: true
|
||||
- type: textarea
|
||||
id: feature-description
|
||||
validations:
|
||||
required: true
|
||||
attributes:
|
||||
label: Feature Description
|
||||
description: |
|
||||
Please provide a clear and concise description of the feature you would like to see added to LangChain.
|
||||
|
||||
What specific functionality are you requesting? Be as detailed as possible.
|
||||
placeholder: |
|
||||
I would like LangChain to support...
|
||||
|
||||
This feature would allow users to...
|
||||
- type: textarea
|
||||
id: use-case
|
||||
validations:
|
||||
required: true
|
||||
attributes:
|
||||
label: Use Case
|
||||
description: |
|
||||
Describe the specific use case or problem this feature would solve.
|
||||
|
||||
Why do you need this feature? What problem does it solve for you or other users?
|
||||
placeholder: |
|
||||
I'm trying to build an application that...
|
||||
|
||||
Currently, I have to work around this by...
|
||||
|
||||
This feature would help me/users to...
|
||||
- type: textarea
|
||||
id: proposed-solution
|
||||
validations:
|
||||
required: false
|
||||
attributes:
|
||||
label: Proposed Solution
|
||||
description: |
|
||||
If you have ideas about how this feature could be implemented, please describe them here.
|
||||
|
||||
This is optional but can be helpful for maintainers to understand your vision.
|
||||
placeholder: |
|
||||
I think this could be implemented by...
|
||||
|
||||
The API could look like...
|
||||
|
||||
```python
|
||||
# Example of how the feature might work
|
||||
```
|
||||
- type: textarea
|
||||
id: alternatives
|
||||
validations:
|
||||
required: false
|
||||
attributes:
|
||||
label: Alternatives Considered
|
||||
description: |
|
||||
Have you considered any alternative solutions or workarounds?
|
||||
|
||||
What other approaches have you tried or considered?
|
||||
placeholder: |
|
||||
I've tried using...
|
||||
|
||||
Alternative approaches I considered:
|
||||
1. ...
|
||||
2. ...
|
||||
|
||||
But these don't work because...
|
||||
- type: textarea
|
||||
id: additional-context
|
||||
validations:
|
||||
required: false
|
||||
attributes:
|
||||
label: Additional Context
|
||||
description: |
|
||||
Add any other context, screenshots, examples, or references that would help explain your feature request.
|
||||
placeholder: |
|
||||
Related issues: #...
|
||||
|
||||
Similar features in other libraries:
|
||||
- ...
|
||||
|
||||
Additional context or examples:
|
||||
- ...
|
||||
7
.github/ISSUE_TEMPLATE/privileged.yml
vendored
7
.github/ISSUE_TEMPLATE/privileged.yml
vendored
@@ -4,12 +4,7 @@ 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 on the [LangChain Forum](https://forum.langchain.com/) 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 pull requests.
|
||||
If you are not a LangChain maintainer, employee, or were not asked directly by a maintainer to create an issue, then please start the conversation on the [LangChain Forum](https://forum.langchain.com/) instead.
|
||||
- type: checkboxes
|
||||
id: privileged
|
||||
attributes:
|
||||
|
||||
91
.github/ISSUE_TEMPLATE/task.yml
vendored
Normal file
91
.github/ISSUE_TEMPLATE/task.yml
vendored
Normal file
@@ -0,0 +1,91 @@
|
||||
name: "📋 Task"
|
||||
description: Create a task for project management and tracking by LangChain maintainers. If you are not a maintainer, please use other templates or the forum.
|
||||
labels: ["task"]
|
||||
type: task
|
||||
body:
|
||||
- type: markdown
|
||||
attributes:
|
||||
value: |
|
||||
Thanks for creating a task to help organize LangChain development.
|
||||
|
||||
This template is for **maintainer tasks** such as project management, development planning, refactoring, documentation updates, and other organizational work.
|
||||
|
||||
If you are not a LangChain maintainer or were not asked directly by a maintainer to create a task, then please start the conversation on the [LangChain Forum](https://forum.langchain.com/) instead or use the appropriate bug report or feature request templates on the previous page.
|
||||
- type: checkboxes
|
||||
id: maintainer
|
||||
attributes:
|
||||
label: Maintainer task
|
||||
description: Confirm that you are allowed to create a task here.
|
||||
options:
|
||||
- label: I am a LangChain maintainer, or was asked directly by a LangChain maintainer to create a task here.
|
||||
required: true
|
||||
- type: textarea
|
||||
id: task-description
|
||||
attributes:
|
||||
label: Task Description
|
||||
description: |
|
||||
Provide a clear and detailed description of the task.
|
||||
|
||||
What needs to be done? Be specific about the scope and requirements.
|
||||
placeholder: |
|
||||
This task involves...
|
||||
|
||||
The goal is to...
|
||||
|
||||
Specific requirements:
|
||||
- ...
|
||||
- ...
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
id: acceptance-criteria
|
||||
attributes:
|
||||
label: Acceptance Criteria
|
||||
description: |
|
||||
Define the criteria that must be met for this task to be considered complete.
|
||||
|
||||
What are the specific deliverables or outcomes expected?
|
||||
placeholder: |
|
||||
This task will be complete when:
|
||||
- [ ] ...
|
||||
- [ ] ...
|
||||
- [ ] ...
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
id: context
|
||||
attributes:
|
||||
label: Context and Background
|
||||
description: |
|
||||
Provide any relevant context, background information, or links to related issues/PRs.
|
||||
|
||||
Why is this task needed? What problem does it solve?
|
||||
placeholder: |
|
||||
Background:
|
||||
- ...
|
||||
|
||||
Related issues/PRs:
|
||||
- #...
|
||||
|
||||
Additional context:
|
||||
- ...
|
||||
validations:
|
||||
required: false
|
||||
- type: textarea
|
||||
id: dependencies
|
||||
attributes:
|
||||
label: Dependencies
|
||||
description: |
|
||||
List any dependencies or blockers for this task.
|
||||
|
||||
Are there other tasks, issues, or external factors that need to be completed first?
|
||||
placeholder: |
|
||||
This task depends on:
|
||||
- [ ] Issue #...
|
||||
- [ ] PR #...
|
||||
- [ ] External dependency: ...
|
||||
|
||||
Blocked by:
|
||||
- ...
|
||||
validations:
|
||||
required: false
|
||||
9
.github/PULL_REQUEST_TEMPLATE.md
vendored
9
.github/PULL_REQUEST_TEMPLATE.md
vendored
@@ -1,3 +1,5 @@
|
||||
(Replace this entire block of text)
|
||||
|
||||
Thank you for contributing to LangChain! Follow these steps to mark your pull request as ready for review. **If any of these steps are not completed, your PR will not be considered for review.**
|
||||
|
||||
- [ ] **PR title**: Follows the format: {TYPE}({SCOPE}): {DESCRIPTION}
|
||||
@@ -9,14 +11,13 @@ Thank you for contributing to LangChain! Follow these steps to mark your pull re
|
||||
- feat, fix, docs, style, refactor, perf, test, build, ci, chore, revert, release
|
||||
- Allowed `{SCOPE}` values (optional):
|
||||
- core, cli, langchain, standard-tests, docs, anthropic, chroma, deepseek, exa, fireworks, groq, huggingface, mistralai, nomic, ollama, openai, perplexity, prompty, qdrant, xai
|
||||
- Note: the `{DESCRIPTION}` must not start with an uppercase letter.
|
||||
- *Note:* the `{DESCRIPTION}` must not start with an uppercase letter.
|
||||
- Once you've written the title, please delete this checklist item; do not include it in the PR.
|
||||
|
||||
- [ ] **PR message**: ***Delete this entire checklist*** and replace with
|
||||
- **Description:** a description of the change. Include a [closing keyword](https://docs.github.com/en/issues/tracking-your-work-with-issues/using-issues/linking-a-pull-request-to-an-issue#linking-a-pull-request-to-an-issue-using-a-keyword) if applicable to a relevant issue.
|
||||
- **Issue:** the issue # it fixes, if applicable (e.g. Fixes #123)
|
||||
- **Dependencies:** any dependencies required for this change
|
||||
- **Twitter handle:** if your PR gets announced, and you'd like a mention, we'll gladly shout you out!
|
||||
|
||||
- [ ] **Add tests and docs**: If you're adding a new integration, you must include:
|
||||
1. A test for the integration, preferably unit tests that do not rely on network access,
|
||||
@@ -26,7 +27,7 @@ Thank you for contributing to LangChain! Follow these steps to mark your pull re
|
||||
|
||||
Additional guidelines:
|
||||
|
||||
- Make sure optional dependencies are imported within a function.
|
||||
- Please do not add dependencies to `pyproject.toml` files (even optional ones) unless they are **required** for unit tests.
|
||||
- Most PRs should not touch more than one package.
|
||||
- Please do not add dependencies to `pyproject.toml` files (even optional ones) unless they are **required** for unit tests.
|
||||
- Changes should be backwards compatible.
|
||||
- Make sure optional dependencies are imported within a function.
|
||||
|
||||
2
.github/actions/people/action.yml
vendored
2
.github/actions/people/action.yml
vendored
@@ -1,4 +1,6 @@
|
||||
# Adapted from https://github.com/tiangolo/fastapi/blob/master/.github/actions/people/action.yml
|
||||
# TODO: fix this, migrate to new docs repo?
|
||||
|
||||
name: "Generate LangChain People"
|
||||
description: "Generate the data for the LangChain People page"
|
||||
author: "Jacob Lee <jacob@langchain.dev>"
|
||||
|
||||
24
.github/actions/uv_setup/action.yml
vendored
24
.github/actions/uv_setup/action.yml
vendored
@@ -1,12 +1,24 @@
|
||||
# TODO: https://docs.astral.sh/uv/guides/integration/github/#caching
|
||||
# Helper to set up Python and uv with caching
|
||||
|
||||
name: uv-install
|
||||
description: Set up Python and uv
|
||||
description: Set up Python and uv with caching
|
||||
|
||||
inputs:
|
||||
python-version:
|
||||
description: Python version, supporting MAJOR.MINOR only
|
||||
required: true
|
||||
enable-cache:
|
||||
description: Enable caching for uv dependencies
|
||||
required: false
|
||||
default: "true"
|
||||
cache-suffix:
|
||||
description: Custom cache key suffix for cache invalidation
|
||||
required: false
|
||||
default: ""
|
||||
working-directory:
|
||||
description: Working directory for cache glob scoping
|
||||
required: false
|
||||
default: "**"
|
||||
|
||||
env:
|
||||
UV_VERSION: "0.5.25"
|
||||
@@ -15,7 +27,13 @@ runs:
|
||||
using: composite
|
||||
steps:
|
||||
- name: Install uv and set the python version
|
||||
uses: astral-sh/setup-uv@v5
|
||||
uses: astral-sh/setup-uv@v6
|
||||
with:
|
||||
version: ${{ env.UV_VERSION }}
|
||||
python-version: ${{ inputs.python-version }}
|
||||
enable-cache: ${{ inputs.enable-cache }}
|
||||
cache-dependency-glob: |
|
||||
${{ inputs.working-directory }}/pyproject.toml
|
||||
${{ inputs.working-directory }}/uv.lock
|
||||
${{ inputs.working-directory }}/requirements*.txt
|
||||
cache-suffix: ${{ inputs.cache-suffix }}
|
||||
|
||||
80
.github/pr-file-labeler.yml
vendored
Normal file
80
.github/pr-file-labeler.yml
vendored
Normal file
@@ -0,0 +1,80 @@
|
||||
# Label PRs (config)
|
||||
# Automatically applies labels based on changed files and branch patterns
|
||||
|
||||
# Core packages
|
||||
core:
|
||||
- changed-files:
|
||||
- any-glob-to-any-file:
|
||||
- "libs/core/**/*"
|
||||
|
||||
langchain:
|
||||
- changed-files:
|
||||
- any-glob-to-any-file:
|
||||
- "libs/langchain/**/*"
|
||||
- "libs/langchain_v1/**/*"
|
||||
|
||||
v1:
|
||||
- changed-files:
|
||||
- any-glob-to-any-file:
|
||||
- "libs/langchain_v1/**/*"
|
||||
|
||||
cli:
|
||||
- changed-files:
|
||||
- any-glob-to-any-file:
|
||||
- "libs/cli/**/*"
|
||||
|
||||
standard-tests:
|
||||
- changed-files:
|
||||
- any-glob-to-any-file:
|
||||
- "libs/standard-tests/**/*"
|
||||
|
||||
# Partner integrations
|
||||
integration:
|
||||
- changed-files:
|
||||
- any-glob-to-any-file:
|
||||
- "libs/partners/**/*"
|
||||
|
||||
# Infrastructure and DevOps
|
||||
infra:
|
||||
- changed-files:
|
||||
- any-glob-to-any-file:
|
||||
- ".github/**/*"
|
||||
- "Makefile"
|
||||
- ".pre-commit-config.yaml"
|
||||
- "scripts/**/*"
|
||||
- "docker/**/*"
|
||||
- "Dockerfile*"
|
||||
|
||||
github_actions:
|
||||
- changed-files:
|
||||
- any-glob-to-any-file:
|
||||
- ".github/workflows/**/*"
|
||||
- ".github/actions/**/*"
|
||||
|
||||
dependencies:
|
||||
- changed-files:
|
||||
- any-glob-to-any-file:
|
||||
- "**/pyproject.toml"
|
||||
- "uv.lock"
|
||||
- "**/requirements*.txt"
|
||||
- "**/poetry.lock"
|
||||
|
||||
# Documentation
|
||||
documentation:
|
||||
- changed-files:
|
||||
- any-glob-to-any-file:
|
||||
- "docs/**/*"
|
||||
- "**/*.md"
|
||||
- "**/*.rst"
|
||||
- "**/README*"
|
||||
|
||||
# Security related changes
|
||||
security:
|
||||
- changed-files:
|
||||
- any-glob-to-any-file:
|
||||
- "**/*security*"
|
||||
- "**/*auth*"
|
||||
- "**/*credential*"
|
||||
- "**/*secret*"
|
||||
- "**/*token*"
|
||||
- ".github/workflows/security*"
|
||||
41
.github/pr-title-labeler.yml
vendored
Normal file
41
.github/pr-title-labeler.yml
vendored
Normal file
@@ -0,0 +1,41 @@
|
||||
# PR title labeler config
|
||||
#
|
||||
# Labels PRs based on conventional commit patterns in titles
|
||||
#
|
||||
# Format: type(scope): description or type!: description (breaking)
|
||||
|
||||
add-missing-labels: true
|
||||
clear-prexisting: false
|
||||
include-commits: false
|
||||
include-title: true
|
||||
label-for-breaking-changes: breaking
|
||||
|
||||
label-mapping:
|
||||
documentation: ["docs"]
|
||||
feature: ["feat"]
|
||||
fix: ["fix"]
|
||||
infra: ["build", "ci", "chore"]
|
||||
integration:
|
||||
[
|
||||
"anthropic",
|
||||
"chroma",
|
||||
"deepseek",
|
||||
"exa",
|
||||
"fireworks",
|
||||
"groq",
|
||||
"huggingface",
|
||||
"mistralai",
|
||||
"nomic",
|
||||
"ollama",
|
||||
"openai",
|
||||
"perplexity",
|
||||
"prompty",
|
||||
"qdrant",
|
||||
"xai",
|
||||
]
|
||||
linting: ["style"]
|
||||
performance: ["perf"]
|
||||
refactor: ["refactor"]
|
||||
release: ["release"]
|
||||
revert: ["revert"]
|
||||
tests: ["test"]
|
||||
38
.github/scripts/check_diff.py
vendored
38
.github/scripts/check_diff.py
vendored
@@ -1,3 +1,18 @@
|
||||
"""Analyze git diffs to determine which directories need to be tested.
|
||||
|
||||
Intelligently determines which LangChain packages and directories need to be tested,
|
||||
linted, or built based on the changes. Handles dependency relationships between
|
||||
packages, maps file changes to appropriate CI job configurations, and outputs JSON
|
||||
configurations for GitHub Actions.
|
||||
|
||||
- Maps changed files to affected package directories (libs/core, libs/partners/*, etc.)
|
||||
- Builds dependency graph to include dependent packages when core components change
|
||||
- Generates test matrix configurations with appropriate Python versions
|
||||
- Handles special cases for Pydantic version testing and performance benchmarks
|
||||
|
||||
Used as part of the check_diffs workflow.
|
||||
"""
|
||||
|
||||
import glob
|
||||
import json
|
||||
import os
|
||||
@@ -17,7 +32,7 @@ LANGCHAIN_DIRS = [
|
||||
"libs/langchain_v1",
|
||||
]
|
||||
|
||||
# when set to True, we are ignoring core dependents
|
||||
# When set to True, we are ignoring core dependents
|
||||
# in order to be able to get CI to pass for each individual
|
||||
# package that depends on core
|
||||
# e.g. if you touch core, we don't then add textsplitters/etc to CI
|
||||
@@ -49,9 +64,9 @@ def all_package_dirs() -> Set[str]:
|
||||
|
||||
|
||||
def dependents_graph() -> dict:
|
||||
"""
|
||||
Construct a mapping of package -> dependents, such that we can
|
||||
run tests on all dependents of a package when a change is made.
|
||||
"""Construct a mapping of package -> dependents
|
||||
|
||||
Done such that we can run tests on all dependents of a package when a change is made.
|
||||
"""
|
||||
dependents = defaultdict(set)
|
||||
|
||||
@@ -121,25 +136,24 @@ def _get_configs_for_single_dir(job: str, dir_: str) -> List[Dict[str, str]]:
|
||||
if job == "codspeed":
|
||||
py_versions = ["3.12"] # 3.13 is not yet supported
|
||||
elif dir_ == "libs/core":
|
||||
py_versions = ["3.9", "3.10", "3.11", "3.12", "3.13"]
|
||||
py_versions = ["3.10", "3.11", "3.12", "3.13"]
|
||||
# custom logic for specific directories
|
||||
elif dir_ == "libs/partners/milvus":
|
||||
# milvus doesn't allow 3.12 because they declare deps in funny way
|
||||
py_versions = ["3.9", "3.11"]
|
||||
|
||||
elif dir_ in PY_312_MAX_PACKAGES:
|
||||
py_versions = ["3.9", "3.12"]
|
||||
py_versions = ["3.10", "3.12"]
|
||||
|
||||
elif dir_ == "libs/langchain" and job == "extended-tests":
|
||||
py_versions = ["3.9", "3.13"]
|
||||
py_versions = ["3.10", "3.13"]
|
||||
elif dir_ == "libs/langchain_v1":
|
||||
py_versions = ["3.10", "3.13"]
|
||||
elif dir_ in {"libs/cli"}:
|
||||
py_versions = ["3.10", "3.13"]
|
||||
|
||||
elif dir_ == ".":
|
||||
# unable to install with 3.13 because tokenizers doesn't support 3.13 yet
|
||||
py_versions = ["3.9", "3.12"]
|
||||
py_versions = ["3.10", "3.12"]
|
||||
else:
|
||||
py_versions = ["3.9", "3.13"]
|
||||
py_versions = ["3.10", "3.13"]
|
||||
|
||||
return [{"working-directory": dir_, "python-version": py_v} for py_v in py_versions]
|
||||
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
"""Check that no dependencies allow prereleases unless we're releasing a prerelease."""
|
||||
|
||||
import sys
|
||||
|
||||
import tomllib
|
||||
@@ -6,15 +8,14 @@ if __name__ == "__main__":
|
||||
# Get the TOML file path from the command line argument
|
||||
toml_file = sys.argv[1]
|
||||
|
||||
# read toml file
|
||||
with open(toml_file, "rb") as file:
|
||||
toml_data = tomllib.load(file)
|
||||
|
||||
# see if we're releasing an rc
|
||||
# See if we're releasing an rc or dev version
|
||||
version = toml_data["project"]["version"]
|
||||
releasing_rc = "rc" in version or "dev" in version
|
||||
|
||||
# if not, iterate through dependencies and make sure none allow prereleases
|
||||
# If not, iterate through dependencies and make sure none allow prereleases
|
||||
if not releasing_rc:
|
||||
dependencies = toml_data["project"]["dependencies"]
|
||||
for dep_version in dependencies:
|
||||
|
||||
45
.github/scripts/get_min_versions.py
vendored
45
.github/scripts/get_min_versions.py
vendored
@@ -1,3 +1,5 @@
|
||||
"""Get minimum versions of dependencies from a pyproject.toml file."""
|
||||
|
||||
import sys
|
||||
from collections import defaultdict
|
||||
from typing import Optional
|
||||
@@ -5,7 +7,7 @@ from typing import Optional
|
||||
if sys.version_info >= (3, 11):
|
||||
import tomllib
|
||||
else:
|
||||
# for python 3.10 and below, which doesnt have stdlib tomllib
|
||||
# For Python 3.10 and below, which doesnt have stdlib tomllib
|
||||
import tomli as tomllib
|
||||
|
||||
import re
|
||||
@@ -34,14 +36,13 @@ SKIP_IF_PULL_REQUEST = [
|
||||
|
||||
|
||||
def get_pypi_versions(package_name: str) -> List[str]:
|
||||
"""
|
||||
Fetch all available versions for a package from PyPI.
|
||||
"""Fetch all available versions for a package from PyPI.
|
||||
|
||||
Args:
|
||||
package_name (str): Name of the package
|
||||
package_name: Name of the package
|
||||
|
||||
Returns:
|
||||
List[str]: List of all available versions
|
||||
List of all available versions
|
||||
|
||||
Raises:
|
||||
requests.exceptions.RequestException: If PyPI API request fails
|
||||
@@ -54,24 +55,23 @@ def get_pypi_versions(package_name: str) -> List[str]:
|
||||
|
||||
|
||||
def get_minimum_version(package_name: str, spec_string: str) -> Optional[str]:
|
||||
"""
|
||||
Find the minimum published version that satisfies the given constraints.
|
||||
"""Find the minimum published version that satisfies the given constraints.
|
||||
|
||||
Args:
|
||||
package_name (str): Name of the package
|
||||
spec_string (str): Version specification string (e.g., ">=0.2.43,<0.4.0,!=0.3.0")
|
||||
package_name: Name of the package
|
||||
spec_string: Version specification string (e.g., ">=0.2.43,<0.4.0,!=0.3.0")
|
||||
|
||||
Returns:
|
||||
Optional[str]: Minimum compatible version or None if no compatible version found
|
||||
Minimum compatible version or None if no compatible version found
|
||||
"""
|
||||
# rewrite occurrences of ^0.0.z to 0.0.z (can be anywhere in constraint string)
|
||||
# Rewrite occurrences of ^0.0.z to 0.0.z (can be anywhere in constraint string)
|
||||
spec_string = re.sub(r"\^0\.0\.(\d+)", r"0.0.\1", spec_string)
|
||||
# rewrite occurrences of ^0.y.z to >=0.y.z,<0.y+1 (can be anywhere in constraint string)
|
||||
# Rewrite occurrences of ^0.y.z to >=0.y.z,<0.y+1 (can be anywhere in constraint string)
|
||||
for y in range(1, 10):
|
||||
spec_string = re.sub(
|
||||
rf"\^0\.{y}\.(\d+)", rf">=0.{y}.\1,<0.{y + 1}", spec_string
|
||||
)
|
||||
# rewrite occurrences of ^x.y.z to >=x.y.z,<x+1.0.0 (can be anywhere in constraint string)
|
||||
# Rewrite occurrences of ^x.y.z to >=x.y.z,<x+1.0.0 (can be anywhere in constraint string)
|
||||
for x in range(1, 10):
|
||||
spec_string = re.sub(
|
||||
rf"\^{x}\.(\d+)\.(\d+)", rf">={x}.\1.\2,<{x + 1}", spec_string
|
||||
@@ -154,22 +154,25 @@ def get_min_version_from_toml(
|
||||
|
||||
|
||||
def check_python_version(version_string, constraint_string):
|
||||
"""
|
||||
Check if the given Python version matches the given constraints.
|
||||
"""Check if the given Python version matches the given constraints.
|
||||
|
||||
:param version_string: A string representing the Python version (e.g. "3.8.5").
|
||||
:param constraint_string: A string representing the package's Python version constraints (e.g. ">=3.6, <4.0").
|
||||
:return: True if the version matches the constraints, False otherwise.
|
||||
Args:
|
||||
version_string: A string representing the Python version (e.g. "3.8.5").
|
||||
constraint_string: A string representing the package's Python version
|
||||
constraints (e.g. ">=3.6, <4.0").
|
||||
|
||||
Returns:
|
||||
True if the version matches the constraints
|
||||
"""
|
||||
|
||||
# rewrite occurrences of ^0.0.z to 0.0.z (can be anywhere in constraint string)
|
||||
# Rewrite occurrences of ^0.0.z to 0.0.z (can be anywhere in constraint string)
|
||||
constraint_string = re.sub(r"\^0\.0\.(\d+)", r"0.0.\1", constraint_string)
|
||||
# rewrite occurrences of ^0.y.z to >=0.y.z,<0.y+1.0 (can be anywhere in constraint string)
|
||||
# Rewrite occurrences of ^0.y.z to >=0.y.z,<0.y+1.0 (can be anywhere in constraint string)
|
||||
for y in range(1, 10):
|
||||
constraint_string = re.sub(
|
||||
rf"\^0\.{y}\.(\d+)", rf">=0.{y}.\1,<0.{y + 1}.0", constraint_string
|
||||
)
|
||||
# rewrite occurrences of ^x.y.z to >=x.y.z,<x+1.0.0 (can be anywhere in constraint string)
|
||||
# Rewrite occurrences of ^x.y.z to >=x.y.z,<x+1.0.0 (can be anywhere in constraint string)
|
||||
for x in range(1, 10):
|
||||
constraint_string = re.sub(
|
||||
rf"\^{x}\.0\.(\d+)", rf">={x}.0.\1,<{x + 1}.0.0", constraint_string
|
||||
|
||||
20
.github/scripts/prep_api_docs_build.py
vendored
20
.github/scripts/prep_api_docs_build.py
vendored
@@ -1,5 +1,8 @@
|
||||
#!/usr/bin/env python
|
||||
"""Script to sync libraries from various repositories into the main langchain repository."""
|
||||
"""Sync libraries from various repositories into this monorepo.
|
||||
|
||||
Moves cloned partner packages into libs/partners structure.
|
||||
"""
|
||||
|
||||
import os
|
||||
import shutil
|
||||
@@ -10,7 +13,7 @@ import yaml
|
||||
|
||||
|
||||
def load_packages_yaml() -> Dict[str, Any]:
|
||||
"""Load and parse the packages.yml file."""
|
||||
"""Load and parse packages.yml."""
|
||||
with open("langchain/libs/packages.yml", "r") as f:
|
||||
return yaml.safe_load(f)
|
||||
|
||||
@@ -61,12 +64,15 @@ def move_libraries(packages: list) -> None:
|
||||
|
||||
|
||||
def main():
|
||||
"""Main function to orchestrate the library sync process."""
|
||||
"""Orchestrate the library sync process."""
|
||||
try:
|
||||
# Load packages configuration
|
||||
package_yaml = load_packages_yaml()
|
||||
|
||||
# Clean target directories
|
||||
# Clean/empty target directories in preparation for moving new ones
|
||||
#
|
||||
# Only for packages in the langchain-ai org or explicitly included via
|
||||
# include_in_api_ref, excluding 'langchain' itself and 'langchain-ai21'
|
||||
clean_target_directories(
|
||||
[
|
||||
p
|
||||
@@ -80,7 +86,9 @@ def main():
|
||||
]
|
||||
)
|
||||
|
||||
# Move libraries to their new locations
|
||||
# Move cloned libraries to their new locations, only for packages in the
|
||||
# langchain-ai org or explicitly included via include_in_api_ref,
|
||||
# excluding 'langchain' itself and 'langchain-ai21'
|
||||
move_libraries(
|
||||
[
|
||||
p
|
||||
@@ -95,7 +103,7 @@ def main():
|
||||
]
|
||||
)
|
||||
|
||||
# Delete ones without a pyproject.toml
|
||||
# Delete partner packages without a pyproject.toml
|
||||
for partner in Path("langchain/libs/partners").iterdir():
|
||||
if partner.is_dir() and not (partner / "pyproject.toml").exists():
|
||||
print(f"Removing {partner} as it does not have a pyproject.toml")
|
||||
|
||||
12
.github/workflows/_compile_integration_test.yml
vendored
12
.github/workflows/_compile_integration_test.yml
vendored
@@ -1,3 +1,11 @@
|
||||
# Validates that a package's integration tests compile without syntax or import errors.
|
||||
#
|
||||
# (If an integration test fails to compile, it won't run.)
|
||||
#
|
||||
# Called as part of check_diffs.yml workflow
|
||||
#
|
||||
# Runs pytest with compile marker to check syntax/imports.
|
||||
|
||||
name: '🔗 Compile Integration Tests'
|
||||
|
||||
on:
|
||||
@@ -27,12 +35,14 @@ jobs:
|
||||
timeout-minutes: 20
|
||||
name: 'Python ${{ inputs.python-version }}'
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/checkout@v5
|
||||
|
||||
- name: '🐍 Set up Python ${{ inputs.python-version }} + UV'
|
||||
uses: "./.github/actions/uv_setup"
|
||||
with:
|
||||
python-version: ${{ inputs.python-version }}
|
||||
cache-suffix: compile-integration-tests-${{ inputs.working-directory }}
|
||||
working-directory: ${{ inputs.working-directory }}
|
||||
|
||||
- name: '📦 Install Integration Dependencies'
|
||||
shell: bash
|
||||
|
||||
13
.github/workflows/_integration_test.yml
vendored
13
.github/workflows/_integration_test.yml
vendored
@@ -1,3 +1,10 @@
|
||||
|
||||
# Runs `make integration_tests` on the specified package.
|
||||
#
|
||||
# Manually triggered via workflow_dispatch for testing with real APIs.
|
||||
#
|
||||
# Installs integration test dependencies and executes full test suite.
|
||||
|
||||
name: '🚀 Integration Tests'
|
||||
run-name: 'Test ${{ inputs.working-directory }} on Python ${{ inputs.python-version }}'
|
||||
|
||||
@@ -28,12 +35,14 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
name: 'Python ${{ inputs.python-version }}'
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/checkout@v5
|
||||
|
||||
- name: '🐍 Set up Python ${{ inputs.python-version }} + UV'
|
||||
uses: "./.github/actions/uv_setup"
|
||||
with:
|
||||
python-version: ${{ inputs.python-version }}
|
||||
cache-suffix: integration-tests-${{ inputs.working-directory }}
|
||||
working-directory: ${{ inputs.working-directory }}
|
||||
|
||||
- name: '📦 Install Integration Dependencies'
|
||||
shell: bash
|
||||
@@ -81,7 +90,7 @@ jobs:
|
||||
run: |
|
||||
make integration_tests
|
||||
|
||||
- name: Ensure the tests did not create any additional files
|
||||
- name: 'Ensure testing did not create/modify files'
|
||||
shell: bash
|
||||
run: |
|
||||
set -eu
|
||||
|
||||
36
.github/workflows/_lint.yml
vendored
36
.github/workflows/_lint.yml
vendored
@@ -1,6 +1,11 @@
|
||||
name: '🧹 Code Linting'
|
||||
# Runs code quality checks using ruff, mypy, and other linting tools
|
||||
# Checks both package code and test code for consistency
|
||||
# Runs linting.
|
||||
#
|
||||
# Uses the package's Makefile to run the checks, specifically the
|
||||
# `lint_package` and `lint_tests` targets.
|
||||
#
|
||||
# Called as part of check_diffs.yml workflow.
|
||||
|
||||
name: '🧹 Linting'
|
||||
|
||||
on:
|
||||
workflow_call:
|
||||
@@ -33,22 +38,16 @@ jobs:
|
||||
timeout-minutes: 20
|
||||
steps:
|
||||
- name: '📋 Checkout Code'
|
||||
uses: actions/checkout@v4
|
||||
uses: actions/checkout@v5
|
||||
|
||||
- name: '🐍 Set up Python ${{ inputs.python-version }} + UV'
|
||||
uses: "./.github/actions/uv_setup"
|
||||
with:
|
||||
python-version: ${{ inputs.python-version }}
|
||||
cache-suffix: lint-${{ inputs.working-directory }}
|
||||
working-directory: ${{ inputs.working-directory }}
|
||||
|
||||
- name: '📦 Install Lint & Typing Dependencies'
|
||||
# Also installs dev/lint/test/typing dependencies, to ensure we have
|
||||
# type hints for as many of our libraries as possible.
|
||||
# This helps catch errors that require dependencies to be spotted, for example:
|
||||
# https://github.com/langchain-ai/langchain/pull/10249/files#diff-935185cd488d015f026dcd9e19616ff62863e8cde8c0bee70318d3ccbca98341
|
||||
#
|
||||
# If you change this configuration, make sure to change the `cache-key`
|
||||
# in the `poetry_setup` action above to stop using the old cache.
|
||||
# It doesn't matter how you change it, any change will cause a cache-bust.
|
||||
working-directory: ${{ inputs.working-directory }}
|
||||
run: |
|
||||
uv sync --group lint --group typing
|
||||
@@ -58,20 +57,13 @@ jobs:
|
||||
run: |
|
||||
make lint_package
|
||||
|
||||
- name: '📦 Install Unit Test Dependencies'
|
||||
# Also installs dev/lint/test/typing dependencies, to ensure we have
|
||||
# type hints for as many of our libraries as possible.
|
||||
# This helps catch errors that require dependencies to be spotted, for example:
|
||||
# https://github.com/langchain-ai/langchain/pull/10249/files#diff-935185cd488d015f026dcd9e19616ff62863e8cde8c0bee70318d3ccbca98341
|
||||
#
|
||||
# If you change this configuration, make sure to change the `cache-key`
|
||||
# in the `poetry_setup` action above to stop using the old cache.
|
||||
# It doesn't matter how you change it, any change will cause a cache-bust.
|
||||
- name: '📦 Install Test Dependencies (non-partners)'
|
||||
# (For directories NOT starting with libs/partners/)
|
||||
if: ${{ ! startsWith(inputs.working-directory, 'libs/partners/') }}
|
||||
working-directory: ${{ inputs.working-directory }}
|
||||
run: |
|
||||
uv sync --inexact --group test
|
||||
- name: '📦 Install Unit + Integration Test Dependencies'
|
||||
- name: '📦 Install Test Dependencies'
|
||||
if: ${{ startsWith(inputs.working-directory, 'libs/partners/') }}
|
||||
working-directory: ${{ inputs.working-directory }}
|
||||
run: |
|
||||
|
||||
84
.github/workflows/_release.yml
vendored
84
.github/workflows/_release.yml
vendored
@@ -1,3 +1,9 @@
|
||||
# Builds and publishes LangChain packages to PyPI.
|
||||
#
|
||||
# Manually triggered, though can be used as a reusable workflow (workflow_call).
|
||||
#
|
||||
# Handles version bumping, building, and publishing to PyPI with authentication.
|
||||
|
||||
name: '🚀 Package Release'
|
||||
run-name: 'Release ${{ inputs.working-directory }} ${{ inputs.release-version }}'
|
||||
on:
|
||||
@@ -43,7 +49,7 @@ jobs:
|
||||
version: ${{ steps.check-version.outputs.version }}
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/checkout@v5
|
||||
|
||||
- name: Set up Python + uv
|
||||
uses: "./.github/actions/uv_setup"
|
||||
@@ -52,8 +58,8 @@ jobs:
|
||||
|
||||
# We want to keep this build stage *separate* from the release stage,
|
||||
# so that there's no sharing of permissions between them.
|
||||
# The release stage has trusted publishing and GitHub repo contents write access,
|
||||
# and we want to keep the scope of that access limited just to the release job.
|
||||
# (Release stage has trusted publishing and GitHub repo contents write access,
|
||||
#
|
||||
# Otherwise, a malicious `build` step (e.g. via a compromised dependency)
|
||||
# could get access to our GitHub or PyPI credentials.
|
||||
#
|
||||
@@ -92,7 +98,7 @@ jobs:
|
||||
outputs:
|
||||
release-body: ${{ steps.generate-release-body.outputs.release-body }}
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/checkout@v5
|
||||
with:
|
||||
repository: langchain-ai/langchain
|
||||
path: langchain
|
||||
@@ -183,13 +189,36 @@ jobs:
|
||||
needs:
|
||||
- build
|
||||
- release-notes
|
||||
uses:
|
||||
./.github/workflows/_test_release.yml
|
||||
permissions: write-all
|
||||
with:
|
||||
working-directory: ${{ inputs.working-directory }}
|
||||
dangerous-nonmaster-release: ${{ inputs.dangerous-nonmaster-release }}
|
||||
secrets: inherit
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
# This permission is used for trusted publishing:
|
||||
# https://blog.pypi.org/posts/2023-04-20-introducing-trusted-publishers/
|
||||
#
|
||||
# Trusted publishing has to also be configured on PyPI for each package:
|
||||
# https://docs.pypi.org/trusted-publishers/adding-a-publisher/
|
||||
id-token: write
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v5
|
||||
|
||||
- uses: actions/download-artifact@v5
|
||||
with:
|
||||
name: dist
|
||||
path: ${{ inputs.working-directory }}/dist/
|
||||
|
||||
- name: Publish to test PyPI
|
||||
uses: pypa/gh-action-pypi-publish@release/v1
|
||||
with:
|
||||
packages-dir: ${{ inputs.working-directory }}/dist/
|
||||
verbose: true
|
||||
print-hash: true
|
||||
repository-url: https://test.pypi.org/legacy/
|
||||
# We overwrite any existing distributions with the same name and version.
|
||||
# This is *only for CI use* and is *extremely dangerous* otherwise!
|
||||
# https://github.com/pypa/gh-action-pypi-publish#tolerating-release-package-file-duplicates
|
||||
skip-existing: true
|
||||
# Temp workaround since attestations are on by default as of gh-action-pypi-publish v1.11.0
|
||||
attestations: false
|
||||
|
||||
pre-release-checks:
|
||||
needs:
|
||||
@@ -199,7 +228,7 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
timeout-minutes: 20
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/checkout@v5
|
||||
|
||||
# We explicitly *don't* set up caching here. This ensures our tests are
|
||||
# maximally sensitive to catching breakage.
|
||||
@@ -265,16 +294,19 @@ jobs:
|
||||
run: |
|
||||
VIRTUAL_ENV=.venv uv pip install dist/*.whl
|
||||
|
||||
- name: Run unit tests
|
||||
run: make tests
|
||||
working-directory: ${{ inputs.working-directory }}
|
||||
|
||||
- name: Check for prerelease versions
|
||||
# Block release if any dependencies allow prerelease versions
|
||||
# (unless this is itself a prerelease version)
|
||||
working-directory: ${{ inputs.working-directory }}
|
||||
run: |
|
||||
uv run python $GITHUB_WORKSPACE/.github/scripts/check_prerelease_dependencies.py pyproject.toml
|
||||
|
||||
- name: Run unit tests
|
||||
run: make tests
|
||||
working-directory: ${{ inputs.working-directory }}
|
||||
|
||||
- name: Get minimum versions
|
||||
# Find the minimum published versions that satisfies the given constraints
|
||||
working-directory: ${{ inputs.working-directory }}
|
||||
id: min-version
|
||||
run: |
|
||||
@@ -289,7 +321,8 @@ jobs:
|
||||
env:
|
||||
MIN_VERSIONS: ${{ steps.min-version.outputs.min-versions }}
|
||||
run: |
|
||||
VIRTUAL_ENV=.venv uv pip install --force-reinstall $MIN_VERSIONS --editable .
|
||||
VIRTUAL_ENV=.venv uv pip install --force-reinstall --editable .
|
||||
VIRTUAL_ENV=.venv uv pip install --force-reinstall $MIN_VERSIONS
|
||||
make tests
|
||||
working-directory: ${{ inputs.working-directory }}
|
||||
|
||||
@@ -298,6 +331,7 @@ jobs:
|
||||
working-directory: ${{ inputs.working-directory }}
|
||||
|
||||
- name: Run integration tests
|
||||
# Uses the Makefile's `integration_tests` target for the specified package
|
||||
if: ${{ startsWith(inputs.working-directory, 'libs/partners/') }}
|
||||
env:
|
||||
AI21_API_KEY: ${{ secrets.AI21_API_KEY }}
|
||||
@@ -338,7 +372,10 @@ jobs:
|
||||
working-directory: ${{ inputs.working-directory }}
|
||||
|
||||
# Test select published packages against new core
|
||||
# Done when code changes are made to langchain-core
|
||||
test-prior-published-packages-against-new-core:
|
||||
# Installs the new core with old partners: Installs the new unreleased core
|
||||
# alongside the previously published partner packages and runs integration tests
|
||||
needs:
|
||||
- build
|
||||
- release-notes
|
||||
@@ -362,10 +399,11 @@ jobs:
|
||||
AZURE_OPENAI_LLM_DEPLOYMENT_NAME: ${{ secrets.AZURE_OPENAI_LLM_DEPLOYMENT_NAME }}
|
||||
AZURE_OPENAI_EMBEDDINGS_DEPLOYMENT_NAME: ${{ secrets.AZURE_OPENAI_EMBEDDINGS_DEPLOYMENT_NAME }}
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/checkout@v5
|
||||
|
||||
# We implement this conditional as Github Actions does not have good support
|
||||
# for conditionally needing steps. https://github.com/actions/runner/issues/491
|
||||
# TODO: this seems to be resolved upstream, so we can probably remove this workaround
|
||||
- name: Check if libs/core
|
||||
run: |
|
||||
if [ "${{ startsWith(inputs.working-directory, 'libs/core') }}" != "true" ]; then
|
||||
@@ -393,7 +431,7 @@ jobs:
|
||||
git ls-remote --tags origin "langchain-${{ matrix.partner }}*" \
|
||||
| awk '{print $2}' \
|
||||
| sed 's|refs/tags/||' \
|
||||
| grep -Ev '==[^=]*(\.?dev[0-9]*|\.?rc[0-9]*)$' \
|
||||
| grep -E '[0-9]+\.[0-9]+\.[0-9]+([a-zA-Z]+[0-9]+)?$' \
|
||||
| sort -Vr \
|
||||
| head -n 1
|
||||
)"
|
||||
@@ -420,6 +458,7 @@ jobs:
|
||||
make integration_tests
|
||||
|
||||
publish:
|
||||
# Publishes the package to PyPI
|
||||
needs:
|
||||
- build
|
||||
- release-notes
|
||||
@@ -440,7 +479,7 @@ jobs:
|
||||
working-directory: ${{ inputs.working-directory }}
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/checkout@v5
|
||||
|
||||
- name: Set up Python + uv
|
||||
uses: "./.github/actions/uv_setup"
|
||||
@@ -462,6 +501,7 @@ jobs:
|
||||
attestations: false
|
||||
|
||||
mark-release:
|
||||
# Marks the GitHub release with the new version tag
|
||||
needs:
|
||||
- build
|
||||
- release-notes
|
||||
@@ -471,7 +511,7 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
# This permission is needed by `ncipollo/release-action` to
|
||||
# create the GitHub release.
|
||||
# create the GitHub release/tag
|
||||
contents: write
|
||||
|
||||
defaults:
|
||||
@@ -479,7 +519,7 @@ jobs:
|
||||
working-directory: ${{ inputs.working-directory }}
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/checkout@v5
|
||||
|
||||
- name: Set up Python + uv
|
||||
uses: "./.github/actions/uv_setup"
|
||||
|
||||
10
.github/workflows/_test.yml
vendored
10
.github/workflows/_test.yml
vendored
@@ -1,6 +1,7 @@
|
||||
name: '🧪 Unit Testing'
|
||||
# Runs unit tests with both current and minimum supported dependency versions
|
||||
# to ensure compatibility across the supported range
|
||||
# to ensure compatibility across the supported range.
|
||||
|
||||
name: '🧪 Unit Testing'
|
||||
|
||||
on:
|
||||
workflow_call:
|
||||
@@ -32,13 +33,16 @@ jobs:
|
||||
name: 'Python ${{ inputs.python-version }}'
|
||||
steps:
|
||||
- name: '📋 Checkout Code'
|
||||
uses: actions/checkout@v4
|
||||
uses: actions/checkout@v5
|
||||
|
||||
- name: '🐍 Set up Python ${{ inputs.python-version }} + UV'
|
||||
uses: "./.github/actions/uv_setup"
|
||||
id: setup-python
|
||||
with:
|
||||
python-version: ${{ inputs.python-version }}
|
||||
cache-suffix: test-${{ inputs.working-directory }}
|
||||
working-directory: ${{ inputs.working-directory }}
|
||||
|
||||
- name: '📦 Install Test Dependencies'
|
||||
shell: bash
|
||||
run: uv sync --group test --dev
|
||||
|
||||
11
.github/workflows/_test_doc_imports.yml
vendored
11
.github/workflows/_test_doc_imports.yml
vendored
@@ -1,3 +1,10 @@
|
||||
# Validates that all import statements in `.ipynb` notebooks are correct and functional.
|
||||
#
|
||||
# Called as part of check_diffs.yml.
|
||||
#
|
||||
# Installs test dependencies and LangChain packages in editable mode and
|
||||
# runs check_imports.py.
|
||||
|
||||
name: '📑 Documentation Import Testing'
|
||||
|
||||
on:
|
||||
@@ -21,12 +28,14 @@ jobs:
|
||||
name: '🔍 Check Doc Imports (Python ${{ inputs.python-version }})'
|
||||
steps:
|
||||
- name: '📋 Checkout Code'
|
||||
uses: actions/checkout@v4
|
||||
uses: actions/checkout@v5
|
||||
|
||||
- name: '🐍 Set up Python ${{ inputs.python-version }} + UV'
|
||||
uses: "./.github/actions/uv_setup"
|
||||
with:
|
||||
python-version: ${{ inputs.python-version }}
|
||||
cache-suffix: test-doc-imports-${{ inputs.working-directory }}
|
||||
working-directory: ${{ inputs.working-directory }}
|
||||
|
||||
- name: '📦 Install Test Dependencies'
|
||||
shell: bash
|
||||
|
||||
6
.github/workflows/_test_pydantic.yml
vendored
6
.github/workflows/_test_pydantic.yml
vendored
@@ -1,3 +1,5 @@
|
||||
# Facilitate unit testing against different Pydantic versions for a provided package.
|
||||
|
||||
name: '🐍 Pydantic Version Testing'
|
||||
|
||||
on:
|
||||
@@ -34,12 +36,14 @@ jobs:
|
||||
name: 'Pydantic ~=${{ inputs.pydantic-version }}'
|
||||
steps:
|
||||
- name: '📋 Checkout Code'
|
||||
uses: actions/checkout@v4
|
||||
uses: actions/checkout@v5
|
||||
|
||||
- name: '🐍 Set up Python ${{ inputs.python-version }} + UV'
|
||||
uses: "./.github/actions/uv_setup"
|
||||
with:
|
||||
python-version: ${{ inputs.python-version }}
|
||||
cache-suffix: test-pydantic-${{ inputs.working-directory }}
|
||||
working-directory: ${{ inputs.working-directory }}
|
||||
|
||||
- name: '📦 Install Test Dependencies'
|
||||
shell: bash
|
||||
|
||||
106
.github/workflows/_test_release.yml
vendored
106
.github/workflows/_test_release.yml
vendored
@@ -1,106 +0,0 @@
|
||||
name: '🧪 Test Release Package'
|
||||
|
||||
on:
|
||||
workflow_call:
|
||||
inputs:
|
||||
working-directory:
|
||||
required: true
|
||||
type: string
|
||||
description: "From which folder this pipeline executes"
|
||||
dangerous-nonmaster-release:
|
||||
required: false
|
||||
type: boolean
|
||||
default: false
|
||||
description: "Release from a non-master branch (danger!)"
|
||||
|
||||
env:
|
||||
PYTHON_VERSION: "3.11"
|
||||
UV_FROZEN: "true"
|
||||
|
||||
jobs:
|
||||
build:
|
||||
if: github.ref == 'refs/heads/master' || inputs.dangerous-nonmaster-release
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
outputs:
|
||||
pkg-name: ${{ steps.check-version.outputs.pkg-name }}
|
||||
version: ${{ steps.check-version.outputs.version }}
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- name: '🐍 Set up Python + UV'
|
||||
uses: "./.github/actions/uv_setup"
|
||||
with:
|
||||
python-version: ${{ env.PYTHON_VERSION }}
|
||||
|
||||
# We want to keep this build stage *separate* from the release stage,
|
||||
# so that there's no sharing of permissions between them.
|
||||
# The release stage has trusted publishing and GitHub repo contents write access,
|
||||
# and we want to keep the scope of that access limited just to the release job.
|
||||
# Otherwise, a malicious `build` step (e.g. via a compromised dependency)
|
||||
# could get access to our GitHub or PyPI credentials.
|
||||
#
|
||||
# Per the trusted publishing GitHub Action:
|
||||
# > It is strongly advised to separate jobs for building [...]
|
||||
# > from the publish job.
|
||||
# https://github.com/pypa/gh-action-pypi-publish#non-goals
|
||||
- name: '📦 Build Project for Distribution'
|
||||
run: uv build
|
||||
working-directory: ${{ inputs.working-directory }}
|
||||
|
||||
- name: '⬆️ Upload Build Artifacts'
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: test-dist
|
||||
path: ${{ inputs.working-directory }}/dist/
|
||||
|
||||
- name: '🔍 Extract Version Information'
|
||||
id: check-version
|
||||
shell: python
|
||||
working-directory: ${{ inputs.working-directory }}
|
||||
run: |
|
||||
import os
|
||||
import tomllib
|
||||
with open("pyproject.toml", "rb") as f:
|
||||
data = tomllib.load(f)
|
||||
pkg_name = data["project"]["name"]
|
||||
version = data["project"]["version"]
|
||||
with open(os.environ["GITHUB_OUTPUT"], "a") as f:
|
||||
f.write(f"pkg-name={pkg_name}\n")
|
||||
f.write(f"version={version}\n")
|
||||
|
||||
publish:
|
||||
needs:
|
||||
- build
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
# This permission is used for trusted publishing:
|
||||
# https://blog.pypi.org/posts/2023-04-20-introducing-trusted-publishers/
|
||||
#
|
||||
# Trusted publishing has to also be configured on PyPI for each package:
|
||||
# https://docs.pypi.org/trusted-publishers/adding-a-publisher/
|
||||
id-token: write
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- uses: actions/download-artifact@v5
|
||||
with:
|
||||
name: test-dist
|
||||
path: ${{ inputs.working-directory }}/dist/
|
||||
|
||||
- name: Publish to test PyPI
|
||||
uses: pypa/gh-action-pypi-publish@release/v1
|
||||
with:
|
||||
packages-dir: ${{ inputs.working-directory }}/dist/
|
||||
verbose: true
|
||||
print-hash: true
|
||||
repository-url: https://test.pypi.org/legacy/
|
||||
|
||||
# We overwrite any existing distributions with the same name and version.
|
||||
# This is *only for CI use* and is *extremely dangerous* otherwise!
|
||||
# https://github.com/pypa/gh-action-pypi-publish#tolerating-release-package-file-duplicates
|
||||
skip-existing: true
|
||||
# Temp workaround since attestations are on by default as of gh-action-pypi-publish v1.11.0
|
||||
attestations: false
|
||||
50
.github/workflows/api_doc_build.yml
vendored
50
.github/workflows/api_doc_build.yml
vendored
@@ -1,11 +1,19 @@
|
||||
# Build the API reference documentation.
|
||||
#
|
||||
# Runs daily. Can also be triggered manually for immediate updates.
|
||||
#
|
||||
# Built HTML pushed to langchain-ai/langchain-api-docs-html.
|
||||
#
|
||||
# Looks for langchain-ai org repos in packages.yml and checks them out.
|
||||
# Calls prep_api_docs_build.py.
|
||||
|
||||
name: '📚 API Docs'
|
||||
run-name: 'Build & Deploy API Reference'
|
||||
# Runs daily or can be triggered manually for immediate updates
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
schedule:
|
||||
- cron: '0 13 * * *' # Daily at 1PM UTC
|
||||
- cron: '0 13 * * *' # Runs daily at 1PM UTC (9AM EDT/6AM PDT)
|
||||
env:
|
||||
PYTHON_VERSION: "3.11"
|
||||
|
||||
@@ -17,10 +25,10 @@ jobs:
|
||||
permissions:
|
||||
contents: read
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/checkout@v5
|
||||
with:
|
||||
path: langchain
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/checkout@v5
|
||||
with:
|
||||
repository: langchain-ai/langchain-api-docs-html
|
||||
path: langchain-api-docs-html
|
||||
@@ -31,6 +39,8 @@ jobs:
|
||||
uses: mikefarah/yq@master
|
||||
with:
|
||||
cmd: |
|
||||
# Extract repos from packages.yml that are in the langchain-ai org
|
||||
# (excluding 'langchain' itself)
|
||||
yq '
|
||||
.packages[]
|
||||
| select(
|
||||
@@ -72,29 +82,36 @@ jobs:
|
||||
done
|
||||
|
||||
- name: '🐍 Setup Python ${{ env.PYTHON_VERSION }}'
|
||||
uses: actions/setup-python@v5
|
||||
uses: actions/setup-python@v6
|
||||
id: setup-python
|
||||
with:
|
||||
python-version: ${{ env.PYTHON_VERSION }}
|
||||
|
||||
- name: '📦 Install Initial Python Dependencies'
|
||||
- name: '📦 Install Initial Python Dependencies using uv'
|
||||
working-directory: langchain
|
||||
run: |
|
||||
python -m pip install -U uv
|
||||
python -m uv pip install --upgrade --no-cache-dir pip setuptools pyyaml
|
||||
|
||||
- name: '📦 Organize Library Directories'
|
||||
# Places cloned partner packages into libs/partners structure
|
||||
run: python langchain/.github/scripts/prep_api_docs_build.py
|
||||
|
||||
- name: '🧹 Remove Old HTML Files'
|
||||
- name: '🧹 Clear Prior Build'
|
||||
run:
|
||||
# Remove artifacts from prior docs build
|
||||
rm -rf langchain-api-docs-html/api_reference_build/html
|
||||
|
||||
- name: '📦 Install Documentation Dependencies'
|
||||
- name: '📦 Install Documentation Dependencies using uv'
|
||||
working-directory: langchain
|
||||
run: |
|
||||
# Install all partner packages in editable mode with overrides
|
||||
python -m uv pip install $(ls ./libs/partners | xargs -I {} echo "./libs/partners/{}") --overrides ./docs/vercel_overrides.txt
|
||||
|
||||
# Install core langchain and other main packages
|
||||
python -m uv pip install libs/core libs/langchain libs/text-splitters libs/community libs/experimental libs/standard-tests
|
||||
|
||||
# Install Sphinx and related packages for building docs
|
||||
python -m uv pip install -r docs/api_reference/requirements.txt
|
||||
|
||||
- name: '🔧 Configure Git Settings'
|
||||
@@ -106,14 +123,29 @@ jobs:
|
||||
- name: '📚 Build API Documentation'
|
||||
working-directory: langchain
|
||||
run: |
|
||||
# Generate the API reference RST files
|
||||
python docs/api_reference/create_api_rst.py
|
||||
|
||||
# Build the HTML documentation using Sphinx
|
||||
# -T: show full traceback on exception
|
||||
# -E: don't use cached environment (force rebuild, ignore cached doctrees)
|
||||
# -b html: build HTML docs (vs PDS, etc.)
|
||||
# -d: path for the cached environment (parsed document trees / doctrees)
|
||||
# - Separate from output dir for faster incremental builds
|
||||
# -c: path to conf.py
|
||||
# -j auto: parallel build using all available CPU cores
|
||||
python -m sphinx -T -E -b html -d ../langchain-api-docs-html/_build/doctrees -c docs/api_reference docs/api_reference ../langchain-api-docs-html/api_reference_build/html -j auto
|
||||
|
||||
# Post-process the generated HTML
|
||||
python docs/api_reference/scripts/custom_formatter.py ../langchain-api-docs-html/api_reference_build/html
|
||||
|
||||
# Default index page is blank so we copy in the actual home page.
|
||||
cp ../langchain-api-docs-html/api_reference_build/html/{reference,index}.html
|
||||
|
||||
# Removes Sphinx's intermediate build artifacts after the build is complete.
|
||||
rm -rf ../langchain-api-docs-html/_build/
|
||||
|
||||
# https://github.com/marketplace/actions/add-commit
|
||||
# Commit and push changes to langchain-api-docs-html repo
|
||||
- uses: EndBug/add-and-commit@v9
|
||||
with:
|
||||
cwd: langchain-api-docs-html
|
||||
|
||||
8
.github/workflows/check-broken-links.yml
vendored
8
.github/workflows/check-broken-links.yml
vendored
@@ -1,9 +1,11 @@
|
||||
# Runs broken link checker in /docs on a daily schedule.
|
||||
|
||||
name: '🔗 Check Broken Links'
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
schedule:
|
||||
- cron: '0 13 * * *'
|
||||
- cron: '0 13 * * *' # Runs daily at 1PM UTC (9AM EDT/6AM PDT)
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
@@ -13,9 +15,9 @@ jobs:
|
||||
if: github.repository_owner == 'langchain-ai' || github.event_name != 'schedule'
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/checkout@v5
|
||||
- name: '🟢 Setup Node.js 18.x'
|
||||
uses: actions/setup-node@v4
|
||||
uses: actions/setup-node@v5
|
||||
with:
|
||||
node-version: 18.x
|
||||
cache: "yarn"
|
||||
|
||||
10
.github/workflows/check_core_versions.yml
vendored
10
.github/workflows/check_core_versions.yml
vendored
@@ -1,6 +1,8 @@
|
||||
name: '🔍 Check `core` Version Equality'
|
||||
# Ensures version numbers in pyproject.toml and version.py stay in sync
|
||||
# Prevents releases with mismatched version numbers
|
||||
# Ensures version numbers in pyproject.toml and version.py stay in sync.
|
||||
#
|
||||
# (Prevents releases with mismatched version numbers)
|
||||
|
||||
name: '🔍 Check Version Equality'
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
@@ -16,7 +18,7 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/checkout@v5
|
||||
|
||||
- name: '✅ Verify pyproject.toml & version.py Match'
|
||||
run: |
|
||||
|
||||
93
.github/workflows/check_diffs.yml
vendored
93
.github/workflows/check_diffs.yml
vendored
@@ -1,3 +1,18 @@
|
||||
# Primary CI workflow.
|
||||
#
|
||||
# Only runs against packages that have changed files.
|
||||
#
|
||||
# Runs:
|
||||
# - Linting (_lint.yml)
|
||||
# - Unit Tests (_test.yml)
|
||||
# - Pydantic compatibility tests (_test_pydantic.yml)
|
||||
# - Documentation import tests (_test_doc_imports.yml)
|
||||
# - Integration test compilation checks (_compile_integration_test.yml)
|
||||
# - Extended test suites that require additional dependencies
|
||||
# - Codspeed benchmarks (if not labeled 'codspeed-ignore')
|
||||
#
|
||||
# Reports status to GitHub checks and PR status.
|
||||
|
||||
name: '🔧 CI'
|
||||
|
||||
on:
|
||||
@@ -11,8 +26,8 @@ on:
|
||||
# cancel the earlier run in favor of the next run.
|
||||
#
|
||||
# There's no point in testing an outdated version of the code. GitHub only allows
|
||||
# a limited number of job runners to be active at the same time, so it's better to cancel
|
||||
# pointless jobs early so that more useful jobs can run sooner.
|
||||
# a limited number of job runners to be active at the same time, so it's better to
|
||||
# cancel pointless jobs early so that more useful jobs can run sooner.
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.ref }}
|
||||
cancel-in-progress: true
|
||||
@@ -33,9 +48,9 @@ jobs:
|
||||
if: ${{ !contains(github.event.pull_request.labels.*.name, 'ci-ignore') }}
|
||||
steps:
|
||||
- name: '📋 Checkout Code'
|
||||
uses: actions/checkout@v4
|
||||
uses: actions/checkout@v5
|
||||
- name: '🐍 Setup Python 3.11'
|
||||
uses: actions/setup-python@v5
|
||||
uses: actions/setup-python@v6
|
||||
with:
|
||||
python-version: '3.11'
|
||||
- name: '📂 Get Changed Files'
|
||||
@@ -54,6 +69,7 @@ jobs:
|
||||
dependencies: ${{ steps.set-matrix.outputs.dependencies }}
|
||||
test-doc-imports: ${{ steps.set-matrix.outputs.test-doc-imports }}
|
||||
test-pydantic: ${{ steps.set-matrix.outputs.test-pydantic }}
|
||||
codspeed: ${{ steps.set-matrix.outputs.codspeed }}
|
||||
# Run linting only on packages that have changed files
|
||||
lint:
|
||||
needs: [ build ]
|
||||
@@ -110,6 +126,7 @@ jobs:
|
||||
|
||||
# Verify integration tests compile without actually running them (faster feedback)
|
||||
compile-integration-tests:
|
||||
name: 'Compile Integration Tests'
|
||||
needs: [ build ]
|
||||
if: ${{ needs.build.outputs.compile-integration-tests != '[]' }}
|
||||
strategy:
|
||||
@@ -138,12 +155,14 @@ jobs:
|
||||
run:
|
||||
working-directory: ${{ matrix.job-configs.working-directory }}
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/checkout@v5
|
||||
|
||||
- name: '🐍 Set up Python ${{ matrix.job-configs.python-version }} + UV'
|
||||
uses: "./.github/actions/uv_setup"
|
||||
with:
|
||||
python-version: ${{ matrix.job-configs.python-version }}
|
||||
cache-suffix: extended-tests-${{ matrix.job-configs.working-directory }}
|
||||
working-directory: ${{ matrix.job-configs.working-directory }}
|
||||
|
||||
- name: '📦 Install Dependencies & Run Extended Tests'
|
||||
shell: bash
|
||||
@@ -166,10 +185,72 @@ jobs:
|
||||
# and `set -e` above will cause the step to fail.
|
||||
echo "$STATUS" | grep 'nothing to commit, working tree clean'
|
||||
|
||||
# Run codspeed benchmarks only on packages that have changed files
|
||||
codspeed:
|
||||
name: '⚡ CodSpeed Benchmarks'
|
||||
needs: [ build ]
|
||||
if: ${{ needs.build.outputs.codspeed != '[]' && !contains(github.event.pull_request.labels.*.name, 'codspeed-ignore') }}
|
||||
runs-on: ubuntu-latest
|
||||
strategy:
|
||||
matrix:
|
||||
job-configs: ${{ fromJson(needs.build.outputs.codspeed) }}
|
||||
fail-fast: false
|
||||
steps:
|
||||
- uses: actions/checkout@v5
|
||||
|
||||
# We have to use 3.12 as 3.13 is not yet supported
|
||||
- name: '📦 Install UV Package Manager'
|
||||
uses: astral-sh/setup-uv@v6
|
||||
with:
|
||||
python-version: "3.12"
|
||||
|
||||
- uses: actions/setup-python@v6
|
||||
with:
|
||||
python-version: "3.12"
|
||||
|
||||
- name: '📦 Install Test Dependencies'
|
||||
run: uv sync --group test
|
||||
working-directory: ${{ matrix.job-configs.working-directory }}
|
||||
|
||||
- name: '⚡ Run Benchmarks: ${{ matrix.job-configs.working-directory }}'
|
||||
uses: CodSpeedHQ/action@v4
|
||||
env:
|
||||
ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }}
|
||||
ANTHROPIC_FILES_API_IMAGE_ID: ${{ secrets.ANTHROPIC_FILES_API_IMAGE_ID }}
|
||||
ANTHROPIC_FILES_API_PDF_ID: ${{ secrets.ANTHROPIC_FILES_API_PDF_ID }}
|
||||
AZURE_OPENAI_API_VERSION: ${{ secrets.AZURE_OPENAI_API_VERSION }}
|
||||
AZURE_OPENAI_API_BASE: ${{ secrets.AZURE_OPENAI_API_BASE }}
|
||||
AZURE_OPENAI_API_KEY: ${{ secrets.AZURE_OPENAI_API_KEY }}
|
||||
AZURE_OPENAI_CHAT_DEPLOYMENT_NAME: ${{ secrets.AZURE_OPENAI_CHAT_DEPLOYMENT_NAME }}
|
||||
AZURE_OPENAI_LEGACY_CHAT_DEPLOYMENT_NAME: ${{ secrets.AZURE_OPENAI_LEGACY_CHAT_DEPLOYMENT_NAME }}
|
||||
AZURE_OPENAI_LLM_DEPLOYMENT_NAME: ${{ secrets.AZURE_OPENAI_LLM_DEPLOYMENT_NAME }}
|
||||
AZURE_OPENAI_EMBEDDINGS_DEPLOYMENT_NAME: ${{ secrets.AZURE_OPENAI_EMBEDDINGS_DEPLOYMENT_NAME }}
|
||||
COHERE_API_KEY: ${{ secrets.COHERE_API_KEY }}
|
||||
DEEPSEEK_API_KEY: ${{ secrets.DEEPSEEK_API_KEY }}
|
||||
EXA_API_KEY: ${{ secrets.EXA_API_KEY }}
|
||||
FIREWORKS_API_KEY: ${{ secrets.FIREWORKS_API_KEY }}
|
||||
GROQ_API_KEY: ${{ secrets.GROQ_API_KEY }}
|
||||
HUGGINGFACEHUB_API_TOKEN: ${{ secrets.HUGGINGFACEHUB_API_TOKEN }}
|
||||
MISTRAL_API_KEY: ${{ secrets.MISTRAL_API_KEY }}
|
||||
NOMIC_API_KEY: ${{ secrets.NOMIC_API_KEY }}
|
||||
OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }}
|
||||
PPLX_API_KEY: ${{ secrets.PPLX_API_KEY }}
|
||||
XAI_API_KEY: ${{ secrets.XAI_API_KEY }}
|
||||
with:
|
||||
token: ${{ secrets.CODSPEED_TOKEN }}
|
||||
run: |
|
||||
cd ${{ matrix.job-configs.working-directory }}
|
||||
if [ "${{ matrix.job-configs.working-directory }}" = "libs/core" ]; then
|
||||
uv run --no-sync pytest ./tests/benchmarks --codspeed
|
||||
else
|
||||
uv run --no-sync pytest ./tests/ --codspeed
|
||||
fi
|
||||
mode: ${{ matrix.job-configs.working-directory == 'libs/core' && 'walltime' || 'instrumentation' }}
|
||||
|
||||
# Final status check - ensures all required jobs passed before allowing merge
|
||||
ci_success:
|
||||
name: '✅ CI Success'
|
||||
needs: [build, lint, test, compile-integration-tests, extended-tests, test-doc-imports, test-pydantic]
|
||||
needs: [build, lint, test, compile-integration-tests, extended-tests, test-doc-imports, test-pydantic, codspeed]
|
||||
if: |
|
||||
always()
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
7
.github/workflows/check_new_docs.yml
vendored
7
.github/workflows/check_new_docs.yml
vendored
@@ -1,3 +1,6 @@
|
||||
# For integrations, we run check_templates.py to ensure that new docs use the correct
|
||||
# templates based on their type. See the script for more details.
|
||||
|
||||
name: '📑 Integration Docs Lint'
|
||||
|
||||
on:
|
||||
@@ -22,8 +25,8 @@ jobs:
|
||||
build:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/setup-python@v5
|
||||
- uses: actions/checkout@v5
|
||||
- uses: actions/setup-python@v6
|
||||
with:
|
||||
python-version: '3.10'
|
||||
- id: files
|
||||
|
||||
66
.github/workflows/codspeed.yml
vendored
66
.github/workflows/codspeed.yml
vendored
@@ -1,66 +0,0 @@
|
||||
name: '⚡ CodSpeed'
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- master
|
||||
pull_request:
|
||||
workflow_dispatch:
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
env:
|
||||
AZURE_OPENAI_CHAT_DEPLOYMENT_NAME: foo
|
||||
AZURE_OPENAI_LEGACY_CHAT_DEPLOYMENT_NAME: foo
|
||||
DEEPSEEK_API_KEY: foo
|
||||
FIREWORKS_API_KEY: foo
|
||||
|
||||
jobs:
|
||||
codspeed:
|
||||
name: 'Benchmark'
|
||||
runs-on: ubuntu-latest
|
||||
if: ${{ !contains(github.event.pull_request.labels.*.name, 'codspeed-ignore') }}
|
||||
strategy:
|
||||
matrix:
|
||||
include:
|
||||
- working-directory: libs/core
|
||||
mode: walltime
|
||||
- working-directory: libs/partners/openai
|
||||
- working-directory: libs/partners/anthropic
|
||||
- working-directory: libs/partners/deepseek
|
||||
- working-directory: libs/partners/fireworks
|
||||
- working-directory: libs/partners/xai
|
||||
- working-directory: libs/partners/mistralai
|
||||
- working-directory: libs/partners/groq
|
||||
fail-fast: false
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
# We have to use 3.12 as 3.13 is not yet supported
|
||||
- name: '📦 Install UV Package Manager'
|
||||
uses: astral-sh/setup-uv@v6
|
||||
with:
|
||||
python-version: "3.12"
|
||||
|
||||
- uses: actions/setup-python@v5
|
||||
with:
|
||||
python-version: "3.12"
|
||||
|
||||
- name: '📦 Install Test Dependencies'
|
||||
run: uv sync --group test
|
||||
working-directory: ${{ matrix.working-directory }}
|
||||
|
||||
- name: '⚡ Run Benchmarks: ${{ matrix.working-directory }}'
|
||||
uses: CodSpeedHQ/action@v3
|
||||
with:
|
||||
token: ${{ secrets.CODSPEED_TOKEN }}
|
||||
run: |
|
||||
cd ${{ matrix.working-directory }}
|
||||
if [ "${{ matrix.working-directory }}" = "libs/core" ]; then
|
||||
uv run --no-sync pytest ./tests/benchmarks --codspeed
|
||||
else
|
||||
uv run --no-sync pytest ./tests/ --codspeed
|
||||
fi
|
||||
mode: ${{ matrix.mode || 'instrumentation' }}
|
||||
10
.github/workflows/extract_ignored_words_list.py
vendored
10
.github/workflows/extract_ignored_words_list.py
vendored
@@ -1,10 +0,0 @@
|
||||
import toml
|
||||
|
||||
pyproject_toml = toml.load("pyproject.toml")
|
||||
|
||||
# Extract the ignore words list (adjust the key as per your TOML structure)
|
||||
ignore_words_list = (
|
||||
pyproject_toml.get("tool", {}).get("codespell", {}).get("ignore-words-list")
|
||||
)
|
||||
|
||||
print(f"::set-output name=ignore_words_list::{ignore_words_list}")
|
||||
8
.github/workflows/people.yml
vendored
8
.github/workflows/people.yml
vendored
@@ -1,9 +1,11 @@
|
||||
# Updates the LangChain People data by fetching the latest info from the LangChain Git.
|
||||
# TODO: broken/not used
|
||||
|
||||
name: '👥 LangChain People'
|
||||
run-name: 'Update People Data'
|
||||
# This workflow updates the LangChain People data by fetching the latest information from the LangChain Git
|
||||
on:
|
||||
schedule:
|
||||
- cron: "0 14 1 * *"
|
||||
- cron: "0 14 1 * *" # Runs at 14:00 UTC on the 1st of every month (10AM EDT/7AM PDT)
|
||||
push:
|
||||
branches: [jacob/people]
|
||||
workflow_dispatch:
|
||||
@@ -19,7 +21,7 @@ jobs:
|
||||
env:
|
||||
GITHUB_CONTEXT: ${{ toJson(github) }}
|
||||
run: echo "$GITHUB_CONTEXT"
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/checkout@v5
|
||||
# Ref: https://github.com/actions/runner/issues/2033
|
||||
- name: '🔧 Fix Git Safe Directory in Container'
|
||||
run: mkdir -p /home/runner/work/_temp/_github_home && printf "[safe]\n\tdirectory = /github/workspace" > /home/runner/work/_temp/_github_home/.gitconfig
|
||||
|
||||
28
.github/workflows/pr_labeler_file.yml
vendored
Normal file
28
.github/workflows/pr_labeler_file.yml
vendored
Normal file
@@ -0,0 +1,28 @@
|
||||
# Label PRs based on changed files.
|
||||
#
|
||||
# See `.github/pr-file-labeler.yml` to see rules for each label/directory.
|
||||
|
||||
name: "🏷️ Pull Request Labeler"
|
||||
|
||||
on:
|
||||
# Safe since we're not checking out or running the PR's code
|
||||
# Never check out the PR's head in a pull_request_target job
|
||||
pull_request_target:
|
||||
types: [opened, synchronize, reopened, edited]
|
||||
|
||||
jobs:
|
||||
labeler:
|
||||
name: 'label'
|
||||
permissions:
|
||||
contents: read
|
||||
pull-requests: write
|
||||
issues: write
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- name: Label Pull Request
|
||||
uses: actions/labeler@v6
|
||||
with:
|
||||
repo-token: "${{ secrets.GITHUB_TOKEN }}"
|
||||
configuration-path: .github/pr-file-labeler.yml
|
||||
sync-labels: false
|
||||
28
.github/workflows/pr_labeler_title.yml
vendored
Normal file
28
.github/workflows/pr_labeler_title.yml
vendored
Normal file
@@ -0,0 +1,28 @@
|
||||
# Label PRs based on their titles.
|
||||
#
|
||||
# See `.github/pr-title-labeler.yml` to see rules for each label/title pattern.
|
||||
|
||||
name: "🏷️ PR Title Labeler"
|
||||
|
||||
on:
|
||||
# Safe since we're not checking out or running the PR's code
|
||||
# Never check out the PR's head in a pull_request_target job
|
||||
pull_request_target:
|
||||
types: [opened, synchronize, reopened, edited]
|
||||
|
||||
jobs:
|
||||
pr-title-labeler:
|
||||
name: 'label'
|
||||
permissions:
|
||||
contents: read
|
||||
pull-requests: write
|
||||
issues: write
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- name: Label PR based on title
|
||||
# Archived repo; latest commit (v0.1.0)
|
||||
uses: grafana/pr-labeler-action@f19222d3ef883d2ca5f04420fdfe8148003763f0
|
||||
with:
|
||||
token: ${{ secrets.GITHUB_TOKEN }}
|
||||
configuration-path: .github/pr-title-labeler.yml
|
||||
72
.github/workflows/pr_lint.yml
vendored
72
.github/workflows/pr_lint.yml
vendored
@@ -1,50 +1,43 @@
|
||||
# -----------------------------------------------------------------------------
|
||||
# PR Title Lint Workflow
|
||||
# PR title linting.
|
||||
#
|
||||
# Purpose:
|
||||
# Enforces Conventional Commits format for pull request titles to maintain a
|
||||
# clear, consistent, and machine-readable change history across our repository.
|
||||
# This helps with automated changelog generation and semantic versioning.
|
||||
# FORMAT (Conventional Commits 1.0.0):
|
||||
#
|
||||
# Enforced Commit Message Format (Conventional Commits 1.0.0):
|
||||
# <type>[optional scope]: <description>
|
||||
# [optional body]
|
||||
# [optional footer(s)]
|
||||
#
|
||||
# Examples:
|
||||
# feat(core): add multi‐tenant support
|
||||
# fix(cli): resolve flag parsing error
|
||||
# docs: update API usage examples
|
||||
# docs(openai): update API usage examples
|
||||
#
|
||||
# Allowed Types:
|
||||
# • feat — a new feature (MINOR bump)
|
||||
# • fix — a bug fix (PATCH bump)
|
||||
# • docs — documentation only changes
|
||||
# • style — formatting, missing semi-colons, etc.; no code change
|
||||
# • refactor — code change that neither fixes a bug nor adds a feature
|
||||
# • perf — code change that improves performance
|
||||
# • test — adding missing tests or correcting existing tests
|
||||
# • build — changes that affect the build system or external dependencies
|
||||
# • ci — continuous integration/configuration changes
|
||||
# • chore — other changes that don't modify src or test files
|
||||
# • revert — reverts a previous commit
|
||||
# • release — prepare a new release
|
||||
# * feat — a new feature (MINOR)
|
||||
# * fix — a bug fix (PATCH)
|
||||
# * docs — documentation only changes (either in /docs or code comments)
|
||||
# * style — formatting, linting, etc.; no code change or typing refactors
|
||||
# * refactor — code change that neither fixes a bug nor adds a feature
|
||||
# * perf — code change that improves performance
|
||||
# * test — adding tests or correcting existing
|
||||
# * build — changes that affect the build system/external dependencies
|
||||
# * ci — continuous integration/configuration changes
|
||||
# * chore — other changes that don't modify source or test files
|
||||
# * revert — reverts a previous commit
|
||||
# * release — prepare a new release
|
||||
#
|
||||
# Allowed Scopes (optional):
|
||||
# core, cli, langchain, standard-tests, docs, anthropic, chroma, deepseek,
|
||||
# exa, fireworks, groq, huggingface, mistralai, nomic, ollama, openai,
|
||||
# perplexity, prompty, qdrant, xai
|
||||
# core, cli, langchain, langchain_v1, langchain_legacy, standard-tests,
|
||||
# text-splitters, docs, anthropic, chroma, deepseek, exa, fireworks, groq,
|
||||
# huggingface, mistralai, nomic, ollama, openai, perplexity, prompty, qdrant,
|
||||
# xai, infra
|
||||
#
|
||||
# Rules & Tips for New Committers:
|
||||
# 1. Subject (type) must start with a lowercase letter and, if possible, be
|
||||
# followed by a scope wrapped in parenthesis `(scope)`
|
||||
# 2. Breaking changes:
|
||||
# – Append "!" after type/scope (e.g., feat!: drop Node 12 support)
|
||||
# – Or include a footer "BREAKING CHANGE: <details>"
|
||||
# 3. Example PR titles:
|
||||
# feat(core): add multi‐tenant support
|
||||
# fix(cli): resolve flag parsing error
|
||||
# docs: update API usage examples
|
||||
# docs(openai): update API usage examples
|
||||
# Rules:
|
||||
# 1. The 'Type' must start with a lowercase letter.
|
||||
# 2. Breaking changes: append "!" after type/scope (e.g., feat!: drop x support)
|
||||
#
|
||||
# Resources:
|
||||
# • Conventional Commits spec: https://www.conventionalcommits.org/en/v1.0.0/
|
||||
# -----------------------------------------------------------------------------
|
||||
# Enforces Conventional Commits format for pull request titles to maintain a clear and
|
||||
# machine-readable change history.
|
||||
|
||||
name: '🏷️ PR Title Lint'
|
||||
|
||||
@@ -56,13 +49,13 @@ on:
|
||||
types: [opened, edited, synchronize]
|
||||
|
||||
jobs:
|
||||
# Validates that PR title follows Conventional Commits specification
|
||||
# Validates that PR title follows Conventional Commits 1.0.0 specification
|
||||
lint-pr-title:
|
||||
name: 'Validate PR Title Format'
|
||||
name: 'validate format'
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: '✅ Validate Conventional Commits Format'
|
||||
uses: amannn/action-semantic-pull-request@v5
|
||||
uses: amannn/action-semantic-pull-request@v6
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
with:
|
||||
@@ -84,6 +77,7 @@ jobs:
|
||||
cli
|
||||
langchain
|
||||
langchain_v1
|
||||
langchain_legacy
|
||||
standard-tests
|
||||
text-splitters
|
||||
docs
|
||||
|
||||
10
.github/workflows/run_notebooks.yml
vendored
10
.github/workflows/run_notebooks.yml
vendored
@@ -1,3 +1,5 @@
|
||||
# Integration tests for documentation notebooks.
|
||||
|
||||
name: '📓 Validate Documentation Notebooks'
|
||||
run-name: 'Test notebooks in ${{ inputs.working-directory }}'
|
||||
on:
|
||||
@@ -26,21 +28,23 @@ jobs:
|
||||
if: github.repository == 'langchain-ai/langchain' || github.event_name != 'schedule'
|
||||
name: '📑 Test Documentation Notebooks'
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/checkout@v5
|
||||
|
||||
- name: '🐍 Set up Python + UV'
|
||||
uses: "./.github/actions/uv_setup"
|
||||
with:
|
||||
python-version: ${{ github.event.inputs.python_version || '3.11' }}
|
||||
cache-suffix: run-notebooks-${{ github.event.inputs.working-directory || 'all' }}
|
||||
working-directory: ${{ github.event.inputs.working-directory || '**' }}
|
||||
|
||||
- name: '🔐 Authenticate to Google Cloud'
|
||||
id: 'auth'
|
||||
uses: google-github-actions/auth@v2
|
||||
uses: google-github-actions/auth@v3
|
||||
with:
|
||||
credentials_json: '${{ secrets.GOOGLE_CREDENTIALS }}'
|
||||
|
||||
- name: '🔐 Configure AWS Credentials'
|
||||
uses: aws-actions/configure-aws-credentials@v4
|
||||
uses: aws-actions/configure-aws-credentials@v5
|
||||
with:
|
||||
aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
|
||||
aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
|
||||
|
||||
34
.github/workflows/scheduled_test.yml
vendored
34
.github/workflows/scheduled_test.yml
vendored
@@ -1,15 +1,21 @@
|
||||
# Routine integration tests against partner libraries with live API credentials.
|
||||
#
|
||||
# Uses `make integration_tests` for each library in the matrix.
|
||||
#
|
||||
# Runs daily. Can also be triggered manually for immediate updates.
|
||||
|
||||
name: '⏰ Scheduled Integration Tests'
|
||||
run-name: "Run Integration Tests - ${{ inputs.working-directory-force || 'all libs' }} (Python ${{ inputs.python-version-force || '3.9, 3.11' }})"
|
||||
run-name: "Run Integration Tests - ${{ inputs.working-directory-force || 'all libs' }} (Python ${{ inputs.python-version-force || '3.10, 3.13' }})"
|
||||
|
||||
on:
|
||||
workflow_dispatch: # Allows maintainers to trigger the workflow manually in GitHub UI
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
working-directory-force:
|
||||
type: string
|
||||
description: "From which folder this pipeline executes - defaults to all in matrix - example value: libs/partners/anthropic"
|
||||
python-version-force:
|
||||
type: string
|
||||
description: "Python version to use - defaults to 3.9 and 3.11 in matrix - example value: 3.9"
|
||||
description: "Python version to use - defaults to 3.10 and 3.13 in matrix - example value: 3.11"
|
||||
schedule:
|
||||
- cron: '0 13 * * *' # Runs daily at 1PM UTC (9AM EDT/6AM PDT)
|
||||
|
||||
@@ -20,7 +26,7 @@ env:
|
||||
POETRY_VERSION: "1.8.4"
|
||||
UV_FROZEN: "true"
|
||||
DEFAULT_LIBS: '["libs/partners/openai", "libs/partners/anthropic", "libs/partners/fireworks", "libs/partners/groq", "libs/partners/mistralai", "libs/partners/xai", "libs/partners/google-vertexai", "libs/partners/google-genai", "libs/partners/aws"]'
|
||||
POETRY_LIBS: ("libs/partners/google-vertexai" "libs/partners/google-genai" "libs/partners/aws")
|
||||
POETRY_LIBS: ("libs/partners/aws")
|
||||
|
||||
jobs:
|
||||
# Generate dynamic test matrix based on input parameters or defaults
|
||||
@@ -40,9 +46,9 @@ jobs:
|
||||
PYTHON_VERSION_FORCE: ${{ github.event.inputs.python-version-force || '' }}
|
||||
run: |
|
||||
# echo "matrix=..." where matrix is a json formatted str with keys python-version and working-directory
|
||||
# python-version should default to 3.9 and 3.11, but is overridden to [PYTHON_VERSION_FORCE] if set
|
||||
# python-version should default to 3.10 and 3.13, but is overridden to [PYTHON_VERSION_FORCE] if set
|
||||
# working-directory should default to DEFAULT_LIBS, but is overridden to [WORKING_DIRECTORY_FORCE] if set
|
||||
python_version='["3.9", "3.11"]'
|
||||
python_version='["3.10", "3.13"]'
|
||||
working_directory="$DEFAULT_LIBS"
|
||||
if [ -n "$PYTHON_VERSION_FORCE" ]; then
|
||||
python_version="[\"$PYTHON_VERSION_FORCE\"]"
|
||||
@@ -54,13 +60,13 @@ jobs:
|
||||
echo $matrix
|
||||
echo "matrix=$matrix" >> $GITHUB_OUTPUT
|
||||
# Run integration tests against partner libraries with live API credentials
|
||||
# Tests are run with both Poetry and UV depending on the library's setup
|
||||
# Tests are run with Poetry or UV depending on the library's setup
|
||||
build:
|
||||
if: github.repository_owner == 'langchain-ai' || github.event_name != 'schedule'
|
||||
name: '🐍 Python ${{ matrix.python-version }}: ${{ matrix.working-directory }}'
|
||||
runs-on: ubuntu-latest
|
||||
needs: [compute-matrix]
|
||||
timeout-minutes: 20
|
||||
timeout-minutes: 30
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
@@ -68,14 +74,14 @@ jobs:
|
||||
working-directory: ${{ fromJSON(needs.compute-matrix.outputs.matrix).working-directory }}
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/checkout@v5
|
||||
with:
|
||||
path: langchain
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/checkout@v5
|
||||
with:
|
||||
repository: langchain-ai/langchain-google
|
||||
path: langchain-google
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/checkout@v5
|
||||
with:
|
||||
repository: langchain-ai/langchain-aws
|
||||
path: langchain-aws
|
||||
@@ -106,12 +112,12 @@ jobs:
|
||||
|
||||
- name: '🔐 Authenticate to Google Cloud'
|
||||
id: 'auth'
|
||||
uses: google-github-actions/auth@v2
|
||||
uses: google-github-actions/auth@v3
|
||||
with:
|
||||
credentials_json: '${{ secrets.GOOGLE_CREDENTIALS }}'
|
||||
|
||||
- name: '🔐 Configure AWS Credentials'
|
||||
uses: aws-actions/configure-aws-credentials@v4
|
||||
uses: aws-actions/configure-aws-credentials@v5
|
||||
with:
|
||||
aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
|
||||
aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
|
||||
@@ -161,7 +167,7 @@ jobs:
|
||||
make integration_tests
|
||||
|
||||
- name: '🧹 Clean up External Libraries'
|
||||
# Clean up external libraries to avoid affecting git status check
|
||||
# Clean up external libraries to avoid affecting the following git status check
|
||||
run: |
|
||||
rm -rf \
|
||||
langchain/libs/partners/google-genai \
|
||||
|
||||
9
.github/workflows/v1_changes.md
vendored
Normal file
9
.github/workflows/v1_changes.md
vendored
Normal file
@@ -0,0 +1,9 @@
|
||||
With the deprecation of v0 docs, the following files will need to be migrated/supported
|
||||
in the new docs repo:
|
||||
|
||||
- run_notebooks.yml: New repo should run Integration tests on code snippets?
|
||||
- people.yml: Need to fix and somehow display on the new docs site
|
||||
- Subsequently, `.github/actions/people/`
|
||||
- _test_doc_imports.yml
|
||||
- check_new_docs.yml
|
||||
- check-broken-links.yml
|
||||
@@ -2,110 +2,104 @@ repos:
|
||||
- repo: local
|
||||
hooks:
|
||||
- id: core
|
||||
name: format core
|
||||
name: format and lint core
|
||||
language: system
|
||||
entry: make -C libs/core format
|
||||
entry: make -C libs/core format lint
|
||||
files: ^libs/core/
|
||||
pass_filenames: false
|
||||
- id: langchain
|
||||
name: format langchain
|
||||
name: format and lint langchain
|
||||
language: system
|
||||
entry: make -C libs/langchain format
|
||||
entry: make -C libs/langchain format lint
|
||||
files: ^libs/langchain/
|
||||
pass_filenames: false
|
||||
- id: standard-tests
|
||||
name: format standard-tests
|
||||
name: format and lint standard-tests
|
||||
language: system
|
||||
entry: make -C libs/standard-tests format
|
||||
entry: make -C libs/standard-tests format lint
|
||||
files: ^libs/standard-tests/
|
||||
pass_filenames: false
|
||||
- id: text-splitters
|
||||
name: format text-splitters
|
||||
name: format and lint text-splitters
|
||||
language: system
|
||||
entry: make -C libs/text-splitters format
|
||||
entry: make -C libs/text-splitters format lint
|
||||
files: ^libs/text-splitters/
|
||||
pass_filenames: false
|
||||
- id: anthropic
|
||||
name: format partners/anthropic
|
||||
name: format and lint partners/anthropic
|
||||
language: system
|
||||
entry: make -C libs/partners/anthropic format
|
||||
entry: make -C libs/partners/anthropic format lint
|
||||
files: ^libs/partners/anthropic/
|
||||
pass_filenames: false
|
||||
- id: chroma
|
||||
name: format partners/chroma
|
||||
name: format and lint partners/chroma
|
||||
language: system
|
||||
entry: make -C libs/partners/chroma format
|
||||
entry: make -C libs/partners/chroma format lint
|
||||
files: ^libs/partners/chroma/
|
||||
pass_filenames: false
|
||||
- id: couchbase
|
||||
name: format partners/couchbase
|
||||
language: system
|
||||
entry: make -C libs/partners/couchbase format
|
||||
files: ^libs/partners/couchbase/
|
||||
pass_filenames: false
|
||||
- id: exa
|
||||
name: format partners/exa
|
||||
name: format and lint partners/exa
|
||||
language: system
|
||||
entry: make -C libs/partners/exa format
|
||||
entry: make -C libs/partners/exa format lint
|
||||
files: ^libs/partners/exa/
|
||||
pass_filenames: false
|
||||
- id: fireworks
|
||||
name: format partners/fireworks
|
||||
name: format and lint partners/fireworks
|
||||
language: system
|
||||
entry: make -C libs/partners/fireworks format
|
||||
entry: make -C libs/partners/fireworks format lint
|
||||
files: ^libs/partners/fireworks/
|
||||
pass_filenames: false
|
||||
- id: groq
|
||||
name: format partners/groq
|
||||
name: format and lint partners/groq
|
||||
language: system
|
||||
entry: make -C libs/partners/groq format
|
||||
entry: make -C libs/partners/groq format lint
|
||||
files: ^libs/partners/groq/
|
||||
pass_filenames: false
|
||||
- id: huggingface
|
||||
name: format partners/huggingface
|
||||
name: format and lint partners/huggingface
|
||||
language: system
|
||||
entry: make -C libs/partners/huggingface format
|
||||
entry: make -C libs/partners/huggingface format lint
|
||||
files: ^libs/partners/huggingface/
|
||||
pass_filenames: false
|
||||
- id: mistralai
|
||||
name: format partners/mistralai
|
||||
name: format and lint partners/mistralai
|
||||
language: system
|
||||
entry: make -C libs/partners/mistralai format
|
||||
entry: make -C libs/partners/mistralai format lint
|
||||
files: ^libs/partners/mistralai/
|
||||
pass_filenames: false
|
||||
- id: nomic
|
||||
name: format partners/nomic
|
||||
name: format and lint partners/nomic
|
||||
language: system
|
||||
entry: make -C libs/partners/nomic format
|
||||
entry: make -C libs/partners/nomic format lint
|
||||
files: ^libs/partners/nomic/
|
||||
pass_filenames: false
|
||||
- id: ollama
|
||||
name: format partners/ollama
|
||||
name: format and lint partners/ollama
|
||||
language: system
|
||||
entry: make -C libs/partners/ollama format
|
||||
entry: make -C libs/partners/ollama format lint
|
||||
files: ^libs/partners/ollama/
|
||||
pass_filenames: false
|
||||
- id: openai
|
||||
name: format partners/openai
|
||||
name: format and lint partners/openai
|
||||
language: system
|
||||
entry: make -C libs/partners/openai format
|
||||
entry: make -C libs/partners/openai format lint
|
||||
files: ^libs/partners/openai/
|
||||
pass_filenames: false
|
||||
- id: prompty
|
||||
name: format partners/prompty
|
||||
name: format and lint partners/prompty
|
||||
language: system
|
||||
entry: make -C libs/partners/prompty format
|
||||
entry: make -C libs/partners/prompty format lint
|
||||
files: ^libs/partners/prompty/
|
||||
pass_filenames: false
|
||||
- id: qdrant
|
||||
name: format partners/qdrant
|
||||
name: format and lint partners/qdrant
|
||||
language: system
|
||||
entry: make -C libs/partners/qdrant format
|
||||
entry: make -C libs/partners/qdrant format lint
|
||||
files: ^libs/partners/qdrant/
|
||||
pass_filenames: false
|
||||
- id: root
|
||||
name: format docs, cookbook
|
||||
name: format and lint docs, cookbook
|
||||
language: system
|
||||
entry: make format
|
||||
entry: make format lint
|
||||
files: ^(docs|cookbook)/
|
||||
pass_filenames: false
|
||||
|
||||
@@ -1,25 +0,0 @@
|
||||
# Read the Docs configuration file
|
||||
# See https://docs.readthedocs.io/en/stable/config-file/v2.html for details
|
||||
version: 2
|
||||
|
||||
# Set the version of Python and other tools you might need
|
||||
build:
|
||||
os: ubuntu-22.04
|
||||
tools:
|
||||
python: "3.11"
|
||||
commands:
|
||||
- mkdir -p $READTHEDOCS_OUTPUT
|
||||
- cp -r api_reference_build/* $READTHEDOCS_OUTPUT
|
||||
|
||||
# Build documentation in the docs/ directory with Sphinx
|
||||
sphinx:
|
||||
configuration: docs/api_reference/conf.py
|
||||
|
||||
# If using Sphinx, optionally build your docs in additional formats such as PDF
|
||||
formats:
|
||||
- pdf
|
||||
|
||||
# Optionally declare the Python requirements required to build your docs
|
||||
python:
|
||||
install:
|
||||
- requirements: docs/api_reference/requirements.txt
|
||||
7
.vscode/settings.json
vendored
7
.vscode/settings.json
vendored
@@ -78,5 +78,10 @@
|
||||
"editor.insertSpaces": true
|
||||
},
|
||||
"python.terminal.activateEnvironment": false,
|
||||
"python.defaultInterpreterPath": "./.venv/bin/python"
|
||||
"python.defaultInterpreterPath": "./.venv/bin/python",
|
||||
"github.copilot.chat.commitMessageGeneration.instructions": [
|
||||
{
|
||||
"file": ".github/workflows/pr_lint.yml"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
325
AGENTS.md
Normal file
325
AGENTS.md
Normal file
@@ -0,0 +1,325 @@
|
||||
# Global Development Guidelines for LangChain Projects
|
||||
|
||||
## Core Development Principles
|
||||
|
||||
### 1. Maintain Stable Public Interfaces ⚠️ CRITICAL
|
||||
|
||||
**Always attempt to preserve function signatures, argument positions, and names for exported/public methods.**
|
||||
|
||||
❌ **Bad - Breaking Change:**
|
||||
|
||||
```python
|
||||
def get_user(id, verbose=False): # Changed from `user_id`
|
||||
pass
|
||||
```
|
||||
|
||||
✅ **Good - Stable Interface:**
|
||||
|
||||
```python
|
||||
def get_user(user_id: str, verbose: bool = False) -> User:
|
||||
"""Retrieve user by ID with optional verbose output."""
|
||||
pass
|
||||
```
|
||||
|
||||
**Before making ANY changes to public APIs:**
|
||||
|
||||
- Check if the function/class is exported in `__init__.py`
|
||||
- Look for existing usage patterns in tests and examples
|
||||
- Use keyword-only arguments for new parameters: `*, new_param: str = "default"`
|
||||
- Mark experimental features clearly with docstring warnings (using reStructuredText, like `.. warning::`)
|
||||
|
||||
🧠 *Ask yourself:* "Would this change break someone's code if they used it last week?"
|
||||
|
||||
### 2. Code Quality Standards
|
||||
|
||||
**All Python code MUST include type hints and return types.**
|
||||
|
||||
❌ **Bad:**
|
||||
|
||||
```python
|
||||
def p(u, d):
|
||||
return [x for x in u if x not in d]
|
||||
```
|
||||
|
||||
✅ **Good:**
|
||||
|
||||
```python
|
||||
def filter_unknown_users(users: list[str], known_users: set[str]) -> list[str]:
|
||||
"""Filter out users that are not in the known users set.
|
||||
|
||||
Args:
|
||||
users: List of user identifiers to filter.
|
||||
known_users: Set of known/valid user identifiers.
|
||||
|
||||
Returns:
|
||||
List of users that are not in the known_users set.
|
||||
"""
|
||||
return [user for user in users if user not in known_users]
|
||||
```
|
||||
|
||||
**Style Requirements:**
|
||||
|
||||
- Use descriptive, **self-explanatory variable names**. Avoid overly short or cryptic identifiers.
|
||||
- Attempt to break up complex functions (>20 lines) into smaller, focused functions where it makes sense
|
||||
- Avoid unnecessary abstraction or premature optimization
|
||||
- Follow existing patterns in the codebase you're modifying
|
||||
|
||||
### 3. Testing Requirements
|
||||
|
||||
**Every new feature or bugfix MUST be covered by unit tests.**
|
||||
|
||||
**Test Organization:**
|
||||
|
||||
- Unit tests: `tests/unit_tests/` (no network calls allowed)
|
||||
- Integration tests: `tests/integration_tests/` (network calls permitted)
|
||||
- Use `pytest` as the testing framework
|
||||
|
||||
**Test Quality Checklist:**
|
||||
|
||||
- [ ] Tests fail when your new logic is broken
|
||||
- [ ] Happy path is covered
|
||||
- [ ] Edge cases and error conditions are tested
|
||||
- [ ] Use fixtures/mocks for external dependencies
|
||||
- [ ] Tests are deterministic (no flaky tests)
|
||||
|
||||
Checklist questions:
|
||||
|
||||
- [ ] Does the test suite fail if your new logic is broken?
|
||||
- [ ] Are all expected behaviors exercised (happy path, invalid input, etc)?
|
||||
- [ ] Do tests use fixtures or mocks where needed?
|
||||
|
||||
```python
|
||||
def test_filter_unknown_users():
|
||||
"""Test filtering unknown users from a list."""
|
||||
users = ["alice", "bob", "charlie"]
|
||||
known_users = {"alice", "bob"}
|
||||
|
||||
result = filter_unknown_users(users, known_users)
|
||||
|
||||
assert result == ["charlie"]
|
||||
assert len(result) == 1
|
||||
```
|
||||
|
||||
### 4. Security and Risk Assessment
|
||||
|
||||
**Security Checklist:**
|
||||
|
||||
- No `eval()`, `exec()`, or `pickle` on user-controlled input
|
||||
- Proper exception handling (no bare `except:`) and use a `msg` variable for error messages
|
||||
- Remove unreachable/commented code before committing
|
||||
- Race conditions or resource leaks (file handles, sockets, threads).
|
||||
- Ensure proper resource cleanup (file handles, connections)
|
||||
|
||||
❌ **Bad:**
|
||||
|
||||
```python
|
||||
def load_config(path):
|
||||
with open(path) as f:
|
||||
return eval(f.read()) # ⚠️ Never eval config
|
||||
```
|
||||
|
||||
✅ **Good:**
|
||||
|
||||
```python
|
||||
import json
|
||||
|
||||
def load_config(path: str) -> dict:
|
||||
with open(path) as f:
|
||||
return json.load(f)
|
||||
```
|
||||
|
||||
### 5. Documentation Standards
|
||||
|
||||
**Use Google-style docstrings with Args section for all public functions.**
|
||||
|
||||
❌ **Insufficient Documentation:**
|
||||
|
||||
```python
|
||||
def send_email(to, msg):
|
||||
"""Send an email to a recipient."""
|
||||
```
|
||||
|
||||
✅ **Complete Documentation:**
|
||||
|
||||
```python
|
||||
def send_email(to: str, msg: str, *, priority: str = "normal") -> bool:
|
||||
"""
|
||||
Send an email to a recipient with specified priority.
|
||||
|
||||
Args:
|
||||
to: The email address of the recipient.
|
||||
msg: The message body to send.
|
||||
priority: Email priority level (``'low'``, ``'normal'``, ``'high'``).
|
||||
|
||||
Returns:
|
||||
True if email was sent successfully, False otherwise.
|
||||
|
||||
Raises:
|
||||
InvalidEmailError: If the email address format is invalid.
|
||||
SMTPConnectionError: If unable to connect to email server.
|
||||
"""
|
||||
```
|
||||
|
||||
**Documentation Guidelines:**
|
||||
|
||||
- Types go in function signatures, NOT in docstrings
|
||||
- Focus on "why" rather than "what" in descriptions
|
||||
- Document all parameters, return values, and exceptions
|
||||
- Keep descriptions concise but clear
|
||||
- Use reStructuredText for docstrings to enable rich formatting
|
||||
|
||||
📌 *Tip:* Keep descriptions concise but clear. Only document return values if non-obvious.
|
||||
|
||||
### 6. Architectural Improvements
|
||||
|
||||
**When you encounter code that could be improved, suggest better designs:**
|
||||
|
||||
❌ **Poor Design:**
|
||||
|
||||
```python
|
||||
def process_data(data, db_conn, email_client, logger):
|
||||
# Function doing too many things
|
||||
validated = validate_data(data)
|
||||
result = db_conn.save(validated)
|
||||
email_client.send_notification(result)
|
||||
logger.log(f"Processed {len(data)} items")
|
||||
return result
|
||||
```
|
||||
|
||||
✅ **Better Design:**
|
||||
|
||||
```python
|
||||
@dataclass
|
||||
class ProcessingResult:
|
||||
"""Result of data processing operation."""
|
||||
items_processed: int
|
||||
success: bool
|
||||
errors: List[str] = field(default_factory=list)
|
||||
|
||||
class DataProcessor:
|
||||
"""Handles data validation, storage, and notification."""
|
||||
|
||||
def __init__(self, db_conn: Database, email_client: EmailClient):
|
||||
self.db = db_conn
|
||||
self.email = email_client
|
||||
|
||||
def process(self, data: List[dict]) -> ProcessingResult:
|
||||
"""Process and store data with notifications."""
|
||||
validated = self._validate_data(data)
|
||||
result = self.db.save(validated)
|
||||
self._notify_completion(result)
|
||||
return result
|
||||
```
|
||||
|
||||
**Design Improvement Areas:**
|
||||
|
||||
If there's a **cleaner**, **more scalable**, or **simpler** design, highlight it and suggest improvements that would:
|
||||
|
||||
- Reduce code duplication through shared utilities
|
||||
- Make unit testing easier
|
||||
- Improve separation of concerns (single responsibility)
|
||||
- Make unit testing easier through dependency injection
|
||||
- Add clarity without adding complexity
|
||||
- Prefer dataclasses for structured data
|
||||
|
||||
## Development Tools & Commands
|
||||
|
||||
### Package Management
|
||||
|
||||
```bash
|
||||
# Add package
|
||||
uv add package-name
|
||||
|
||||
# Sync project dependencies
|
||||
uv sync
|
||||
uv lock
|
||||
```
|
||||
|
||||
### Testing
|
||||
|
||||
```bash
|
||||
# Run unit tests (no network)
|
||||
make test
|
||||
|
||||
# Don't run integration tests, as API keys must be set
|
||||
|
||||
# Run specific test file
|
||||
uv run --group test pytest tests/unit_tests/test_specific.py
|
||||
```
|
||||
|
||||
### Code Quality
|
||||
|
||||
```bash
|
||||
# Lint code
|
||||
make lint
|
||||
|
||||
# Format code
|
||||
make format
|
||||
|
||||
# Type checking
|
||||
uv run --group lint mypy .
|
||||
```
|
||||
|
||||
### Dependency Management Patterns
|
||||
|
||||
**Local Development Dependencies:**
|
||||
|
||||
```toml
|
||||
[tool.uv.sources]
|
||||
langchain-core = { path = "../core", editable = true }
|
||||
langchain-tests = { path = "../standard-tests", editable = true }
|
||||
```
|
||||
|
||||
**For tools, use the `@tool` decorator from `langchain_core.tools`:**
|
||||
|
||||
```python
|
||||
from langchain_core.tools import tool
|
||||
|
||||
@tool
|
||||
def search_database(query: str) -> str:
|
||||
"""Search the database for relevant information.
|
||||
|
||||
Args:
|
||||
query: The search query string.
|
||||
"""
|
||||
# Implementation here
|
||||
return results
|
||||
```
|
||||
|
||||
## Commit Standards
|
||||
|
||||
**Use Conventional Commits format for PR titles:**
|
||||
|
||||
- `feat(core): add multi-tenant support`
|
||||
- `fix(cli): resolve flag parsing error`
|
||||
- `docs: update API usage examples`
|
||||
- `docs(openai): update API usage examples`
|
||||
|
||||
## Framework-Specific Guidelines
|
||||
|
||||
- Follow the existing patterns in `langchain-core` for base abstractions
|
||||
- Use `langchain_core.callbacks` for execution tracking
|
||||
- Implement proper streaming support where applicable
|
||||
- Avoid deprecated components like legacy `LLMChain`
|
||||
|
||||
### Partner Integrations
|
||||
|
||||
- Follow the established patterns in existing partner libraries
|
||||
- Implement standard interfaces (`BaseChatModel`, `BaseEmbeddings`, etc.)
|
||||
- Include comprehensive integration tests
|
||||
- Document API key requirements and authentication
|
||||
|
||||
---
|
||||
|
||||
## Quick Reference Checklist
|
||||
|
||||
Before submitting code changes:
|
||||
|
||||
- [ ] **Breaking Changes**: Verified no public API changes
|
||||
- [ ] **Type Hints**: All functions have complete type annotations
|
||||
- [ ] **Tests**: New functionality is fully tested
|
||||
- [ ] **Security**: No dangerous patterns (eval, silent failures, etc.)
|
||||
- [ ] **Documentation**: Google-style docstrings for public functions
|
||||
- [ ] **Code Quality**: `make lint` and `make format` pass
|
||||
- [ ] **Architecture**: Suggested improvements where applicable
|
||||
- [ ] **Commit Message**: Follows Conventional Commits format
|
||||
16
Makefile
16
Makefile
@@ -1,4 +1,4 @@
|
||||
.PHONY: all clean help docs_build docs_clean docs_linkcheck api_docs_build api_docs_clean api_docs_linkcheck spell_check spell_fix lint lint_package lint_tests format format_diff
|
||||
.PHONY: all clean help docs_build docs_clean docs_linkcheck api_docs_build api_docs_clean api_docs_linkcheck lint lint_package lint_tests format format_diff
|
||||
|
||||
.EXPORT_ALL_VARIABLES:
|
||||
UV_FROZEN = true
|
||||
@@ -78,18 +78,6 @@ api_docs_linkcheck:
|
||||
fi
|
||||
@echo "✅ API link check complete"
|
||||
|
||||
## spell_check: Run codespell on the project.
|
||||
spell_check:
|
||||
@echo "✏️ Checking spelling across project..."
|
||||
uv run --group codespell codespell --toml pyproject.toml
|
||||
@echo "✅ Spell check complete"
|
||||
|
||||
## spell_fix: Run codespell on the project and fix the errors.
|
||||
spell_fix:
|
||||
@echo "✏️ Fixing spelling errors across project..."
|
||||
uv run --group codespell codespell --toml pyproject.toml -w
|
||||
@echo "✅ Spelling errors fixed"
|
||||
|
||||
######################
|
||||
# LINTING AND FORMATTING
|
||||
######################
|
||||
@@ -100,7 +88,7 @@ lint lint_package lint_tests:
|
||||
uv run --group lint ruff check docs cookbook
|
||||
uv run --group lint ruff format docs cookbook cookbook --diff
|
||||
git --no-pager grep 'from langchain import' docs cookbook | grep -vE 'from langchain import (hub)' && echo "Error: no importing langchain from root in docs, except for hub" && exit 1 || exit 0
|
||||
|
||||
|
||||
git --no-pager grep 'api.python.langchain.com' -- docs/docs ':!docs/docs/additional_resources/arxiv_references.mdx' ':!docs/docs/integrations/document_loaders/sitemap.ipynb' || exit 0 && \
|
||||
echo "Error: you should link python.langchain.com/api_reference, not api.python.langchain.com in the docs" && \
|
||||
exit 1
|
||||
|
||||
110
README.md
110
README.md
@@ -1,85 +1,75 @@
|
||||
<picture>
|
||||
<source media="(prefers-color-scheme: light)" srcset="docs/static/img/logo-dark.svg">
|
||||
<source media="(prefers-color-scheme: dark)" srcset="docs/static/img/logo-light.svg">
|
||||
<img alt="LangChain Logo" src="docs/static/img/logo-dark.svg" width="80%">
|
||||
</picture>
|
||||
<p align="center">
|
||||
<picture>
|
||||
<source media="(prefers-color-scheme: light)" srcset="docs/static/img/logo-dark.svg">
|
||||
<source media="(prefers-color-scheme: dark)" srcset="docs/static/img/logo-light.svg">
|
||||
<img alt="LangChain Logo" src="docs/static/img/logo-dark.svg" width="80%">
|
||||
</picture>
|
||||
</p>
|
||||
|
||||
<div>
|
||||
<br>
|
||||
</div>
|
||||
<p align="center">
|
||||
The platform for reliable agents.
|
||||
</p>
|
||||
|
||||
[](https://github.com/langchain-ai/langchain/releases)
|
||||
[](https://opensource.org/licenses/MIT)
|
||||
[](https://pypistats.org/packages/langchain-core)
|
||||
[](https://star-history.com/#langchain-ai/langchain)
|
||||
[](https://vscode.dev/redirect?url=vscode://ms-vscode-remote.remote-containers/cloneInVolume?url=https://github.com/langchain-ai/langchain)
|
||||
[<img src="https://github.com/codespaces/badge.svg" alt="Open in Github Codespace" title="Open in Github Codespace" width="150" height="20">](https://codespaces.new/langchain-ai/langchain)
|
||||
[](https://codspeed.io/langchain-ai/langchain)
|
||||
[](https://twitter.com/langchainai)
|
||||
<p align="center">
|
||||
<a href="https://opensource.org/licenses/MIT" target="_blank">
|
||||
<img src="https://img.shields.io/pypi/l/langchain-core?style=flat-square" alt="PyPI - License">
|
||||
</a>
|
||||
<a href="https://pypistats.org/packages/langchain-core" target="_blank">
|
||||
<img src="https://img.shields.io/pepy/dt/langchain" alt="PyPI - Downloads">
|
||||
</a>
|
||||
<a href="https://vscode.dev/redirect?url=vscode://ms-vscode-remote.remote-containers/cloneInVolume?url=https://github.com/langchain-ai/langchain" target="_blank">
|
||||
<img src="https://img.shields.io/static/v1?label=Dev%20Containers&message=Open&color=blue&logo=visualstudiocode&style=flat-square" alt="Open in Dev Containers">
|
||||
</a>
|
||||
<a href="https://codespaces.new/langchain-ai/langchain" target="_blank">
|
||||
<img src="https://github.com/codespaces/badge.svg" alt="Open in Github Codespace" title="Open in Github Codespace" width="150" height="20">
|
||||
</a>
|
||||
<a href="https://codspeed.io/langchain-ai/langchain" target="_blank">
|
||||
<img src="https://img.shields.io/endpoint?url=https://codspeed.io/badge.json" alt="CodSpeed Badge">
|
||||
</a>
|
||||
<a href="https://twitter.com/langchainai" target="_blank">
|
||||
<img src="https://img.shields.io/twitter/url/https/twitter.com/langchainai.svg?style=social&label=Follow%20%40LangChainAI" alt="Twitter / X">
|
||||
</a>
|
||||
</p>
|
||||
|
||||
> [!NOTE]
|
||||
> Looking for the JS/TS library? Check out [LangChain.js](https://github.com/langchain-ai/langchainjs).
|
||||
|
||||
LangChain is a framework for building LLM-powered applications. It helps you chain
|
||||
together interoperable components and third-party integrations to simplify AI
|
||||
application development — all while future-proofing decisions as the underlying
|
||||
technology evolves.
|
||||
LangChain is a framework for building LLM-powered applications. It helps you chain together interoperable components and third-party integrations to simplify AI application development — all while future-proofing decisions as the underlying technology evolves.
|
||||
|
||||
```bash
|
||||
pip install -U langchain
|
||||
```
|
||||
|
||||
To learn more about LangChain, check out
|
||||
[the docs](https://python.langchain.com/docs/introduction/). If you’re looking for more
|
||||
advanced customization or agent orchestration, check out
|
||||
[LangGraph](https://langchain-ai.github.io/langgraph/), our framework for building
|
||||
controllable agent workflows.
|
||||
---
|
||||
|
||||
**Documentation**: To learn more about LangChain, check out [the docs](https://python.langchain.com/docs/introduction/).
|
||||
|
||||
If you're looking for more advanced customization or agent orchestration, check out [LangGraph](https://langchain-ai.github.io/langgraph/), our framework for building controllable agent workflows.
|
||||
|
||||
> [!NOTE]
|
||||
> Looking for the JS/TS library? Check out [LangChain.js](https://github.com/langchain-ai/langchainjs).
|
||||
|
||||
## Why use LangChain?
|
||||
|
||||
LangChain helps developers build applications powered by LLMs through a standard
|
||||
interface for models, embeddings, vector stores, and more.
|
||||
LangChain helps developers build applications powered by LLMs through a standard interface for models, embeddings, vector stores, and more.
|
||||
|
||||
Use LangChain for:
|
||||
|
||||
- **Real-time data augmentation**. Easily connect LLMs to diverse data sources and
|
||||
external/internal systems, drawing from LangChain’s vast library of integrations with
|
||||
model providers, tools, vector stores, retrievers, and more.
|
||||
- **Model interoperability**. Swap models in and out as your engineering team
|
||||
experiments to find the best choice for your application’s needs. As the industry
|
||||
frontier evolves, adapt quickly — LangChain’s abstractions keep you moving without
|
||||
losing momentum.
|
||||
- **Real-time data augmentation**. Easily connect LLMs to diverse data sources and external/internal systems, drawing from LangChain’s vast library of integrations with model providers, tools, vector stores, retrievers, and more.
|
||||
- **Model interoperability**. Swap models in and out as your engineering team experiments to find the best choice for your application’s needs. As the industry frontier evolves, adapt quickly — LangChain’s abstractions keep you moving without losing momentum.
|
||||
|
||||
## LangChain’s ecosystem
|
||||
|
||||
While the LangChain framework can be used standalone, it also integrates seamlessly
|
||||
with any LangChain product, giving developers a full suite of tools when building LLM
|
||||
applications.
|
||||
While the LangChain framework can be used standalone, it also integrates seamlessly with any LangChain product, giving developers a full suite of tools when building LLM applications.
|
||||
|
||||
To improve your LLM application development, pair LangChain with:
|
||||
|
||||
- [LangSmith](https://www.langchain.com/langsmith) - Helpful for agent evals and
|
||||
observability. Debug poor-performing LLM app runs, evaluate agent trajectories, gain
|
||||
visibility in production, and improve performance over time.
|
||||
- [LangGraph](https://langchain-ai.github.io/langgraph/) - Build agents that can
|
||||
reliably handle complex tasks with LangGraph, our low-level agent orchestration
|
||||
framework. LangGraph offers customizable architecture, long-term memory, and
|
||||
human-in-the-loop workflows — and is trusted in production by companies like LinkedIn,
|
||||
Uber, Klarna, and GitLab.
|
||||
- [LangGraph Platform](https://docs.langchain.com/langgraph-platform) - Deploy
|
||||
and scale agents effortlessly with a purpose-built deployment platform for long-running, stateful workflows. Discover, reuse, configure, and share agents across
|
||||
teams — and iterate quickly with visual prototyping in
|
||||
[LangGraph Studio](https://langchain-ai.github.io/langgraph/concepts/langgraph_studio/).
|
||||
- [LangSmith](https://www.langchain.com/langsmith) - Helpful for agent evals and observability. Debug poor-performing LLM app runs, evaluate agent trajectories, gain visibility in production, and improve performance over time.
|
||||
- [LangGraph](https://langchain-ai.github.io/langgraph/) - Build agents that can reliably handle complex tasks with LangGraph, our low-level agent orchestration framework. LangGraph offers customizable architecture, long-term memory, and human-in-the-loop workflows — and is trusted in production by companies like LinkedIn, Uber, Klarna, and GitLab.
|
||||
- [LangGraph Platform](https://docs.langchain.com/langgraph-platform) - Deploy and scale agents effortlessly with a purpose-built deployment platform for long-running, stateful workflows. Discover, reuse, configure, and share agents across teams — and iterate quickly with visual prototyping in [LangGraph Studio](https://langchain-ai.github.io/langgraph/concepts/langgraph_studio/).
|
||||
|
||||
## Additional resources
|
||||
|
||||
- [Tutorials](https://python.langchain.com/docs/tutorials/): Simple walkthroughs with
|
||||
guided examples on getting started with LangChain.
|
||||
- [How-to Guides](https://python.langchain.com/docs/how_to/): Quick, actionable code
|
||||
snippets for topics such as tool calling, RAG use cases, and more.
|
||||
- [Conceptual Guides](https://python.langchain.com/docs/concepts/): Explanations of key
|
||||
concepts behind the LangChain framework.
|
||||
- [Tutorials](https://python.langchain.com/docs/tutorials/): Simple walkthroughs with guided examples on getting started with LangChain.
|
||||
- [How-to Guides](https://python.langchain.com/docs/how_to/): Quick, actionable code snippets for topics such as tool calling, RAG use cases, and more.
|
||||
- [Conceptual Guides](https://python.langchain.com/docs/concepts/): Explanations of key concepts behind the LangChain framework.
|
||||
- [LangChain Forum](https://forum.langchain.com/): Connect with the community and share all of your technical questions, ideas, and feedback.
|
||||
- [API Reference](https://python.langchain.com/api_reference/): Detailed reference on
|
||||
navigating base packages and integrations for LangChain.
|
||||
- [API Reference](https://python.langchain.com/api_reference/): Detailed reference on navigating base packages and integrations for LangChain.
|
||||
- [Chat LangChain](https://chat.langchain.com/): Ask questions & chat with our documentation.
|
||||
|
||||
10
SECURITY.md
10
SECURITY.md
@@ -22,9 +22,7 @@ Example scenarios with mitigation strategies:
|
||||
* A user may ask an agent with write access to an external API to write malicious data to the API, or delete data from that API. To mitigate, give the agent read-only API keys, or limit it to only use endpoints that are already resistant to such misuse.
|
||||
* A user may ask an agent with access to a database to drop a table or mutate the schema. To mitigate, scope the credentials to only the tables that the agent needs to access and consider issuing READ-ONLY credentials.
|
||||
|
||||
If you're building applications that access external resources like file systems, APIs
|
||||
or databases, consider speaking with your company's security team to determine how to best
|
||||
design and secure your applications.
|
||||
If you're building applications that access external resources like file systems, APIs or databases, consider speaking with your company's security team to determine how to best design and secure your applications.
|
||||
|
||||
## Reporting OSS Vulnerabilities
|
||||
|
||||
@@ -37,10 +35,8 @@ open source projects at [huntr](https://huntr.com/bounties/disclose/?target=http
|
||||
Before reporting a vulnerability, please review:
|
||||
|
||||
1) In-Scope Targets and Out-of-Scope Targets below.
|
||||
2) The [langchain-ai/langchain](https://python.langchain.com/docs/contributing/repo_structure) monorepo structure.
|
||||
3) The [Best Practices](#best-practices) above to
|
||||
understand what we consider to be a security vulnerability vs. developer
|
||||
responsibility.
|
||||
2) The [langchain-ai/langchain](https://docs.langchain.com/oss/python/contributing/code#supporting-packages) monorepo structure.
|
||||
3) The [Best Practices](#best-practices) above to understand what we consider to be a security vulnerability vs. developer responsibility.
|
||||
|
||||
### In-Scope Targets
|
||||
|
||||
|
||||
@@ -64,3 +64,4 @@ Notebook | Description
|
||||
[visual_RAG_vdms.ipynb](https://github.com/langchain-ai/langchain/tree/master/cookbook/visual_RAG_vdms.ipynb) | Performs Visual Retrieval-Augmented-Generation (RAG) using videos and scene descriptions generated by open source models.
|
||||
[contextual_rag.ipynb](https://github.com/langchain-ai/langchain/tree/master/cookbook/contextual_rag.ipynb) | Performs contextual retrieval-augmented generation (RAG) prepending chunk-specific explanatory context to each chunk before embedding.
|
||||
[rag-agents-locally-on-intel-cpu.ipynb](https://github.com/langchain-ai/langchain/tree/master/cookbook/local_rag_agents_intel_cpu.ipynb) | Build a RAG agent locally with open source models that routes questions through one of two paths to find answers. The agent generates answers based on documents retrieved from either the vector database or retrieved from web search. If the vector database lacks relevant information, the agent opts for web search. Open-source models for LLM and embeddings are used locally on an Intel Xeon CPU to execute this pipeline.
|
||||
[rag_mlflow_tracking_evaluation.ipynb](https://github.com/langchain-ai/langchain/tree/master/cookbook/rag_mlflow_tracking_evaluation.ipynb) | Guide on how to create a RAG pipeline and track + evaluate it with MLflow.
|
||||
|
||||
@@ -47,10 +47,12 @@
|
||||
"source": [
|
||||
"### Prerequisites\n",
|
||||
"\n",
|
||||
"Please install the Oracle Database [python-oracledb driver](https://pypi.org/project/oracledb/) to use LangChain with Oracle AI Vector Search:\n",
|
||||
"You'll need to install `langchain-oracledb` with `python -m pip install -U langchain-oracledb` to use this integration.\n",
|
||||
"\n",
|
||||
"The `python-oracledb` driver is installed automatically as a dependency of langchain-oracledb.\n",
|
||||
"\n",
|
||||
"```\n",
|
||||
"$ python -m pip install --upgrade oracledb\n",
|
||||
"$ python -m pip install -U langchain-oracledb\n",
|
||||
"```"
|
||||
]
|
||||
},
|
||||
@@ -217,7 +219,7 @@
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"from langchain_community.embeddings.oracleai import OracleEmbeddings\n",
|
||||
"from langchain_oracledb.embeddings.oracleai import OracleEmbeddings\n",
|
||||
"\n",
|
||||
"# please update with your related information\n",
|
||||
"# make sure that you have onnx file in the system\n",
|
||||
@@ -296,7 +298,7 @@
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"from langchain_community.document_loaders.oracleai import OracleDocLoader\n",
|
||||
"from langchain_oracledb.document_loaders.oracleai import OracleDocLoader\n",
|
||||
"from langchain_core.documents import Document\n",
|
||||
"\n",
|
||||
"# loading from Oracle Database table\n",
|
||||
@@ -354,7 +356,7 @@
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"from langchain_community.utilities.oracleai import OracleSummary\n",
|
||||
"from langchain_oracledb.utilities.oracleai import OracleSummary\n",
|
||||
"from langchain_core.documents import Document\n",
|
||||
"\n",
|
||||
"# using 'database' provider\n",
|
||||
@@ -395,7 +397,7 @@
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"from langchain_community.document_loaders.oracleai import OracleTextSplitter\n",
|
||||
"from langchain_oracledb.document_loaders.oracleai import OracleTextSplitter\n",
|
||||
"from langchain_core.documents import Document\n",
|
||||
"\n",
|
||||
"# split by default parameters\n",
|
||||
@@ -452,7 +454,7 @@
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"from langchain_community.embeddings.oracleai import OracleEmbeddings\n",
|
||||
"from langchain_oracledb.embeddings.oracleai import OracleEmbeddings\n",
|
||||
"from langchain_core.documents import Document\n",
|
||||
"\n",
|
||||
"# using ONNX model loaded to Oracle Database\n",
|
||||
@@ -498,14 +500,14 @@
|
||||
"import sys\n",
|
||||
"\n",
|
||||
"import oracledb\n",
|
||||
"from langchain_community.document_loaders.oracleai import (\n",
|
||||
"from langchain_oracledb.document_loaders.oracleai import (\n",
|
||||
" OracleDocLoader,\n",
|
||||
" OracleTextSplitter,\n",
|
||||
")\n",
|
||||
"from langchain_community.embeddings.oracleai import OracleEmbeddings\n",
|
||||
"from langchain_community.utilities.oracleai import OracleSummary\n",
|
||||
"from langchain_community.vectorstores import oraclevs\n",
|
||||
"from langchain_community.vectorstores.oraclevs import OracleVS\n",
|
||||
"from langchain_oracledb.embeddings.oracleai import OracleEmbeddings\n",
|
||||
"from langchain_oracledb.utilities.oracleai import OracleSummary\n",
|
||||
"from langchain_oracledb.vectorstores import oraclevs\n",
|
||||
"from langchain_oracledb.vectorstores.oraclevs import OracleVS\n",
|
||||
"from langchain_community.vectorstores.utils import DistanceStrategy\n",
|
||||
"from langchain_core.documents import Document"
|
||||
]
|
||||
@@ -677,19 +679,19 @@
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"query = \"What is Oracle AI Vector Store?\"\n",
|
||||
"filter = {\"document_id\": [\"1\"]}\n",
|
||||
"db_filter = {\"document_id\": \"1\"}\n",
|
||||
"\n",
|
||||
"# Similarity search without a filter\n",
|
||||
"print(vectorstore.similarity_search(query, 1))\n",
|
||||
"\n",
|
||||
"# Similarity search with a filter\n",
|
||||
"print(vectorstore.similarity_search(query, 1, filter=filter))\n",
|
||||
"print(vectorstore.similarity_search(query, 1, filter=db_filter))\n",
|
||||
"\n",
|
||||
"# Similarity search with relevance score\n",
|
||||
"print(vectorstore.similarity_search_with_score(query, 1))\n",
|
||||
"\n",
|
||||
"# Similarity search with relevance score with filter\n",
|
||||
"print(vectorstore.similarity_search_with_score(query, 1, filter=filter))\n",
|
||||
"print(vectorstore.similarity_search_with_score(query, 1, filter=db_filter))\n",
|
||||
"\n",
|
||||
"# Max marginal relevance search\n",
|
||||
"print(vectorstore.max_marginal_relevance_search(query, 1, fetch_k=20, lambda_mult=0.5))\n",
|
||||
@@ -697,7 +699,7 @@
|
||||
"# Max marginal relevance search with filter\n",
|
||||
"print(\n",
|
||||
" vectorstore.max_marginal_relevance_search(\n",
|
||||
" query, 1, fetch_k=20, lambda_mult=0.5, filter=filter\n",
|
||||
" query, 1, fetch_k=20, lambda_mult=0.5, filter=db_filter\n",
|
||||
" )\n",
|
||||
")"
|
||||
]
|
||||
|
||||
455
cookbook/rag_mlflow_tracking_evaluation.ipynb
Normal file
455
cookbook/rag_mlflow_tracking_evaluation.ipynb
Normal file
@@ -0,0 +1,455 @@
|
||||
{
|
||||
"cells": [
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "3716230e",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"# RAG Pipeline with MLflow Tracking, Tracing & Evaluation\n",
|
||||
"\n",
|
||||
"This notebook demonstrates how to build a complete Retrieval-Augmented Generation (RAG) pipeline using LangChain and integrate it with MLflow for experiment tracking, tracing, and evaluation.\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"- **RAG Pipeline Construction**: Build a complete RAG system using LangChain components\n",
|
||||
"- **MLflow Integration**: Track experiments, parameters, and artifacts\n",
|
||||
"- **Tracing**: Monitor inputs, outputs, retrieved documents, scores, prompts, and timings\n",
|
||||
"- **Evaluation**: Use MLflow's built-in scorers to assess RAG performance\n",
|
||||
"- **Best Practices**: Implement proper configuration management and reproducible experiments\n",
|
||||
"\n",
|
||||
"We'll build a RAG system that can answer questions about academic papers by:\n",
|
||||
"1. Loading and chunking documents from ArXiv\n",
|
||||
"2. Creating embeddings and a vector store\n",
|
||||
"3. Setting up a retrieval-augmented generation chain\n",
|
||||
"4. Tracking all experiments with MLflow\n",
|
||||
"5. Evaluating the system's performance\n",
|
||||
"\n",
|
||||
""
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "2f7561c4",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"#### Setup"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "0814ebe9",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"%pip install -U langchain mlflow langchain-community arxiv pymupdf langchain-text-splitters langchain-openai"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 1,
|
||||
"id": "747399b6",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"import os\n",
|
||||
"import mlflow\n",
|
||||
"from mlflow.genai.scorers import RelevanceToQuery, Correctness, ExpectationsGuidelines\n",
|
||||
"from langchain_community.document_loaders import ArxivLoader\n",
|
||||
"from langchain.text_splitter import RecursiveCharacterTextSplitter\n",
|
||||
"from langchain_core.vectorstores import InMemoryVectorStore\n",
|
||||
"from langchain_openai import OpenAIEmbeddings, ChatOpenAI\n",
|
||||
"from langchain_core.prompts import ChatPromptTemplate\n",
|
||||
"from langchain_core.runnables import RunnableLambda, RunnablePassthrough\n",
|
||||
"from langchain_core.output_parsers import StrOutputParser"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "4141ee05",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"os.environ[\"OPENAI_API_KEY\"] = \"<YOUR OPENAI API KEY>\"\n",
|
||||
"\n",
|
||||
"mlflow.set_experiment(\"LangChain-RAG-MLflow\")\n",
|
||||
"mlflow.langchain.autolog()"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "dd5eb41b",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"Define all hyperparameters and configuration in a centralized dictionary. This makes it easy to:\n",
|
||||
"- Track different experiment configurations\n",
|
||||
"- Reproduce results\n",
|
||||
"- Perform hyperparameter tuning\n",
|
||||
"\n",
|
||||
"**Key Parameters**:\n",
|
||||
"- `chunk_size`: Size of text chunks for document splitting\n",
|
||||
"- `chunk_overlap`: Overlap between consecutive chunks\n",
|
||||
"- `retriever_k`: Number of documents to retrieve\n",
|
||||
"- `embeddings_model`: OpenAI embedding model\n",
|
||||
"- `llm`: Language model for generation\n",
|
||||
"- `temperature`: Sampling temperature for the LLM"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 3,
|
||||
"id": "6dcdc5d8",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"CONFIG = {\n",
|
||||
" \"chunk_size\": 400,\n",
|
||||
" \"chunk_overlap\": 80,\n",
|
||||
" \"retriever_k\": 3,\n",
|
||||
" \"embeddings_model\": \"text-embedding-3-small\",\n",
|
||||
" \"system_prompt\": \"You are a helpful assistant. Use the following context to answer the question. Use three sentences maximum and keep the answer concise.\",\n",
|
||||
" \"llm\": \"gpt-5-nano\",\n",
|
||||
" \"temperature\": 0,\n",
|
||||
"}"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "8a2985f1",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"#### ArXiv Dcoument Loading and Processing"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 4,
|
||||
"id": "1f32aa36",
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"{'Published': '2023-08-02', 'Title': 'Attention Is All You Need', 'Authors': 'Ashish Vaswani, Noam Shazeer, Niki Parmar, Jakob Uszkoreit, Llion Jones, Aidan N. Gomez, Lukasz Kaiser, Illia Polosukhin', 'Summary': 'The dominant sequence transduction models are based on complex recurrent or\\nconvolutional neural networks in an encoder-decoder configuration. The best\\nperforming models also connect the encoder and decoder through an attention\\nmechanism. We propose a new simple network architecture, the Transformer, based\\nsolely on attention mechanisms, dispensing with recurrence and convolutions\\nentirely. Experiments on two machine translation tasks show these models to be\\nsuperior in quality while being more parallelizable and requiring significantly\\nless time to train. Our model achieves 28.4 BLEU on the WMT 2014\\nEnglish-to-German translation task, improving over the existing best results,\\nincluding ensembles by over 2 BLEU. On the WMT 2014 English-to-French\\ntranslation task, our model establishes a new single-model state-of-the-art\\nBLEU score of 41.8 after training for 3.5 days on eight GPUs, a small fraction\\nof the training costs of the best models from the literature. We show that the\\nTransformer generalizes well to other tasks by applying it successfully to\\nEnglish constituency parsing both with large and limited training data.'}\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"# Load documents from ArXiv\n",
|
||||
"loader = ArxivLoader(\n",
|
||||
" query=\"1706.03762\",\n",
|
||||
" load_max_docs=1,\n",
|
||||
")\n",
|
||||
"docs = loader.load()\n",
|
||||
"print(docs[0].metadata)\n",
|
||||
"\n",
|
||||
"# Split documents into chunks\n",
|
||||
"splitter = RecursiveCharacterTextSplitter(\n",
|
||||
" chunk_size=CONFIG[\"chunk_size\"],\n",
|
||||
" chunk_overlap=CONFIG[\"chunk_overlap\"],\n",
|
||||
")\n",
|
||||
"chunks = splitter.split_documents(docs)\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"# Join chunks into a single string\n",
|
||||
"def join_chunks(chunks):\n",
|
||||
" return \"\\n\\n\".join([chunk.page_content for chunk in chunks])"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "6e194ab4",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"#### Vector Store and Retriever Setup"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 5,
|
||||
"id": "26dfbeaa",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"# Create embeddings\n",
|
||||
"embeddings = OpenAIEmbeddings(model=CONFIG[\"embeddings_model\"])\n",
|
||||
"\n",
|
||||
"# Create vector store from documents\n",
|
||||
"vectorstore = InMemoryVectorStore.from_documents(\n",
|
||||
" chunks,\n",
|
||||
" embedding=embeddings,\n",
|
||||
")\n",
|
||||
"\n",
|
||||
"# Create retriever\n",
|
||||
"retriever = vectorstore.as_retriever(search_kwargs={\"k\": CONFIG[\"retriever_k\"]})"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "bc1f181b",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"#### RAG Chain Construction using [LCEL](https://python.langchain.com/docs/concepts/lcel/)\n",
|
||||
"\n",
|
||||
"Flow:\n",
|
||||
"1. Query → Retriever (finds relevant chunks)\n",
|
||||
"2. Chunks → join_chunks (creates context)\n",
|
||||
"3. Context + Query → Prompt Template\n",
|
||||
"4. Prompt → Language Model → Response\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 6,
|
||||
"id": "6a810dc3",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"# Initialize the language model\n",
|
||||
"llm = ChatOpenAI(model=CONFIG[\"llm\"], temperature=CONFIG[\"temperature\"])\n",
|
||||
"\n",
|
||||
"# Create the prompt template\n",
|
||||
"prompt = ChatPromptTemplate.from_messages(\n",
|
||||
" [\n",
|
||||
" (\"system\", CONFIG[\"system_prompt\"] + \"\\n\\nContext:\\n{context}\\n\\n\"),\n",
|
||||
" (\"human\", \"\\n{question}\\n\"),\n",
|
||||
" ]\n",
|
||||
")\n",
|
||||
"\n",
|
||||
"# Construct the RAG chain\n",
|
||||
"rag_chain = (\n",
|
||||
" {\n",
|
||||
" \"context\": retriever | RunnableLambda(join_chunks),\n",
|
||||
" \"question\": RunnablePassthrough(),\n",
|
||||
" }\n",
|
||||
" | prompt\n",
|
||||
" | llm\n",
|
||||
" | StrOutputParser()\n",
|
||||
")"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "c04bd019",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"#### Prediction Function with MLflow Tracing\n",
|
||||
"\n",
|
||||
"Create a prediction function decorated with `@mlflow.trace` to automatically log:\n",
|
||||
"- Input queries\n",
|
||||
"- Retrieved documents\n",
|
||||
"- Generated responses\n",
|
||||
"- Execution time\n",
|
||||
"- Chain intermediate steps"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 7,
|
||||
"id": "7b45fc04",
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"Question: What is the main idea of the paper?\n",
|
||||
"Response: The main idea is to replace recurrent/convolutional sequence models with a pure attention-based architecture called the Transformer. It uses self-attention to model dependencies between all positions in the input and output, enabling full parallelization and better handling of long-range relations. This approach achieves strong results on translation and can extend to other modalities.\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"@mlflow.trace\n",
|
||||
"def predict_fn(question: str) -> str:\n",
|
||||
" return rag_chain.invoke(question)\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"# Test the prediction function\n",
|
||||
"sample_question = \"What is the main idea of the paper?\"\n",
|
||||
"response = predict_fn(sample_question)\n",
|
||||
"print(f\"Question: {sample_question}\")\n",
|
||||
"print(f\"Response: {response}\")"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "421469de",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"#### Evaluation Dataset and Scoring\n",
|
||||
"\n",
|
||||
"Define an evaluation dataset and run systematic evaluation using [MLflow's built-in scorers](https://mlflow.org/docs/latest/genai/eval-monitor/scorers/llm-judge/predefined/#available-scorers):\n",
|
||||
"\n",
|
||||
"<u>Evaluation Components:</u>\n",
|
||||
"- **Dataset**: Questions with expected concepts and facts\n",
|
||||
"- **Scorers**: \n",
|
||||
" - `RelevanceToQuery`: Measures how relevant the response is to the question\n",
|
||||
" - `Correctness`: Evaluates factual accuracy of the response\n",
|
||||
" - `ExpectationsGuidelines`: Checks that output matches expectation guidelines\n",
|
||||
"\n",
|
||||
"<u>Best Practices:</u>\n",
|
||||
"- Create diverse test cases covering different query types\n",
|
||||
"- Include expected concepts to guide evaluation\n",
|
||||
"- Use multiple scoring metrics for comprehensive assessment"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 8,
|
||||
"id": "5c1dc4f2",
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stderr",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"2025/08/23 20:14:39 INFO mlflow.models.evaluation.utils.trace: Auto tracing is temporarily enabled during the model evaluation for computing some metrics and debugging. To disable tracing, call `mlflow.autolog(disable=True)`.\n",
|
||||
"2025/08/23 20:14:39 INFO mlflow.genai.utils.data_validation: Testing model prediction with the first sample in the dataset.\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"data": {
|
||||
"application/vnd.jupyter.widget-view+json": {
|
||||
"model_id": "2b6c6687efa24796b39c7951d589d481",
|
||||
"version_major": 2,
|
||||
"version_minor": 0
|
||||
},
|
||||
"text/plain": [
|
||||
"Evaluating: 0%| | 0/3 [Elapsed: 00:00, Remaining: ?] "
|
||||
]
|
||||
},
|
||||
"metadata": {},
|
||||
"output_type": "display_data"
|
||||
},
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"\n",
|
||||
"✨ Evaluation completed.\n",
|
||||
"\n",
|
||||
"Metrics and evaluation results are logged to the MLflow run:\n",
|
||||
" Run name: \u001b[94mbaseline_eval\u001b[0m\n",
|
||||
" Run ID: \u001b[94ma2218d9f24c9415f8040d3b77af103a9\u001b[0m\n",
|
||||
"\n",
|
||||
"To view the detailed evaluation results with sample-wise scores,\n",
|
||||
"open the \u001b[93m\u001b[1mTraces\u001b[0m tab in the Run page in the MLflow UI.\n",
|
||||
"\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"# Define evaluation dataset\n",
|
||||
"eval_dataset = [\n",
|
||||
" {\n",
|
||||
" \"inputs\": {\"question\": \"What is the main idea of the paper?\"},\n",
|
||||
" \"expectations\": {\n",
|
||||
" \"key_concepts\": [\"attention mechanism\", \"transformer\", \"neural network\"],\n",
|
||||
" \"expected_facts\": [\n",
|
||||
" \"attention mechanism is a key component of the transformer model\"\n",
|
||||
" ],\n",
|
||||
" \"guidelines\": [\"The response must be factual and concise\"],\n",
|
||||
" },\n",
|
||||
" },\n",
|
||||
" {\n",
|
||||
" \"inputs\": {\n",
|
||||
" \"question\": \"What's the difference between a transformer and a recurrent neural network?\"\n",
|
||||
" },\n",
|
||||
" \"expectations\": {\n",
|
||||
" \"key_concepts\": [\"sequential\", \"attention mechanism\", \"hidden state\"],\n",
|
||||
" \"expected_facts\": [\n",
|
||||
" \"transformer processes data in parallel while RNN processes data sequentially\"\n",
|
||||
" ],\n",
|
||||
" \"guidelines\": [\n",
|
||||
" \"The response must be factual and focus on the difference between the two models\"\n",
|
||||
" ],\n",
|
||||
" },\n",
|
||||
" },\n",
|
||||
" {\n",
|
||||
" \"inputs\": {\"question\": \"What does the attention mechanism do?\"},\n",
|
||||
" \"expectations\": {\n",
|
||||
" \"key_concepts\": [\"query\", \"key\", \"value\", \"relationship\", \"similarity\"],\n",
|
||||
" \"expected_facts\": [\n",
|
||||
" \"attention allows the model to weigh the importance of different parts of the input sequence when processing it\"\n",
|
||||
" ],\n",
|
||||
" \"guidelines\": [\n",
|
||||
" \"The response must be factual and explain the concept of attention\"\n",
|
||||
" ],\n",
|
||||
" },\n",
|
||||
" },\n",
|
||||
"]\n",
|
||||
"\n",
|
||||
"# Run evaluation with MLflow\n",
|
||||
"with mlflow.start_run(run_name=\"baseline_eval\") as run:\n",
|
||||
" # Log configuration parameters\n",
|
||||
" mlflow.log_params(CONFIG)\n",
|
||||
"\n",
|
||||
" # Run evaluation\n",
|
||||
" results = mlflow.genai.evaluate(\n",
|
||||
" data=eval_dataset,\n",
|
||||
" predict_fn=predict_fn,\n",
|
||||
" scorers=[RelevanceToQuery(), Correctness(), ExpectationsGuidelines()],\n",
|
||||
" )"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "52b137c7",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"#### Launch MLflow UI to check out the results\n",
|
||||
"\n",
|
||||
"<u>What you'll see in the UI:</u>\n",
|
||||
"- **Experiments**: Compare different RAG configurations\n",
|
||||
"- **Runs**: Individual experiment runs with metrics and parameters\n",
|
||||
"- **Traces**: Detailed execution traces showing retrieval and generation steps\n",
|
||||
"- **Evaluation Results**: Scoring metrics and detailed comparisons\n",
|
||||
"- **Artifacts**: Saved models, datasets, and other files\n",
|
||||
"\n",
|
||||
"Navigate to `http://localhost:5000` after running the command below."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "817c3799",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"!mlflow ui"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "c75861e3",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"You should see something like this\n",
|
||||
"\n",
|
||||
""
|
||||
]
|
||||
}
|
||||
],
|
||||
"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.13.5"
|
||||
}
|
||||
},
|
||||
"nbformat": 4,
|
||||
"nbformat_minor": 5
|
||||
}
|
||||
153
docs/README.md
153
docs/README.md
@@ -1,3 +1,154 @@
|
||||
# LangChain Documentation
|
||||
|
||||
For more information on contributing to our documentation, see the [Documentation Contributing Guide](https://python.langchain.com/docs/contributing/how_to/documentation)
|
||||
For more information on contributing to our documentation, see the [Documentation Contributing Guide](https://python.langchain.com/docs/contributing/how_to/documentation).
|
||||
|
||||
## Structure
|
||||
|
||||
The primary documentation is located in the `docs/` directory. This directory contains
|
||||
both the source files for the main documentation as well as the API reference doc
|
||||
build process.
|
||||
|
||||
### API Reference
|
||||
|
||||
API reference documentation is located in `docs/api_reference/` and is generated from
|
||||
the codebase using Sphinx.
|
||||
|
||||
The API reference have additional build steps that differ from the main documentation.
|
||||
|
||||
#### Deployment Process
|
||||
|
||||
Currently, the build process roughly follows these steps:
|
||||
|
||||
1. Using the `api_doc_build.yml` GitHub workflow, the API reference docs are
|
||||
[built](#build-technical-details) and copied to the `langchain-api-docs-html`
|
||||
repository. This workflow is triggered either (1) on a cron routine interval or (2)
|
||||
triggered manually.
|
||||
|
||||
In short, the workflow extracts all `langchain-ai`-org-owned repos defined in
|
||||
`langchain/libs/packages.yml`, clones them locally (in the workflow runner's file
|
||||
system), and then builds the API reference RST files (using `create_api_rst.py`).
|
||||
Following post-processing, the HTML files are pushed to the
|
||||
`langchain-api-docs-html` repository.
|
||||
2. After the HTML files are in the `langchain-api-docs-html` repository, they are **not**
|
||||
automatically published to the [live docs site](https://python.langchain.com/api_reference/).
|
||||
|
||||
The docs site is served by Vercel. The Vercel deployment process copies the HTML
|
||||
files from the `langchain-api-docs-html` repository and deploys them to the live
|
||||
site. Deployments are triggered on each new commit pushed to `master`.
|
||||
|
||||
#### Build Technical Details
|
||||
|
||||
The build process creates a virtual monorepo by syncing multiple repositories, then generates comprehensive API documentation:
|
||||
|
||||
1. **Repository Sync Phase:**
|
||||
- `.github/scripts/prep_api_docs_build.py` - Clones external partner repos and organizes them into the `libs/partners/` structure to create a virtual monorepo for documentation building
|
||||
|
||||
2. **RST Generation Phase:**
|
||||
- `docs/api_reference/create_api_rst.py` - Main script that **generates RST files** from Python source code
|
||||
- Scans `libs/` directories and extracts classes/functions from each module (using `inspect`)
|
||||
- Creates `.rst` files using specialized templates for different object types
|
||||
- Templates in `docs/api_reference/templates/` (`pydantic.rst`, `runnable_pydantic.rst`, etc.)
|
||||
|
||||
3. **HTML Build Phase:**
|
||||
- Sphinx-based, uses `sphinx.ext.autodoc` (auto-extracts docstrings from the codebase)
|
||||
- `docs/api_reference/conf.py` (sphinx config) configures `autodoc` and other extensions
|
||||
- `sphinx-build` processes the generated `.rst` files into HTML using autodoc
|
||||
- `docs/api_reference/scripts/custom_formatter.py` - Post-processes the generated HTML
|
||||
- Copies `reference.html` to `index.html` to create the default landing page (artifact? might not need to do this - just put everyhing in index directly?)
|
||||
|
||||
4. **Deployment:**
|
||||
- `.github/workflows/api_doc_build.yml` - Workflow responsible for orchestrating the entire build and deployment process
|
||||
- Built HTML files are committed and pushed to the `langchain-api-docs-html` repository
|
||||
|
||||
#### Local Build
|
||||
|
||||
For local development and testing of API documentation, use the Makefile targets in the repository root:
|
||||
|
||||
```bash
|
||||
# Full build
|
||||
make api_docs_build
|
||||
```
|
||||
|
||||
Like the CI process, this target:
|
||||
|
||||
- Installs the CLI package in editable mode
|
||||
- Generates RST files for all packages using `create_api_rst.py`
|
||||
- Builds HTML documentation with Sphinx
|
||||
- Post-processes the HTML with `custom_formatter.py`
|
||||
- Opens the built documentation (`reference.html`) in your browser
|
||||
|
||||
**Quick Preview:**
|
||||
|
||||
```bash
|
||||
make api_docs_quick_preview API_PKG=openai
|
||||
```
|
||||
|
||||
- Generates RST files for only the specified package (default: `text-splitters`)
|
||||
- Builds and post-processes HTML documentation
|
||||
- Opens the preview in your browser
|
||||
|
||||
Both targets automatically clean previous builds and handle the complete build pipeline locally, mirroring the CI process but for faster iteration during development.
|
||||
|
||||
#### Documentation Standards
|
||||
|
||||
**Docstring Format:**
|
||||
The API reference uses **Google-style docstrings** with reStructuredText markup. Sphinx processes these through the `sphinx.ext.napoleon` extension to generate documentation.
|
||||
|
||||
**Required format:**
|
||||
|
||||
```python
|
||||
def example_function(param1: str, param2: int = 5) -> bool:
|
||||
"""Brief description of the function.
|
||||
|
||||
Longer description can go here. Use reStructuredText syntax for
|
||||
rich formatting like **bold** and *italic*.
|
||||
|
||||
TODO: code: figure out what works?
|
||||
|
||||
Args:
|
||||
param1: Description of the first parameter.
|
||||
param2: Description of the second parameter with default value.
|
||||
|
||||
Returns:
|
||||
Description of the return value.
|
||||
|
||||
Raises:
|
||||
ValueError: When param1 is empty.
|
||||
TypeError: When param2 is not an integer.
|
||||
|
||||
.. warning::
|
||||
This function is experimental and may change.
|
||||
"""
|
||||
```
|
||||
|
||||
**Special Markers:**
|
||||
|
||||
- `:private:` in docstrings excludes members from documentation
|
||||
- `.. warning::` adds warning admonitions
|
||||
|
||||
#### Site Styling and Assets
|
||||
|
||||
**Theme and Styling:**
|
||||
|
||||
- Uses [**PyData Sphinx Theme**](https://pydata-sphinx-theme.readthedocs.io/en/stable/index.html) (`pydata_sphinx_theme`)
|
||||
- Custom CSS in `docs/api_reference/_static/css/custom.css` with LangChain-specific:
|
||||
- Color palette
|
||||
- Inter font family
|
||||
- Custom navbar height and sidebar formatting
|
||||
- Deprecated/beta feature styling
|
||||
|
||||
**Static Assets:**
|
||||
|
||||
- Logos: `_static/wordmark-api.svg` (light) and `_static/wordmark-api-dark.svg` (dark mode)
|
||||
- Favicon: `_static/img/brand/favicon.png`
|
||||
- Custom CSS: `_static/css/custom.css`
|
||||
|
||||
**Post-Processing:**
|
||||
|
||||
- `scripts/custom_formatter.py` cleans up generated HTML:
|
||||
- Shortens TOC entries from `ClassName.method()` to `method()`
|
||||
|
||||
**Analytics and Integration:**
|
||||
|
||||
- GitHub integration (source links, edit buttons)
|
||||
- Example backlinking through custom `ExampleLinksDirective`
|
||||
|
||||
@@ -50,7 +50,7 @@ class GalleryGridDirective(SphinxDirective):
|
||||
individual cards + ["image", "header", "content", "title"].
|
||||
|
||||
Danger:
|
||||
This directive can only be used in the context of a Myst documentation page as
|
||||
This directive can only be used in the context of a MyST documentation page as
|
||||
the templates use Markdown flavored formatting.
|
||||
"""
|
||||
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
"""Configuration file for the Sphinx documentation builder."""
|
||||
|
||||
# Configuration file for the Sphinx documentation builder.
|
||||
#
|
||||
# This file only contains a selection of the most common options. For a full
|
||||
# list see the documentation:
|
||||
# https://www.sphinx-doc.org/en/master/usage/configuration.html
|
||||
@@ -20,16 +18,18 @@ from docutils.parsers.rst.directives.admonitions import BaseAdmonition
|
||||
from docutils.statemachine import StringList
|
||||
from sphinx.util.docutils import SphinxDirective
|
||||
|
||||
# If extensions (or modules to document with autodoc) are in another directory,
|
||||
# add these directories to sys.path here. If the directory is relative to the
|
||||
# documentation root, use os.path.abspath to make it absolute, like shown here.
|
||||
|
||||
# Add paths to Python import system so Sphinx can import LangChain modules
|
||||
# This allows autodoc to introspect and document the actual code
|
||||
_DIR = Path(__file__).parent.absolute()
|
||||
sys.path.insert(0, os.path.abspath("."))
|
||||
sys.path.insert(0, os.path.abspath("../../libs/langchain"))
|
||||
sys.path.insert(0, os.path.abspath(".")) # Current directory
|
||||
sys.path.insert(0, os.path.abspath("../../libs/langchain")) # LangChain main package
|
||||
|
||||
# Load package metadata from pyproject.toml (for version info, etc.)
|
||||
with (_DIR.parents[1] / "libs" / "langchain" / "pyproject.toml").open("r") as f:
|
||||
data = toml.load(f)
|
||||
|
||||
# Load mapping of classes to example notebooks for backlinking
|
||||
# This file is generated by scripts that scan our tutorial/example notebooks
|
||||
with (_DIR / "guide_imports.json").open("r") as f:
|
||||
imported_classes = json.load(f)
|
||||
|
||||
@@ -86,6 +86,7 @@ class Beta(BaseAdmonition):
|
||||
|
||||
|
||||
def setup(app):
|
||||
"""Register custom directives and hooks with Sphinx."""
|
||||
app.add_directive("example_links", ExampleLinksDirective)
|
||||
app.add_directive("beta", Beta)
|
||||
app.connect("autodoc-skip-member", skip_private_members)
|
||||
@@ -125,7 +126,7 @@ extensions = [
|
||||
"sphinx.ext.viewcode",
|
||||
"sphinxcontrib.autodoc_pydantic",
|
||||
"IPython.sphinxext.ipython_console_highlighting",
|
||||
"myst_parser",
|
||||
"myst_parser", # For generated index.md and reference.md
|
||||
"_extensions.gallery_directive",
|
||||
"sphinx_design",
|
||||
"sphinx_copybutton",
|
||||
@@ -258,6 +259,7 @@ html_static_path = ["_static"]
|
||||
html_css_files = ["css/custom.css"]
|
||||
html_use_index = False
|
||||
|
||||
# Only used on the generated index.md and reference.md files
|
||||
myst_enable_extensions = ["colon_fence"]
|
||||
|
||||
# generate autosummary even if no references
|
||||
@@ -268,11 +270,11 @@ autosummary_ignore_module_all = False
|
||||
html_copy_source = False
|
||||
html_show_sourcelink = False
|
||||
|
||||
googleanalytics_id = "G-9B66JQQH2F"
|
||||
|
||||
# Set canonical URL from the Read the Docs Domain
|
||||
html_baseurl = os.environ.get("READTHEDOCS_CANONICAL_URL", "")
|
||||
|
||||
googleanalytics_id = "G-9B66JQQH2F"
|
||||
|
||||
# Tell Jinja2 templates the build is running on Read the Docs
|
||||
if os.environ.get("READTHEDOCS", "") == "True":
|
||||
html_context["READTHEDOCS"] = True
|
||||
|
||||
@@ -1,4 +1,41 @@
|
||||
"""Script for auto-generating api_reference.rst."""
|
||||
"""Auto-generate API reference documentation (RST files) for LangChain packages.
|
||||
|
||||
* Automatically discovers all packages in `libs/` and `libs/partners/`
|
||||
* For each package, recursively walks the filesystem to:
|
||||
* Load Python modules using importlib
|
||||
* Extract classes and functions using Python's inspect module
|
||||
* Classify objects by type (Pydantic models, Runnables, TypedDicts, etc.)
|
||||
* Filter out private members (names starting with '_') and deprecated items
|
||||
* Creates structured RST files with:
|
||||
* Module-level documentation pages with autosummary tables
|
||||
* Different Sphinx templates based on object type (see templates/ directory)
|
||||
* Proper cross-references and navigation structure
|
||||
* Separation of current vs deprecated APIs
|
||||
* Generates a directory tree like:
|
||||
```
|
||||
docs/api_reference/
|
||||
├── index.md # Main landing page with package gallery
|
||||
├── reference.md # Package overview and navigation
|
||||
├── core/ # langchain-core documentation
|
||||
│ ├── index.rst
|
||||
│ ├── callbacks.rst
|
||||
│ └── ...
|
||||
├── langchain/ # langchain documentation
|
||||
│ ├── index.rst
|
||||
│ └── ...
|
||||
└── partners/ # Integration packages
|
||||
├── openai/
|
||||
├── anthropic/
|
||||
└── ...
|
||||
```
|
||||
|
||||
## Key Features
|
||||
|
||||
* Respects privacy markers:
|
||||
* Modules with `:private:` in docstring are excluded entirely
|
||||
* Objects with `:private:` in docstring are filtered out
|
||||
* Names starting with '_' are treated as private
|
||||
"""
|
||||
|
||||
import importlib
|
||||
import inspect
|
||||
@@ -177,12 +214,13 @@ def _load_package_modules(
|
||||
Traversal based on the file system makes it easy to determine which
|
||||
of the modules/packages are part of the package vs. 3rd party or built-in.
|
||||
|
||||
Parameters:
|
||||
package_directory (Union[str, Path]): Path to the package directory.
|
||||
submodule (Optional[str]): Optional name of submodule to load.
|
||||
Args:
|
||||
package_directory: Path to the package directory.
|
||||
submodule: Optional name of submodule to load.
|
||||
|
||||
Returns:
|
||||
Dict[str, ModuleMembers]: A dictionary where keys are module names and values are ModuleMembers objects.
|
||||
A dictionary where keys are module names and values are `ModuleMembers`
|
||||
objects.
|
||||
"""
|
||||
package_path = (
|
||||
Path(package_directory)
|
||||
@@ -199,12 +237,13 @@ def _load_package_modules(
|
||||
package_path = package_path / submodule
|
||||
|
||||
for file_path in package_path.rglob("*.py"):
|
||||
# Skip private modules
|
||||
if file_path.name.startswith("_"):
|
||||
continue
|
||||
|
||||
# Skip integration_template and project_template directories (for libs/cli)
|
||||
if "integration_template" in file_path.parts:
|
||||
continue
|
||||
|
||||
if "project_template" in file_path.parts:
|
||||
continue
|
||||
|
||||
@@ -215,8 +254,13 @@ def _load_package_modules(
|
||||
continue
|
||||
|
||||
# Get the full namespace of the module
|
||||
# Example: langchain_core/schema/output_parsers.py ->
|
||||
# langchain_core.schema.output_parsers
|
||||
namespace = str(relative_module_name).replace(".py", "").replace("/", ".")
|
||||
|
||||
# Keep only the top level namespace
|
||||
# Example: langchain_core.schema.output_parsers ->
|
||||
# langchain_core
|
||||
top_namespace = namespace.split(".")[0]
|
||||
|
||||
try:
|
||||
@@ -253,16 +297,16 @@ def _construct_doc(
|
||||
members_by_namespace: Dict[str, ModuleMembers],
|
||||
package_version: str,
|
||||
) -> List[typing.Tuple[str, str]]:
|
||||
"""Construct the contents of the reference.rst file for the given package.
|
||||
"""Construct the contents of the `reference.rst` for the given package.
|
||||
|
||||
Args:
|
||||
package_namespace: The package top level namespace
|
||||
members_by_namespace: The members of the package, dict organized by top level
|
||||
module contains a list of classes and functions
|
||||
inside of the top level namespace.
|
||||
members_by_namespace: The members of the package dict organized by top level.
|
||||
Module contains a list of classes and functions inside of the top level
|
||||
namespace.
|
||||
|
||||
Returns:
|
||||
The contents of the reference.rst file.
|
||||
The string contents of the reference.rst file.
|
||||
"""
|
||||
docs = []
|
||||
index_doc = f"""\
|
||||
@@ -465,10 +509,13 @@ def _construct_doc(
|
||||
|
||||
|
||||
def _build_rst_file(package_name: str = "langchain") -> None:
|
||||
"""Create a rst file for building of documentation.
|
||||
"""Create a rst file for a given package.
|
||||
|
||||
Args:
|
||||
package_name: Can be either "langchain" or "core" or "experimental".
|
||||
package_name: Name of the package to create the rst file for.
|
||||
|
||||
Returns:
|
||||
The rst file is created in the same directory as this script.
|
||||
"""
|
||||
package_dir = _package_dir(package_name)
|
||||
package_members = _load_package_modules(package_dir)
|
||||
@@ -487,7 +534,7 @@ def _package_namespace(package_name: str) -> str:
|
||||
"""Returns the package name used.
|
||||
|
||||
Args:
|
||||
package_name: Can be either "langchain" or "core" or "experimental".
|
||||
package_name: Can be either "langchain" or "core"
|
||||
|
||||
Returns:
|
||||
modified package_name: Can be either "langchain" or "langchain_{package_name}"
|
||||
@@ -500,7 +547,10 @@ def _package_namespace(package_name: str) -> str:
|
||||
|
||||
|
||||
def _package_dir(package_name: str = "langchain") -> Path:
|
||||
"""Return the path to the directory containing the documentation."""
|
||||
"""Return the path to the directory containing the documentation.
|
||||
|
||||
Attempts to find the package in `libs/` first, then `libs/partners/`.
|
||||
"""
|
||||
if (ROOT_DIR / "libs" / package_name).exists():
|
||||
return ROOT_DIR / "libs" / package_name / _package_namespace(package_name)
|
||||
else:
|
||||
@@ -514,7 +564,7 @@ def _package_dir(package_name: str = "langchain") -> Path:
|
||||
|
||||
|
||||
def _get_package_version(package_dir: Path) -> str:
|
||||
"""Return the version of the package."""
|
||||
"""Return the version of the package by reading the `pyproject.toml`."""
|
||||
try:
|
||||
with open(package_dir.parent / "pyproject.toml", "r") as f:
|
||||
pyproject = toml.load(f)
|
||||
@@ -540,6 +590,15 @@ def _out_file_path(package_name: str) -> Path:
|
||||
|
||||
|
||||
def _build_index(dirs: List[str]) -> None:
|
||||
"""Build the index.md file for the API reference.
|
||||
|
||||
Args:
|
||||
dirs: List of package directories to include in the index.
|
||||
|
||||
Returns:
|
||||
The index.md file is created in the same directory as this script.
|
||||
"""
|
||||
|
||||
custom_names = {
|
||||
"aws": "AWS",
|
||||
"ai21": "AI21",
|
||||
@@ -550,7 +609,6 @@ def _build_index(dirs: List[str]) -> None:
|
||||
"langchain",
|
||||
"text-splitters",
|
||||
"community",
|
||||
"experimental",
|
||||
"standard-tests",
|
||||
]
|
||||
main_ = [dir_ for dir_ in ordered if dir_ in dirs]
|
||||
@@ -648,9 +706,14 @@ See the full list of integrations in the Section Navigation.
|
||||
{integration_tree}
|
||||
```
|
||||
"""
|
||||
# Write the reference.md file
|
||||
with open(HERE / "reference.md", "w") as f:
|
||||
f.write(doc)
|
||||
|
||||
# Write a dummy index.md file that points to reference.md
|
||||
# Sphinx requires an index file to exist in each doc directory
|
||||
# TODO: investigate why we don't just put everything in index.md directly?
|
||||
# if it works it works I guess
|
||||
dummy_index = """\
|
||||
# API reference
|
||||
|
||||
@@ -666,8 +729,11 @@ Reference<reference>
|
||||
|
||||
|
||||
def main(dirs: Optional[list] = None) -> None:
|
||||
"""Generate the api_reference.rst file for each package."""
|
||||
print("Starting to build API reference files.")
|
||||
"""Generate the `api_reference.rst` file for each package.
|
||||
|
||||
If dirs is None, generate for all packages in `libs/` and `libs/partners/`.
|
||||
Otherwise generate only for the specified package(s).
|
||||
"""
|
||||
if not dirs:
|
||||
dirs = [
|
||||
p.parent.name
|
||||
@@ -676,18 +742,17 @@ def main(dirs: Optional[list] = None) -> None:
|
||||
if p.parent.parent.name in ("libs", "partners")
|
||||
]
|
||||
for dir_ in sorted(dirs):
|
||||
# Skip any hidden directories
|
||||
# Skip any hidden directories prefixed with a dot
|
||||
# Some of these could be present by mistake in the code base
|
||||
# e.g., .pytest_cache from running tests from the wrong location.
|
||||
# (e.g., .pytest_cache from running tests from the wrong location)
|
||||
if dir_.startswith("."):
|
||||
print("Skipping dir:", dir_)
|
||||
continue
|
||||
else:
|
||||
print("Building package:", dir_)
|
||||
print("Building:", dir_)
|
||||
_build_rst_file(package_name=dir_)
|
||||
|
||||
_build_index(sorted(dirs))
|
||||
print("API reference files built.")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
|
||||
File diff suppressed because one or more lines are too long
@@ -1,12 +1,12 @@
|
||||
autodoc_pydantic>=2,<3
|
||||
sphinx>=8,<9
|
||||
myst-parser>=3
|
||||
sphinx-autobuild>=2024
|
||||
pydata-sphinx-theme>=0.15
|
||||
toml>=0.10.2
|
||||
myst-nb>=1.1.1
|
||||
pyyaml
|
||||
sphinx-design
|
||||
sphinx-copybutton
|
||||
beautifulsoup4
|
||||
sphinxcontrib-googleanalytics
|
||||
pydata-sphinx-theme>=0.15
|
||||
myst-parser>=3
|
||||
myst-nb>=1.1.1
|
||||
toml>=0.10.2
|
||||
pyyaml
|
||||
beautifulsoup4
|
||||
|
||||
@@ -1,3 +1,10 @@
|
||||
"""Post-process generated HTML files to clean up table-of-contents headers.
|
||||
|
||||
Runs after Sphinx generates the API reference HTML. It finds TOC entries like
|
||||
"ClassName.method_name()" and shortens them to just "method_name()" for better
|
||||
readability in the sidebar navigation.
|
||||
"""
|
||||
|
||||
import sys
|
||||
from glob import glob
|
||||
from pathlib import Path
|
||||
|
||||
@@ -3,9 +3,9 @@
|
||||
Here are some things to keep in mind for all types of contributions:
|
||||
|
||||
- Follow the ["fork and pull request"](https://docs.github.com/en/get-started/exploring-projects-on-github/contributing-to-a-project) workflow.
|
||||
- Fill out the checked-in pull request template when opening pull requests. Note related issues and tag relevant maintainers.
|
||||
- Fill out the checked-in pull request template when opening pull requests. Note related issues.
|
||||
- Ensure your PR passes formatting, linting, and testing checks before requesting a review.
|
||||
- If you would like comments or feedback on your current progress, please open an issue or discussion and tag a maintainer.
|
||||
- If you would like comments or feedback on your current progress, please open an issue or discussion.
|
||||
- See the sections on [Testing](setup.mdx#testing) and [Formatting and Linting](setup.mdx#formatting-and-linting) for how to run these checks locally.
|
||||
- Backwards compatibility is key. Your changes must not be breaking, except in case of critical bug and security fixes.
|
||||
- Look for duplicate PRs or issues that have already been opened before opening a new one.
|
||||
|
||||
@@ -189,40 +189,6 @@ This can be very helpful when you've made changes to only certain parts of the p
|
||||
|
||||
We recognize linting can be annoying - if you do not want to do it, please contact a project maintainer, and they can help you with it. We do not want this to be a blocker for good code getting contributed.
|
||||
|
||||
### Spellcheck
|
||||
|
||||
Spellchecking for this project is done via [codespell](https://github.com/codespell-project/codespell).
|
||||
Note that `codespell` finds common typos, so it could have false-positive (correctly spelled but rarely used) and false-negatives (not finding misspelled) words.
|
||||
|
||||
To check spelling for this project:
|
||||
|
||||
```bash
|
||||
# If you have `make` installed:
|
||||
make spell_check
|
||||
|
||||
# If you don't have `make` (Windows alternative):
|
||||
uv run --all-groups codespell --toml pyproject.toml
|
||||
```
|
||||
|
||||
To fix spelling in place:
|
||||
|
||||
```bash
|
||||
# If you have `make` installed:
|
||||
make spell_fix
|
||||
|
||||
# If you don't have `make` (Windows alternative):
|
||||
uv run --all-groups codespell --toml pyproject.toml -w
|
||||
```
|
||||
|
||||
If codespell is incorrectly flagging a word, you can skip spellcheck for that word by adding it to the codespell config in the `pyproject.toml` file.
|
||||
|
||||
```python
|
||||
[tool.codespell]
|
||||
...
|
||||
# Add here:
|
||||
ignore-words-list = 'momento,collison,ned,foor,reworkd,parth,whats,aapply,mysogyny,unsecure'
|
||||
```
|
||||
|
||||
### Pre-commit
|
||||
|
||||
We use [pre-commit](https://pre-commit.com/) to ensure commits are formatted/linted.
|
||||
|
||||
@@ -72,7 +72,7 @@ See [supported integrations](/docs/integrations/chat/) for details on getting st
|
||||
|
||||
### Example selectors
|
||||
|
||||
[Example Selectors](/docs/concepts/example_selectors) are responsible for selecting the correct few shot examples to pass to the prompt.
|
||||
[Example Selectors](/docs/concepts/example_selectors) are responsible for selecting the correct few-shot examples to pass to the prompt.
|
||||
|
||||
- [How to: use example selectors](/docs/how_to/example_selectors)
|
||||
- [How to: select examples by length](/docs/how_to/example_selectors_length_based)
|
||||
@@ -168,7 +168,7 @@ See [supported integrations](/docs/integrations/vectorstores/) for details on ge
|
||||
|
||||
Indexing is the process of keeping your vectorstore in-sync with the underlying data source.
|
||||
|
||||
- [How to: reindex data to keep your vectorstore in sync with the underlying data source](/docs/how_to/indexing)
|
||||
- [How to: reindex data to keep your vectorstore in-sync with the underlying data source](/docs/how_to/indexing)
|
||||
|
||||
### Tools
|
||||
|
||||
|
||||
@@ -61,7 +61,7 @@
|
||||
" * document addition by id (`add_documents` method with `ids` argument)\n",
|
||||
" * delete by id (`delete` method with `ids` argument)\n",
|
||||
"\n",
|
||||
"Compatible Vectorstores: `Aerospike`, `AnalyticDB`, `AstraDB`, `AwaDB`, `AzureCosmosDBNoSqlVectorSearch`, `AzureCosmosDBVectorSearch`, `AzureSearch`, `Bagel`, `Cassandra`, `Chroma`, `CouchbaseVectorStore`, `DashVector`, `DatabricksVectorSearch`, `DeepLake`, `Dingo`, `ElasticVectorSearch`, `ElasticsearchStore`, `FAISS`, `HanaDB`, `Milvus`, `MongoDBAtlasVectorSearch`, `MyScale`, `OpenSearchVectorSearch`, `PGVector`, `Pinecone`, `Qdrant`, `Redis`, `Rockset`, `ScaNN`, `SingleStoreDB`, `SupabaseVectorStore`, `SurrealDBStore`, `TimescaleVector`, `Vald`, `VDMS`, `Vearch`, `VespaStore`, `Weaviate`, `Yellowbrick`, `ZepVectorStore`, `TencentVectorDB`, `OpenSearchVectorSearch`.\n",
|
||||
"Compatible Vectorstores: `AnalyticDB`, `AstraDB`, `AwaDB`, `AzureCosmosDBNoSqlVectorSearch`, `AzureCosmosDBVectorSearch`, `AzureSearch`, `Bagel`, `Cassandra`, `Chroma`, `CouchbaseVectorStore`, `DashVector`, `DatabricksVectorSearch`, `DeepLake`, `Dingo`, `ElasticVectorSearch`, `ElasticsearchStore`, `FAISS`, `HanaDB`, `Milvus`, `MongoDBAtlasVectorSearch`, `MyScale`, `OpenSearchVectorSearch`, `PGVector`, `Pinecone`, `Qdrant`, `Redis`, `Rockset`, `ScaNN`, `SingleStoreDB`, `SupabaseVectorStore`, `SurrealDBStore`, `TimescaleVector`, `Vald`, `VDMS`, `Vearch`, `VespaStore`, `Weaviate`, `Yellowbrick`, `ZepVectorStore`, `TencentVectorDB`, `OpenSearchVectorSearch`.\n",
|
||||
" \n",
|
||||
"## Caution\n",
|
||||
"\n",
|
||||
|
||||
@@ -58,7 +58,7 @@
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 10,
|
||||
"execution_count": null,
|
||||
"id": "1fcf7b27-1cc3-420a-b920-0420b5892e20",
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
@@ -102,7 +102,7 @@
|
||||
" ],\n",
|
||||
"}\n",
|
||||
"response = llm.invoke([message])\n",
|
||||
"print(response.text())"
|
||||
"print(response.text)"
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -133,7 +133,7 @@
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 2,
|
||||
"execution_count": null,
|
||||
"id": "99d27f8f-ae78-48bc-9bf2-3cef35213ec7",
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
@@ -163,7 +163,7 @@
|
||||
" ],\n",
|
||||
"}\n",
|
||||
"response = llm.invoke([message])\n",
|
||||
"print(response.text())"
|
||||
"print(response.text)"
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -176,7 +176,7 @@
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 4,
|
||||
"execution_count": null,
|
||||
"id": "325fb4ca",
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
@@ -198,7 +198,7 @@
|
||||
" ],\n",
|
||||
"}\n",
|
||||
"response = llm.invoke([message])\n",
|
||||
"print(response.text())"
|
||||
"print(response.text)"
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -234,7 +234,7 @@
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 3,
|
||||
"execution_count": null,
|
||||
"id": "6c1455a9-699a-4702-a7e0-7f6eaec76a21",
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
@@ -284,7 +284,7 @@
|
||||
" ],\n",
|
||||
"}\n",
|
||||
"response = llm.invoke([message])\n",
|
||||
"print(response.text())"
|
||||
"print(response.text)"
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -312,7 +312,7 @@
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 4,
|
||||
"execution_count": null,
|
||||
"id": "55e1d937-3b22-4deb-b9f0-9e688f0609dc",
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
@@ -342,7 +342,7 @@
|
||||
" ],\n",
|
||||
"}\n",
|
||||
"response = llm.invoke([message])\n",
|
||||
"print(response.text())"
|
||||
"print(response.text)"
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -417,7 +417,7 @@
|
||||
" ],\n",
|
||||
"}\n",
|
||||
"response = llm.invoke([message])\n",
|
||||
"print(response.text())"
|
||||
"print(response.text)"
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -443,7 +443,7 @@
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 2,
|
||||
"execution_count": null,
|
||||
"id": "83593b9d-a8d3-4c99-9dac-64e0a9d397cb",
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
@@ -488,13 +488,13 @@
|
||||
" ],\n",
|
||||
"}\n",
|
||||
"response = llm.invoke([message])\n",
|
||||
"print(response.text())\n",
|
||||
"print(response.text)\n",
|
||||
"response.usage_metadata"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 3,
|
||||
"execution_count": null,
|
||||
"id": "9bbf578e-794a-4dc0-a469-78c876ccd4a3",
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
@@ -530,7 +530,7 @@
|
||||
" ],\n",
|
||||
"}\n",
|
||||
"response = llm.invoke([message, response, next_message])\n",
|
||||
"print(response.text())\n",
|
||||
"print(response.text)\n",
|
||||
"response.usage_metadata"
|
||||
]
|
||||
},
|
||||
@@ -600,7 +600,7 @@
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 5,
|
||||
"execution_count": null,
|
||||
"id": "ae076c9b-ff8f-461d-9349-250f396c9a25",
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
@@ -641,7 +641,7 @@
|
||||
" ],\n",
|
||||
"}\n",
|
||||
"response = llm.invoke([message])\n",
|
||||
"print(response.text())"
|
||||
"print(response.text)"
|
||||
]
|
||||
},
|
||||
{
|
||||
|
||||
@@ -54,7 +54,7 @@
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 2,
|
||||
"execution_count": null,
|
||||
"id": "5df2e558-321d-4cf7-994e-2815ac37e704",
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
@@ -75,7 +75,7 @@
|
||||
"\n",
|
||||
"chain = prompt | llm\n",
|
||||
"response = chain.invoke({\"image_url\": url})\n",
|
||||
"print(response.text())"
|
||||
"print(response.text)"
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -117,7 +117,7 @@
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 4,
|
||||
"execution_count": null,
|
||||
"id": "25e4829e-0073-49a8-9669-9f43e5778383",
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
@@ -144,7 +144,7 @@
|
||||
" \"cache_type\": \"ephemeral\",\n",
|
||||
" }\n",
|
||||
")\n",
|
||||
"print(response.text())"
|
||||
"print(response.text)"
|
||||
]
|
||||
},
|
||||
{
|
||||
|
||||
@@ -668,7 +668,7 @@
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 14,
|
||||
"execution_count": null,
|
||||
"id": "df0370e3",
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
@@ -685,7 +685,7 @@
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"structured_llm = llm.with_structured_output(None, method=\"json_mode\")\n",
|
||||
"structured_llm = llm.with_structured_output(None, method=\"json_schema\")\n",
|
||||
"\n",
|
||||
"structured_llm.invoke(\n",
|
||||
" \"Tell me a joke about cats, respond in JSON with `setup` and `punchline` keys\"\n",
|
||||
|
||||
@@ -39,6 +39,16 @@
|
||||
"/>\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "ecc06359",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"See also: [How to summarize through parallelization](/docs/how_to/summarize_map_reduce/) and\n",
|
||||
"[How to summarize through iterative refinement](/docs/how_to/summarize_refine/).\n",
|
||||
"\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 1,
|
||||
|
||||
@@ -55,7 +55,7 @@
|
||||
"source": [
|
||||
"## Defining tool schemas\n",
|
||||
"\n",
|
||||
"For a model to be able to call tools, we need to pass in tool schemas that describe what the tool does and what it's arguments are. Chat models that support tool calling features implement a `.bind_tools()` method for passing tool schemas to the model. Tool schemas can be passed in as Python functions (with typehints and docstrings), Pydantic models, TypedDict classes, or LangChain [Tool objects](https://python.langchain.com/api_reference/core/tools/langchain_core.tools.base.BaseTool.html#basetool). Subsequent invocations of the model will pass in these tool schemas along with the prompt.\n",
|
||||
"For a model to be able to call tools, we need to pass in tool schemas that describe what the tool does and what its arguments are. Chat models that support tool calling features implement a `.bind_tools()` method for passing tool schemas to the model. Tool schemas can be passed in as Python functions (with typehints and docstrings), Pydantic models, TypedDict classes, or LangChain [Tool objects](https://python.langchain.com/api_reference/core/tools/langchain_core.tools.base.BaseTool.html#basetool). Subsequent invocations of the model will pass in these tool schemas along with the prompt.\n",
|
||||
"\n",
|
||||
"### Python functions\n",
|
||||
"Our tool schemas can be Python functions:"
|
||||
|
||||
@@ -7,10 +7,7 @@
|
||||
"source": [
|
||||
"# Confident\n",
|
||||
"\n",
|
||||
">[DeepEval](https://confident-ai.com) package for unit testing LLMs.\n",
|
||||
"> Using Confident, everyone can build robust language models through faster iterations\n",
|
||||
"> using both unit testing and integration testing. We provide support for each step in the iteration\n",
|
||||
"> from synthetic data creation to testing.\n"
|
||||
">[DeepEval](https://confident-ai.com) package for unit testing LLMs."
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -42,7 +39,7 @@
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"%pip install --upgrade --quiet langchain langchain-openai langchain-community deepeval langchain-chroma"
|
||||
"!pip install deepeval langchain langchain-openai"
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -64,11 +61,29 @@
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 11,
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
"text/html": [
|
||||
"<pre style=\"white-space:pre;overflow-x:auto;line-height:normal;font-family:Menlo,'DejaVu Sans Mono',consolas,'Courier New',monospace\">🎉🥳 Congratulations! You've successfully logged in! 🙌 \n",
|
||||
"</pre>\n"
|
||||
],
|
||||
"text/plain": [
|
||||
"🎉🥳 Congratulations! You've successfully logged in! 🙌 \n"
|
||||
]
|
||||
},
|
||||
"metadata": {},
|
||||
"output_type": "display_data"
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"!deepeval login"
|
||||
"import os\n",
|
||||
"import deepeval\n",
|
||||
"\n",
|
||||
"api_key = os.getenv(\"DEEPEVAL_API_KEY\")\n",
|
||||
"deepeval.login(api_key)"
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -76,12 +91,9 @@
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"### Setup DeepEval\n",
|
||||
"### Setup Confident AI Callback (Modern)\n",
|
||||
"\n",
|
||||
"You can, by default, use the `DeepEvalCallbackHandler` to set up the metrics you want to track. However, this has limited support for metrics at the moment (more to be added soon). It currently supports:\n",
|
||||
"- [Answer Relevancy](https://docs.confident-ai.com/docs/measuring_llm_performance/answer_relevancy)\n",
|
||||
"- [Bias](https://docs.confident-ai.com/docs/measuring_llm_performance/debias)\n",
|
||||
"- [Toxicness](https://docs.confident-ai.com/docs/measuring_llm_performance/non_toxic)"
|
||||
"The previous DeepEvalCallbackHandler and metric tracking are deprecated. Please use the new integration below."
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -90,10 +102,15 @@
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"from deepeval.metrics.answer_relevancy import AnswerRelevancy\n",
|
||||
"from deepeval.integrations.langchain import CallbackHandler\n",
|
||||
"\n",
|
||||
"# Here we want to make sure the answer is minimally relevant\n",
|
||||
"answer_relevancy_metric = AnswerRelevancy(minimum_score=0.5)"
|
||||
"handler = CallbackHandler(\n",
|
||||
" name=\"My Trace\",\n",
|
||||
" tags=[\"production\", \"v1\"],\n",
|
||||
" metadata={\"experiment\": \"A/B\"},\n",
|
||||
" thread_id=\"thread-123\",\n",
|
||||
" user_id=\"user-456\",\n",
|
||||
")"
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -103,186 +120,11 @@
|
||||
"source": [
|
||||
"## Get Started"
|
||||
]
|
||||
},
|
||||
{
|
||||
"attachments": {},
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"To use the `DeepEvalCallbackHandler`, we need the `implementation_name`. "
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"from langchain_community.callbacks.confident_callback import DeepEvalCallbackHandler\n",
|
||||
"\n",
|
||||
"deepeval_callback = DeepEvalCallbackHandler(\n",
|
||||
" implementation_name=\"langchainQuickstart\", metrics=[answer_relevancy_metric]\n",
|
||||
")"
|
||||
]
|
||||
},
|
||||
{
|
||||
"attachments": {},
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"### Scenario 1: Feeding into LLM\n",
|
||||
"\n",
|
||||
"You can then feed it into your LLM with OpenAI."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 7,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
"text/plain": [
|
||||
"LLMResult(generations=[[Generation(text='\\n\\nQ: What did the fish say when he hit the wall? \\nA: Dam.', generation_info={'finish_reason': 'stop', 'logprobs': None})], [Generation(text='\\n\\nThe Moon \\n\\nThe moon is high in the midnight sky,\\nSparkling like a star above.\\nThe night so peaceful, so serene,\\nFilling up the air with love.\\n\\nEver changing and renewing,\\nA never-ending light of grace.\\nThe moon remains a constant view,\\nA reminder of life’s gentle pace.\\n\\nThrough time and space it guides us on,\\nA never-fading beacon of hope.\\nThe moon shines down on us all,\\nAs it continues to rise and elope.', generation_info={'finish_reason': 'stop', 'logprobs': None})], [Generation(text='\\n\\nQ. What did one magnet say to the other magnet?\\nA. \"I find you very attractive!\"', generation_info={'finish_reason': 'stop', 'logprobs': None})], [Generation(text=\"\\n\\nThe world is charged with the grandeur of God.\\nIt will flame out, like shining from shook foil;\\nIt gathers to a greatness, like the ooze of oil\\nCrushed. Why do men then now not reck his rod?\\n\\nGenerations have trod, have trod, have trod;\\nAnd all is seared with trade; bleared, smeared with toil;\\nAnd wears man's smudge and shares man's smell: the soil\\nIs bare now, nor can foot feel, being shod.\\n\\nAnd for all this, nature is never spent;\\nThere lives the dearest freshness deep down things;\\nAnd though the last lights off the black West went\\nOh, morning, at the brown brink eastward, springs —\\n\\nBecause the Holy Ghost over the bent\\nWorld broods with warm breast and with ah! bright wings.\\n\\n~Gerard Manley Hopkins\", generation_info={'finish_reason': 'stop', 'logprobs': None})], [Generation(text='\\n\\nQ: What did one ocean say to the other ocean?\\nA: Nothing, they just waved.', generation_info={'finish_reason': 'stop', 'logprobs': None})], [Generation(text=\"\\n\\nA poem for you\\n\\nOn a field of green\\n\\nThe sky so blue\\n\\nA gentle breeze, the sun above\\n\\nA beautiful world, for us to love\\n\\nLife is a journey, full of surprise\\n\\nFull of joy and full of surprise\\n\\nBe brave and take small steps\\n\\nThe future will be revealed with depth\\n\\nIn the morning, when dawn arrives\\n\\nA fresh start, no reason to hide\\n\\nSomewhere down the road, there's a heart that beats\\n\\nBelieve in yourself, you'll always succeed.\", generation_info={'finish_reason': 'stop', 'logprobs': None})]], llm_output={'token_usage': {'completion_tokens': 504, 'total_tokens': 528, 'prompt_tokens': 24}, 'model_name': 'text-davinci-003'})"
|
||||
]
|
||||
},
|
||||
"execution_count": 7,
|
||||
"metadata": {},
|
||||
"output_type": "execute_result"
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"from langchain_openai import OpenAI\n",
|
||||
"\n",
|
||||
"llm = OpenAI(\n",
|
||||
" temperature=0,\n",
|
||||
" callbacks=[deepeval_callback],\n",
|
||||
" verbose=True,\n",
|
||||
" openai_api_key=\"<YOUR_API_KEY>\",\n",
|
||||
")\n",
|
||||
"output = llm.generate(\n",
|
||||
" [\n",
|
||||
" \"What is the best evaluation tool out there? (no bias at all)\",\n",
|
||||
" ]\n",
|
||||
")"
|
||||
]
|
||||
},
|
||||
{
|
||||
"attachments": {},
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"You can then check the metric if it was successful by calling the `is_successful()` method."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"answer_relevancy_metric.is_successful()\n",
|
||||
"# returns True/False"
|
||||
]
|
||||
},
|
||||
{
|
||||
"attachments": {},
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"Once you have ran that, you should be able to see our dashboard below. \n",
|
||||
"\n",
|
||||
""
|
||||
]
|
||||
},
|
||||
{
|
||||
"attachments": {},
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"### Scenario 2: Tracking an LLM in a chain without callbacks\n",
|
||||
"\n",
|
||||
"To track an LLM in a chain without callbacks, you can plug into it at the end.\n",
|
||||
"\n",
|
||||
"We can start by defining a simple chain as shown below."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"import requests\n",
|
||||
"from langchain.chains import RetrievalQA\n",
|
||||
"from langchain_chroma import Chroma\n",
|
||||
"from langchain_community.document_loaders import TextLoader\n",
|
||||
"from langchain_openai import OpenAI, OpenAIEmbeddings\n",
|
||||
"from langchain_text_splitters import CharacterTextSplitter\n",
|
||||
"\n",
|
||||
"text_file_url = \"https://raw.githubusercontent.com/hwchase17/chat-your-data/master/state_of_the_union.txt\"\n",
|
||||
"\n",
|
||||
"openai_api_key = \"sk-XXX\"\n",
|
||||
"\n",
|
||||
"with open(\"state_of_the_union.txt\", \"w\") as f:\n",
|
||||
" response = requests.get(text_file_url)\n",
|
||||
" f.write(response.text)\n",
|
||||
"\n",
|
||||
"loader = TextLoader(\"state_of_the_union.txt\")\n",
|
||||
"documents = loader.load()\n",
|
||||
"text_splitter = CharacterTextSplitter(chunk_size=1000, chunk_overlap=0)\n",
|
||||
"texts = text_splitter.split_documents(documents)\n",
|
||||
"\n",
|
||||
"embeddings = OpenAIEmbeddings(openai_api_key=openai_api_key)\n",
|
||||
"docsearch = Chroma.from_documents(texts, embeddings)\n",
|
||||
"\n",
|
||||
"qa = RetrievalQA.from_chain_type(\n",
|
||||
" llm=OpenAI(openai_api_key=openai_api_key),\n",
|
||||
" chain_type=\"stuff\",\n",
|
||||
" retriever=docsearch.as_retriever(),\n",
|
||||
")\n",
|
||||
"\n",
|
||||
"# Providing a new question-answering pipeline\n",
|
||||
"query = \"Who is the president?\"\n",
|
||||
"result = qa.run(query)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"attachments": {},
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"After defining a chain, you can then manually check for answer similarity."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"answer_relevancy_metric.measure(result, query)\n",
|
||||
"answer_relevancy_metric.is_successful()"
|
||||
]
|
||||
},
|
||||
{
|
||||
"attachments": {},
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"### What's next?\n",
|
||||
"\n",
|
||||
"You can create your own custom metrics [here](https://docs.confident-ai.com/docs/quickstart/custom-metrics). \n",
|
||||
"\n",
|
||||
"DeepEval also offers other features such as being able to [automatically create unit tests](https://docs.confident-ai.com/docs/quickstart/synthetic-data-creation), [tests for hallucination](https://docs.confident-ai.com/docs/measuring_llm_performance/factual_consistency).\n",
|
||||
"\n",
|
||||
"If you are interested, check out our Github repository here [https://github.com/confident-ai/deepeval](https://github.com/confident-ai/deepeval). We welcome any PRs and discussions on how to improve LLM performance."
|
||||
]
|
||||
}
|
||||
],
|
||||
"metadata": {
|
||||
"kernelspec": {
|
||||
"display_name": "Python 3 (ipykernel)",
|
||||
"display_name": "langchain",
|
||||
"language": "python",
|
||||
"name": "python3"
|
||||
},
|
||||
@@ -296,12 +138,7 @@
|
||||
"name": "python",
|
||||
"nbconvert_exporter": "python",
|
||||
"pygments_lexer": "ipython3",
|
||||
"version": "3.10.12"
|
||||
},
|
||||
"vscode": {
|
||||
"interpreter": {
|
||||
"hash": "a53ebf4a859167383b364e7e7521d0add3c2dbbdecce4edf676e8c4634ff3fbb"
|
||||
}
|
||||
"version": "3.12.11"
|
||||
}
|
||||
},
|
||||
"nbformat": 4,
|
||||
|
||||
288
docs/docs/integrations/chat/aimlapi.ipynb
Normal file
288
docs/docs/integrations/chat/aimlapi.ipynb
Normal file
@@ -0,0 +1,288 @@
|
||||
{
|
||||
"cells": [
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "fbeb3f1eb129d115",
|
||||
"metadata": {
|
||||
"collapsed": false
|
||||
},
|
||||
"source": [
|
||||
"---\n",
|
||||
"sidebar_label: AI/ML API\n",
|
||||
"---"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "6051ba9cfc65a60a",
|
||||
"metadata": {
|
||||
"collapsed": false
|
||||
},
|
||||
"source": [
|
||||
"# ChatAimlapi\n",
|
||||
"\n",
|
||||
"This page will help you get started with AI/ML API [chat models](/docs/concepts/chat_models.mdx). For detailed documentation of all ChatAimlapi features and configurations, head to the [API reference](https://docs.aimlapi.com/?utm_source=langchain&utm_medium=github&utm_campaign=integration).\n",
|
||||
"\n",
|
||||
"AI/ML API provides access to **300+ models** (Deepseek, Gemini, ChatGPT, etc.) via high-uptime and high-rate API."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "512f94fa4bea2628",
|
||||
"metadata": {
|
||||
"collapsed": false
|
||||
},
|
||||
"source": [
|
||||
"## Overview\n",
|
||||
"### Integration details\n",
|
||||
"\n",
|
||||
"| Class | Package | Local | Serializable | JS support | Package downloads | Package latest |\n",
|
||||
"| :--- | :--- | :---: | :---: | :---: | :---: | :---: |\n",
|
||||
"| ChatAimlapi | langchain-aimlapi | ✅ | beta | ❌ |  |  |"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "7163684608502d37",
|
||||
"metadata": {
|
||||
"collapsed": false
|
||||
},
|
||||
"source": [
|
||||
"### Model features\n",
|
||||
"| Tool calling | Structured output | JSON mode | Image input | Audio input | Video input | Token-level streaming | Native async | Token usage | Logprobs |\n",
|
||||
"|:------------:|:-----------------:|:---------:|:-----------:|:-----------:|:-----------:|:---------------------:|:------------:|:-----------:|:--------:|\n",
|
||||
"| ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "bb9345d5b24a7741",
|
||||
"metadata": {
|
||||
"collapsed": false
|
||||
},
|
||||
"source": [
|
||||
"## Setup\n",
|
||||
"To access AI/ML API models, sign up at [aimlapi.com](https://aimlapi.com/app/?utm_source=langchain&utm_medium=github&utm_campaign=integration), generate an API key, and set the `AIMLAPI_API_KEY` environment variable:"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 1,
|
||||
"id": "b26280519672f194",
|
||||
"metadata": {
|
||||
"collapsed": false,
|
||||
"ExecuteTime": {
|
||||
"end_time": "2025-08-07T07:16:58.837623Z",
|
||||
"start_time": "2025-08-07T07:16:55.346214Z"
|
||||
}
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"import getpass\n",
|
||||
"import os\n",
|
||||
"\n",
|
||||
"if \"AIMLAPI_API_KEY\" not in os.environ:\n",
|
||||
" os.environ[\"AIMLAPI_API_KEY\"] = getpass.getpass(\"Enter your AI/ML API key: \")"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "fa131229e62dfd47",
|
||||
"metadata": {
|
||||
"collapsed": false
|
||||
},
|
||||
"source": [
|
||||
"### Installation\n",
|
||||
"Install the `langchain-aimlapi` package:"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 2,
|
||||
"id": "3777dc00d768299e",
|
||||
"metadata": {
|
||||
"collapsed": false,
|
||||
"ExecuteTime": {
|
||||
"end_time": "2025-08-07T07:17:11.195741Z",
|
||||
"start_time": "2025-08-07T07:17:02.288142Z"
|
||||
}
|
||||
},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"Note: you may need to restart the kernel to use updated packages.\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"%pip install -qU langchain-aimlapi"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "d168108b0c4f9d7",
|
||||
"metadata": {
|
||||
"collapsed": false
|
||||
},
|
||||
"source": [
|
||||
"## Instantiation\n",
|
||||
"Now we can instantiate the `ChatAimlapi` model and generate chat completions:"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 3,
|
||||
"id": "f29131e65e47bd16",
|
||||
"metadata": {
|
||||
"collapsed": false,
|
||||
"ExecuteTime": {
|
||||
"end_time": "2025-08-07T07:17:23.499746Z",
|
||||
"start_time": "2025-08-07T07:17:11.196747Z"
|
||||
}
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"from langchain_aimlapi import ChatAimlapi\n",
|
||||
"\n",
|
||||
"llm = ChatAimlapi(\n",
|
||||
" model=\"meta-llama/Llama-3-70b-chat-hf\",\n",
|
||||
" temperature=0.7,\n",
|
||||
" max_tokens=512,\n",
|
||||
" timeout=30,\n",
|
||||
" max_retries=3,\n",
|
||||
")"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "861b87289f8e146d",
|
||||
"metadata": {
|
||||
"collapsed": false
|
||||
},
|
||||
"source": [
|
||||
"## Invocation\n",
|
||||
"You can invoke the model with a list of messages:"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 4,
|
||||
"id": "430b1cff2e6d77b4",
|
||||
"metadata": {
|
||||
"collapsed": false,
|
||||
"ExecuteTime": {
|
||||
"end_time": "2025-08-07T07:17:30.586261Z",
|
||||
"start_time": "2025-08-07T07:17:29.074409Z"
|
||||
}
|
||||
},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"J'adore la programmation.\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"messages = [\n",
|
||||
" (\"system\", \"You are a helpful assistant that translates English to French.\"),\n",
|
||||
" (\"human\", \"I love programming.\"),\n",
|
||||
"]\n",
|
||||
"\n",
|
||||
"ai_msg = llm.invoke(messages)\n",
|
||||
"print(ai_msg.content)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "5463797524a19b2e",
|
||||
"metadata": {
|
||||
"collapsed": false
|
||||
},
|
||||
"source": [
|
||||
"## Chaining\n",
|
||||
"We can chain the model with a prompt template as follows:"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 5,
|
||||
"id": "bf6defc12a0c5d78",
|
||||
"metadata": {
|
||||
"collapsed": false,
|
||||
"ExecuteTime": {
|
||||
"end_time": "2025-08-07T07:17:36.368436Z",
|
||||
"start_time": "2025-08-07T07:17:34.770581Z"
|
||||
}
|
||||
},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"Ich liebe das Programmieren.\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"from langchain_core.prompts import ChatPromptTemplate\n",
|
||||
"\n",
|
||||
"prompt = ChatPromptTemplate.from_messages(\n",
|
||||
" [\n",
|
||||
" (\n",
|
||||
" \"system\",\n",
|
||||
" \"You are a helpful assistant that translates {input_language} to {output_language}.\",\n",
|
||||
" ),\n",
|
||||
" (\"human\", \"{input}\"),\n",
|
||||
" ]\n",
|
||||
")\n",
|
||||
"\n",
|
||||
"chain = prompt | llm\n",
|
||||
"response = chain.invoke(\n",
|
||||
" {\n",
|
||||
" \"input_language\": \"English\",\n",
|
||||
" \"output_language\": \"German\",\n",
|
||||
" \"input\": \"I love programming.\",\n",
|
||||
" }\n",
|
||||
")\n",
|
||||
"print(response.content)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "fcf0bf10a872355c",
|
||||
"metadata": {
|
||||
"collapsed": false
|
||||
},
|
||||
"source": [
|
||||
"## API reference\n",
|
||||
"\n",
|
||||
"For detailed documentation of all ChatAimlapi features and configurations, visit the [API Reference](https://docs.aimlapi.com/?utm_source=langchain&utm_medium=github&utm_campaign=integration)."
|
||||
]
|
||||
}
|
||||
],
|
||||
"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
|
||||
}
|
||||
@@ -19,7 +19,7 @@
|
||||
"\n",
|
||||
"This notebook provides a quick overview for getting started with Anthropic [chat models](/docs/concepts/chat_models). For detailed documentation of all ChatAnthropic features and configurations head to the [API reference](https://python.langchain.com/api_reference/anthropic/chat_models/langchain_anthropic.chat_models.ChatAnthropic.html).\n",
|
||||
"\n",
|
||||
"Anthropic has several chat models. You can find information about their latest models and their costs, context windows, and supported input types in the [Anthropic docs](https://docs.anthropic.com/en/docs/models-overview).\n",
|
||||
"Anthropic has several chat models. You can find information about their latest models and their costs, context windows, and supported input types in the [Anthropic docs](https://docs.anthropic.com/en/docs/about-claude/models/overview).\n",
|
||||
"\n",
|
||||
"\n",
|
||||
":::info AWS Bedrock and Google VertexAI\n",
|
||||
@@ -840,7 +840,7 @@
|
||||
"source": [
|
||||
"## Token-efficient tool use\n",
|
||||
"\n",
|
||||
"Anthropic supports a (beta) [token-efficient tool use](https://docs.anthropic.com/en/docs/build-with-claude/tool-use/token-efficient-tool-use) feature. To use it, specify the relevant beta-headers when instantiating the model."
|
||||
"Anthropic supports a (beta) [token-efficient tool use](https://docs.anthropic.com/en/docs/agents-and-tools/tool-use/token-efficient-tool-use) feature. To use it, specify the relevant beta-headers when instantiating the model."
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -970,8 +970,8 @@
|
||||
"source": [
|
||||
"### In tool results (agentic RAG)\n",
|
||||
"\n",
|
||||
":::info Requires ``langchain-anthropic>=0.3.17``\n",
|
||||
"\n",
|
||||
":::info\n",
|
||||
"Requires ``langchain-anthropic>=0.3.17``\n",
|
||||
":::\n",
|
||||
"\n",
|
||||
"Claude supports a [search_result](https://docs.anthropic.com/en/docs/build-with-claude/search-results) content block representing citable results from queries against a knowledge base or other custom source. These content blocks can be passed to claude both top-line (as in the above example) and within a tool result. This allows Claude to cite elements of its response using the result of a tool call.\n",
|
||||
@@ -998,8 +998,6 @@
|
||||
" ]\n",
|
||||
"```\n",
|
||||
"\n",
|
||||
"We also need to specify the `search-results-2025-06-09` beta when instantiating ChatAnthropic. You can see an end-to-end example below.\n",
|
||||
"\n",
|
||||
"<details>\n",
|
||||
"<summary>End to end example with LangGraph</summary>\n",
|
||||
"\n",
|
||||
@@ -1193,6 +1191,40 @@
|
||||
"response.content"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "74247a07-b153-444f-9c56-77659aeefc88",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## Context management\n",
|
||||
"\n",
|
||||
"Anthropic supports a context editing feature that will automatically manage the model's context window (e.g., by clearing tool results).\n",
|
||||
"\n",
|
||||
"See [Anthropic documentation](https://docs.claude.com/en/docs/build-with-claude/context-editing) for details and configuration options.\n",
|
||||
"\n",
|
||||
":::info\n",
|
||||
"Requires ``langchain-anthropic>=0.3.21``\n",
|
||||
":::"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "cbb79c5d-37b5-4212-b36f-f27366192cf9",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"from langchain_anthropic import ChatAnthropic\n",
|
||||
"\n",
|
||||
"llm = ChatAnthropic(\n",
|
||||
" model=\"claude-sonnet-4-5-20250929\",\n",
|
||||
" betas=[\"context-management-2025-06-27\"],\n",
|
||||
" context_management={\"edits\": [{\"type\": \"clear_tool_uses_20250919\"}]},\n",
|
||||
")\n",
|
||||
"llm_with_tools = llm.bind_tools([{\"type\": \"web_search_20250305\", \"name\": \"web_search\"}])\n",
|
||||
"response = llm_with_tools.invoke(\"Search for recent developments in AI\")"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "cbfec7a9-d9df-4d12-844e-d922456dd9bf",
|
||||
@@ -1200,7 +1232,7 @@
|
||||
"source": [
|
||||
"## Built-in tools\n",
|
||||
"\n",
|
||||
"Anthropic supports a variety of [built-in tools](https://docs.anthropic.com/en/docs/build-with-claude/tool-use/text-editor-tool), which can be bound to the model in the [usual way](/docs/how_to/tool_calling/). Claude will generate tool calls adhering to its internal schema for the tool:"
|
||||
"Anthropic supports a variety of [built-in tools](https://docs.anthropic.com/en/docs/agents-and-tools/tool-use/text-editor-tool), which can be bound to the model in the [usual way](/docs/how_to/tool_calling/). Claude will generate tool calls adhering to its internal schema for the tool:"
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -1210,7 +1242,7 @@
|
||||
"source": [
|
||||
"### Web search\n",
|
||||
"\n",
|
||||
"Claude can use a [web search tool](https://docs.anthropic.com/en/docs/build-with-claude/tool-use/web-search-tool) to run searches and ground its responses with citations."
|
||||
"Claude can use a [web search tool](https://docs.anthropic.com/en/docs/agents-and-tools/tool-use/web-search-tool) to run searches and ground its responses with citations."
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -1292,6 +1324,58 @@
|
||||
"print(f\"Key Points: {result.key_points}\")"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "c580c20a",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"### Web fetching\n",
|
||||
"\n",
|
||||
"Claude can use a [web fetching tool](https://docs.anthropic.com/en/docs/agents-and-tools/tool-use/web-fetch-tool) to run searches and ground its responses with citations."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "5cf6ad08",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
":::info\n",
|
||||
"Web search tool is supported since ``langchain-anthropic>=0.3.20``\n",
|
||||
":::"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "c4804be1",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"from langchain_anthropic import ChatAnthropic\n",
|
||||
"\n",
|
||||
"llm = ChatAnthropic(\n",
|
||||
" model=\"claude-3-5-haiku-latest\",\n",
|
||||
" betas=[\"web-fetch-2025-09-10\"], # Enable web fetch beta\n",
|
||||
")\n",
|
||||
"\n",
|
||||
"tool = {\"type\": \"web_fetch_20250910\", \"name\": \"web_fetch\", \"max_uses\": 3}\n",
|
||||
"llm_with_tools = llm.bind_tools([tool])\n",
|
||||
"\n",
|
||||
"response = llm_with_tools.invoke(\n",
|
||||
" \"Please analyze the content at https://example.com/article\"\n",
|
||||
")"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "088c41d0",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
":::warning\n",
|
||||
"Note: you must add the `'web-fetch-2025-09-10'` beta header to use this tool.\n",
|
||||
":::"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "1478cdc6-2e52-4870-80f9-b4ddf88f2db2",
|
||||
@@ -1301,14 +1385,14 @@
|
||||
"\n",
|
||||
"Claude can use a [code execution tool](https://docs.anthropic.com/en/docs/agents-and-tools/tool-use/code-execution-tool) to execute Python code in a sandboxed environment.\n",
|
||||
"\n",
|
||||
":::info Code execution is supported since ``langchain-anthropic>=0.3.14``\n",
|
||||
"\n",
|
||||
":::info\n",
|
||||
"Code execution is supported since ``langchain-anthropic>=0.3.14``\n",
|
||||
":::"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 1,
|
||||
"execution_count": null,
|
||||
"id": "2ce13632-a2da-439f-a429-f66481501630",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
@@ -1317,7 +1401,7 @@
|
||||
"\n",
|
||||
"llm = ChatAnthropic(\n",
|
||||
" model=\"claude-sonnet-4-20250514\",\n",
|
||||
" betas=[\"code-execution-2025-05-22\"],\n",
|
||||
" betas=[\"code-execution-2025-05-22\"], # Enable code execution beta\n",
|
||||
")\n",
|
||||
"\n",
|
||||
"tool = {\"type\": \"code_execution_20250522\", \"name\": \"code_execution\"}\n",
|
||||
@@ -1328,6 +1412,16 @@
|
||||
")"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "a6b5e15a",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
":::warning\n",
|
||||
"Note: you must add the `'code_execution_20250522'` beta header to use this tool.\n",
|
||||
":::"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "24076f91-3a3d-4e53-9618-429888197061",
|
||||
@@ -1397,6 +1491,38 @@
|
||||
"</details>"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "29405da2-d2ef-415c-b674-6e29073cd05e",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"### Memory tool\n",
|
||||
"\n",
|
||||
"Claude supports a memory tool for client-side storage and retrieval of context across conversational threads. See docs [here](https://docs.claude.com/en/docs/agents-and-tools/tool-use/memory-tool) for details.\n",
|
||||
"\n",
|
||||
":::info\n",
|
||||
"Requires ``langchain-anthropic>=0.3.21``\n",
|
||||
":::"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "bbd76eaa-041f-4fb8-8346-ca8fe0001c01",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"from langchain_anthropic import ChatAnthropic\n",
|
||||
"\n",
|
||||
"llm = ChatAnthropic(\n",
|
||||
" model=\"claude-sonnet-4-5-20250929\",\n",
|
||||
" betas=[\"context-management-2025-06-27\"],\n",
|
||||
")\n",
|
||||
"llm_with_tools = llm.bind_tools([{\"type\": \"memory_20250818\", \"name\": \"memory\"}])\n",
|
||||
"\n",
|
||||
"response = llm_with_tools.invoke(\"What are my interests?\")"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "040f381a-1768-479a-9a5e-aa2d7d77e0d5",
|
||||
@@ -1406,14 +1532,14 @@
|
||||
"\n",
|
||||
"Claude can use a [MCP connector tool](https://docs.anthropic.com/en/docs/agents-and-tools/mcp-connector) for model-generated calls to remote MCP servers.\n",
|
||||
"\n",
|
||||
":::info Remote MCP is supported since ``langchain-anthropic>=0.3.14``\n",
|
||||
"\n",
|
||||
":::info\n",
|
||||
"Remote MCP is supported since ``langchain-anthropic>=0.3.14``\n",
|
||||
":::"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 1,
|
||||
"execution_count": null,
|
||||
"id": "22fc4a89-e6d8-4615-96cb-2e117349aebf",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
@@ -1425,17 +1551,17 @@
|
||||
" \"type\": \"url\",\n",
|
||||
" \"url\": \"https://mcp.deepwiki.com/mcp\",\n",
|
||||
" \"name\": \"deepwiki\",\n",
|
||||
" \"tool_configuration\": { # optional configuration\n",
|
||||
" \"tool_configuration\": { # Optional configuration\n",
|
||||
" \"enabled\": True,\n",
|
||||
" \"allowed_tools\": [\"ask_question\"],\n",
|
||||
" },\n",
|
||||
" \"authorization_token\": \"PLACEHOLDER\", # optional authorization\n",
|
||||
" \"authorization_token\": \"PLACEHOLDER\", # Optional authorization\n",
|
||||
" }\n",
|
||||
"]\n",
|
||||
"\n",
|
||||
"llm = ChatAnthropic(\n",
|
||||
" model=\"claude-sonnet-4-20250514\",\n",
|
||||
" betas=[\"mcp-client-2025-04-04\"],\n",
|
||||
" betas=[\"mcp-client-2025-04-04\"], # Enable MCP beta\n",
|
||||
" mcp_servers=mcp_servers,\n",
|
||||
")\n",
|
||||
"\n",
|
||||
@@ -1445,6 +1571,16 @@
|
||||
")"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "0d6d7197",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
":::warning\n",
|
||||
"Note: you must add the `'mcp-client-2025-04-04'` beta header to use this tool.\n",
|
||||
":::"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "2fd5d545-a40d-42b1-ad0c-0a79e2536c9b",
|
||||
@@ -1452,12 +1588,12 @@
|
||||
"source": [
|
||||
"### Text editor\n",
|
||||
"\n",
|
||||
"The text editor tool can be used to view and modify text files. See docs [here](https://docs.anthropic.com/en/docs/build-with-claude/tool-use/text-editor-tool) for details."
|
||||
"The text editor tool can be used to view and modify text files. See docs [here](https://docs.anthropic.com/en/docs/agents-and-tools/tool-use/text-editor-tool) for details."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 1,
|
||||
"execution_count": null,
|
||||
"id": "30a0af36-2327-4b1d-9ba5-e47cb72db0be",
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
@@ -1493,7 +1629,7 @@
|
||||
"response = llm_with_tools.invoke(\n",
|
||||
" \"There's a syntax error in my primes.py file. Can you help me fix it?\"\n",
|
||||
")\n",
|
||||
"print(response.text())\n",
|
||||
"print(response.text)\n",
|
||||
"response.tool_calls"
|
||||
]
|
||||
},
|
||||
|
||||
@@ -243,12 +243,12 @@
|
||||
"id": "0ef05abb-9c04-4dc3-995e-f857779644d5",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"You can filter to text using the [.text()](https://python.langchain.com/api_reference/core/messages/langchain_core.messages.ai.AIMessage.html#langchain_core.messages.ai.AIMessage.text) method on the output:"
|
||||
"You can filter to text using the [.text](https://python.langchain.com/api_reference/core/messages/langchain_core.messages.ai.AIMessage.html#langchain_core.messages.ai.AIMessage.text) property on the output:"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 5,
|
||||
"execution_count": null,
|
||||
"id": "2a4e743f-ea7d-4e5a-9b12-f9992362de8b",
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
@@ -262,7 +262,7 @@
|
||||
],
|
||||
"source": [
|
||||
"for chunk in llm.stream(messages):\n",
|
||||
" print(chunk.text(), end=\"|\")"
|
||||
" print(chunk.text, end=\"|\")"
|
||||
]
|
||||
},
|
||||
{
|
||||
|
||||
@@ -31,7 +31,7 @@
|
||||
"\n",
|
||||
"| [Tool calling](/docs/how_to/tool_calling) | [Structured output](/docs/how_to/structured_output/) | JSON mode | [Image input](/docs/how_to/multimodal_inputs/) | Audio input | Video input | [Token-level streaming](/docs/how_to/chat_streaming/) | Native async | [Token usage](/docs/how_to/chat_token_usage_tracking/) | [Logprobs](/docs/how_to/logprobs/) |\n",
|
||||
"| :---: | :---: | :---: | :---: | :---: | :---: | :---: | :---: | :---: | :---: |\n",
|
||||
"| ✅ | ✅ | ❌ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ❌ |\n",
|
||||
"| ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ❌ |\n",
|
||||
"\n",
|
||||
"### Setup\n",
|
||||
"\n",
|
||||
@@ -653,15 +653,35 @@
|
||||
"\n",
|
||||
"# Initialize the model\n",
|
||||
"llm = ChatGoogleGenerativeAI(model=\"gemini-2.0-flash\", temperature=0)\n",
|
||||
"structured_llm = llm.with_structured_output(Person)\n",
|
||||
"\n",
|
||||
"# Method 1: Default function calling approach\n",
|
||||
"structured_llm_default = llm.with_structured_output(Person)\n",
|
||||
"\n",
|
||||
"# Method 2: Native JSON mode\n",
|
||||
"structured_llm_json = llm.with_structured_output(Person, method=\"json_mode\")\n",
|
||||
"\n",
|
||||
"# Invoke the model with a query asking for structured information\n",
|
||||
"result = structured_llm.invoke(\n",
|
||||
"result = structured_llm_json.invoke(\n",
|
||||
" \"Who was the 16th president of the USA, and how tall was he in meters?\"\n",
|
||||
")\n",
|
||||
"print(result)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "g9w06ld1ggq",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"### Structured Output Methods\n",
|
||||
"\n",
|
||||
"Two methods are supported for structured output:\n",
|
||||
"\n",
|
||||
"- **`method=\"function_calling\"` (default)**: Uses tool calling to extract structured data. Compatible with all Gemini models.\n",
|
||||
"- **`method=\"json_mode\"`**: Uses Gemini's native structured output with `responseSchema`. More reliable but requires Gemini 1.5+ models.\n",
|
||||
"\n",
|
||||
"The `json_mode` method is **recommended for better reliability** as it constrains the model's generation process directly rather than relying on post-processing tool calls."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "90d4725e",
|
||||
|
||||
@@ -261,7 +261,7 @@
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 5,
|
||||
"execution_count": null,
|
||||
"id": "c5fac0e9-05a4-4fc1-a3b3-e5bbb24b971b",
|
||||
"metadata": {
|
||||
"colab": {
|
||||
@@ -286,7 +286,7 @@
|
||||
],
|
||||
"source": [
|
||||
"async for token in llm.astream(\"Hello, please explain how antibiotics work\"):\n",
|
||||
" print(token.text(), end=\"\")"
|
||||
" print(token.text, end=\"\")"
|
||||
]
|
||||
},
|
||||
{
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
"source": [
|
||||
"# ChatOCIGenAI\n",
|
||||
"\n",
|
||||
"This notebook provides a quick overview for getting started with OCIGenAI [chat models](/docs/concepts/chat_models). For detailed documentation of all ChatOCIGenAI features and configurations head to the [API reference](https://python.langchain.com/api_reference/community/chat_models/langchain_community.chat_models.oci_generative_ai.ChatOCIGenAI.html).\n",
|
||||
"This notebook provides a quick overview for getting started with OCIGenAI [chat models](/docs/concepts/chat_models). For detailed documentation of all ChatOCIGenAI features and configurations head to the [API reference](https://pypi.org/project/langchain-oci/).\n",
|
||||
"\n",
|
||||
"Oracle Cloud Infrastructure (OCI) Generative AI is a fully managed service that provides a set of state-of-the-art, customizable large language models (LLMs) that cover a wide range of use cases, and which is available through a single API.\n",
|
||||
"Using the OCI Generative AI service you can access ready-to-use pretrained models, or create and host your own fine-tuned custom models based on your own data on dedicated AI clusters. Detailed documentation of the service and API is available __[here](https://docs.oracle.com/en-us/iaas/Content/generative-ai/home.htm)__ and __[here](https://docs.oracle.com/en-us/iaas/api/#/en/generative-ai/20231130/)__.\n",
|
||||
@@ -26,9 +26,9 @@
|
||||
"## Overview\n",
|
||||
"### Integration details\n",
|
||||
"\n",
|
||||
"| Class | Package | Local | Serializable | [JS support](https://js.langchain.com/docs/integrations/chat/oci_generative_ai) |\n",
|
||||
"| :--- | :--- | :---: | :---: | :---: |\n",
|
||||
"| [ChatOCIGenAI](https://python.langchain.com/api_reference/community/chat_models/langchain_community.chat_models.oci_generative_ai.ChatOCIGenAI.html) | [langchain-community](https://python.langchain.com/api_reference/community/index.html) | ❌ | ❌ | ❌ |\n",
|
||||
"| Class | Package | Local | Serializable | [JS support](https://js.langchain.com/docs/integrations/chat/oci_generative_ai) |\n",
|
||||
"| :--- |:---------------------------------------------------------------------------------| :---: | :---: | :---: |\n",
|
||||
"| [ChatOCIGenAI](https://python.langchain.com/api_reference/community/chat_models/langchain_community.chat_models.oci_generative_ai.ChatOCIGenAI.html) | [langchain-oci](https://github.com/oracle/langchain-oracle) | ❌ | ❌ | ❌ |\n",
|
||||
"\n",
|
||||
"### Model features\n",
|
||||
"| [Tool calling](/docs/how_to/tool_calling/) | [Structured output](/docs/how_to/structured_output/) | [JSON mode](/docs/how_to/structured_output/#advanced-specifying-the-method-for-structuring-outputs) | [Image input](/docs/how_to/multimodal_inputs/) | Audio input | Video input | [Token-level streaming](/docs/how_to/chat_streaming/) | Native async | [Token usage](/docs/how_to/chat_token_usage_tracking/) | [Logprobs](/docs/how_to/logprobs/) |\n",
|
||||
@@ -37,7 +37,7 @@
|
||||
"\n",
|
||||
"## Setup\n",
|
||||
"\n",
|
||||
"To access OCIGenAI models you'll need to install the `oci` and `langchain-community` packages.\n",
|
||||
"To access OCIGenAI models you'll need to install the `oci` and `langchain-oci` packages.\n",
|
||||
"\n",
|
||||
"### Credentials\n",
|
||||
"\n",
|
||||
@@ -84,13 +84,15 @@
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"from langchain_oci.chat_models import ChatOCIGenAI\n",
|
||||
"from langchain_core.messages import AIMessage, HumanMessage, SystemMessage\n",
|
||||
"\n",
|
||||
"chat = ChatOCIGenAI(\n",
|
||||
" model_id=\"cohere.command-r-16k\",\n",
|
||||
" model_id=\"cohere.command-r-plus-08-2024\",\n",
|
||||
" service_endpoint=\"https://inference.generativeai.us-chicago-1.oci.oraclecloud.com\",\n",
|
||||
" compartment_id=\"MY_OCID\",\n",
|
||||
" model_kwargs={\"temperature\": 0.7, \"max_tokens\": 500},\n",
|
||||
" compartment_id=\"compartment_id\",\n",
|
||||
" model_kwargs={\"temperature\": 0, \"max_tokens\": 500},\n",
|
||||
" auth_type=\"SECURITY_TOKEN\",\n",
|
||||
" auth_profile=\"auth_profile_name\",\n",
|
||||
" auth_file_location=\"auth_file_location\",\n",
|
||||
")"
|
||||
]
|
||||
},
|
||||
@@ -110,14 +112,7 @@
|
||||
"tags": []
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"messages = [\n",
|
||||
" SystemMessage(content=\"your are an AI assistant.\"),\n",
|
||||
" AIMessage(content=\"Hi there human!\"),\n",
|
||||
" HumanMessage(content=\"tell me a joke.\"),\n",
|
||||
"]\n",
|
||||
"response = chat.invoke(messages)"
|
||||
]
|
||||
"source": "response = chat.invoke(\"Tell me one fact about Earth\")"
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
@@ -146,13 +141,22 @@
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"from langchain_core.prompts import ChatPromptTemplate\n",
|
||||
"from langchain_core.prompts import PromptTemplate\n",
|
||||
"from langchain_oci.chat_models import ChatOCIGenAI\n",
|
||||
"\n",
|
||||
"prompt = ChatPromptTemplate.from_template(\"Tell me a joke about {topic}\")\n",
|
||||
"chain = prompt | chat\n",
|
||||
"\n",
|
||||
"response = chain.invoke({\"topic\": \"dogs\"})\n",
|
||||
"print(response.content)"
|
||||
"llm = ChatOCIGenAI(\n",
|
||||
" model_id=\"cohere.command-r-plus-08-2024\",\n",
|
||||
" service_endpoint=\"https://inference.generativeai.us-chicago-1.oci.oraclecloud.com\",\n",
|
||||
" compartment_id=\"compartment_id\",\n",
|
||||
" model_kwargs={\"temperature\": 0, \"max_tokens\": 500},\n",
|
||||
" auth_type=\"SECURITY_TOKEN\",\n",
|
||||
" auth_profile=\"auth_profile_name\",\n",
|
||||
" auth_file_location=\"auth_file_location\",\n",
|
||||
")\n",
|
||||
"prompt = PromptTemplate(input_variables=[\"query\"], template=\"{query}\")\n",
|
||||
"llm_chain = prompt | llm\n",
|
||||
"response = llm_chain.invoke(\"what is the capital of france?\")\n",
|
||||
"print(response)"
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -162,7 +166,7 @@
|
||||
"source": [
|
||||
"## API reference\n",
|
||||
"\n",
|
||||
"For detailed documentation of all ChatOCIGenAI features and configurations head to the API reference: https://python.langchain.com/api_reference/community/chat_models/langchain_community.chat_models.oci_generative_ai.ChatOCIGenAI.html"
|
||||
"For detailed documentation of all ChatOCIGenAI features and configurations head to the API reference: https://pypi.org/project/langchain-oci/"
|
||||
]
|
||||
}
|
||||
],
|
||||
|
||||
@@ -814,7 +814,7 @@
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 2,
|
||||
"execution_count": null,
|
||||
"id": "1f758726-33ef-4c04-8a54-49adb783bbb3",
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
@@ -860,7 +860,7 @@
|
||||
"llm_with_tools = llm.bind_tools([tool])\n",
|
||||
"\n",
|
||||
"response = llm_with_tools.invoke(\"What is deep research by OpenAI?\")\n",
|
||||
"print(response.text())"
|
||||
"print(response.text)"
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -1151,7 +1151,7 @@
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 8,
|
||||
"execution_count": null,
|
||||
"id": "073f6010-6b0e-4db6-b2d3-7427c8dec95b",
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
@@ -1167,7 +1167,7 @@
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"response_2.text()"
|
||||
"response_2.text"
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -1198,7 +1198,7 @@
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 10,
|
||||
"execution_count": null,
|
||||
"id": "b6da5bd6-a44a-4c64-970b-30da26b003d6",
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
@@ -1214,7 +1214,7 @@
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"response_2.text()"
|
||||
"response_2.text"
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -1404,7 +1404,7 @@
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 1,
|
||||
"execution_count": null,
|
||||
"id": "51d3e4d3-ea78-426c-9205-aecb0937fca7",
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
@@ -1428,13 +1428,13 @@
|
||||
"messages = [{\"role\": \"user\", \"content\": first_query}]\n",
|
||||
"\n",
|
||||
"response = llm_with_tools.invoke(messages)\n",
|
||||
"response_text = response.text()\n",
|
||||
"response_text = response.text\n",
|
||||
"print(f\"{response_text[:100]}... {response_text[-100:]}\")"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 2,
|
||||
"execution_count": null,
|
||||
"id": "b248bedf-2050-4c17-a90e-3a26eeb1b055",
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
@@ -1460,7 +1460,7 @@
|
||||
" ]\n",
|
||||
")\n",
|
||||
"second_response = llm_with_tools.invoke(messages)\n",
|
||||
"print(second_response.text())"
|
||||
"print(second_response.text)"
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -1482,7 +1482,7 @@
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 3,
|
||||
"execution_count": null,
|
||||
"id": "009e541a-b372-410e-b9dd-608a8052ce09",
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
@@ -1502,12 +1502,12 @@
|
||||
" output_version=\"responses/v1\",\n",
|
||||
")\n",
|
||||
"response = llm.invoke(\"Hi, I'm Bob.\")\n",
|
||||
"print(response.text())"
|
||||
"print(response.text)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 4,
|
||||
"execution_count": null,
|
||||
"id": "393a443a-4c5f-4a07-bc0e-c76e529b35e3",
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
@@ -1524,7 +1524,7 @@
|
||||
" \"What is my name?\",\n",
|
||||
" previous_response_id=response.response_metadata[\"id\"],\n",
|
||||
")\n",
|
||||
"print(second_response.text())"
|
||||
"print(second_response.text)"
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -1589,7 +1589,7 @@
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 2,
|
||||
"execution_count": null,
|
||||
"id": "8d322f3a-0732-45ab-ac95-dfd4596e0d85",
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
@@ -1616,7 +1616,7 @@
|
||||
"response = llm.invoke(\"What is 3^3?\")\n",
|
||||
"\n",
|
||||
"# Output\n",
|
||||
"response.text()"
|
||||
"response.text"
|
||||
]
|
||||
},
|
||||
{
|
||||
|
||||
408
docs/docs/integrations/chat/qwen.ipynb
Normal file
408
docs/docs/integrations/chat/qwen.ipynb
Normal file
@@ -0,0 +1,408 @@
|
||||
{
|
||||
"cells": [
|
||||
{
|
||||
"cell_type": "raw",
|
||||
"id": "afaf8039",
|
||||
"metadata": {
|
||||
"vscode": {
|
||||
"languageId": "raw"
|
||||
}
|
||||
},
|
||||
"source": [
|
||||
"---\n",
|
||||
"sidebar_label: Qwen\n",
|
||||
"---"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "e49f1e0d",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"# ChatQwen\n",
|
||||
"\n",
|
||||
"This will help you get started with Qwen [chat models](../../concepts/chat_models.mdx). For detailed documentation of all ChatQwen features and configurations head to the [API reference](https://pypi.org/project/langchain-qwq/).\n",
|
||||
"\n",
|
||||
"## Overview\n",
|
||||
"### Integration details\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"| Class | Package | Local | Serializable | Package downloads | Package latest |\n",
|
||||
"| :--- | :--- | :---: | :---: | :---: | :---: |\n",
|
||||
"| [ChatQwen](https://pypi.org/project/langchain-qwq/) | [langchain-qwq](https://pypi.org/project/langchain-qwq/) | ❌ | beta |  |  |\n",
|
||||
"\n",
|
||||
"### Model features\n",
|
||||
"| [Tool calling](../../how_to/tool_calling.ipynb) | [Structured output](../../how_to/structured_output.ipynb) | JSON mode | [Image input](../../how_to/multimodal_inputs.ipynb) | Audio input | Video input | [Token-level streaming](../../how_to/chat_streaming.ipynb) | Native async | [Token usage](../../how_to/chat_token_usage_tracking.ipynb) | [Logprobs](../../how_to/logprobs.ipynb) |\n",
|
||||
"| :---: | :---: | :---: | :---: | :---: | :---: | :---: | :---: | :---: | :---: |\n",
|
||||
"| ✅ | ✅ | ✅ |✅ | ❌ | ✅ | ✅ | ✅ | ✅ | ❌ | \n",
|
||||
"\n",
|
||||
"## Setup\n",
|
||||
"\n",
|
||||
"To access Qwen models you'll need to create an Alibaba Cloud account, get an API key, and install the `langchain-qwq` integration package.\n",
|
||||
"\n",
|
||||
"### Credentials\n",
|
||||
"\n",
|
||||
"Head to [Alibaba's API Key page](https://account.alibabacloud.com/login/login.htm?oauth_callback=https%3A%2F%2Fbailian.console.alibabacloud.com%2F%3FapiKey%3D1&lang=en#/api-key) to sign up to Alibaba Cloud and generate an API key. Once you've done this set the `DASHSCOPE_API_KEY` environment variable:"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 1,
|
||||
"id": "433e8d2b-9519-4b49-b2c4-7ab65b046c94",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"import getpass\n",
|
||||
"import os\n",
|
||||
"\n",
|
||||
"if not os.getenv(\"DASHSCOPE_API_KEY\"):\n",
|
||||
" os.environ[\"DASHSCOPE_API_KEY\"] = getpass.getpass(\"Enter your Dashscope API key: \")"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "0730d6a1-c893-4840-9817-5e5251676d5d",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"### Installation\n",
|
||||
"\n",
|
||||
"The LangChain QwQ integration lives in the `langchain-qwq` package:"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "652d6238-1f87-422a-b135-f5abbb8652fc",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"%pip install -qU langchain-qwq"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "a38cde65-254d-4219-a441-068766c0d4b5",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## Instantiation\n",
|
||||
"\n",
|
||||
"Now we can instantiate our model object and generate chat completions:"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 2,
|
||||
"id": "cb09c344-1836-4e0c-acf8-11d13ac1dbae",
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
"text/plain": [
|
||||
"AIMessage(content='Hello! How can I assist you today? 😊', additional_kwargs={}, response_metadata={'finish_reason': 'stop', 'model_name': 'qwen-flash'}, id='run--62798a20-d425-48ab-91fc-8e62e37c6084-0', usage_metadata={'input_tokens': 9, 'output_tokens': 11, 'total_tokens': 20, 'input_token_details': {}, 'output_token_details': {}})"
|
||||
]
|
||||
},
|
||||
"execution_count": 2,
|
||||
"metadata": {},
|
||||
"output_type": "execute_result"
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"from langchain_qwq import ChatQwen\n",
|
||||
"\n",
|
||||
"llm = ChatQwen(model=\"qwen-flash\")\n",
|
||||
"response = llm.invoke(\"Hello\")\n",
|
||||
"\n",
|
||||
"response"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "2b4f3e15",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## Invocation"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 3,
|
||||
"id": "62e0dbc3",
|
||||
"metadata": {
|
||||
"tags": []
|
||||
},
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
"text/plain": [
|
||||
"AIMessage(content=\"J'adore la programmation.\", additional_kwargs={}, response_metadata={'finish_reason': 'stop', 'model_name': 'qwen-flash'}, id='run--33f905e0-880a-4a67-ab83-313fd7a06369-0', usage_metadata={'input_tokens': 32, 'output_tokens': 8, 'total_tokens': 40, 'input_token_details': {}, 'output_token_details': {}})"
|
||||
]
|
||||
},
|
||||
"execution_count": 3,
|
||||
"metadata": {},
|
||||
"output_type": "execute_result"
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"messages = [\n",
|
||||
" (\n",
|
||||
" \"system\",\n",
|
||||
" \"You are a helpful assistant that translates English to French.\"\n",
|
||||
" \"Translate the user sentence.\",\n",
|
||||
" ),\n",
|
||||
" (\"human\", \"I love programming.\"),\n",
|
||||
"]\n",
|
||||
"ai_msg = llm.invoke(messages)\n",
|
||||
"ai_msg"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "18e2bfc0-7e78-4528-a73f-499ac150dca8",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## Chaining\n",
|
||||
"\n",
|
||||
"We can [chain](../../how_to/sequence.ipynb) our model with a prompt template like so:"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 4,
|
||||
"id": "e197d1d7-a070-4c96-9f8a-a0e86d046e0b",
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
"text/plain": [
|
||||
"AIMessage(content='Ich liebe Programmierung.', additional_kwargs={}, response_metadata={'finish_reason': 'stop', 'model_name': 'qwen-flash'}, id='run--9d8bab6d-d6fe-4b9f-95f2-c30c3ff0a50e-0', usage_metadata={'input_tokens': 28, 'output_tokens': 5, 'total_tokens': 33, 'input_token_details': {}, 'output_token_details': {}})"
|
||||
]
|
||||
},
|
||||
"execution_count": 4,
|
||||
"metadata": {},
|
||||
"output_type": "execute_result"
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"from langchain_core.prompts import ChatPromptTemplate\n",
|
||||
"\n",
|
||||
"prompt = ChatPromptTemplate(\n",
|
||||
" [\n",
|
||||
" (\n",
|
||||
" \"system\",\n",
|
||||
" \"You are a helpful assistant that translates\"\n",
|
||||
" \"{input_language} to {output_language}.\",\n",
|
||||
" ),\n",
|
||||
" (\"human\", \"{input}\"),\n",
|
||||
" ]\n",
|
||||
")\n",
|
||||
"\n",
|
||||
"chain = prompt | llm\n",
|
||||
"chain.invoke(\n",
|
||||
" {\n",
|
||||
" \"input_language\": \"English\",\n",
|
||||
" \"output_language\": \"German\",\n",
|
||||
" \"input\": \"I love programming.\",\n",
|
||||
" }\n",
|
||||
")"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "8d1b3ef3",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## Tool Calling\n",
|
||||
"ChatQwen supports tool calling API that lets you describe tools and their arguments, and have the model return a JSON object with a tool to invoke and the inputs to that tool."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "6db1a355",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"### Use with `bind_tools`"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 6,
|
||||
"id": "15fb6a6d",
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"content='' additional_kwargs={'tool_calls': [{'index': 0, 'id': 'call_f0c2cc49307f480db78a45', 'function': {'arguments': '{\"first_int\": 5, \"second_int\": 42}', 'name': 'multiply'}, 'type': 'function'}]} response_metadata={'finish_reason': 'tool_calls', 'model_name': 'qwen-flash'} id='run--27c5aafb-9710-42f5-ab78-5a2ad1d9050e-0' tool_calls=[{'name': 'multiply', 'args': {'first_int': 5, 'second_int': 42}, 'id': 'call_f0c2cc49307f480db78a45', 'type': 'tool_call'}] usage_metadata={'input_tokens': 166, 'output_tokens': 27, 'total_tokens': 193, 'input_token_details': {}, 'output_token_details': {}}\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"from langchain_core.tools import tool\n",
|
||||
"\n",
|
||||
"from langchain_qwq import ChatQwen\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",
|
||||
"llm = ChatQwen(model=\"qwen-flash\")\n",
|
||||
"\n",
|
||||
"llm_with_tools = llm.bind_tools([multiply])\n",
|
||||
"\n",
|
||||
"msg = llm_with_tools.invoke(\"What's 5 times forty two\")\n",
|
||||
"\n",
|
||||
"print(msg)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "cc8ffd89-c474-45a7-a123-e0b1d362f54f",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"### vision Support"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "3e8a7d46-d1f6-4ae8-835a-266ca47e4daf",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"#### Image"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 7,
|
||||
"id": "54f69db3-fa51-4b9a-885c-1353968066e3",
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"This image depicts a cozy, rustic Christmas scene set against a wooden backdrop. The arrangement features a variety of festive decorations that evoke a warm, holiday atmosphere:\n",
|
||||
"\n",
|
||||
"- **Centerpiece**: A decorative reindeer figurine with large antlers stands prominently in the background.\n",
|
||||
"- **Miniature Trees**: Two small, snow-dusted artificial Christmas trees flank the reindeer, adding to the wintry feel.\n",
|
||||
"- **Candles**: Three log-shaped candle holders made from birch bark are lit, casting a soft, warm glow. Two are in the foreground, and one is slightly behind them.\n",
|
||||
"- **\"Merry Christmas\" Sign**: A wooden cutout sign spelling \"MERRY CHRISTMAS\" is placed on the left, decorated with a tiny golden gift box and a small reindeer silhouette.\n",
|
||||
"- **Holiday Elements**: Pinecones, red berries, greenery, and fairy lights are scattered throughout, enhancing the natural, festive theme.\n",
|
||||
"- **Other Details**: A white sack with \"SANTA\" written on it is partially visible on the left, along with a large glass ornament and twinkling string lights.\n",
|
||||
"\n",
|
||||
"The overall aesthetic is warm, inviting, and traditional, emphasizing natural materials like wood, pine, and birch bark. It captures the essence of a rustic, homemade Christmas celebration.\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"from langchain_core.messages import HumanMessage\n",
|
||||
"\n",
|
||||
"model = ChatQwen(model=\"qwen-vl-max-latest\")\n",
|
||||
"\n",
|
||||
"messages = [\n",
|
||||
" HumanMessage(\n",
|
||||
" content=[\n",
|
||||
" {\n",
|
||||
" \"type\": \"image_url\",\n",
|
||||
" \"image_url\": {\"url\": \"https://example.com/image/image.png\"},\n",
|
||||
" },\n",
|
||||
" {\"type\": \"text\", \"text\": \"What do you see in this image?\"},\n",
|
||||
" ]\n",
|
||||
" )\n",
|
||||
"]\n",
|
||||
"\n",
|
||||
"response = model.invoke(messages)\n",
|
||||
"print(response.content)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "b1faea19-932f-4dc8-b0af-60e3507eee08",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"#### Video"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "59355c38-d3e2-4051-811a-2b99286ea01b",
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"This video features a young woman with a warm and cheerful expression, standing outdoors in a well-lit environment. She has short, neatly styled brown hair with bangs and is wearing a soft pink knitted cardigan over a white top. A delicate necklace adorns her neck, adding a subtle touch of elegance to her outfit.\n",
|
||||
"\n",
|
||||
"Throughout the video, she maintains eye contact with the camera, smiling gently and occasionally opening her mouth as if speaking or laughing. Her facial expressions are natural and engaging, suggesting a friendly and approachable demeanor. The background is softly blurred, indicating a shallow depth of field, which keeps the focus on her. It appears to be an urban setting with modern buildings, possibly a residential or commercial area.\n",
|
||||
"\n",
|
||||
"The lighting is bright and natural, likely from sunlight, casting a soft glow on her face and highlighting her features. The overall tone of the video is pleasant and inviting, evoking a sense of warmth and positivity.\n",
|
||||
"\n",
|
||||
"In the top right corner of the frames, there is a watermark that reads \"通义·AI合成,\" which indicates that this video was generated using AI technology by Tongyi Lab, a company known for its advancements in artificial intelligence and digital content creation. This suggests that the video may be a demonstration of AI-generated human-like avatars or synthetic media.\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"from langchain_core.messages import HumanMessage\n",
|
||||
"\n",
|
||||
"model = ChatQwen(model=\"qwen-vl-max-latest\")\n",
|
||||
"\n",
|
||||
"messages = [\n",
|
||||
" HumanMessage(\n",
|
||||
" content=[\n",
|
||||
" {\n",
|
||||
" \"type\": \"video_url\",\n",
|
||||
" \"video_url\": {\"url\": \"https://example.com/video/1.mp4\"},\n",
|
||||
" },\n",
|
||||
" {\"type\": \"text\", \"text\": \"Can you tell me about this video?\"},\n",
|
||||
" ]\n",
|
||||
" )\n",
|
||||
"]\n",
|
||||
"\n",
|
||||
"response = model.invoke(messages)\n",
|
||||
"print(response.content)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "3a5bb5ca-c3ae-4a58-be67-2cd18574b9a3",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## API reference\n",
|
||||
"\n",
|
||||
"For detailed documentation of all ChatQwen features and configurations head to the [API reference](https://pypi.org/project/langchain-qwq/)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "ce1026e3",
|
||||
"metadata": {},
|
||||
"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.9"
|
||||
}
|
||||
},
|
||||
"nbformat": 4,
|
||||
"nbformat_minor": 5
|
||||
}
|
||||
@@ -34,7 +34,7 @@
|
||||
"### Model features\n",
|
||||
"| [Tool calling](../../how_to/tool_calling.ipynb) | [Structured output](../../how_to/structured_output.ipynb) | JSON mode | [Image input](../../how_to/multimodal_inputs.ipynb) | Audio input | Video input | [Token-level streaming](../../how_to/chat_streaming.ipynb) | Native async | [Token usage](../../how_to/chat_token_usage_tracking.ipynb) | [Logprobs](../../how_to/logprobs.ipynb) |\n",
|
||||
"| :---: | :---: | :---: | :---: | :---: | :---: | :---: | :---: | :---: | :---: |\n",
|
||||
"| ✅ | ✅ | ✅ |❌ | ❌ | ❌ | ✅ | ✅ | ✅ | ❌ | \n",
|
||||
"| ✅ | ✅ | ✅ |✅ | ❌ | ✅ | ✅ | ✅ | ✅ | ❌ | \n",
|
||||
"\n",
|
||||
"## Setup\n",
|
||||
"\n",
|
||||
@@ -47,7 +47,7 @@
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 2,
|
||||
"execution_count": 1,
|
||||
"id": "433e8d2b-9519-4b49-b2c4-7ab65b046c94",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
@@ -91,7 +91,7 @@
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 3,
|
||||
"execution_count": 2,
|
||||
"id": "cb09c344-1836-4e0c-acf8-11d13ac1dbae",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
@@ -117,7 +117,7 @@
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 4,
|
||||
"execution_count": 3,
|
||||
"id": "62e0dbc3",
|
||||
"metadata": {
|
||||
"tags": []
|
||||
@@ -126,10 +126,10 @@
|
||||
{
|
||||
"data": {
|
||||
"text/plain": [
|
||||
"AIMessage(content=\"J'aime la programmation.\", additional_kwargs={'reasoning_content': 'Okay, the user wants me to translate \"I love programming.\" into French. Let\\'s start by breaking down the sentence. The subject is \"I\", which in French is \"Je\". The verb is \"love\", which in this context is present tense, so \"aime\". The object is \"programming\". Now, \"programming\" in French can be \"la programmation\". \\n\\nWait, should it be \"programmation\" or \"programmation\"? Let me confirm the spelling. Yes, \"programmation\" is correct. Now, putting it all together: \"Je aime la programmation.\" Hmm, but in French, there\\'s a tendency to contract \"je\" and \"aime\". Wait, actually, \"je\" followed by a vowel sound usually takes \"j\\'\". So it should be \"J\\'aime la programmation.\" \\n\\nLet me double-check. \"J\\'aime\" is the correct contraction for \"I love\". The definite article \"la\" is needed because \"programmation\" is a feminine noun. Yes, \"programmation\" is a feminine noun, so \"la\" is correct. \\n\\nIs there any other way to say it? Maybe \"J\\'adore la programmation\" for \"I love\" in a stronger sense, but the user didn\\'t specify the intensity. Since the original is straightforward, \"J\\'aime la programmation.\" is the direct translation. \\n\\nI think that\\'s it. No mistakes there. So the final translation should be \"J\\'aime la programmation.\"'}, response_metadata={'model_name': 'qwq-plus'}, id='run-5045cd6a-edbd-4b2f-bf24-b7bdf3777fb9-0', usage_metadata={'input_tokens': 32, 'output_tokens': 326, 'total_tokens': 358, 'input_token_details': {}, 'output_token_details': {}})"
|
||||
"AIMessage(content=\"J'aime la programmation.\", additional_kwargs={'reasoning_content': 'Okay, the user wants me to translate \"I love programming.\" into French. Let me start by recalling the basic translation. The verb \"love\" in French is \"aimer\", and \"programming\" is \"la programmation\". So the literal translation would be \"J\\'aime la programmation.\" But wait, I should check if there\\'s any context or nuances I need to consider. The user mentioned they\\'re a helpful assistant, so maybe they want a more natural or commonly used phrase. Sometimes in French, people might use \"adorer\" instead of \"aimer\" for stronger emphasis, but \"aimer\" is more standard here. Also, the structure \"J\\'aime\" is correct for \"I love\". No need for any articles if it\\'s a general statement, but \"la programmation\" is a feminine noun, so the article is necessary. Let me confirm the gender of \"programmation\"—yes, it\\'s feminine. So \"la\" is correct. I think that\\'s it. The translation should be \"J\\'aime la programmation.\"'}, response_metadata={'model_name': 'qwq-plus'}, id='run--396edf0f-ab92-4317-99be-cc9f5377c312-0', usage_metadata={'input_tokens': 32, 'output_tokens': 229, 'total_tokens': 261, 'input_token_details': {}, 'output_token_details': {}})"
|
||||
]
|
||||
},
|
||||
"execution_count": 4,
|
||||
"execution_count": 3,
|
||||
"metadata": {},
|
||||
"output_type": "execute_result"
|
||||
}
|
||||
@@ -159,17 +159,17 @@
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 5,
|
||||
"execution_count": 4,
|
||||
"id": "e197d1d7-a070-4c96-9f8a-a0e86d046e0b",
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
"text/plain": [
|
||||
"AIMessage(content='Ich liebe das Programmieren.', additional_kwargs={'reasoning_content': 'Okay, the user wants me to translate \"I love programming.\" into German. Let me think. The verb \"love\" is \"lieben\" or \"mögen\" in German, but \"lieben\" is more like love, while \"mögen\" is prefer. Since it\\'s about programming, which is a strong affection, \"lieben\" is better. The subject is \"I\", which is \"ich\". Then \"programming\" is \"Programmierung\" or \"Coding\". But \"Programmierung\" is more formal. Alternatively, sometimes people say \"ich liebe es zu programmieren\" which is \"I love to program\". Hmm, maybe the direct translation would be \"Ich liebe die Programmierung.\" But maybe the more natural way is \"Ich liebe es zu programmieren.\" Let me check. Both are correct, but the second one might sound more natural in everyday speech. The user might prefer the concise version. Alternatively, maybe \"Ich liebe die Programmierung.\" is better. Wait, the original is \"programming\" as a noun. So using the noun form would be appropriate. So \"Ich liebe die Programmierung.\" But sometimes people also use \"Coding\" in German, like \"Ich liebe das Coding.\" But that\\'s more anglicism. Probably better to stick with \"Programmierung\". Alternatively, \"Programmieren\" as a noun. Oh right! \"Programmieren\" can be a noun when used in the accusative case. So \"Ich liebe das Programmieren.\" That\\'s correct and natural. Yes, that\\'s the best translation. So the answer is \"Ich liebe das Programmieren.\"'}, response_metadata={'model_name': 'qwq-plus'}, id='run-2c418451-51d8-4319-8269-2ce129363a1a-0', usage_metadata={'input_tokens': 28, 'output_tokens': 341, 'total_tokens': 369, 'input_token_details': {}, 'output_token_details': {}})"
|
||||
"AIMessage(content='Ich liebe das Programmieren.', additional_kwargs={'reasoning_content': 'Okay, the user wants to translate \"I love programming.\" into German. Let\\'s start by breaking down the sentence. The subject is \"I,\" which translates to \"Ich\" in German. The verb \"love\" is \"liebe\" in present tense for the first person singular. Then \"programming\" is a noun. Now, in German, the word for programming, especially in the context of computer programming, is \"Programmierung.\" However, sometimes people might use \"Programmieren\" as well. Wait, but \"Programmierung\" is the noun form, so \"die Programmierung.\" The structure in German would be \"Ich liebe die Programmierung.\" Alternatively, could it be \"Programmieren\" as the verb in a nominalized form? Let me think. If you say \"Ich liebe das Programmieren,\" that\\'s also correct because \"das Programmieren\" is the gerundive form, which is commonly used for activities. So both are possible. Which one is more natural? Hmm. \"Das Programmieren\" might be more common in everyday language. Let me check some examples. For instance, \"I love cooking\" would be \"Ich liebe das Kochen.\" So following that pattern, \"Ich liebe das Programmieren\" would be the equivalent. Therefore, maybe \"Programmieren\" with the article \"das\" is better here. But the user might just want a direct translation without the article. Wait, the original sentence is \"I love programming,\" which is a noun, so in German, you need an article. So the correct translation would include \"das\" before the noun. So the correct sentence is \"Ich liebe das Programmieren.\" Alternatively, if they want to use the noun without an article, maybe in a more abstract sense, but I think \"das\" is necessary here. Let me confirm. Yes, in German, when using the noun form of a verb like this, you need the article. So the best translation is \"Ich liebe das Programmieren.\" I think that\\'s the most natural way to say it. Alternatively, \"Programmierung\" is more formal, but \"Programmieren\" is more commonly used in such contexts. So I\\'ll go with \"Ich liebe das Programmieren.\"'}, response_metadata={'model_name': 'qwq-plus'}, id='run--0ceaba8a-7842-48fb-8bec-eb96d2c83ed4-0', usage_metadata={'input_tokens': 28, 'output_tokens': 466, 'total_tokens': 494, 'input_token_details': {}, 'output_token_details': {}})"
|
||||
]
|
||||
},
|
||||
"execution_count": 5,
|
||||
"execution_count": 4,
|
||||
"metadata": {},
|
||||
"output_type": "execute_result"
|
||||
}
|
||||
@@ -217,7 +217,7 @@
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 6,
|
||||
"execution_count": 5,
|
||||
"id": "15fb6a6d",
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
@@ -225,12 +225,13 @@
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"content='' additional_kwargs={'reasoning_content': 'Okay, the user is asking \"What\\'s 5 times forty two\". Let me break this down. First, I need to identify the numbers involved. The first number is 5, which is straightforward. The second number is forty two, which is 42 in digits. The operation they want is multiplication.\\n\\nLooking at the tools provided, there\\'s a function called multiply that takes two integers. So I should use that. The parameters are first_int and second_int. \\n\\nI need to convert \"forty two\" to 42. Since the function requires integers, both numbers should be in integer form. So 5 and 42. \\n\\nNow, I\\'ll structure the tool call. The function name is multiply, and the arguments should be first_int: 5 and second_int: 42. I\\'ll make sure the JSON is correctly formatted without any syntax errors. Let me double-check the parameters to ensure they\\'re required and of the right type. Yep, both are required and integers. \\n\\nNo examples were provided, but the function\\'s purpose is clear. So the correct tool call should be to multiply those two numbers. I think that\\'s all. No other functions are needed here.'} response_metadata={'model_name': 'qwq-plus'} id='run-638895aa-fdde-4567-bcfa-7d8e5d4f24af-0' tool_calls=[{'name': 'multiply', 'args': {'first_int': 5, 'second_int': 42}, 'id': 'call_d088275851c140529ed2ad', 'type': 'tool_call'}] usage_metadata={'input_tokens': 176, 'output_tokens': 277, 'total_tokens': 453, 'input_token_details': {}, 'output_token_details': {}}\n"
|
||||
"content='' additional_kwargs={'reasoning_content': 'Okay, the user is asking \"What\\'s 5 times forty two\". Let me break this down. They want the product of 5 and 42. The function provided is called multiply, which takes two integers. First, I need to parse the numbers from the question. The first integer is 5, straightforward. The second is forty two, which is 42 in numeric form. So I should call the multiply function with first_int=5 and second_int=42. Let me double-check the parameters: both are required and of type integer. Yep, that\\'s correct. No examples given, but the function should handle these numbers. Alright, time to format the tool call.'} response_metadata={'model_name': 'qwq-plus'} id='run--3c5ff46c-3fc8-4caf-a665-2405aeef2948-0' tool_calls=[{'name': 'multiply', 'args': {'first_int': 5, 'second_int': 42}, 'id': 'call_33fb94c6662d44928e56ec', 'type': 'tool_call'}] usage_metadata={'input_tokens': 176, 'output_tokens': 173, 'total_tokens': 349, 'input_token_details': {}, 'output_token_details': {}}\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"from langchain_core.tools import tool\n",
|
||||
"\n",
|
||||
"from langchain_qwq import ChatQwQ\n",
|
||||
"\n",
|
||||
"\n",
|
||||
@@ -249,6 +250,170 @@
|
||||
"print(msg)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "88aa9980-1bd6-4cc9-aeac-4c9011e617fc",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"### vision Support"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "79e372e3-7050-4038-bf88-d1e8f5ddae09",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"#### Image"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 7,
|
||||
"id": "c2372365-7208-42f9-a147-deffdc390313",
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"The image depicts a charming Christmas-themed arrangement set against a rustic wooden backdrop, creating a warm and festive atmosphere. Here's a detailed breakdown:\n",
|
||||
"\n",
|
||||
"### **Background & Setting**\n",
|
||||
"- **Wooden Wall**: A horizontally paneled wooden wall forms the backdrop, giving a cozy, cabin-like feel.\n",
|
||||
"- **Foreground Surface**: The decorations rest on a smooth wooden surface (likely a table or desk), enhancing the natural, earthy tone of the scene.\n",
|
||||
"\n",
|
||||
"### **Key Elements**\n",
|
||||
"1. **Snow-Covered Trees**:\n",
|
||||
" - Two miniature evergreen trees dusted with artificial snow flank the sides of the arrangement, evoking a wintry landscape.\n",
|
||||
"\n",
|
||||
"2. **String Lights**:\n",
|
||||
" - A strand of white bulb lights stretches across the back, weaving through the decor and adding a soft, glowing ambiance.\n",
|
||||
"\n",
|
||||
"3. **Ornamental Sphere**:\n",
|
||||
" - A reflective gold sphere with striped patterns sits near the center-left, catching and dispersing light.\n",
|
||||
"\n",
|
||||
"4. **\"Merry Christmas\" Sign**:\n",
|
||||
" - A wooden cutout spelling \"MERRY CHRISTMAS\" in capital letters serves as the focal point. The letters feature star-shaped cutouts, allowing light to shine through.\n",
|
||||
"\n",
|
||||
"5. **Reindeer Figurine**:\n",
|
||||
" - A brown reindeer with white facial markings and large antlers stands prominently on the right, facing forward and adding a playful touch.\n",
|
||||
"\n",
|
||||
"6. **Candle Holders**:\n",
|
||||
" - Three birch-bark candle holders are arranged in front of the reindeer. Two hold lit tealights, casting a warm glow, while the third remains unlit.\n",
|
||||
"\n",
|
||||
"7. **Natural Accents**:\n",
|
||||
" - **Pinecones**: Scattered throughout, adding texture and a woodland feel.\n",
|
||||
" - **Berry Branches**: Red-berried greenery (likely holly) weaves behind the sign, introducing vibrant color.\n",
|
||||
" - **Pine Branches**: Fresh-looking branches enhance the seasonal authenticity.\n",
|
||||
"\n",
|
||||
"8. **Gift Box**:\n",
|
||||
" - A small golden gift box with a bow sits near the left, symbolizing holiday gifting.\n",
|
||||
"\n",
|
||||
"9. **Textile Detail**:\n",
|
||||
" - A fabric piece with \"Christmas\" embroidered on it peeks from the left, partially obscured but contributing to the thematic unity.\n",
|
||||
"\n",
|
||||
"### **Color Palette & Mood**\n",
|
||||
"- **Warm Tones**: Browns (wood, reindeer), golds (ornament, gift box), and whites (snow, lights) dominate, creating a inviting glow.\n",
|
||||
"- **Cool Accents**: Greens (trees, branches) and reds (berries) provide contrast, balancing the warmth.\n",
|
||||
"- **Lighting**: The lit candles and string lights cast a soft, flickering illumination, enhancing the intimate, celebratory vibe.\n",
|
||||
"\n",
|
||||
"### **Composition**\n",
|
||||
"- **Balance**: The arrangement is symmetrical, with trees and candles on either side framing the central sign and reindeer.\n",
|
||||
"- **Depth**: Layered elements (trees, lights, branches) create visual interest, drawing the eye inward.\n",
|
||||
"\n",
|
||||
"This image beautifully captures the essence of a cozy, handmade Christmas display, blending traditional symbols with natural textures to evoke nostalgia and joy.\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"from langchain_core.messages import HumanMessage\n",
|
||||
"\n",
|
||||
"model = ChatQwQ(model=\"qvq-max-latest\")\n",
|
||||
"\n",
|
||||
"messages = [\n",
|
||||
" HumanMessage(\n",
|
||||
" content=[\n",
|
||||
" {\n",
|
||||
" \"type\": \"image_url\",\n",
|
||||
" \"image_url\": {\"url\": \"https://example.com/image/image.png\"},\n",
|
||||
" },\n",
|
||||
" {\"type\": \"text\", \"text\": \"What do you see in this image?\"},\n",
|
||||
" ]\n",
|
||||
" )\n",
|
||||
"]\n",
|
||||
"\n",
|
||||
"response = model.invoke(messages)\n",
|
||||
"print(response.content)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "9242acf7-9a66-40b1-98b5-b113d28fc6ec",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"#### Video"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 10,
|
||||
"id": "f0a9e542-7a85-44d2-8576-14314a50d948",
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"The image provided is a still frame from a video featuring a young woman with short brown hair and bangs, smiling brightly at the camera. Here's a detailed breakdown:\n",
|
||||
"\n",
|
||||
"### **Description of the Image:**\n",
|
||||
"- **Subject:** A youthful female with a cheerful expression, showcasing a wide smile with visible teeth.\n",
|
||||
"- **Appearance:** \n",
|
||||
" - Short, neatly styled brown hair with blunt bangs.\n",
|
||||
" - Natural makeup emphasizing clear skin and subtle eye makeup.\n",
|
||||
" - Wearing a white round-neck shirt layered under a light pink knitted cardigan.\n",
|
||||
" - Accessories include a delicate necklace with a small pendant and small earrings.\n",
|
||||
"- **Background:** An outdoor setting with blurred architectural elements (e.g., buildings with columns), suggesting a campus, park, or residential area.\n",
|
||||
"- **Lighting:** Soft, natural daylight, enhancing the warm and inviting atmosphere.\n",
|
||||
"\n",
|
||||
"### **Key Details About the Video:**\n",
|
||||
"1. **AI-Generated Content:** The watermark (\"通义·AI合成\" / \"Tongyi AI Synthesis\") indicates this image was created using Alibaba's Tongyi AI model, known for generating hyper-realistic visuals.\n",
|
||||
"2. **Style & Purpose:** The high-quality, photorealistic style suggests the video may demonstrate AI imaging capabilities, potentially for advertising, entertainment, or educational purposes.\n",
|
||||
"3. **Context Clues:** The subject's casual yet polished look and the pleasant outdoor setting imply a positive, approachable theme (e.g., lifestyle, technology promotion, or social media content).\n",
|
||||
"\n",
|
||||
"### **What We Can Infer About the Video:**\n",
|
||||
"- Likely showcases dynamic AI-generated scenes featuring the same character in various poses or interactions.\n",
|
||||
"- May highlight realism in digital avatars or synthetic media.\n",
|
||||
"- Could be part of a demo reel, tutorial, or creative project emphasizing AI artistry.\n",
|
||||
"\n",
|
||||
"### **Limitations:**\n",
|
||||
"- As only a single frame is provided, specifics about the video's length, narrative, or additional scenes cannot be determined.\n",
|
||||
"\n",
|
||||
"If you have more frames or context, feel free to share! 😊\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"from langchain_core.messages import HumanMessage\n",
|
||||
"\n",
|
||||
"model = ChatQwQ(model=\"qvq-max-latest\")\n",
|
||||
"\n",
|
||||
"messages = [\n",
|
||||
" HumanMessage(\n",
|
||||
" content=[\n",
|
||||
" {\n",
|
||||
" \"type\": \"video_url\",\n",
|
||||
" \"video_url\": {\"url\": \"https://example.com/video/1.mp4\"},\n",
|
||||
" },\n",
|
||||
" {\"type\": \"text\", \"text\": \"Can you tell me about this video?\"},\n",
|
||||
" ]\n",
|
||||
" )\n",
|
||||
"]\n",
|
||||
"\n",
|
||||
"response = model.invoke(messages)\n",
|
||||
"print(response.content)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "3a5bb5ca-c3ae-4a58-be67-2cd18574b9a3",
|
||||
@@ -258,11 +423,19 @@
|
||||
"\n",
|
||||
"For detailed documentation of all ChatQwQ features and configurations head to the [API reference](https://pypi.org/project/langchain-qwq/)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "824f0c67-5f3b-4079-bc17-2cf92755bdd5",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": []
|
||||
}
|
||||
],
|
||||
"metadata": {
|
||||
"kernelspec": {
|
||||
"display_name": "Python 3",
|
||||
"display_name": "Python 3 (ipykernel)",
|
||||
"language": "python",
|
||||
"name": "python3"
|
||||
},
|
||||
@@ -276,7 +449,7 @@
|
||||
"name": "python",
|
||||
"nbconvert_exporter": "python",
|
||||
"pygments_lexer": "ipython3",
|
||||
"version": "3.13.1"
|
||||
"version": "3.11.9"
|
||||
}
|
||||
},
|
||||
"nbformat": 4,
|
||||
|
||||
@@ -16,13 +16,7 @@
|
||||
"This notebook covers how to load documents from Oracle Autonomous Database.\n",
|
||||
"\n",
|
||||
"## Prerequisites\n",
|
||||
"1. Install python-oracledb:\n",
|
||||
"\n",
|
||||
" `pip install oracledb`\n",
|
||||
" \n",
|
||||
" See [Installing python-oracledb](https://python-oracledb.readthedocs.io/en/latest/user_guide/installation.html).\n",
|
||||
"\n",
|
||||
"2. A database that python-oracledb's default 'Thin' mode can connected to. This is true of Oracle Autonomous Database, see [python-oracledb Architecture](https://python-oracledb.readthedocs.io/en/latest/user_guide/introduction.html#architecture).\n"
|
||||
"1. A database that python-oracledb's default 'Thin' mode can connected to. This is true of Oracle Autonomous Database, see [python-oracledb Architecture](https://python-oracledb.readthedocs.io/en/latest/user_guide/introduction.html#architecture).\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -38,17 +32,12 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"collapsed": false,
|
||||
"jupyter": {
|
||||
"outputs_hidden": false
|
||||
}
|
||||
},
|
||||
"outputs": [],
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"pip install oracledb"
|
||||
"You'll need to install `langchain-oracledb` with `python -m pip install -U langchain-oracledb` to use this integration.\n",
|
||||
"\n",
|
||||
"The `python-oracledb` driver is installed automatically as a dependency of langchain-oracledb."
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -62,7 +51,21 @@
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"from langchain_community.document_loaders import OracleAutonomousDatabaseLoader\n",
|
||||
"# python -m pip install -U langchain-oracledb"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"collapsed": false,
|
||||
"jupyter": {
|
||||
"outputs_hidden": false
|
||||
}
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"from langchain_oracledb.document_loaders import OracleAutonomousDatabaseLoader\n",
|
||||
"from settings import s"
|
||||
]
|
||||
},
|
||||
@@ -99,7 +102,7 @@
|
||||
" config_dir=s.CONFIG_DIR,\n",
|
||||
" wallet_location=s.WALLET_LOCATION,\n",
|
||||
" wallet_password=s.PASSWORD,\n",
|
||||
" tns_name=s.TNS_NAME,\n",
|
||||
" dsn=s.DSN,\n",
|
||||
")\n",
|
||||
"doc_1 = doc_loader_1.load()\n",
|
||||
"\n",
|
||||
@@ -108,7 +111,7 @@
|
||||
" user=s.USERNAME,\n",
|
||||
" password=s.PASSWORD,\n",
|
||||
" schema=s.SCHEMA,\n",
|
||||
" connection_string=s.CONNECTION_STRING,\n",
|
||||
" dsn=s.DSN,\n",
|
||||
" wallet_location=s.WALLET_LOCATION,\n",
|
||||
" wallet_password=s.PASSWORD,\n",
|
||||
")\n",
|
||||
@@ -147,7 +150,7 @@
|
||||
" password=s.PASSWORD,\n",
|
||||
" schema=s.SCHEMA,\n",
|
||||
" config_dir=s.CONFIG_DIR,\n",
|
||||
" tns_name=s.TNS_NAME,\n",
|
||||
" dsn=s.DSN,\n",
|
||||
" parameters=[\"Direct Sales\"],\n",
|
||||
")\n",
|
||||
"doc_3 = doc_loader_3.load()\n",
|
||||
@@ -157,7 +160,7 @@
|
||||
" user=s.USERNAME,\n",
|
||||
" password=s.PASSWORD,\n",
|
||||
" schema=s.SCHEMA,\n",
|
||||
" connection_string=s.CONNECTION_STRING,\n",
|
||||
" dsn=s.DSN,\n",
|
||||
" parameters=[\"Direct Sales\"],\n",
|
||||
")\n",
|
||||
"doc_4 = doc_loader_4.load()"
|
||||
|
||||
@@ -42,7 +42,9 @@
|
||||
"source": [
|
||||
"### Prerequisites\n",
|
||||
"\n",
|
||||
"Please install Oracle Python Client driver to use Langchain with Oracle AI Vector Search. "
|
||||
"You'll need to install `langchain-oracledb` with `python -m pip install -U langchain-oracledb` to use this integration.\n",
|
||||
"\n",
|
||||
"The `python-oracledb` driver is installed automatically as a dependency of langchain-oracledb."
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -51,7 +53,7 @@
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"# pip install oracledb"
|
||||
"# python -m pip install -U langchain-oracledb"
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -154,7 +156,7 @@
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"from langchain_community.document_loaders.oracleai import OracleDocLoader\n",
|
||||
"from langchain_oracledb.document_loaders.oracleai import OracleDocLoader\n",
|
||||
"from langchain_core.documents import Document\n",
|
||||
"\n",
|
||||
"\"\"\"\n",
|
||||
@@ -199,7 +201,7 @@
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"from langchain_community.document_loaders.oracleai import OracleTextSplitter\n",
|
||||
"from langchain_oracledb.document_loaders.oracleai import OracleTextSplitter\n",
|
||||
"from langchain_core.documents import Document\n",
|
||||
"\n",
|
||||
"\"\"\"\n",
|
||||
|
||||
357
docs/docs/integrations/llms/aimlapi.ipynb
Normal file
357
docs/docs/integrations/llms/aimlapi.ipynb
Normal file
@@ -0,0 +1,357 @@
|
||||
{
|
||||
"cells": [
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"source": [
|
||||
"---\n",
|
||||
"sidebar_label: AI/ML API\n",
|
||||
"---"
|
||||
],
|
||||
"metadata": {
|
||||
"collapsed": false
|
||||
},
|
||||
"id": "c74887ead73c5eb4"
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"source": [
|
||||
"# AimlapiLLM\n",
|
||||
"\n",
|
||||
"This page will help you get started with AI/ML API [text completion models](/docs/concepts/text_llms). For detailed documentation of all AimlapiLLM features and configurations, head to the [API reference](https://docs.aimlapi.com/?utm_source=langchain&utm_medium=github&utm_campaign=integration).\n",
|
||||
"\n",
|
||||
"AI/ML API provides access to **300+ models** (Deepseek, Gemini, ChatGPT, etc.) via high-uptime and high-rate API."
|
||||
],
|
||||
"metadata": {
|
||||
"collapsed": false
|
||||
},
|
||||
"id": "c1895707cde83d90"
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"source": [
|
||||
"## Overview\n",
|
||||
"### Integration details\n",
|
||||
"\n",
|
||||
"| Class | Package | Local | Serializable | JS support | Package downloads | Package latest |\n",
|
||||
"| :--- | :--- | :---: | :---: | :---: | :---: | :---: |\n",
|
||||
"| AimlapiLLM | langchain-aimlapi | ✅ | beta | ❌ |  |  |"
|
||||
],
|
||||
"metadata": {
|
||||
"collapsed": false
|
||||
},
|
||||
"id": "72b0a510b6eac641"
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"source": [
|
||||
"### Model features\n",
|
||||
"| Tool calling | Structured output | JSON mode | Image input | Audio input | Video input | Token-level streaming | Native async | Token usage | Logprobs |\n",
|
||||
"|:------------:|:-----------------:|:---------:|:-----------:|:-----------:|:-----------:|:---------------------:|:------------:|:-----------:|:--------:|\n",
|
||||
"| ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |\n"
|
||||
],
|
||||
"metadata": {
|
||||
"collapsed": false
|
||||
},
|
||||
"id": "4b87089494d8877d"
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"source": [
|
||||
"## Setup\n",
|
||||
"To access AI/ML API models, sign up at [aimlapi.com](https://aimlapi.com/app/?utm_source=langchain&utm_medium=github&utm_campaign=integration), generate an API key, and set the `AIMLAPI_API_KEY` environment variable:"
|
||||
],
|
||||
"metadata": {
|
||||
"collapsed": false
|
||||
},
|
||||
"id": "2c45017efcc36569"
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"import getpass\n",
|
||||
"import os\n",
|
||||
"\n",
|
||||
"if \"AIMLAPI_API_KEY\" not in os.environ:\n",
|
||||
" os.environ[\"AIMLAPI_API_KEY\"] = getpass.getpass(\"Enter your AI/ML API key: \")"
|
||||
],
|
||||
"metadata": {
|
||||
"collapsed": false,
|
||||
"ExecuteTime": {
|
||||
"end_time": "2025-08-07T07:24:48.681319Z",
|
||||
"start_time": "2025-08-07T07:24:47.490206Z"
|
||||
}
|
||||
},
|
||||
"id": "86b05af725c45941",
|
||||
"execution_count": 1
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"source": [
|
||||
"### Installation\n",
|
||||
"Install the `langchain-aimlapi` package:"
|
||||
],
|
||||
"metadata": {
|
||||
"collapsed": false
|
||||
},
|
||||
"id": "51171ba92cb2b382"
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"Note: you may need to restart the kernel to use updated packages.\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"%pip install -qU langchain-aimlapi"
|
||||
],
|
||||
"metadata": {
|
||||
"collapsed": false,
|
||||
"ExecuteTime": {
|
||||
"end_time": "2025-08-07T07:18:08.606708Z",
|
||||
"start_time": "2025-08-07T07:17:59.901457Z"
|
||||
}
|
||||
},
|
||||
"id": "2b15cbaf7d5e1560",
|
||||
"execution_count": 2
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"source": [
|
||||
"## Instantiation\n",
|
||||
"Now we can instantiate the `AimlapiLLM` model and generate text completions:"
|
||||
],
|
||||
"metadata": {
|
||||
"collapsed": false
|
||||
},
|
||||
"id": "e94379f9d37fe6b3"
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"from langchain_aimlapi import AimlapiLLM\n",
|
||||
"\n",
|
||||
"llm = AimlapiLLM(\n",
|
||||
" model=\"gpt-3.5-turbo-instruct\",\n",
|
||||
" temperature=0.5,\n",
|
||||
" max_tokens=256,\n",
|
||||
")"
|
||||
],
|
||||
"metadata": {
|
||||
"collapsed": false,
|
||||
"ExecuteTime": {
|
||||
"end_time": "2025-08-07T07:46:52.875867Z",
|
||||
"start_time": "2025-08-07T07:46:52.869961Z"
|
||||
}
|
||||
},
|
||||
"id": "8a3af681997723b0",
|
||||
"execution_count": 23
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"source": [
|
||||
"## Invocation\n",
|
||||
"You can invoke the model with a prompt:"
|
||||
],
|
||||
"metadata": {
|
||||
"collapsed": false
|
||||
},
|
||||
"id": "c983ab1d95887e8f"
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"\n",
|
||||
"\n",
|
||||
"Bubble sort is a simple sorting algorithm that repeatedly steps through the list to be sorted, compares each pair of adjacent items and swaps them if they are in the wrong order. This process is repeated until the entire list is sorted.\n",
|
||||
"\n",
|
||||
"The algorithm gets its name from the way smaller elements \"bubble\" to the top of the list. It is commonly used for educational purposes due to its simplicity, but it is not a very efficient sorting algorithm for large data sets.\n",
|
||||
"\n",
|
||||
"Here is an implementation of the bubble sort algorithm in Python:\n",
|
||||
"\n",
|
||||
"1. Start by defining a function that takes in a list as its argument.\n",
|
||||
"2. Set a variable \"swapped\" to True, indicating that a swap has occurred.\n",
|
||||
"3. Create a while loop that runs as long as the \"swapped\" variable is True.\n",
|
||||
"4. Inside the loop, set the \"swapped\" variable to False.\n",
|
||||
"5. Create a for loop that iterates through the list, starting from the first element and ending at the second to last element.\n",
|
||||
"6. Inside the for loop, compare the current element with the next element. If the current element is larger than the next element, swap them and set the \"swapped\" variable to True.\n",
|
||||
"7. After the for loop, if the \"swapped\" variable\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"response = llm.invoke(\"Explain the bubble sort algorithm in Python.\")\n",
|
||||
"print(response)"
|
||||
],
|
||||
"metadata": {
|
||||
"collapsed": false,
|
||||
"ExecuteTime": {
|
||||
"end_time": "2025-08-07T07:46:57.209950Z",
|
||||
"start_time": "2025-08-07T07:46:53.935975Z"
|
||||
}
|
||||
},
|
||||
"id": "9a193081f431a42a",
|
||||
"execution_count": 24
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"source": [
|
||||
"## Streaming Invocation\n",
|
||||
"You can also stream responses token-by-token:"
|
||||
],
|
||||
"metadata": {
|
||||
"collapsed": false
|
||||
},
|
||||
"id": "1afedb28f556c7bd"
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
" \n",
|
||||
"\n",
|
||||
"1. Python\n",
|
||||
"Python has been consistently growing in popularity and has become one of the most widely used programming languages in recent years. It is used for a wide range of applications such as web development, data analysis, machine learning, and artificial intelligence. Its simple syntax and readability make it an attractive choice for beginners and experienced programmers alike. With the rise of data-driven technology and automation, Python is projected to be the most in-demand language in 2025.\n",
|
||||
"\n",
|
||||
"2. JavaScript\n",
|
||||
"JavaScript continues to dominate the web development scene and is expected to maintain its position as a top programming language in 2025. With the increasing use of front-end frameworks like React and Angular, JavaScript is crucial for building dynamic and interactive user interfaces. Additionally, the rise of serverless architecture and the popularity of Node.js make JavaScript an essential language for both front-end and back-end development.\n",
|
||||
"\n",
|
||||
"3. Go\n",
|
||||
"Go, also known as Golang, is a relatively new programming language developed by Google. It is designed for"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"llm = AimlapiLLM(\n",
|
||||
" model=\"gpt-3.5-turbo-instruct\",\n",
|
||||
")\n",
|
||||
"\n",
|
||||
"for chunk in llm.stream(\"List top 5 programming languages in 2025 with reasons.\"):\n",
|
||||
" print(chunk, end=\"\", flush=True)"
|
||||
],
|
||||
"metadata": {
|
||||
"collapsed": false,
|
||||
"ExecuteTime": {
|
||||
"end_time": "2025-08-07T07:49:25.223233Z",
|
||||
"start_time": "2025-08-07T07:49:22.101498Z"
|
||||
}
|
||||
},
|
||||
"id": "a132c9183f648fb4",
|
||||
"execution_count": 26
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"source": [
|
||||
"## API reference\n",
|
||||
"\n",
|
||||
"For detailed documentation of all AimlapiLLM features and configurations, visit the [API Reference](https://docs.aimlapi.com/?utm_source=langchain&utm_medium=github&utm_campaign=integration).\n"
|
||||
],
|
||||
"metadata": {
|
||||
"collapsed": false
|
||||
},
|
||||
"id": "7b4ab33058dc0974"
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"source": [
|
||||
"## Chaining\n",
|
||||
"\n",
|
||||
"You can also easily combine with a prompt template for easy structuring of user input. We can do this using [LCEL](/docs/concepts/lcel)"
|
||||
],
|
||||
"metadata": {
|
||||
"collapsed": false
|
||||
},
|
||||
"id": "900f36a35477c8ae"
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"from langchain_core.prompts import PromptTemplate\n",
|
||||
"\n",
|
||||
"prompt = PromptTemplate.from_template(\"Tell me a joke about {topic}\")\n",
|
||||
"chain = prompt | llm"
|
||||
],
|
||||
"metadata": {
|
||||
"collapsed": false,
|
||||
"ExecuteTime": {
|
||||
"end_time": "2025-08-07T07:49:34.857042Z",
|
||||
"start_time": "2025-08-07T07:49:34.853032Z"
|
||||
}
|
||||
},
|
||||
"id": "d7f10052eb4ff249",
|
||||
"execution_count": 27
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
"text/plain": "\"\\n\\nWhy do bears have fur coats?\\n\\nBecause they'd look silly in sweaters! \""
|
||||
},
|
||||
"execution_count": 28,
|
||||
"metadata": {},
|
||||
"output_type": "execute_result"
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"chain.invoke({\"topic\": \"bears\"})"
|
||||
],
|
||||
"metadata": {
|
||||
"collapsed": false,
|
||||
"ExecuteTime": {
|
||||
"end_time": "2025-08-07T07:49:48.565804Z",
|
||||
"start_time": "2025-08-07T07:49:35.558426Z"
|
||||
}
|
||||
},
|
||||
"id": "184c333c60f94b05",
|
||||
"execution_count": 28
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"source": [
|
||||
"## API reference\n",
|
||||
"\n",
|
||||
"For detailed documentation of all `AI/ML API` llm features and configurations head to the API reference: [API Reference](https://docs.aimlapi.com/?utm_source=langchain&utm_medium=github&utm_campaign=integration)"
|
||||
],
|
||||
"metadata": {
|
||||
"collapsed": false
|
||||
},
|
||||
"id": "804f3a79a8046ec1"
|
||||
}
|
||||
],
|
||||
"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
|
||||
}
|
||||
@@ -22,30 +22,28 @@
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## Setup\n",
|
||||
"Ensure that the oci sdk and the langchain-community package are installed"
|
||||
"Ensure that the oci sdk and the langchain-community package are installed\n",
|
||||
"\n",
|
||||
":::caution You are currently on a page documenting the use of Oracle's text generation models. Which are deprecated."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"cell_type": "code",
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"!pip install -U langchain-oci"
|
||||
]
|
||||
"execution_count": null,
|
||||
"source": "!pip install -U langchain-oci"
|
||||
},
|
||||
{
|
||||
"metadata": {},
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## Usage"
|
||||
]
|
||||
"source": "## Usage"
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"cell_type": "code",
|
||||
"outputs": [],
|
||||
"execution_count": null,
|
||||
"source": [
|
||||
"from langchain_oci.llms import OCIGenAI\n",
|
||||
"\n",
|
||||
|
||||
@@ -1,26 +0,0 @@
|
||||
# Aerospike
|
||||
|
||||
>[Aerospike](https://aerospike.com/docs/vector) is a high-performance, distributed database known for its speed and scalability, now with support for vector storage and search, enabling retrieval and search of embedding vectors for machine learning and AI applications.
|
||||
> See the documentation for Aerospike Vector Search (AVS) [here](https://aerospike.com/docs/vector).
|
||||
|
||||
## Installation and Setup
|
||||
|
||||
Install the AVS Python SDK and AVS langchain vector store:
|
||||
|
||||
```bash
|
||||
pip install aerospike-vector-search langchain-aerospike
|
||||
```
|
||||
|
||||
See the documentation for the Python SDK [here](https://aerospike-vector-search-python-client.readthedocs.io/en/latest/index.html).
|
||||
The documentation for the AVS langchain vector store is [here](https://langchain-aerospike.readthedocs.io/en/latest/).
|
||||
|
||||
## Vector Store
|
||||
|
||||
To import this vectorstore:
|
||||
|
||||
```python
|
||||
from langchain_aerospike.vectorstores import Aerospike
|
||||
```
|
||||
|
||||
See a usage example [here](https://python.langchain.com/docs/integrations/vectorstores/aerospike/).
|
||||
|
||||
272
docs/docs/integrations/providers/aimlapi.ipynb
Normal file
272
docs/docs/integrations/providers/aimlapi.ipynb
Normal file
@@ -0,0 +1,272 @@
|
||||
{
|
||||
"cells": [
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"source": [
|
||||
"# AI/ML API LLM\n",
|
||||
"\n",
|
||||
"[AI/ML API](https://aimlapi.com/app/?utm_source=langchain&utm_medium=github&utm_campaign=integration) provides an API to query **300+ leading AI models** (Deepseek, Gemini, ChatGPT, etc.) with enterprise-grade performance.\n",
|
||||
"\n",
|
||||
"This example demonstrates how to use LangChain to interact with AI/ML API models."
|
||||
],
|
||||
"metadata": {
|
||||
"collapsed": false
|
||||
},
|
||||
"id": "bb9dcd1ba7b0f560"
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"source": [
|
||||
"## Installation"
|
||||
],
|
||||
"metadata": {
|
||||
"collapsed": false
|
||||
},
|
||||
"id": "e4c35f60c565d369"
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"Requirement already satisfied: langchain-aimlapi in c:\\users\\tuman\\appdata\\local\\programs\\python\\python312\\lib\\site-packages (0.1.0)\n",
|
||||
"Requirement already satisfied: langchain-core<0.4.0,>=0.3.15 in c:\\users\\tuman\\appdata\\local\\programs\\python\\python312\\lib\\site-packages (from langchain-aimlapi) (0.3.67)\n",
|
||||
"Requirement already satisfied: langsmith>=0.3.45 in c:\\users\\tuman\\appdata\\local\\programs\\python\\python312\\lib\\site-packages (from langchain-core<0.4.0,>=0.3.15->langchain-aimlapi) (0.4.4)\n",
|
||||
"Requirement already satisfied: tenacity!=8.4.0,<10.0.0,>=8.1.0 in c:\\users\\tuman\\appdata\\local\\programs\\python\\python312\\lib\\site-packages (from langchain-core<0.4.0,>=0.3.15->langchain-aimlapi) (9.1.2)\n",
|
||||
"Requirement already satisfied: jsonpatch<2.0,>=1.33 in c:\\users\\tuman\\appdata\\local\\programs\\python\\python312\\lib\\site-packages (from langchain-core<0.4.0,>=0.3.15->langchain-aimlapi) (1.33)\n",
|
||||
"Requirement already satisfied: PyYAML>=5.3 in c:\\users\\tuman\\appdata\\local\\programs\\python\\python312\\lib\\site-packages (from langchain-core<0.4.0,>=0.3.15->langchain-aimlapi) (6.0.2)\n",
|
||||
"Requirement already satisfied: packaging<25,>=23.2 in c:\\users\\tuman\\appdata\\local\\programs\\python\\python312\\lib\\site-packages (from langchain-core<0.4.0,>=0.3.15->langchain-aimlapi) (24.2)\n",
|
||||
"Requirement already satisfied: typing-extensions>=4.7 in c:\\users\\tuman\\appdata\\local\\programs\\python\\python312\\lib\\site-packages (from langchain-core<0.4.0,>=0.3.15->langchain-aimlapi) (4.14.0)\n",
|
||||
"Requirement already satisfied: pydantic>=2.7.4 in c:\\users\\tuman\\appdata\\local\\programs\\python\\python312\\lib\\site-packages (from langchain-core<0.4.0,>=0.3.15->langchain-aimlapi) (2.11.7)\n",
|
||||
"Requirement already satisfied: jsonpointer>=1.9 in c:\\users\\tuman\\appdata\\local\\programs\\python\\python312\\lib\\site-packages (from jsonpatch<2.0,>=1.33->langchain-core<0.4.0,>=0.3.15->langchain-aimlapi) (3.0.0)\n",
|
||||
"Requirement already satisfied: httpx<1,>=0.23.0 in c:\\users\\tuman\\appdata\\local\\programs\\python\\python312\\lib\\site-packages (from langsmith>=0.3.45->langchain-core<0.4.0,>=0.3.15->langchain-aimlapi) (0.28.1)\n",
|
||||
"Requirement already satisfied: orjson<4.0.0,>=3.9.14 in c:\\users\\tuman\\appdata\\local\\programs\\python\\python312\\lib\\site-packages (from langsmith>=0.3.45->langchain-core<0.4.0,>=0.3.15->langchain-aimlapi) (3.10.18)\n",
|
||||
"Requirement already satisfied: requests<3,>=2 in c:\\users\\tuman\\appdata\\local\\programs\\python\\python312\\lib\\site-packages (from langsmith>=0.3.45->langchain-core<0.4.0,>=0.3.15->langchain-aimlapi) (2.32.4)\n",
|
||||
"Requirement already satisfied: requests-toolbelt<2.0.0,>=1.0.0 in c:\\users\\tuman\\appdata\\local\\programs\\python\\python312\\lib\\site-packages (from langsmith>=0.3.45->langchain-core<0.4.0,>=0.3.15->langchain-aimlapi) (1.0.0)\n",
|
||||
"Requirement already satisfied: zstandard<0.24.0,>=0.23.0 in c:\\users\\tuman\\appdata\\roaming\\python\\python312\\site-packages (from langsmith>=0.3.45->langchain-core<0.4.0,>=0.3.15->langchain-aimlapi) (0.23.0)\n",
|
||||
"Requirement already satisfied: annotated-types>=0.6.0 in c:\\users\\tuman\\appdata\\local\\programs\\python\\python312\\lib\\site-packages (from pydantic>=2.7.4->langchain-core<0.4.0,>=0.3.15->langchain-aimlapi) (0.7.0)\n",
|
||||
"Requirement already satisfied: pydantic-core==2.33.2 in c:\\users\\tuman\\appdata\\local\\programs\\python\\python312\\lib\\site-packages (from pydantic>=2.7.4->langchain-core<0.4.0,>=0.3.15->langchain-aimlapi) (2.33.2)\n",
|
||||
"Requirement already satisfied: typing-inspection>=0.4.0 in c:\\users\\tuman\\appdata\\local\\programs\\python\\python312\\lib\\site-packages (from pydantic>=2.7.4->langchain-core<0.4.0,>=0.3.15->langchain-aimlapi) (0.4.1)\n",
|
||||
"Requirement already satisfied: anyio in c:\\users\\tuman\\appdata\\local\\programs\\python\\python312\\lib\\site-packages (from httpx<1,>=0.23.0->langsmith>=0.3.45->langchain-core<0.4.0,>=0.3.15->langchain-aimlapi) (4.9.0)\n",
|
||||
"Requirement already satisfied: certifi in c:\\users\\tuman\\appdata\\local\\programs\\python\\python312\\lib\\site-packages (from httpx<1,>=0.23.0->langsmith>=0.3.45->langchain-core<0.4.0,>=0.3.15->langchain-aimlapi) (2025.6.15)\n",
|
||||
"Requirement already satisfied: httpcore==1.* in c:\\users\\tuman\\appdata\\local\\programs\\python\\python312\\lib\\site-packages (from httpx<1,>=0.23.0->langsmith>=0.3.45->langchain-core<0.4.0,>=0.3.15->langchain-aimlapi) (1.0.9)\n",
|
||||
"Requirement already satisfied: idna in c:\\users\\tuman\\appdata\\local\\programs\\python\\python312\\lib\\site-packages (from httpx<1,>=0.23.0->langsmith>=0.3.45->langchain-core<0.4.0,>=0.3.15->langchain-aimlapi) (3.10)\n",
|
||||
"Requirement already satisfied: h11>=0.16 in c:\\users\\tuman\\appdata\\local\\programs\\python\\python312\\lib\\site-packages (from httpcore==1.*->httpx<1,>=0.23.0->langsmith>=0.3.45->langchain-core<0.4.0,>=0.3.15->langchain-aimlapi) (0.16.0)\n",
|
||||
"Requirement already satisfied: charset_normalizer<4,>=2 in c:\\users\\tuman\\appdata\\local\\programs\\python\\python312\\lib\\site-packages (from requests<3,>=2->langsmith>=0.3.45->langchain-core<0.4.0,>=0.3.15->langchain-aimlapi) (3.4.2)\n",
|
||||
"Requirement already satisfied: urllib3<3,>=1.21.1 in c:\\users\\tuman\\appdata\\local\\programs\\python\\python312\\lib\\site-packages (from requests<3,>=2->langsmith>=0.3.45->langchain-core<0.4.0,>=0.3.15->langchain-aimlapi) (2.5.0)\n",
|
||||
"Requirement already satisfied: sniffio>=1.1 in c:\\users\\tuman\\appdata\\local\\programs\\python\\python312\\lib\\site-packages (from anyio->httpx<1,>=0.23.0->langsmith>=0.3.45->langchain-core<0.4.0,>=0.3.15->langchain-aimlapi) (1.3.1)\n",
|
||||
"Note: you may need to restart the kernel to use updated packages.\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "stderr",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"\n",
|
||||
"[notice] A new release of pip is available: 25.0.1 -> 25.2\n",
|
||||
"[notice] To update, run: python.exe -m pip install --upgrade pip\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"%pip install --upgrade langchain-aimlapi"
|
||||
],
|
||||
"metadata": {
|
||||
"collapsed": false,
|
||||
"ExecuteTime": {
|
||||
"end_time": "2025-08-06T15:22:02.570792Z",
|
||||
"start_time": "2025-08-06T15:21:32.377131Z"
|
||||
}
|
||||
},
|
||||
"id": "77d4a44909effc3c",
|
||||
"execution_count": 4
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"source": [
|
||||
"## Environment\n",
|
||||
"\n",
|
||||
"To use AI/ML API, you'll need an API key which you can generate at:\n",
|
||||
"[https://aimlapi.com/app/](https://aimlapi.com/app/?utm_source=langchain&utm_medium=github&utm_campaign=integration)\n",
|
||||
"\n",
|
||||
"You can pass it via `aimlapi_api_key` parameter or set as environment variable `AIMLAPI_API_KEY`."
|
||||
],
|
||||
"metadata": {
|
||||
"collapsed": false
|
||||
},
|
||||
"id": "c41eaf364c0b414f"
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"import os\n",
|
||||
"import getpass\n",
|
||||
"\n",
|
||||
"if \"AIMLAPI_API_KEY\" not in os.environ:\n",
|
||||
" os.environ[\"AIMLAPI_API_KEY\"] = getpass.getpass(\"Enter your AI/ML API key: \")"
|
||||
],
|
||||
"metadata": {
|
||||
"collapsed": false,
|
||||
"ExecuteTime": {
|
||||
"end_time": "2025-08-07T07:15:37.147559Z",
|
||||
"start_time": "2025-08-07T07:15:30.919160Z"
|
||||
}
|
||||
},
|
||||
"id": "421cd40d4e54de62",
|
||||
"execution_count": 3
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"source": [
|
||||
"## Example: Chat Model"
|
||||
],
|
||||
"metadata": {
|
||||
"collapsed": false
|
||||
},
|
||||
"id": "d9cbe98904f4c5e4"
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"The city that never sleeps! New York City is a treasure trove of excitement, entertainment, and adventure. Here are some fun things to do in NYC:\n",
|
||||
"\n",
|
||||
"**Iconic Attractions:**\n",
|
||||
"\n",
|
||||
"1. **Statue of Liberty and Ellis Island**: Take a ferry to Liberty Island to see the iconic statue up close and visit the Ellis Island Immigration Museum.\n",
|
||||
"2. **Central Park**: A tranquil oasis in the middle of Manhattan, perfect for a stroll, picnic, or bike ride.\n",
|
||||
"3. **Empire State Building**: For a panoramic view of the city, head to the observation deck of this iconic skyscraper.\n",
|
||||
"4. **The Metropolitan Museum of Art**: One of the world's largest and most famous museums, with a collection that spans over 5,000 years of human history.\n",
|
||||
"\n",
|
||||
"**Neighborhood Explorations:**\n",
|
||||
"\n",
|
||||
"1. **SoHo**: Known for its trendy boutiques, art galleries, and cast-iron buildings.\n",
|
||||
"2. **Greenwich Village**: A charming neighborhood with a rich history, known for its bohemian vibe, jazz clubs, and historic brownstones.\n",
|
||||
"3. **Chinatown and Little Italy**: Experience the vibrant cultures of these two iconic neighborhoods, with delicious food, street festivals, and unique shops.\n",
|
||||
"4. **Williamsburg, Brooklyn**: A hip neighborhood with a thriving arts scene, trendy bars, and some of the best restaurants in the city.\n",
|
||||
"\n",
|
||||
"**Food and Drink:**\n",
|
||||
"\n",
|
||||
"1. **Try a classic NYC slice of pizza**: Visit Lombardi's, Joe's Pizza, or Patsy's Pizzeria for a taste of the city's famous pizza.\n",
|
||||
"2. **Bagels with lox and cream cheese**: A classic NYC breakfast at a Jewish deli like Russ & Daughters Cafe or Ess-a-Bagel.\n",
|
||||
"3. **Food markets**: Visit Smorgasburg in Brooklyn or Chelsea Market for a variety of artisanal foods and drinks.\n",
|
||||
"4. **Rooftop bars**: Enjoy a drink with a view at 230 Fifth, the Top of the Strand, or the Roof at The Viceroy Central Park.\n",
|
||||
"**Performing Arts:**\n",
|
||||
"\n",
|
||||
"1. **Broadway shows**: Catch a musical or play on the Great White Way, like Hamilton, The Lion King, or Wicked.\n",
|
||||
"2. **Jazz clubs**: Visit Blue Note Jazz Club, the Village Vanguard, or the Jazz Standard for live music performances.\n",
|
||||
"3. **Lincoln Center**: Home to the New York City Ballet, the Metropolitan Opera, and the Juilliard School.\n",
|
||||
"4. **"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"from langchain_aimlapi import ChatAimlapi\n",
|
||||
"\n",
|
||||
"chat = ChatAimlapi(\n",
|
||||
" model=\"meta-llama/Llama-3-70b-chat-hf\",\n",
|
||||
")\n",
|
||||
"\n",
|
||||
"# Stream response\n",
|
||||
"for chunk in chat.stream(\"Tell me fun things to do in NYC\"):\n",
|
||||
" print(chunk.content, end=\"\", flush=True)\n",
|
||||
"\n",
|
||||
"# Or use invoke()\n",
|
||||
"# response = chat.invoke(\"Tell me fun things to do in NYC\")\n",
|
||||
"# print(response)"
|
||||
],
|
||||
"metadata": {
|
||||
"collapsed": false,
|
||||
"ExecuteTime": {
|
||||
"end_time": "2025-08-07T07:15:59.612289Z",
|
||||
"start_time": "2025-08-07T07:15:47.864231Z"
|
||||
}
|
||||
},
|
||||
"id": "3f73a8e113a58e9b",
|
||||
"execution_count": 4
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"source": [
|
||||
"## Example: Text Completion Model"
|
||||
],
|
||||
"metadata": {
|
||||
"collapsed": false
|
||||
},
|
||||
"id": "7aca59af5cadce80"
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
" # Funkcja ponownie zwraca nową listę, bez zmienienia listy przekazanej jako argument w funkcji\n",
|
||||
" my_list = [16, 12, 16, 3, 2, 6]\n",
|
||||
" new_list = my_list[:]\n",
|
||||
" for x in range(len(new_list)):\n",
|
||||
" for y in range(len(new_list) - 1):\n",
|
||||
" if new_list[y] > new_list[y + 1]:\n",
|
||||
" new_list[y], new_list[y + 1] = new_list[y + 1], new_list[y]\n",
|
||||
" return new_list, my_list\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"def bubble_sort_lib3(list): # Sortowanie z wykorzystaniem zewnętrznej biblioteki poza pętlą\n",
|
||||
" from itertools import permutations\n",
|
||||
" y = len(list)\n",
|
||||
" perms = []\n",
|
||||
" for a in range(0, y + 1):\n",
|
||||
" for subset in permutations(list, a):\n",
|
||||
" \n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"from langchain_aimlapi import AimlapiLLM\n",
|
||||
"\n",
|
||||
"llm = AimlapiLLM(\n",
|
||||
" model=\"gpt-3.5-turbo-instruct\",\n",
|
||||
")\n",
|
||||
"\n",
|
||||
"print(llm.invoke(\"def bubble_sort(): \"))"
|
||||
],
|
||||
"metadata": {
|
||||
"collapsed": false,
|
||||
"ExecuteTime": {
|
||||
"end_time": "2025-08-07T07:16:22.595703Z",
|
||||
"start_time": "2025-08-07T07:16:19.410881Z"
|
||||
}
|
||||
},
|
||||
"id": "2af3be417769efc3",
|
||||
"execution_count": 6
|
||||
}
|
||||
],
|
||||
"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
|
||||
}
|
||||
@@ -21,6 +21,38 @@ pip install deepeval
|
||||
|
||||
See an [example](/docs/integrations/callbacks/confident).
|
||||
|
||||
```python
|
||||
from langchain.callbacks.confident_callback import DeepEvalCallbackHandler
|
||||
|
||||
## Modern Integration Example
|
||||
|
||||
Install the required packages:
|
||||
|
||||
```bash
|
||||
pip install deepeval langchain langchain-openai
|
||||
```
|
||||
|
||||
Authenticate with your API key:
|
||||
|
||||
```python
|
||||
import os
|
||||
import deepeval
|
||||
|
||||
# Load API key from environment variable for security
|
||||
api_key = os.environ.get("DEEPEVAL_API_KEY")
|
||||
deepeval.login(api_key)
|
||||
```
|
||||
|
||||
Use the new callback handler:
|
||||
|
||||
```python
|
||||
from deepeval.integrations.langchain import CallbackHandler
|
||||
|
||||
handler = CallbackHandler(
|
||||
name="My Trace",
|
||||
tags=["production", "v1"],
|
||||
metadata={"experiment": "A/B"},
|
||||
thread_id="thread-123",
|
||||
user_id="user-456"
|
||||
)
|
||||
```
|
||||
|
||||
See the [full example](/docs/integrations/callbacks/confident).
|
||||
@@ -36,7 +36,7 @@ For end-to-end usage check out
|
||||
|
||||
## Additional Resources
|
||||
|
||||
- [LangChain Docling integration GitHub](https://github.com/DS4SD/docling-langchain)
|
||||
- [LangChain Docling integration GitHub](https://github.com/docling-project/docling-langchain)
|
||||
- [LangChain Docling integration PyPI package](https://pypi.org/project/langchain-docling/)
|
||||
- [Docling GitHub](https://github.com/DS4SD/docling)
|
||||
- [Docling docs](https://ds4sd.github.io/docling/)
|
||||
- [Docling GitHub](https://github.com/docling-project/docling)
|
||||
- [Docling docs](https://docling-project.github.io/docling/)
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
Install the python SDK:
|
||||
|
||||
```bash
|
||||
pip install firecrawl-py==0.0.20
|
||||
pip install firecrawl-py
|
||||
```
|
||||
|
||||
## Document loader
|
||||
|
||||
129
docs/docs/integrations/providers/google-bigtable.mdx
Normal file
129
docs/docs/integrations/providers/google-bigtable.mdx
Normal file
@@ -0,0 +1,129 @@
|
||||
# Bigtable
|
||||
|
||||
Bigtable is a scalable, fully managed key-value and wide-column store ideal for fast access to structured, semi-structured, or unstructured data. This page provides an overview of Bigtable's LangChain integrations.
|
||||
|
||||
**Client Library Documentation:** [cloud.google.com/python/docs/reference/langchain-google-bigtable/latest](https://cloud.google.com/python/docs/reference/langchain-google-bigtable/latest)
|
||||
|
||||
**Product Documentation:** [cloud.google.com/bigtable](https://cloud.google.com/bigtable)
|
||||
|
||||
## Quick Start
|
||||
|
||||
To use this library, you first need to:
|
||||
|
||||
1. Select or create a Cloud Platform project.
|
||||
2. Enable billing for your project.
|
||||
3. Enable the Google Cloud Bigtable API.
|
||||
4. Set up Authentication.
|
||||
|
||||
## Installation
|
||||
|
||||
The main package for this integration is `langchain-google-bigtable`.
|
||||
|
||||
```bash
|
||||
pip install -U langchain-google-bigtable
|
||||
```
|
||||
|
||||
## Integrations
|
||||
|
||||
The `langchain-google-bigtable` package provides the following integrations:
|
||||
|
||||
### Vector Store
|
||||
|
||||
With `BigtableVectorStore`, you can store documents and their vector embeddings to find the most similar or relevant information in your database.
|
||||
|
||||
* **Full `VectorStore` Implementation:** Supports all methods from the LangChain `VectorStore` abstract class.
|
||||
* **Async/Sync Support:** All methods are available in both asynchronous and synchronous versions.
|
||||
* **Metadata Filtering:** Powerful filtering on metadata fields, including logical AND/OR combinations.
|
||||
* **Multiple Distance Strategies:** Supports both Cosine and Euclidean distance for similarity search.
|
||||
* **Customizable Storage:** Full control over how content, embeddings, and metadata are stored in Bigtable columns.
|
||||
|
||||
```python
|
||||
from langchain_google_bigtable import BigtableVectorStore
|
||||
|
||||
# Your embedding service and other configurations
|
||||
# embedding_service = ...
|
||||
|
||||
engine = await BigtableEngine.async_initialize(project_id="your-project-id")
|
||||
vector_store = await BigtableVectorStore.create(
|
||||
engine=engine,
|
||||
instance_id="your-instance-id",
|
||||
table_id="your-table-id",
|
||||
embedding_service=embedding_service,
|
||||
collection="your_collection_name",
|
||||
)
|
||||
await vector_store.aadd_documents([your_documents])
|
||||
results = await vector_store.asimilarity_search("your query")
|
||||
```
|
||||
|
||||
|
||||
Learn more in the [Vector Store how-to guide](https://colab.research.google.com/github/googleapis/langchain-google-bigtable-python/blob/main/docs/vector_store.ipynb).
|
||||
|
||||
### Key-value Store
|
||||
|
||||
Use `BigtableByteStore` as a persistent, scalable key-value store for caching, session management, or other storage needs. It supports both synchronous and asynchronous operations.
|
||||
|
||||
```python
|
||||
from langchain_google_bigtable import BigtableByteStore
|
||||
|
||||
# Initialize the store
|
||||
store = await BigtableByteStore.create(
|
||||
project_id="your-project-id",
|
||||
instance_id="your-instance-id",
|
||||
table_id="your-table-id",
|
||||
)
|
||||
|
||||
# Set and get values
|
||||
await store.amset([("key1", b"value1")])
|
||||
retrieved = await store.amget(["key1"])
|
||||
```
|
||||
|
||||
Learn more in the [Key-value Store how-to guide](https://cloud.google.com/python/docs/reference/langchain-google-bigtable/latest/key-value-store).
|
||||
|
||||
### Document Loader
|
||||
|
||||
Use the `BigtableLoader` to load data from a Bigtable table and represent it as LangChain `Document` objects.
|
||||
|
||||
```python
|
||||
from langchain_google_bigtable import BigtableLoader
|
||||
|
||||
loader = BigtableLoader(
|
||||
project_id="your-project-id",
|
||||
instance_id="your-instance-id",
|
||||
table_id="your-table-name"
|
||||
)
|
||||
docs = loader.load()
|
||||
```
|
||||
|
||||
Learn more in the [Document Loader how-to guide](https://cloud.google.com/python/docs/reference/langchain-google-bigtable/latest/document-loader).
|
||||
|
||||
### Chat Message History
|
||||
|
||||
Use `BigtableChatMessageHistory` to store conversation histories, enabling stateful chains and agents.
|
||||
|
||||
```python
|
||||
from langchain_google_bigtable import BigtableChatMessageHistory
|
||||
|
||||
history = BigtableChatMessageHistory(
|
||||
project_id="your-project-id",
|
||||
instance_id="your-instance-id",
|
||||
table_id="your-message-store",
|
||||
session_id="user-session-123"
|
||||
)
|
||||
|
||||
history.add_user_message("Hello!")
|
||||
history.add_ai_message("Hi there!")
|
||||
```
|
||||
|
||||
Learn more in the [Chat Message History how-to guide](https://cloud.google.com/python/docs/reference/langchain-google-bigtable/latest/chat-message-history).
|
||||
|
||||
## Contributions
|
||||
|
||||
Contributions to this library are welcome. Please see the CONTRIBUTING guide in the [package repo](https://github.com/googleapis/langchain-google-bigtable-python/) for more details
|
||||
|
||||
## License
|
||||
|
||||
This project is licensed under the Apache 2.0 License - see the LICENSE file in the [package repo](https://github.com/googleapis/langchain-google-bigtable-python/blob/main/LICENSE) for details.
|
||||
|
||||
## Disclaimer
|
||||
|
||||
This is not an officially supported Google product.
|
||||
@@ -77,7 +77,7 @@ from langchain_ibm import WatsonxRerank
|
||||
See a [usage example](/docs/integrations/tools/ibm_watsonx).
|
||||
|
||||
```python
|
||||
from langchain_ibm import WatsonxToolkit
|
||||
from langchain_ibm.agent_toolkits.utility import WatsonxToolkit
|
||||
```
|
||||
|
||||
## DB2
|
||||
|
||||
@@ -40,11 +40,11 @@ embeddings.embed_query("What is the meaning of life?")
|
||||
```
|
||||
|
||||
## LLMs
|
||||
`ModelScopeLLM` class exposes LLMs from ModelScope.
|
||||
`ModelScopeEndpoint` class exposes LLMs from ModelScope.
|
||||
|
||||
```python
|
||||
from langchain_modelscope import ModelScopeLLM
|
||||
from langchain_modelscope import ModelScopeEndpoint
|
||||
|
||||
llm = ModelScopeLLM(model="Qwen/Qwen2.5-Coder-32B-Instruct")
|
||||
llm = ModelScopeEndpoint(model="Qwen/Qwen2.5-Coder-32B-Instruct")
|
||||
llm.invoke("The meaning of life is")
|
||||
```
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
# Oracle Cloud Infrastructure (OCI)
|
||||
# Oracle Cloud Infrastructure (OCI)
|
||||
|
||||
The `LangChain` integrations related to [Oracle Cloud Infrastructure](https://www.oracle.com/artificial-intelligence/).
|
||||
|
||||
@@ -11,16 +11,14 @@ The `LangChain` integrations related to [Oracle Cloud Infrastructure](https://ww
|
||||
To use, you should have the latest `oci` python SDK and the langchain_community package installed.
|
||||
|
||||
```bash
|
||||
pip install -U langchain_oci
|
||||
python -m pip install -U langchain-oci
|
||||
```
|
||||
|
||||
See [chat](/docs/integrations/llms/oci_generative_ai), [complete](/docs/integrations/chat/oci_generative_ai), and [embedding](/docs/integrations/text_embedding/oci_generative_ai) usage examples.
|
||||
See [chat](/docs/integrations/chat/oci_generative_ai), [complete](/docs/integrations/chat/oci_generative_ai), and [embedding](/docs/integrations/text_embedding/oci_generative_ai) usage examples.
|
||||
|
||||
```python
|
||||
from langchain_oci.chat_models import ChatOCIGenAI
|
||||
|
||||
from langchain_oci.llms import OCIGenAI
|
||||
|
||||
from langchain_oci.embeddings import OCIGenAIEmbeddings
|
||||
```
|
||||
|
||||
|
||||
72
docs/docs/integrations/providers/scraperapi.ipynb
Normal file
72
docs/docs/integrations/providers/scraperapi.ipynb
Normal file
@@ -0,0 +1,72 @@
|
||||
{
|
||||
"cells": [
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"# ScraperAPI\n",
|
||||
"\n",
|
||||
"[ScraperAPI](https://www.scraperapi.com/) enables data collection from any public website with its web scraping API, without worrying about proxies, browsers, or CAPTCHA handling. [langchain-scraperapi](https://github.com/scraperapi/langchain-scraperapi) wraps this service, making it easy for AI agents to browse the web and scrape data from it.\n",
|
||||
"\n",
|
||||
"## Installation and Setup\n",
|
||||
"\n",
|
||||
"- Install the Python package with `pip install langchain-scraperapi`.\n",
|
||||
"- Obtain an API key from [ScraperAPI](https://www.scraperapi.com/) and set the environment variable `SCRAPERAPI_API_KEY`.\n",
|
||||
"\n",
|
||||
"### Tools\n",
|
||||
"\n",
|
||||
"The package offers 3 tools to scrape any website, get structured Google search results, and get structured Amazon search results respectively.\n",
|
||||
"\n",
|
||||
"To import them:"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"%pip install langchain_scraperapi\n",
|
||||
"\n",
|
||||
"from langchain_scraperapi.tools import (\n",
|
||||
" ScraperAPIAmazonSearchTool,\n",
|
||||
" ScraperAPIGoogleSearchTool,\n",
|
||||
" ScraperAPITool,\n",
|
||||
")"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"Example use:"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"tool = ScraperAPITool()\n",
|
||||
"\n",
|
||||
"result = tool.invoke({\"url\": \"https://example.com\", \"output_format\": \"markdown\"})\n",
|
||||
"print(result)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"For a more detailed walkthrough of how to use these tools, visit the [official repository](https://github.com/scraperapi/langchain-scraperapi)."
|
||||
]
|
||||
}
|
||||
],
|
||||
"metadata": {
|
||||
"language_info": {
|
||||
"name": "python"
|
||||
}
|
||||
},
|
||||
"nbformat": 4,
|
||||
"nbformat_minor": 2
|
||||
}
|
||||
140
docs/docs/integrations/providers/superlinked.mdx
Normal file
140
docs/docs/integrations/providers/superlinked.mdx
Normal file
@@ -0,0 +1,140 @@
|
||||
---
|
||||
title: Superlinked
|
||||
description: LangChain integration package for the Superlinked retrieval stack
|
||||
---
|
||||
|
||||
import Link from '@docusaurus/Link';
|
||||
|
||||
### Overview
|
||||
|
||||
Superlinked enables context‑aware retrieval using multiple space types (text similarity, categorical, numerical, recency, and more). The `langchain-superlinked` package provides a LangChain‑native `SuperlinkedRetriever` that plugs directly into your RAG chains.
|
||||
|
||||
### Links
|
||||
|
||||
- <Link to="https://github.com/superlinked/langchain-superlinked">Integration repository</Link>
|
||||
- <Link to="https://links.superlinked.com/langchain_repo_sl">Superlinked core repository</Link>
|
||||
- <Link to="https://links.superlinked.com/langchain_article">Article: Build RAG using LangChain & Superlinked</Link>
|
||||
|
||||
### Install
|
||||
|
||||
```bash
|
||||
pip install -U langchain-superlinked superlinked
|
||||
```
|
||||
|
||||
### Quickstart
|
||||
|
||||
```python
|
||||
import superlinked.framework as sl
|
||||
from langchain_superlinked import SuperlinkedRetriever
|
||||
|
||||
# 1) Define schema
|
||||
class DocumentSchema(sl.Schema):
|
||||
id: sl.IdField
|
||||
content: sl.String
|
||||
|
||||
doc_schema = DocumentSchema()
|
||||
|
||||
# 2) Define space and index
|
||||
text_space = sl.TextSimilaritySpace(
|
||||
text=doc_schema.content, model="sentence-transformers/all-MiniLM-L6-v2"
|
||||
)
|
||||
doc_index = sl.Index([text_space])
|
||||
|
||||
# 3) Define query
|
||||
query = (
|
||||
sl.Query(doc_index)
|
||||
.find(doc_schema)
|
||||
.similar(text_space.text, sl.Param("query_text"))
|
||||
.select([doc_schema.content])
|
||||
.limit(sl.Param("limit"))
|
||||
)
|
||||
|
||||
# 4) Minimal app setup
|
||||
source = sl.InMemorySource(schema=doc_schema)
|
||||
executor = sl.InMemoryExecutor(sources=[source], indices=[doc_index])
|
||||
app = executor.run()
|
||||
source.put([
|
||||
{"id": "1", "content": "Machine learning algorithms process data efficiently."},
|
||||
{"id": "2", "content": "Natural language processing understands human language."},
|
||||
])
|
||||
|
||||
# 5) LangChain retriever
|
||||
retriever = SuperlinkedRetriever(
|
||||
sl_client=app, sl_query=query, page_content_field="content"
|
||||
)
|
||||
|
||||
# Search
|
||||
docs = retriever.invoke("artificial intelligence", limit=2)
|
||||
for d in docs:
|
||||
print(d.page_content)
|
||||
```
|
||||
|
||||
### What the retriever expects (App and Query)
|
||||
|
||||
The retriever takes two core inputs:
|
||||
|
||||
- `sl_client`: a Superlinked App created by running an executor (e.g., `InMemoryExecutor(...).run()`)
|
||||
- `sl_query`: a `QueryDescriptor` returned by chaining `sl.Query(...).find(...).similar(...).select(...).limit(...)`
|
||||
|
||||
Minimal setup:
|
||||
|
||||
```python
|
||||
import superlinked.framework as sl
|
||||
from langchain_superlinked import SuperlinkedRetriever
|
||||
|
||||
class Doc(sl.Schema):
|
||||
id: sl.IdField
|
||||
content: sl.String
|
||||
|
||||
doc = Doc()
|
||||
space = sl.TextSimilaritySpace(text=doc.content, model="sentence-transformers/all-MiniLM-L6-v2")
|
||||
index = sl.Index([space])
|
||||
|
||||
query = (
|
||||
sl.Query(index)
|
||||
.find(doc)
|
||||
.similar(space.text, sl.Param("query_text"))
|
||||
.select([doc.content])
|
||||
.limit(sl.Param("limit"))
|
||||
)
|
||||
|
||||
source = sl.InMemorySource(schema=doc)
|
||||
app = sl.InMemoryExecutor(sources=[source], indices=[index]).run()
|
||||
|
||||
retriever = SuperlinkedRetriever(sl_client=app, sl_query=query, page_content_field="content")
|
||||
```
|
||||
|
||||
Note: For a persistent vector DB, pass `vector_database=...` to the executor (e.g., Qdrant) before `.run()`.
|
||||
|
||||
### Use within a chain
|
||||
|
||||
```python
|
||||
from langchain_core.runnables import RunnablePassthrough
|
||||
from langchain_core.prompts import ChatPromptTemplate
|
||||
from langchain_openai import ChatOpenAI
|
||||
|
||||
def format_docs(docs):
|
||||
return "\n\n".join(doc.page_content for doc in docs)
|
||||
|
||||
prompt = ChatPromptTemplate.from_template(
|
||||
"""
|
||||
Answer based on context:\n\nContext: {context}\nQuestion: {question}
|
||||
"""
|
||||
)
|
||||
|
||||
chain = ({"context": retriever | format_docs, "question": RunnablePassthrough()}
|
||||
| prompt
|
||||
| ChatOpenAI())
|
||||
|
||||
answer = chain.invoke("How does machine learning work?")
|
||||
```
|
||||
|
||||
### Resources
|
||||
|
||||
- <Link to="https://pypi.org/project/langchain-superlinked/">PyPI: langchain-superlinked</Link>
|
||||
- <Link to="https://pypi.org/project/superlinked/">PyPI: superlinked</Link>
|
||||
- <Link to="https://github.com/superlinked/langchain-superlinked">Source repository</Link>
|
||||
- <Link to="https://links.superlinked.com/langchain_repo_sl">Superlinked core repository</Link>
|
||||
- <Link to="https://links.superlinked.com/langchain_article">Build RAG using LangChain & Superlinked (article)</Link>
|
||||
|
||||
|
||||
170
docs/docs/integrations/providers/timbr.mdx
Normal file
170
docs/docs/integrations/providers/timbr.mdx
Normal file
@@ -0,0 +1,170 @@
|
||||
# Timbr
|
||||
|
||||
[Timbr](https://docs.timbr.ai/doc/docs/integration/langchain-sdk/) integrates natural language inputs with Timbr's ontology-driven semantic layer. Leveraging Timbr's robust ontology capabilities, the SDK integrates with Timbr data models and leverages semantic relationships and annotations, enabling users to query data using business-friendly language.
|
||||
|
||||
Timbr provides a pre-built SQL agent, `TimbrSqlAgent`, which can be used for end-to-end purposes from user prompt, through semantic SQL query generation and validation, to query execution and result analysis.
|
||||
|
||||
For customizations and partial usage, you can use LangChain chains and LangGraph nodes with our 5 main tools:
|
||||
|
||||
- `IdentifyTimbrConceptChain` & `IdentifyConceptNode` - Identify relevant concepts from user prompts
|
||||
- `GenerateTimbrSqlChain` & `GenerateTimbrSqlNode` - Generate SQL queries from natural language prompts
|
||||
- `ValidateTimbrSqlChain` & `ValidateSemanticSqlNode` - Validate SQL queries against Timbr knowledge graph schemas
|
||||
- `ExecuteTimbrQueryChain` & `ExecuteSemanticQueryNode` - Execute (semantic and regular) SQL queries against Timbr knowledge graph databases
|
||||
- `GenerateAnswerChain` & `GenerateResponseNode` - Generate human-readable answers based on a given prompt and data rows
|
||||
|
||||
Additionally, `langchain-timbr` provides `TimbrLlmConnector` for manual integration with Timbr's semantic layer using LLM providers. This connector includes the following methods:
|
||||
|
||||
- `get_ontologies` - List Timbr's semantic knowledge graphs
|
||||
- `get_concepts` - List selected knowledge graph ontology representation concepts
|
||||
- `get_views` - List selected knowledge graph ontology representation views
|
||||
- `determine_concept` - Identify relevant concepts from user prompts
|
||||
- `generate_sql` - Generate SQL queries from natural language prompts
|
||||
- `validate_sql` - Validate SQL queries against Timbr knowledge graph schemas
|
||||
- `run_timbr_query` - Execute (semantic and regular) SQL queries against Timbr knowledge graph databases
|
||||
- `run_llm_query` - Execute agent pipeline to determine concept, generate SQL, and run query from natural language prompt
|
||||
|
||||
## Quickstart
|
||||
|
||||
### Installation
|
||||
|
||||
#### Install the package
|
||||
|
||||
```bash
|
||||
pip install langchain-timbr
|
||||
```
|
||||
|
||||
#### Optional: Install with selected LLM provider
|
||||
|
||||
Choose one of: openai, anthropic, google, azure_openai, snowflake, databricks (or 'all')
|
||||
|
||||
```bash
|
||||
pip install 'langchain-timbr[<your selected providers, separated by comma without spaces>]'
|
||||
```
|
||||
|
||||
## Configuration
|
||||
|
||||
Starting from `langchain-timbr` v2.0.0, all chains, agents, and nodes support optional environment-based configuration. You can set the following environment variables to provide default values and simplify setup for the provided tools:
|
||||
|
||||
### Timbr Connection Parameters
|
||||
|
||||
- **TIMBR_URL**: Default Timbr server URL
|
||||
- **TIMBR_TOKEN**: Default Timbr authentication token
|
||||
- **TIMBR_ONTOLOGY**: Default ontology/knowledge graph name
|
||||
|
||||
When these environment variables are set, the corresponding parameters (`url`, `token`, `ontology`) become optional in all chain and agent constructors and will use the environment values as defaults.
|
||||
|
||||
### LLM Configuration Parameters
|
||||
|
||||
- **LLM_TYPE**: The type of LLM provider (one of langchain_timbr LlmTypes enum: 'openai-chat', 'anthropic-chat', 'chat-google-generative-ai', 'azure-openai-chat', 'snowflake-cortex', 'chat-databricks')
|
||||
- **LLM_API_KEY**: The API key for authenticating with the LLM provider
|
||||
- **LLM_MODEL**: The model name or deployment to use
|
||||
- **LLM_TEMPERATURE**: Temperature setting for the LLM
|
||||
- **LLM_ADDITIONAL_PARAMS**: Additional parameters as dict or JSON string
|
||||
|
||||
When LLM environment variables are set, the `llm` parameter becomes optional and will use the `LlmWrapper` with environment configuration.
|
||||
|
||||
Example environment setup:
|
||||
|
||||
```bash
|
||||
# Timbr connection
|
||||
export TIMBR_URL="https://your-timbr-app.com/"
|
||||
export TIMBR_TOKEN="tk_XXXXXXXXXXXXXXXXXXXXXXXX"
|
||||
export TIMBR_ONTOLOGY="timbr_knowledge_graph"
|
||||
|
||||
# LLM configuration
|
||||
export LLM_TYPE="openai-chat"
|
||||
export LLM_API_KEY="your-openai-api-key"
|
||||
export LLM_MODEL="gpt-4o"
|
||||
export LLM_TEMPERATURE="0.1"
|
||||
export LLM_ADDITIONAL_PARAMS='{"max_tokens": 1000}'
|
||||
```
|
||||
|
||||
## Usage
|
||||
|
||||
Import and utilize your intended chain/node, or use TimbrLlmConnector to manually integrate with Timbr's semantic layer. For a complete agent working example, see the [Timbr tool page](/docs/integrations/tools/timbr).
|
||||
|
||||
### ExecuteTimbrQueryChain example
|
||||
|
||||
```python
|
||||
from langchain_timbr import ExecuteTimbrQueryChain
|
||||
|
||||
# You can use the standard LangChain ChatOpenAI/ChatAnthropic models
|
||||
# or any other LLM model based on langchain_core.language_models.chat.BaseChatModel
|
||||
llm = ChatOpenAI(model="gpt-4o", temperature=0, openai_api_key='open-ai-api-key')
|
||||
|
||||
# Optional alternative: Use Timbr's LlmWrapper, which provides generic connections to different LLM providers
|
||||
from langchain_timbr import LlmWrapper, LlmTypes
|
||||
llm = LlmWrapper(llm_type=LlmTypes.OpenAI, api_key="open-ai-api-key", model="gpt-4o")
|
||||
|
||||
execute_timbr_query_chain = ExecuteTimbrQueryChain(
|
||||
llm=llm,
|
||||
url="https://your-timbr-app.com/",
|
||||
token="tk_XXXXXXXXXXXXXXXXXXXXXXXX",
|
||||
ontology="timbr_knowledge_graph",
|
||||
schema="dtimbr", # optional
|
||||
concept="Sales", # optional
|
||||
concepts_list=["Sales","Orders"], # optional
|
||||
views_list=["sales_view"], # optional
|
||||
note="We only need sums", # optional
|
||||
retries=3, # optional
|
||||
should_validate_sql=True # optional
|
||||
)
|
||||
|
||||
result = execute_timbr_query_chain.invoke({"prompt": "What are the total sales for last month?"})
|
||||
rows = result["rows"]
|
||||
sql = result["sql"]
|
||||
concept = result["concept"]
|
||||
schema = result["schema"]
|
||||
error = result.get("error", None)
|
||||
|
||||
usage_metadata = result.get("execute_timbr_usage_metadata", {})
|
||||
determine_concept_usage = usage_metadata.get('determine_concept', {})
|
||||
generate_sql_usage = usage_metadata.get('generate_sql', {})
|
||||
# Each usage_metadata item contains:
|
||||
# * 'approximate': Estimated token count calculated before invoking the LLM
|
||||
# * 'input_tokens'/'output_tokens'/'total_tokens'/etc.: Actual token usage metrics returned by the LLM
|
||||
```
|
||||
|
||||
### Multiple chains using SequentialChain example
|
||||
|
||||
```python
|
||||
from langchain.chains import SequentialChain
|
||||
from langchain_timbr import ExecuteTimbrQueryChain, GenerateAnswerChain
|
||||
from langchain_openai import ChatOpenAI
|
||||
|
||||
# You can use the standard LangChain ChatOpenAI/ChatAnthropic models
|
||||
# or any other LLM model based on langchain_core.language_models.chat.BaseChatModel
|
||||
llm = ChatOpenAI(model="gpt-4o", temperature=0, openai_api_key='open-ai-api-key')
|
||||
|
||||
# Optional alternative: Use Timbr's LlmWrapper, which provides generic connections to different LLM providers
|
||||
from langchain_timbr import LlmWrapper, LlmTypes
|
||||
llm = LlmWrapper(llm_type=LlmTypes.OpenAI, api_key="open-ai-api-key", model="gpt-4o")
|
||||
|
||||
execute_timbr_query_chain = ExecuteTimbrQueryChain(
|
||||
llm=llm,
|
||||
url='https://your-timbr-app.com/',
|
||||
token='tk_XXXXXXXXXXXXXXXXXXXXXXXX',
|
||||
ontology='timbr_knowledge_graph',
|
||||
)
|
||||
|
||||
generate_answer_chain = GenerateAnswerChain(
|
||||
llm=llm,
|
||||
url='https://your-timbr-app.com/',
|
||||
token='tk_XXXXXXXXXXXXXXXXXXXXXXXX',
|
||||
)
|
||||
|
||||
pipeline = SequentialChain(
|
||||
chains=[execute_timbr_query_chain, generate_answer_chain],
|
||||
input_variables=["prompt"],
|
||||
output_variables=["answer", "sql"]
|
||||
)
|
||||
|
||||
result = pipeline.invoke({"prompt": "What are the total sales for last month?"})
|
||||
```
|
||||
|
||||
## Additional Resources
|
||||
|
||||
- [PyPI](https://pypi.org/project/langchain-timbr)
|
||||
- [GitHub](https://github.com/WPSemantix/langchain-timbr)
|
||||
- [LangChain Timbr Docs](https://docs.timbr.ai/doc/docs/integration/langchain-sdk/)
|
||||
- [LangGraph Timbr Docs](https://docs.timbr.ai/doc/docs/integration/langgraph-sdk)
|
||||
68
docs/docs/integrations/providers/zenrows.ipynb
Normal file
68
docs/docs/integrations/providers/zenrows.ipynb
Normal file
@@ -0,0 +1,68 @@
|
||||
{
|
||||
"cells": [
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"id": "_MFfVhVCa15x"
|
||||
},
|
||||
"source": [
|
||||
"# ZenRows\n",
|
||||
"\n",
|
||||
"[ZenRows](https://www.zenrows.com/) is an enterprise-grade web scraping tool that provides advanced web data extraction capabilities at scale. ZenRows specializes in scraping modern websites, bypassing anti-bot systems, extracting structured data from any website, rendering JavaScript-heavy content, accessing geo-restricted websites, and more.\n",
|
||||
"\n",
|
||||
"[langchain-zenrows](https://pypi.org/project/langchain-zenrows/) provides tools that allow LLMs to access web data using ZenRows' powerful scraping infrastructure.\n",
|
||||
"\n",
|
||||
"## Installation and Setup\n",
|
||||
"\n",
|
||||
"```bash\n",
|
||||
"pip install langchain-zenrows\n",
|
||||
"```\n",
|
||||
"\n",
|
||||
"You'll need to set up your ZenRows API key:\n",
|
||||
"\n",
|
||||
"```python\n",
|
||||
"import os\n",
|
||||
"os.environ[\"ZENROWS_API_KEY\"] = \"your-api-key\"\n",
|
||||
"```\n",
|
||||
"\n",
|
||||
"Or you can pass it directly when initializing tools:\n",
|
||||
"\n",
|
||||
"```python\n",
|
||||
"from langchain_zenrows import ZenRowsUniversalScraper\n",
|
||||
"zenrows_scraper_tool = ZenRowsUniversalScraper(zenrows_api_key=\"your-api-key\")\n",
|
||||
"```\n",
|
||||
"\n",
|
||||
"## Tools\n",
|
||||
"\n",
|
||||
"### ZenRowsUniversalScraper\n",
|
||||
"\n",
|
||||
"The ZenRows integration provides comprehensive web scraping features:\n",
|
||||
"\n",
|
||||
"- **JavaScript Rendering**: Scrape modern SPAs and dynamic content\n",
|
||||
"- **Anti-Bot Bypass**: Overcome sophisticated bot detection systems \n",
|
||||
"- **Geo-Targeting**: Access region-specific content with 190+ countries\n",
|
||||
"- **Multiple Output Formats**: HTML, Markdown, Plaintext, PDF, Screenshots\n",
|
||||
"- **CSS Extraction**: Target specific data with CSS selectors\n",
|
||||
"- **Structured Data Extraction**: Automatically extract emails, phone numbers, links, and more\n",
|
||||
"- **Session Management**: Maintain consistent sessions across requests\n",
|
||||
"- **Premium Proxies**: Residential IPs for maximum success rates\n",
|
||||
"\n",
|
||||
"See more in the [ZenRows tool documentation](/docs/integrations/tools/zenrows_universal_scraper)."
|
||||
]
|
||||
}
|
||||
],
|
||||
"metadata": {
|
||||
"colab": {
|
||||
"provenance": []
|
||||
},
|
||||
"kernelspec": {
|
||||
"display_name": "Python 3",
|
||||
"name": "python3"
|
||||
},
|
||||
"language_info": {
|
||||
"name": "python"
|
||||
}
|
||||
},
|
||||
"nbformat": 4,
|
||||
"nbformat_minor": 0
|
||||
}
|
||||
603
docs/docs/integrations/providers/zeusdb.mdx
Normal file
603
docs/docs/integrations/providers/zeusdb.mdx
Normal file
@@ -0,0 +1,603 @@
|
||||
<p align="center" width="100%">
|
||||
<h1 align="center">LangChain ZeusDB Integration</h1>
|
||||
</p>
|
||||
|
||||
A high-performance LangChain integration for ZeusDB, bringing enterprise-grade vector search capabilities to your LangChain applications.
|
||||
|
||||
## Features
|
||||
|
||||
🚀 **High Performance**
|
||||
- Rust-powered vector database backend
|
||||
- Advanced HNSW indexing for sub-millisecond search
|
||||
- Product Quantization for 4x-256x memory compression
|
||||
- Concurrent search with automatic parallelization
|
||||
|
||||
🎯 **LangChain Native**
|
||||
- Full VectorStore API compliance
|
||||
- Async/await support for all operations
|
||||
- Seamless integration with LangChain retrievers
|
||||
- Maximal Marginal Relevance (MMR) search
|
||||
|
||||
🏢 **Enterprise Ready**
|
||||
- Structured logging with performance monitoring
|
||||
- Index persistence with complete state preservation
|
||||
- Advanced metadata filtering
|
||||
- Graceful error handling and fallback mechanisms
|
||||
|
||||
## Quick Start
|
||||
|
||||
### Installation
|
||||
|
||||
```bash
|
||||
pip install -qU langchain-zeusdb
|
||||
```
|
||||
|
||||
### Getting Started
|
||||
|
||||
This example uses *OpenAIEmbeddings*, which requires an OpenAI API key - [Get your OpenAI API key here](https://platform.openai.com/api-keys)
|
||||
|
||||
If you prefer, you can also use this package with any other embedding provider (Hugging Face, Cohere, custom functions, etc.).
|
||||
```bash
|
||||
pip install langchain-openai
|
||||
```
|
||||
|
||||
```python
|
||||
import os
|
||||
import getpass
|
||||
|
||||
os.environ['OPENAI_API_KEY'] = getpass.getpass('OpenAI API Key:')
|
||||
```
|
||||
|
||||
### Basic Usage
|
||||
|
||||
```python
|
||||
from langchain_zeusdb import ZeusDBVectorStore
|
||||
from langchain_openai import OpenAIEmbeddings
|
||||
from zeusdb import VectorDatabase
|
||||
|
||||
# Initialize embeddings
|
||||
embeddings = OpenAIEmbeddings(model="text-embedding-3-small")
|
||||
|
||||
# Create ZeusDB index
|
||||
vdb = VectorDatabase()
|
||||
index = vdb.create(
|
||||
index_type="hnsw",
|
||||
dim=1536,
|
||||
space="cosine"
|
||||
)
|
||||
|
||||
# Create vector store
|
||||
vector_store = ZeusDBVectorStore(
|
||||
zeusdb_index=index,
|
||||
embedding=embeddings
|
||||
)
|
||||
|
||||
# Add documents
|
||||
from langchain_core.documents import Document
|
||||
|
||||
docs = [
|
||||
Document(page_content="ZeusDB is fast", metadata={"source": "docs"}),
|
||||
Document(page_content="LangChain is powerful", metadata={"source": "docs"}),
|
||||
]
|
||||
|
||||
vector_store.add_documents(docs)
|
||||
|
||||
# Search
|
||||
results = vector_store.similarity_search("fast database", k=2)
|
||||
print(f"Found the following {len(results)} results:")
|
||||
print(results)
|
||||
```
|
||||
|
||||
**Expected results:**
|
||||
```
|
||||
Found the following 2 results:
|
||||
[Document(id='ea2b4f13-b0b7-4cef-bb91-0fc4f4c41295', metadata={'source': 'docs'}, page_content='ZeusDB is fast'), Document(id='33dc1e87-a18a-4827-a0df-6ee47eabc7b2', metadata={'source': 'docs'}, page_content='LangChain is powerful')]
|
||||
```
|
||||
|
||||
<br />
|
||||
|
||||
### Factory Methods
|
||||
|
||||
For convenience, you can create and populate a vector store in a single step:
|
||||
|
||||
**Example 1: - Create from texts (creates index and adds texts in one step)**
|
||||
```python
|
||||
vector_store_texts = ZeusDBVectorStore.from_texts(
|
||||
texts=["Hello world", "Goodbye world"],
|
||||
embedding=embeddings,
|
||||
metadatas=[{"source": "text1"}, {"source": "text2"}]
|
||||
)
|
||||
|
||||
print("texts store count:", vector_store_texts.get_vector_count()) # -> 2
|
||||
print("texts store peek:", vector_store_texts.zeusdb_index.list(2)) # [('id1', {...}), ('id2', {...})]
|
||||
|
||||
# Search the texts-based store
|
||||
results = vector_store_texts.similarity_search("Hello", k=1)
|
||||
print(f"Found in texts store: {results[0].page_content}") # -> "Hello world"
|
||||
```
|
||||
|
||||
**Expected results:**
|
||||
```
|
||||
texts store count: 2
|
||||
texts store peek: [('e9c39b44-b610-4e00-91f3-bf652e9989ac', {'source': 'text1', 'text': 'Hello world'}), ('d33f210c-ed53-4006-a64a-a9eee397fec9', {'source': 'text2', 'text': 'Goodbye world'})]
|
||||
Found in texts store: Hello world
|
||||
```
|
||||
|
||||
<br />
|
||||
|
||||
**Example 2: - Create from documents (creates index and adds documents in one step)**
|
||||
```python
|
||||
new_docs = [
|
||||
Document(page_content="Python is great", metadata={"source": "python"}),
|
||||
Document(page_content="JavaScript is flexible", metadata={"source": "js"}),
|
||||
]
|
||||
|
||||
vector_store_docs = ZeusDBVectorStore.from_documents(
|
||||
documents=new_docs,
|
||||
embedding=embeddings
|
||||
)
|
||||
|
||||
print("docs store count:", vector_store_docs.get_vector_count()) # -> 2
|
||||
print("docs store peek:", vector_store_docs.zeusdb_index.list(2)) # [('id3', {...}), ('id4', {...})]
|
||||
|
||||
# Search the documents-based store
|
||||
results = vector_store_docs.similarity_search("Python", k=1)
|
||||
print(f"Found in docs store: {results[0].page_content}") # -> "Python is great"
|
||||
```
|
||||
|
||||
**Expected results:**
|
||||
```
|
||||
docs store count: 2
|
||||
docs store peek: [('aab2d1c1-7e02-4817-8dd8-6fb03570bb6f', {'text': 'Python is great', 'source': 'python'}), ('9a8a82cb-0e70-456c-9db2-556e464de14e', {'text': 'JavaScript is flexible', 'source': 'js'})]
|
||||
Found in docs store: Python is great
|
||||
```
|
||||
|
||||
<br />
|
||||
|
||||
## Advanced Features
|
||||
|
||||
ZeusDB's enterprise-grade capabilities are fully integrated into the LangChain ecosystem, providing quantization, persistence, advanced search features and many other enterprise capabilities.
|
||||
|
||||
### Memory-Efficient Setup with Quantization
|
||||
|
||||
For large datasets, use Product Quantization to reduce memory usage:
|
||||
|
||||
```python
|
||||
# Create quantized index for memory efficiency
|
||||
quantization_config = {
|
||||
'type': 'pq',
|
||||
'subvectors': 8,
|
||||
'bits': 8,
|
||||
'training_size': 10000
|
||||
}
|
||||
|
||||
vdb = VectorDatabase()
|
||||
index = vdb.create(
|
||||
index_type="hnsw",
|
||||
dim=1536,
|
||||
space="cosine",
|
||||
quantization_config=quantization_config
|
||||
)
|
||||
|
||||
vector_store = ZeusDBVectorStore(
|
||||
zeusdb_index=index,
|
||||
embedding=embeddings
|
||||
)
|
||||
```
|
||||
|
||||
Please refer to our [documentation](https://docs.zeusdb.com/en/latest/vector_database/product_quantization.html) for helpful configuration guidelines and recommendations for setting up quantization.
|
||||
|
||||
<br />
|
||||
|
||||
### Persistence
|
||||
|
||||
ZeusDB persistence lets you save a fully populated index to disk and load it later with complete state restoration. This includes vectors, metadata, HNSW graph, and (if enabled) Product Quantization models.
|
||||
|
||||
What gets saved:
|
||||
- Vectors & IDs
|
||||
- Metadata
|
||||
- HNSW graph structure
|
||||
- Quantization config, centroids, and training state (if PQ is enabled)
|
||||
|
||||
|
||||
**How to Save your vector store**
|
||||
```python
|
||||
# Save index
|
||||
vector_store.save_index("my_index.zdb")
|
||||
```
|
||||
|
||||
**How to Load your vector store**
|
||||
```python
|
||||
# Load index
|
||||
loaded_store = ZeusDBVectorStore.load_index(
|
||||
path="my_index.zdb",
|
||||
embedding=embeddings
|
||||
)
|
||||
|
||||
# Verify after load
|
||||
print("vector count:", loaded_store.get_vector_count())
|
||||
print("index info:", loaded_store.info())
|
||||
print("store peek:", loaded_store.zeusdb_index.list(2))
|
||||
```
|
||||
|
||||
**Notes**
|
||||
- The path is a directory, not a single file. Ensure the target is writable.
|
||||
- Saved indexes are cross-platform and include format/version info for compatibility checks.
|
||||
- If you used PQ, both the compression model and state are preserved—no need to retrain after loading.
|
||||
- You can continue to use all vector store APIs (similarity_search, retrievers, etc.) on the loaded_store.
|
||||
|
||||
For further details (including file structure, and further comprehensive examples), see the [documentation](https://docs.zeusdb.com/en/latest/vector_database/persistence.html).
|
||||
|
||||
<br />
|
||||
|
||||
### Advanced Search Options
|
||||
|
||||
Use these to control scoring, diversity, metadata filtering, and retriever integration for your searches.
|
||||
|
||||
#### Similarity search with scores
|
||||
|
||||
Returns `(Document, raw_distance)` pairs from ZeusDB — **lower distance = more similar**.
|
||||
If you prefer normalized relevance in `[0, 1]`, use `similarity_search_with_relevance_scores`.
|
||||
|
||||
```python
|
||||
# Similarity search with scores
|
||||
results_with_scores = vector_store.similarity_search_with_score(
|
||||
query="machine learning",
|
||||
k=5
|
||||
)
|
||||
|
||||
print(results_with_scores)
|
||||
```
|
||||
|
||||
**Expected results:**
|
||||
```
|
||||
[
|
||||
(Document(id='ac0eaf5b-9f02-4ce2-8957-c369a7262c61', metadata={'source': 'docs'}, page_content='LangChain is powerful'), 0.8218843340873718),
|
||||
(Document(id='faae3adf-7cf3-463c-b282-3790b096fa23', metadata={'source': 'docs'}, page_content='ZeusDB is fast'), 0.9140053391456604)
|
||||
]
|
||||
```
|
||||
|
||||
#### MMR search for diversity
|
||||
|
||||
MMR (Maximal Marginal Relevance) balances two forces: relevance to the query and diversity among selected results, reducing near-duplicate answers. Control the trade-off with lambda_mult (1.0 = all relevance, 0.0 = all diversity).
|
||||
|
||||
```python
|
||||
# MMR search for diversity
|
||||
mmr_results = vector_store.max_marginal_relevance_search(
|
||||
query="AI applications",
|
||||
k=5,
|
||||
fetch_k=20,
|
||||
lambda_mult=0.7 # Balance relevance vs diversity
|
||||
)
|
||||
|
||||
print(mmr_results)
|
||||
```
|
||||
|
||||
#### Search with metadata filtering
|
||||
|
||||
Filter results using document metadata you stored when adding docs
|
||||
|
||||
```python
|
||||
# Search with metadata filtering
|
||||
results = vector_store.similarity_search(
|
||||
query="database performance",
|
||||
k=3,
|
||||
filter={"source": "documentation"}
|
||||
)
|
||||
```
|
||||
|
||||
For supported metadata query types and operators, please refer to the [documentation](https://docs.zeusdb.com/en/latest/vector_database/metadata_filtering.html).
|
||||
|
||||
#### As a Retriever
|
||||
|
||||
Turning the vector store into a retriever gives you a standard LangChain interface that chains (e.g., RetrievalQA) can call to fetch context. Under the hood it uses your chosen search type (similarity or mmr) and search_kwargs.
|
||||
|
||||
```python
|
||||
# Convert to retriever for use in chains
|
||||
retriever = vector_store.as_retriever(
|
||||
search_type="mmr",
|
||||
search_kwargs={"k": 3, "lambda_mult": 0.8}
|
||||
)
|
||||
|
||||
# Use with LangChain Expression Language (LCEL) - requires only langchain-core
|
||||
from langchain_core.prompts import ChatPromptTemplate
|
||||
from langchain_core.output_parsers import StrOutputParser
|
||||
from langchain_core.runnables import RunnablePassthrough
|
||||
from langchain_openai import ChatOpenAI
|
||||
|
||||
def format_docs(docs):
|
||||
return "\n\n".join([d.page_content for d in docs])
|
||||
|
||||
template = """Answer the question based only on the following context:
|
||||
{context}
|
||||
|
||||
Question: {question}
|
||||
"""
|
||||
|
||||
prompt = ChatPromptTemplate.from_template(template)
|
||||
llm = ChatOpenAI()
|
||||
|
||||
# Create a chain using LCEL
|
||||
chain = (
|
||||
{"context": retriever | format_docs, "question": RunnablePassthrough()}
|
||||
| prompt
|
||||
| llm
|
||||
| StrOutputParser()
|
||||
)
|
||||
|
||||
# Use the chain
|
||||
answer = chain.invoke("What is ZeusDB?")
|
||||
print(answer)
|
||||
```
|
||||
|
||||
**Expected results:**
|
||||
```
|
||||
ZeusDB is a fast database management system.
|
||||
```
|
||||
|
||||
<br />
|
||||
|
||||
## Async Support
|
||||
|
||||
ZeusDB supports asynchronous operations for non-blocking, concurrent vector operations.
|
||||
|
||||
**When to use async:** web servers (FastAPI/Starlette), agents/pipelines doing parallel searches, or notebooks where you want non-blocking/concurrent retrieval. If you're writing simple scripts, the sync methods are fine.
|
||||
|
||||
Those are **asynchronous operations** - the async/await versions of the regular synchronous methods. Here's what each one does:
|
||||
|
||||
1. `await vector_store.aadd_documents(documents)` - Asynchronously adds documents to the vector store (async version of `add_documents()`)
|
||||
2. `await vector_store.asimilarity_search("query", k=5)` - Asynchronously performs similarity search (async version of `similarity_search()`)
|
||||
3. `await vector_store.adelete(ids=["doc1", "doc2"])` - Asynchronously deletes documents by their IDs (async version of `delete()`)
|
||||
|
||||
The async versions are useful when:
|
||||
- You're building async applications (using `asyncio`, FastAPI, etc.)
|
||||
- You want non-blocking operations that can run concurrently
|
||||
- You're handling multiple requests simultaneously
|
||||
- You want better performance in I/O-bound applications
|
||||
|
||||
For example, instead of blocking while adding documents:
|
||||
|
||||
```python
|
||||
# Synchronous (blocking)
|
||||
vector_store.add_documents(docs) # Blocks until complete
|
||||
|
||||
# Asynchronous (non-blocking)
|
||||
await vector_store.aadd_documents(docs) # Can do other work while this runs
|
||||
```
|
||||
|
||||
All operations support async/await:
|
||||
|
||||
**Script version (`python my_script.py`):**
|
||||
```python
|
||||
import asyncio
|
||||
from langchain_zeusdb import ZeusDBVectorStore
|
||||
from langchain_openai import OpenAIEmbeddings
|
||||
from langchain_core.documents import Document
|
||||
from zeusdb import VectorDatabase
|
||||
|
||||
# Setup
|
||||
embeddings = OpenAIEmbeddings(model="text-embedding-3-small")
|
||||
vdb = VectorDatabase()
|
||||
index = vdb.create(index_type="hnsw", dim=1536, space="cosine")
|
||||
vector_store = ZeusDBVectorStore(zeusdb_index=index, embedding=embeddings)
|
||||
|
||||
docs = [
|
||||
Document(page_content="ZeusDB is fast", metadata={"source": "docs"}),
|
||||
Document(page_content="LangChain is powerful", metadata={"source": "docs"}),
|
||||
]
|
||||
|
||||
async def main():
|
||||
# Add documents asynchronously
|
||||
ids = await vector_store.aadd_documents(docs)
|
||||
print("Added IDs:", ids)
|
||||
|
||||
# Run multiple searches concurrently
|
||||
results_fast, results_powerful = await asyncio.gather(
|
||||
vector_store.asimilarity_search("fast", k=2),
|
||||
vector_store.asimilarity_search("powerful", k=2),
|
||||
)
|
||||
print("Fast results:", [d.page_content for d in results_fast])
|
||||
print("Powerful results:", [d.page_content for d in results_powerful])
|
||||
|
||||
# Delete documents asynchronously
|
||||
deleted = await vector_store.adelete(ids=ids[:1])
|
||||
print("Deleted first doc:", deleted)
|
||||
|
||||
if __name__ == "__main__":
|
||||
asyncio.run(main())
|
||||
```
|
||||
|
||||
**Colab/Notebook/Jupyter version (top-level `await`):**
|
||||
```python
|
||||
from langchain_zeusdb import ZeusDBVectorStore
|
||||
from langchain_openai import OpenAIEmbeddings
|
||||
from langchain_core.documents import Document
|
||||
from zeusdb import VectorDatabase
|
||||
import asyncio
|
||||
|
||||
# Setup
|
||||
embeddings = OpenAIEmbeddings(model="text-embedding-3-small")
|
||||
vdb = VectorDatabase()
|
||||
index = vdb.create(index_type="hnsw", dim=1536, space="cosine")
|
||||
vector_store = ZeusDBVectorStore(zeusdb_index=index, embedding=embeddings)
|
||||
|
||||
docs = [
|
||||
Document(page_content="ZeusDB is fast", metadata={"source": "docs"}),
|
||||
Document(page_content="LangChain is powerful", metadata={"source": "docs"}),
|
||||
]
|
||||
|
||||
# Add documents asynchronously
|
||||
ids = await vector_store.aadd_documents(docs)
|
||||
print("Added IDs:", ids)
|
||||
|
||||
# Run multiple searches concurrently
|
||||
results_fast, results_powerful = await asyncio.gather(
|
||||
vector_store.asimilarity_search("fast", k=2),
|
||||
vector_store.asimilarity_search("powerful", k=2),
|
||||
)
|
||||
print("Fast results:", [d.page_content for d in results_fast])
|
||||
print("Powerful results:", [d.page_content for d in results_powerful])
|
||||
|
||||
# Delete documents asynchronously
|
||||
deleted = await vector_store.adelete(ids=ids[:1])
|
||||
print("Deleted first doc:", deleted)
|
||||
```
|
||||
|
||||
**Expected results:**
|
||||
```
|
||||
Added IDs: ['9c440918-715f-49ba-9b97-0d991d29e997', 'ad59c645-d3ba-4a4a-a016-49ed39514123']
|
||||
Fast results: ['ZeusDB is fast', 'LangChain is powerful']
|
||||
Powerful results: ['LangChain is powerful', 'ZeusDB is fast']
|
||||
Deleted first doc: True
|
||||
```
|
||||
|
||||
<br />
|
||||
|
||||
## Monitoring and Observability
|
||||
|
||||
### Performance Monitoring
|
||||
|
||||
```python
|
||||
# Get index statistics
|
||||
stats = vector_store.get_zeusdb_stats()
|
||||
print(f"Index size: {stats.get('total_vectors', '0')} vectors")
|
||||
print(f"Dimension: {stats.get('dimension')} | Space: {stats.get('space')} | Index type: {stats.get('index_type')}")
|
||||
|
||||
# Benchmark search performance
|
||||
performance = vector_store.benchmark_search_performance(
|
||||
query_count=100,
|
||||
max_threads=4
|
||||
)
|
||||
print(f"Search QPS: {performance.get('parallel_qps', 0):.0f}")
|
||||
|
||||
# Check quantization status
|
||||
if vector_store.is_quantized():
|
||||
progress = vector_store.get_training_progress()
|
||||
print(f"Quantization training: {progress:.1f}% complete")
|
||||
else:
|
||||
print("Index is not quantized")
|
||||
```
|
||||
|
||||
**Expected results:**
|
||||
```
|
||||
Index size: 2 vectors
|
||||
Dimension: 1536 | Space: cosine | Index type: HNSW
|
||||
Search QPS: 53807
|
||||
Index is not quantized
|
||||
```
|
||||
|
||||
### Enterprise Logging
|
||||
|
||||
ZeusDB includes enterprise-grade structured logging that works automatically with smart environment detection:
|
||||
|
||||
```python
|
||||
import logging
|
||||
|
||||
# ZeusDB automatically detects your environment and applies appropriate logging:
|
||||
# - Development: Human-readable logs, WARNING level
|
||||
# - Production: JSON structured logs, ERROR level
|
||||
# - Testing: Minimal output, CRITICAL level
|
||||
# - Jupyter: Clean readable logs, INFO level
|
||||
|
||||
# Operations are automatically logged with performance metrics
|
||||
vector_store.add_documents(docs)
|
||||
# Logs: {"operation":"vector_addition","total_inserted":2,"duration_ms":45}
|
||||
|
||||
# Control logging with environment variables if needed
|
||||
# ZEUSDB_LOG_LEVEL=debug ZEUSDB_LOG_FORMAT=json python your_app.py
|
||||
```
|
||||
|
||||
To learn more about the full features of ZeusDB's enterprise logging capabilities please read the following [documentation](https://docs.zeusdb.com/en/latest/vector_database/logging.html).
|
||||
|
||||
<br />
|
||||
|
||||
## Configuration Options
|
||||
|
||||
### Index Parameters
|
||||
|
||||
```python
|
||||
vdb = VectorDatabase()
|
||||
index = vdb.create(
|
||||
index_type="hnsw", # Index algorithm
|
||||
dim=1536, # Vector dimension
|
||||
space="cosine", # Distance metric: cosine, l2, l1
|
||||
m=16, # HNSW connectivity
|
||||
ef_construction=200, # Build-time search width
|
||||
expected_size=100000, # Expected number of vectors
|
||||
quantization_config=None # Optional quantization
|
||||
)
|
||||
```
|
||||
|
||||
### Search Parameters
|
||||
|
||||
```python
|
||||
results = vector_store.similarity_search(
|
||||
query="search query",
|
||||
k=5, # Number of results
|
||||
ef_search=None, # Runtime search width (auto if None)
|
||||
filter={"key": "value"} # Metadata filter
|
||||
)
|
||||
```
|
||||
|
||||
## Error Handling
|
||||
|
||||
The integration includes comprehensive error handling:
|
||||
|
||||
```python
|
||||
try:
|
||||
results = vector_store.similarity_search("query")
|
||||
print(results)
|
||||
except Exception as e:
|
||||
# Graceful degradation with logging
|
||||
print(f"Search failed: {e}")
|
||||
# Fallback logic here
|
||||
```
|
||||
|
||||
## Requirements
|
||||
|
||||
- **Python**: 3.10 or higher
|
||||
- **ZeusDB**: 0.0.8 or higher
|
||||
- **LangChain Core**: 0.3.74 or higher
|
||||
|
||||
## Installation from Source
|
||||
|
||||
```bash
|
||||
git clone https://github.com/zeusdb/langchain-zeusdb.git
|
||||
cd langchain-zeusdb/libs/zeusdb
|
||||
pip install -e .
|
||||
```
|
||||
|
||||
## Use Cases
|
||||
|
||||
- **RAG Applications**: High-performance retrieval for question answering
|
||||
- **Semantic Search**: Fast similarity search across large document collections
|
||||
- **Recommendation Systems**: Vector-based content and collaborative filtering
|
||||
- **Embeddings Analytics**: Analysis of high-dimensional embedding spaces
|
||||
- **Real-time Applications**: Low-latency vector search for production systems
|
||||
|
||||
## Compatibility
|
||||
|
||||
### LangChain Versions
|
||||
- **LangChain Core**: 0.3.74+
|
||||
|
||||
### Distance Metrics
|
||||
- **Cosine**: Default, normalized similarity
|
||||
- **Euclidean (L2)**: Geometric distance
|
||||
- **Manhattan (L1)**: City-block distance
|
||||
|
||||
### Embedding Models
|
||||
Compatible with any embedding provider:
|
||||
- OpenAI (`text-embedding-3-small`, `text-embedding-3-large`)
|
||||
- Hugging Face Transformers
|
||||
- Cohere Embeddings
|
||||
- Custom embedding functions
|
||||
|
||||
## Support
|
||||
|
||||
- **Documentation**: [docs.zeusdb.com](https://docs.zeusdb.com)
|
||||
- **Issues**: [GitHub Issues](https://github.com/zeusdb/langchain-zeusdb/issues)
|
||||
- **Email**: contact@zeusdb.com
|
||||
|
||||
---
|
||||
|
||||
*Making vector search fast, scalable, and developer-friendly.*
|
||||
1292
docs/docs/integrations/retrievers/superlinked.ipynb
Normal file
1292
docs/docs/integrations/retrievers/superlinked.ipynb
Normal file
File diff suppressed because it is too large
Load Diff
204
docs/docs/integrations/retrievers/superlinked_examples.ipynb
Normal file
204
docs/docs/integrations/retrievers/superlinked_examples.ipynb
Normal file
@@ -0,0 +1,204 @@
|
||||
{
|
||||
"cells": [
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"# SuperlinkedRetriever Examples\n",
|
||||
"\n",
|
||||
"This notebook demonstrates how to build a Superlinked App and Query Descriptor and use them with the LangChain `SuperlinkedRetriever`.\n",
|
||||
"\n",
|
||||
"Install the integration from PyPI:\n",
|
||||
"\n",
|
||||
"```bash\n",
|
||||
"pip install -U langchain-superlinked superlinked\n",
|
||||
"```\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## Setup\n",
|
||||
"\n",
|
||||
"Install the integration and its peer dependency:\n",
|
||||
"\n",
|
||||
"```bash\n",
|
||||
"pip install -U langchain-superlinked superlinked\n",
|
||||
"```\n",
|
||||
"\n",
|
||||
"## Instantiation\n",
|
||||
"\n",
|
||||
"See below for creating a Superlinked App (`sl_client`) and a `QueryDescriptor` (`sl_query`), then wiring them into `SuperlinkedRetriever`.\n",
|
||||
"\n",
|
||||
"## Usage\n",
|
||||
"\n",
|
||||
"Call `retriever.invoke(query_text, **params)` to retrieve `Document` objects. Examples below show single-space and multi-space setups.\n",
|
||||
"\n",
|
||||
"## Use within a chain\n",
|
||||
"\n",
|
||||
"The retriever can be used in LangChain chains by piping it into your prompt and model. See the main Superlinked retriever page for a full RAG example.\n",
|
||||
"\n",
|
||||
"## API reference\n",
|
||||
"\n",
|
||||
"Refer to the API docs:\n",
|
||||
"\n",
|
||||
"- https://python.langchain.com/api_reference/superlinked/retrievers/langchain_superlinked.retrievers.SuperlinkedRetriever.html\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"import superlinked.framework as sl\n",
|
||||
"from langchain_superlinked import SuperlinkedRetriever\n",
|
||||
"from datetime import timedelta\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"# Define schema\n",
|
||||
"class DocumentSchema(sl.Schema):\n",
|
||||
" id: sl.IdField\n",
|
||||
" content: sl.String\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"doc_schema = DocumentSchema()\n",
|
||||
"\n",
|
||||
"# Space + index\n",
|
||||
"text_space = sl.TextSimilaritySpace(\n",
|
||||
" text=doc_schema.content, model=\"sentence-transformers/all-MiniLM-L6-v2\"\n",
|
||||
")\n",
|
||||
"doc_index = sl.Index([text_space])\n",
|
||||
"\n",
|
||||
"# Query descriptor\n",
|
||||
"query = (\n",
|
||||
" sl.Query(doc_index)\n",
|
||||
" .find(doc_schema)\n",
|
||||
" .similar(text_space.text, sl.Param(\"query_text\"))\n",
|
||||
" .select([doc_schema.content])\n",
|
||||
" .limit(sl.Param(\"limit\"))\n",
|
||||
")\n",
|
||||
"\n",
|
||||
"# Minimal app\n",
|
||||
"source = sl.InMemorySource(schema=doc_schema)\n",
|
||||
"executor = sl.InMemoryExecutor(sources=[source], indices=[doc_index])\n",
|
||||
"app = executor.run()\n",
|
||||
"\n",
|
||||
"# Data\n",
|
||||
"source.put(\n",
|
||||
" [\n",
|
||||
" {\"id\": \"1\", \"content\": \"Machine learning algorithms process data efficiently.\"},\n",
|
||||
" {\n",
|
||||
" \"id\": \"2\",\n",
|
||||
" \"content\": \"Natural language processing understands human language.\",\n",
|
||||
" },\n",
|
||||
" {\"id\": \"3\", \"content\": \"Deep learning models require significant compute.\"},\n",
|
||||
" ]\n",
|
||||
")\n",
|
||||
"\n",
|
||||
"# Retriever\n",
|
||||
"retriever = SuperlinkedRetriever(\n",
|
||||
" sl_client=app, sl_query=query, page_content_field=\"content\"\n",
|
||||
")\n",
|
||||
"\n",
|
||||
"retriever.invoke(\"artificial intelligence\", limit=2)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"# Multi-space example (blog posts)\n",
|
||||
"class BlogPostSchema(sl.Schema):\n",
|
||||
" id: sl.IdField\n",
|
||||
" title: sl.String\n",
|
||||
" content: sl.String\n",
|
||||
" category: sl.String\n",
|
||||
" published_date: sl.Timestamp\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"blog = BlogPostSchema()\n",
|
||||
"\n",
|
||||
"content_space = sl.TextSimilaritySpace(\n",
|
||||
" text=blog.content, model=\"sentence-transformers/all-MiniLM-L6-v2\"\n",
|
||||
")\n",
|
||||
"title_space = sl.TextSimilaritySpace(\n",
|
||||
" text=blog.title, model=\"sentence-transformers/all-MiniLM-L6-v2\"\n",
|
||||
")\n",
|
||||
"cat_space = sl.CategoricalSimilaritySpace(\n",
|
||||
" category_input=blog.category, categories=[\"technology\", \"science\", \"business\"]\n",
|
||||
")\n",
|
||||
"recency_space = sl.RecencySpace(\n",
|
||||
" timestamp=blog.published_date,\n",
|
||||
" period_time_list=[\n",
|
||||
" sl.PeriodTime(timedelta(days=30)),\n",
|
||||
" sl.PeriodTime(timedelta(days=90)),\n",
|
||||
" ],\n",
|
||||
")\n",
|
||||
"\n",
|
||||
"blog_index = sl.Index([content_space, title_space, cat_space, recency_space])\n",
|
||||
"\n",
|
||||
"blog_query = (\n",
|
||||
" sl.Query(\n",
|
||||
" blog_index,\n",
|
||||
" weights={\n",
|
||||
" content_space: sl.Param(\"content_weight\"),\n",
|
||||
" title_space: sl.Param(\"title_weight\"),\n",
|
||||
" cat_space: sl.Param(\"category_weight\"),\n",
|
||||
" recency_space: sl.Param(\"recency_weight\"),\n",
|
||||
" },\n",
|
||||
" )\n",
|
||||
" .find(blog)\n",
|
||||
" .similar(content_space.text, sl.Param(\"query_text\"))\n",
|
||||
" .select([blog.title, blog.content, blog.category, blog.published_date])\n",
|
||||
" .limit(sl.Param(\"limit\"))\n",
|
||||
")\n",
|
||||
"\n",
|
||||
"source = sl.InMemorySource(schema=blog)\n",
|
||||
"app = sl.InMemoryExecutor(sources=[source], indices=[blog_index]).run()\n",
|
||||
"\n",
|
||||
"from datetime import datetime\n",
|
||||
"\n",
|
||||
"source.put(\n",
|
||||
" [\n",
|
||||
" {\n",
|
||||
" \"id\": \"p1\",\n",
|
||||
" \"title\": \"Intro to ML\",\n",
|
||||
" \"content\": \"Machine learning 101\",\n",
|
||||
" \"category\": \"technology\",\n",
|
||||
" \"published_date\": int((datetime.now() - timedelta(days=5)).timestamp()),\n",
|
||||
" },\n",
|
||||
" {\n",
|
||||
" \"id\": \"p2\",\n",
|
||||
" \"title\": \"AI in Healthcare\",\n",
|
||||
" \"content\": \"Transforming diagnosis\",\n",
|
||||
" \"category\": \"science\",\n",
|
||||
" \"published_date\": int((datetime.now() - timedelta(days=15)).timestamp()),\n",
|
||||
" },\n",
|
||||
" ]\n",
|
||||
")\n",
|
||||
"\n",
|
||||
"blog_retriever = SuperlinkedRetriever(\n",
|
||||
" sl_client=app,\n",
|
||||
" sl_query=blog_query,\n",
|
||||
" page_content_field=\"content\",\n",
|
||||
" metadata_fields=[\"title\", \"category\", \"published_date\"],\n",
|
||||
")\n",
|
||||
"\n",
|
||||
"blog_retriever.invoke(\n",
|
||||
" \"machine learning\", content_weight=1.0, recency_weight=0.5, limit=2\n",
|
||||
")"
|
||||
]
|
||||
}
|
||||
],
|
||||
"metadata": {
|
||||
"language_info": {
|
||||
"name": "python"
|
||||
}
|
||||
},
|
||||
"nbformat": 4,
|
||||
"nbformat_minor": 2
|
||||
}
|
||||
483
docs/docs/integrations/stores/bigtable.ipynb
Normal file
483
docs/docs/integrations/stores/bigtable.ipynb
Normal file
@@ -0,0 +1,483 @@
|
||||
{
|
||||
"cells": [
|
||||
{
|
||||
"cell_type": "raw",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"---\n",
|
||||
"sidebar_label: Google Bigtable\n",
|
||||
"---"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"# BigtableByteStore\n",
|
||||
"\n",
|
||||
"This guide covers how to use Google Cloud Bigtable as a key-value store.\n",
|
||||
"\n",
|
||||
"[Bigtable](https://cloud.google.com/bigtable) is a key-value and wide-column store, ideal for fast access to structured, semi-structured, or unstructured data. \n",
|
||||
"\n",
|
||||
"[](https://colab.research.google.com/github/googleapis/langchain-google-bigtable-python/blob/main/docs/key_value_store.ipynb)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## Overview\n",
|
||||
"\n",
|
||||
"The `BigtableByteStore` uses Google Cloud Bigtable as a backend for a key-value store. It supports synchronous and asynchronous operations for setting, getting, and deleting key-value pairs.\n",
|
||||
"\n",
|
||||
"### Integration details\n",
|
||||
"| Class | Package | Local | JS support | Package downloads | Package latest |\n",
|
||||
"| :--- | :--- | :---: | :---: | :---: | :---: |\n",
|
||||
"| [BigtableByteStore](https://github.com/googleapis/langchain-google-bigtable-python/blob/main/src/langchain_google_bigtable/key_value_store.py) | [langchain-google-bigtable](https://pypi.org/project/langchain-google-bigtable/) | ❌ | ❌ |  |  |"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## Setup\n",
|
||||
"\n",
|
||||
"### Prerequisites\n",
|
||||
"\n",
|
||||
"To get started, you will need a Google Cloud project with an active Bigtable instance and table. \n",
|
||||
"* [Create a Google Cloud Project](https://developers.google.com/workspace/guides/create-project)\n",
|
||||
"* [Enable the Bigtable API](https://console.cloud.google.com/flows/enableapi?apiid=bigtable.googleapis.com)\n",
|
||||
"* [Create a Bigtable instance and table](https://cloud.google.com/bigtable/docs/creating-instance)\n",
|
||||
"\n",
|
||||
"### Installation\n",
|
||||
"\n",
|
||||
"The integration is in the `langchain-google-bigtable` package. The command below also installs `langchain-google-vertexai` for the embedding cache example."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"%pip install -qU langchain-google-bigtable langchain-google-vertexai"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"### ☁ Set Your Google Cloud Project\n",
|
||||
"Set your Google Cloud project to use its resources within this notebook.\n",
|
||||
"\n",
|
||||
"If you don't know your project ID, you can run `gcloud config list` or see the support page: [Locate the project ID](https://support.google.com/googleapi/answer/7014113)."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"# @markdown Please fill in your project, instance, and table details.\n",
|
||||
"PROJECT_ID = \"your-gcp-project-id\" # @param {type:\"string\"}\n",
|
||||
"INSTANCE_ID = \"your-instance-id\" # @param {type:\"string\"}\n",
|
||||
"TABLE_ID = \"your-table-id\" # @param {type:\"string\"}\n",
|
||||
"\n",
|
||||
"!gcloud config set project {PROJECT_ID}"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"### 🔐 Authentication\n",
|
||||
"Authenticate to Google Cloud to access your project resources.\n",
|
||||
"- For **Colab**, use the cell below.\n",
|
||||
"- For **Vertex AI Workbench**, see the [setup instructions](https://github.com/GoogleCloudPlatform/generative-ai/tree/main/setup-env)."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"from google.colab import auth\n",
|
||||
"\n",
|
||||
"auth.authenticate_user()"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## Instantiation\n",
|
||||
"\n",
|
||||
"To use `BigtableByteStore`, we first ensure a table exists and then initialize a `BigtableEngine` to manage connections."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"from langchain_google_bigtable import (\n",
|
||||
" BigtableByteStore,\n",
|
||||
" BigtableEngine,\n",
|
||||
" init_key_value_store_table,\n",
|
||||
")\n",
|
||||
"\n",
|
||||
"# Ensure the table and column family exist.\n",
|
||||
"init_key_value_store_table(\n",
|
||||
" project_id=PROJECT_ID,\n",
|
||||
" instance_id=INSTANCE_ID,\n",
|
||||
" table_id=TABLE_ID,\n",
|
||||
")"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"### BigtableEngine\n",
|
||||
"A `BigtableEngine` object handles the execution context for the store, especially for async operations. It's recommended to initialize a single engine and reuse it across multiple stores for better performance."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"# Initialize the engine to manage async operations.\n",
|
||||
"engine = await BigtableEngine.async_initialize(\n",
|
||||
" project_id=PROJECT_ID, instance_id=INSTANCE_ID\n",
|
||||
")"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"### BigtableByteStore\n",
|
||||
"\n",
|
||||
"This is the main class for interacting with the key-value store. It provides the methods for setting, getting, and deleting data."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"# Initialize the store.\n",
|
||||
"store = await BigtableByteStore.create(engine=engine, table_id=TABLE_ID)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## Usage\n",
|
||||
"\n",
|
||||
"The store supports both sync (`mset`, `mget`) and async (`amset`, `amget`) methods. This guide uses the async versions."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"### Set\n",
|
||||
"Use `amset` to save key-value pairs to the store."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"kv_pairs = [\n",
|
||||
" (\"key1\", b\"value1\"),\n",
|
||||
" (\"key2\", b\"value2\"),\n",
|
||||
" (\"key3\", b\"value3\"),\n",
|
||||
"]\n",
|
||||
"\n",
|
||||
"await store.amset(kv_pairs)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"### Get\n",
|
||||
"Use `amget` to retrieve values. If a key is not found, `None` is returned for that key."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"retrieved_vals = await store.amget([\"key1\", \"key2\", \"nonexistent_key\"])\n",
|
||||
"print(retrieved_vals)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"### Delete\n",
|
||||
"Use `amdelete` to remove keys from the store."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"await store.amdelete([\"key3\"])\n",
|
||||
"\n",
|
||||
"# Verifying the key was deleted\n",
|
||||
"await store.amget([\"key1\", \"key3\"])"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"### Iterate over keys\n",
|
||||
"Use `ayield_keys` to iterate over all keys or keys with a specific prefix."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"all_keys = [key async for key in store.ayield_keys()]\n",
|
||||
"print(f\"All keys: {all_keys}\")\n",
|
||||
"\n",
|
||||
"prefixed_keys = [key async for key in store.ayield_keys(prefix=\"key1\")]\n",
|
||||
"print(f\"Prefixed keys: {prefixed_keys}\")"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## Advanced Usage: Embedding Caching\n",
|
||||
"\n",
|
||||
"A common use case for a key-value store is to cache expensive operations like computing text embeddings, which saves time and cost."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"from langchain.embeddings import CacheBackedEmbeddings\n",
|
||||
"from langchain_google_vertexai.embeddings import VertexAIEmbeddings\n",
|
||||
"\n",
|
||||
"underlying_embeddings = VertexAIEmbeddings(\n",
|
||||
" project=PROJECT_ID, model_name=\"textembedding-gecko@003\"\n",
|
||||
")\n",
|
||||
"\n",
|
||||
"# Use a namespace to avoid key collisions with other data.\n",
|
||||
"cached_embedder = CacheBackedEmbeddings.from_bytes_store(\n",
|
||||
" underlying_embeddings, store, namespace=\"text-embeddings\"\n",
|
||||
")"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"print(\"First call (computes and caches embedding):\")\n",
|
||||
"%time embedding_result_1 = await cached_embedder.aembed_query(\"Hello, world!\")"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"print(\"\\nSecond call (retrieves from cache):\")\n",
|
||||
"%time embedding_result_2 = await cached_embedder.aembed_query(\"Hello, world!\")"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"### As a Simple Document Retriever\n",
|
||||
"\n",
|
||||
"This section shows how to create a simple retriever using the Bigtable store. It acts as a document persistence layer, fetching documents that match a query prefix."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"from langchain_core.retrievers import BaseRetriever\n",
|
||||
"from langchain_core.documents import Document\n",
|
||||
"from langchain_core.callbacks import CallbackManagerForRetrieverRun\n",
|
||||
"from typing import List, Optional, Any, Union\n",
|
||||
"import json\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"class SimpleKVStoreRetriever(BaseRetriever):\n",
|
||||
" \"\"\"A simple retriever that retrieves documents based on a prefix match in the key-value store.\"\"\"\n",
|
||||
"\n",
|
||||
" store: BigtableByteStore\n",
|
||||
" documents: List[Union[Document, str]]\n",
|
||||
" k: int\n",
|
||||
"\n",
|
||||
" def set_up_store(self):\n",
|
||||
" kv_pairs_to_set = []\n",
|
||||
" for i, doc in enumerate(self.documents):\n",
|
||||
" if isinstance(doc, str):\n",
|
||||
" doc = Document(page_content=doc)\n",
|
||||
" if not doc.id:\n",
|
||||
" doc.id = str(i)\n",
|
||||
" value = (\n",
|
||||
" \"Page Content\\n\"\n",
|
||||
" + doc.page_content\n",
|
||||
" + \"\\nMetadata\"\n",
|
||||
" + json.dumps(doc.metadata)\n",
|
||||
" )\n",
|
||||
" kv_pairs_to_set.append((doc.id, value.encode(\"utf-8\")))\n",
|
||||
" self.store.mset(kv_pairs_to_set)\n",
|
||||
"\n",
|
||||
" async def _aget_relevant_documents(\n",
|
||||
" self,\n",
|
||||
" query: str,\n",
|
||||
" *,\n",
|
||||
" run_manager: Optional[CallbackManagerForRetrieverRun] = None,\n",
|
||||
" ) -> List[Document]:\n",
|
||||
" keys = [key async for key in self.store.ayield_keys(prefix=query)][: self.k]\n",
|
||||
" documents_retrieved = []\n",
|
||||
" async for document in await self.store.amget(keys):\n",
|
||||
" if document:\n",
|
||||
" document_str = document.decode(\"utf-8\")\n",
|
||||
" page_content = document_str.split(\"Content\\n\")[1].split(\"\\nMetadata\")[0]\n",
|
||||
" metadata = json.loads(document_str.split(\"\\nMetadata\")[1])\n",
|
||||
" documents_retrieved.append(\n",
|
||||
" Document(page_content=page_content, metadata=metadata)\n",
|
||||
" )\n",
|
||||
" return documents_retrieved\n",
|
||||
"\n",
|
||||
" def _get_relevant_documents(\n",
|
||||
" self,\n",
|
||||
" query: str,\n",
|
||||
" *,\n",
|
||||
" run_manager: Optional[CallbackManagerForRetrieverRun] = None,\n",
|
||||
" ) -> list[Document]:\n",
|
||||
" keys = [key for key in self.store.yield_keys(prefix=query)][: self.k]\n",
|
||||
" documents_retrieved = []\n",
|
||||
" for document in self.store.mget(keys):\n",
|
||||
" if document:\n",
|
||||
" document_str = document.decode(\"utf-8\")\n",
|
||||
" page_content = document_str.split(\"Content\\n\")[1].split(\"\\nMetadata\")[0]\n",
|
||||
" metadata = json.loads(document_str.split(\"\\nMetadata\")[1])\n",
|
||||
" documents_retrieved.append(\n",
|
||||
" Document(page_content=page_content, metadata=metadata)\n",
|
||||
" )\n",
|
||||
" return documents_retrieved"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"documents = [\n",
|
||||
" Document(\n",
|
||||
" page_content=\"Goldfish are popular pets for beginners, requiring relatively simple care.\",\n",
|
||||
" metadata={\"type\": \"fish\", \"trait\": \"low maintenance\"},\n",
|
||||
" id=\"fish#Goldfish\",\n",
|
||||
" ),\n",
|
||||
" Document(\n",
|
||||
" page_content=\"Cats are independent pets that often enjoy their own space.\",\n",
|
||||
" metadata={\"type\": \"cat\", \"trait\": \"independence\"},\n",
|
||||
" id=\"mammals#Cats\",\n",
|
||||
" ),\n",
|
||||
" Document(\n",
|
||||
" page_content=\"Rabbits are social animals that need plenty of space to hop around.\",\n",
|
||||
" metadata={\"type\": \"rabbit\", \"trait\": \"social\"},\n",
|
||||
" id=\"mammals#Rabbits\",\n",
|
||||
" ),\n",
|
||||
"]"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"retriever_store = BigtableByteStore.create_sync(\n",
|
||||
" engine=engine, instance_id=INSTANCE_ID, table_id=TABLE_ID\n",
|
||||
")\n",
|
||||
"\n",
|
||||
"KVDocumentRetriever = SimpleKVStoreRetriever(\n",
|
||||
" store=retriever_store, documents=documents, k=2\n",
|
||||
")\n",
|
||||
"\n",
|
||||
"KVDocumentRetriever.set_up_store()"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"KVDocumentRetriever.invoke(\"fish\")"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"KVDocumentRetriever.invoke(\"mammals\")"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## API reference\n",
|
||||
"\n",
|
||||
"For full details on the `BigtableByteStore` class, see the source code on [GitHub](https://github.com/googleapis/langchain-google-bigtable-python/blob/main/src/langchain_google_bigtable/key_value_store.py)."
|
||||
]
|
||||
}
|
||||
],
|
||||
"metadata": {
|
||||
"kernelspec": {
|
||||
"display_name": "Python 3",
|
||||
"language": "python",
|
||||
"name": "python3"
|
||||
},
|
||||
"language_info": {
|
||||
"name": "python",
|
||||
"version": "3.10.12"
|
||||
}
|
||||
},
|
||||
"nbformat": 4,
|
||||
"nbformat_minor": 2
|
||||
}
|
||||
319
docs/docs/integrations/text_embedding/aimlapi.ipynb
Normal file
319
docs/docs/integrations/text_embedding/aimlapi.ipynb
Normal file
@@ -0,0 +1,319 @@
|
||||
{
|
||||
"cells": [
|
||||
{
|
||||
"cell_type": "raw",
|
||||
"source": [
|
||||
"---\n",
|
||||
"sidebar_label: AI/ML API Embeddings\n",
|
||||
"---"
|
||||
],
|
||||
"metadata": {
|
||||
"collapsed": false
|
||||
},
|
||||
"id": "24ae9a5bcf0c8c19"
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"source": [
|
||||
"# AimlapiEmbeddings\n",
|
||||
"\n",
|
||||
"This will help you get started with AI/ML API embedding models using LangChain. For detailed documentation on `AimlapiEmbeddings` features and configuration options, please refer to the [API reference](https://docs.aimlapi.com/?utm_source=langchain&utm_medium=github&utm_campaign=integration).\n",
|
||||
"\n",
|
||||
"## Overview\n",
|
||||
"### Integration details\n",
|
||||
"\n",
|
||||
"import { ItemTable } from \"@theme/FeatureTables\";\n",
|
||||
"\n",
|
||||
"<ItemTable category=\"text_embedding\" item=\"AI/ML API\" />\n",
|
||||
"\n",
|
||||
"## Setup\n",
|
||||
"\n",
|
||||
"To access AI/ML API embedding models you'll need to create an account, get an API key, and install the `langchain-aimlapi` integration package.\n",
|
||||
"\n",
|
||||
"### Credentials\n",
|
||||
"\n",
|
||||
"Head to [https://aimlapi.com/app/](https://aimlapi.com/app/?utm_source=langchain&utm_medium=github&utm_campaign=integration) to sign up and generate an API key. Once you've done this, set the `AIMLAPI_API_KEY` environment variable:"
|
||||
],
|
||||
"metadata": {
|
||||
"collapsed": false
|
||||
},
|
||||
"id": "4af58f76e6ce897a"
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"import getpass\n",
|
||||
"import os\n",
|
||||
"\n",
|
||||
"if not os.getenv(\"AIMLAPI_API_KEY\"):\n",
|
||||
" os.environ[\"AIMLAPI_API_KEY\"] = getpass.getpass(\"Enter your AI/ML API key: \")"
|
||||
],
|
||||
"metadata": {
|
||||
"collapsed": false,
|
||||
"ExecuteTime": {
|
||||
"end_time": "2025-08-07T07:50:37.393789Z",
|
||||
"start_time": "2025-08-07T07:50:27.679399Z"
|
||||
}
|
||||
},
|
||||
"id": "3297a770bc0b2b88",
|
||||
"execution_count": 1
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"source": [
|
||||
"To enable automated tracing of your model calls, set your [LangSmith](https://docs.smith.langchain.com/) API key:"
|
||||
],
|
||||
"metadata": {
|
||||
"collapsed": false
|
||||
},
|
||||
"id": "da319ae795659a93"
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"# os.environ[\"LANGSMITH_TRACING\"] = \"true\"\n",
|
||||
"# os.environ[\"LANGSMITH_API_KEY\"] = getpass.getpass(\"Enter your LangSmith API key: \")"
|
||||
],
|
||||
"metadata": {
|
||||
"collapsed": false,
|
||||
"ExecuteTime": {
|
||||
"end_time": "2025-08-07T07:50:40.840377Z",
|
||||
"start_time": "2025-08-07T07:50:40.837144Z"
|
||||
}
|
||||
},
|
||||
"id": "6869f433a2f9dc3e",
|
||||
"execution_count": 2
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"source": [
|
||||
"### Installation\n",
|
||||
"\n",
|
||||
"The LangChain AI/ML API integration lives in the `langchain-aimlapi` package:"
|
||||
],
|
||||
"metadata": {
|
||||
"collapsed": false
|
||||
},
|
||||
"id": "3f6de2cfc36a4dba"
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"Note: you may need to restart the kernel to use updated packages.\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"%pip install -qU langchain-aimlapi"
|
||||
],
|
||||
"metadata": {
|
||||
"collapsed": false,
|
||||
"ExecuteTime": {
|
||||
"end_time": "2025-08-07T07:50:50.693835Z",
|
||||
"start_time": "2025-08-07T07:50:41.453138Z"
|
||||
}
|
||||
},
|
||||
"id": "23c22092f806aa31",
|
||||
"execution_count": 3
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"source": [
|
||||
"## Instantiation\n",
|
||||
"\n",
|
||||
"Now we can instantiate our embeddings model and perform embedding operations:"
|
||||
],
|
||||
"metadata": {
|
||||
"collapsed": false
|
||||
},
|
||||
"id": "db718f4b551164f3"
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"from langchain_aimlapi import AimlapiEmbeddings\n",
|
||||
"\n",
|
||||
"embeddings = AimlapiEmbeddings(\n",
|
||||
" model=\"text-embedding-ada-002\",\n",
|
||||
")"
|
||||
],
|
||||
"metadata": {
|
||||
"collapsed": false,
|
||||
"ExecuteTime": {
|
||||
"end_time": "2025-08-07T07:51:03.046723Z",
|
||||
"start_time": "2025-08-07T07:50:50.694842Z"
|
||||
}
|
||||
},
|
||||
"id": "88b86f20598af88e",
|
||||
"execution_count": 4
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"source": [
|
||||
"## Indexing and Retrieval\n",
|
||||
"\n",
|
||||
"Embedding models are often used in retrieval-augmented generation (RAG) flows. Below is how to index and retrieve data using the `embeddings` object we initialized above with `InMemoryVectorStore`."
|
||||
],
|
||||
"metadata": {
|
||||
"collapsed": false
|
||||
},
|
||||
"id": "847447f4ff1fe82a"
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
"text/plain": "'LangChain is the framework for building context-aware reasoning applications'"
|
||||
},
|
||||
"execution_count": 5,
|
||||
"metadata": {},
|
||||
"output_type": "execute_result"
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"from langchain_core.vectorstores import InMemoryVectorStore\n",
|
||||
"\n",
|
||||
"text = \"LangChain is the framework for building context-aware reasoning applications\"\n",
|
||||
"\n",
|
||||
"vectorstore = InMemoryVectorStore.from_texts(\n",
|
||||
" [text],\n",
|
||||
" embedding=embeddings,\n",
|
||||
")\n",
|
||||
"\n",
|
||||
"retriever = vectorstore.as_retriever()\n",
|
||||
"\n",
|
||||
"retrieved_documents = retriever.invoke(\"What is LangChain?\")\n",
|
||||
"retrieved_documents[0].page_content"
|
||||
],
|
||||
"metadata": {
|
||||
"collapsed": false,
|
||||
"ExecuteTime": {
|
||||
"end_time": "2025-08-07T07:51:05.421030Z",
|
||||
"start_time": "2025-08-07T07:51:03.047729Z"
|
||||
}
|
||||
},
|
||||
"id": "595ccebd97dabeef",
|
||||
"execution_count": 5
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"source": [
|
||||
"## Direct Usage\n",
|
||||
"\n",
|
||||
"You can directly call `embed_query` and `embed_documents` for custom embedding scenarios.\n",
|
||||
"\n",
|
||||
"### Embed single text:"
|
||||
],
|
||||
"metadata": {
|
||||
"collapsed": false
|
||||
},
|
||||
"id": "aa922f78938d1ae1"
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"[-0.0011368310078978539, 0.00714730704203248, -0.014703838154673576, -0.034064359962940216, 0.011239\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"single_vector = embeddings.embed_query(text)\n",
|
||||
"print(str(single_vector)[:100])"
|
||||
],
|
||||
"metadata": {
|
||||
"collapsed": false,
|
||||
"ExecuteTime": {
|
||||
"end_time": "2025-08-07T07:51:06.285037Z",
|
||||
"start_time": "2025-08-07T07:51:05.422035Z"
|
||||
}
|
||||
},
|
||||
"id": "c06952ac53aab22",
|
||||
"execution_count": 6
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"source": [
|
||||
"### Embed multiple texts:"
|
||||
],
|
||||
"metadata": {
|
||||
"collapsed": false
|
||||
},
|
||||
"id": "52c9b7de79992a7b"
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"[-0.0011398226488381624, 0.007080476265400648, -0.014682820066809654, -0.03407655283808708, 0.011276\n",
|
||||
"[-0.005510928109288216, 0.016650190576910973, -0.011078780516982079, -0.03116573952138424, -0.003735\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"text2 = (\n",
|
||||
" \"LangGraph is a library for building stateful, multi-actor applications with LLMs\"\n",
|
||||
")\n",
|
||||
"two_vectors = embeddings.embed_documents([text, text2])\n",
|
||||
"for vector in two_vectors:\n",
|
||||
" print(str(vector)[:100])"
|
||||
],
|
||||
"metadata": {
|
||||
"collapsed": false,
|
||||
"ExecuteTime": {
|
||||
"end_time": "2025-08-07T07:51:07.954778Z",
|
||||
"start_time": "2025-08-07T07:51:06.285544Z"
|
||||
}
|
||||
},
|
||||
"id": "f1dcf3c389e11cc1",
|
||||
"execution_count": 7
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"source": [
|
||||
"## API Reference\n",
|
||||
"\n",
|
||||
"For detailed documentation on `AimlapiEmbeddings` features and configuration options, please refer to the [API reference](https://docs.aimlapi.com/?utm_source=langchain&utm_medium=github&utm_campaign=integration).\n"
|
||||
],
|
||||
"metadata": {
|
||||
"collapsed": false
|
||||
},
|
||||
"id": "a45ff6faef63cab2"
|
||||
}
|
||||
],
|
||||
"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
|
||||
}
|
||||
@@ -103,7 +103,9 @@
|
||||
"cell_type": "markdown",
|
||||
"id": "c84fb993",
|
||||
"metadata": {},
|
||||
"source": "To enable automated tracing of your model calls, set your [LangSmith](https://docs.smith.langchain.com/) API key:"
|
||||
"source": [
|
||||
"To enable automated tracing of your model calls, set your [LangSmith](https://docs.smith.langchain.com/) API key:"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
@@ -157,7 +159,7 @@
|
||||
"from langchain_google_vertexai import VertexAIEmbeddings\n",
|
||||
"\n",
|
||||
"# Initialize the a specific Embeddings Model version\n",
|
||||
"embeddings = VertexAIEmbeddings(model_name=\"text-embedding-004\")"
|
||||
"embeddings = VertexAIEmbeddings(model_name=\"gemini-embedding-001\")"
|
||||
]
|
||||
},
|
||||
{
|
||||
|
||||
@@ -26,13 +26,11 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"cell_type": "code",
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"!pip install -U langchain_oci"
|
||||
]
|
||||
"execution_count": null,
|
||||
"source": "!pip install -U langchain-oci"
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
@@ -75,9 +73,9 @@
|
||||
"\n",
|
||||
"# use default authN method API-key\n",
|
||||
"embeddings = OCIGenAIEmbeddings(\n",
|
||||
" model_id=\"MY_EMBEDDING_MODEL\",\n",
|
||||
" model_id=\"cohere.embed-v4.0\",\n",
|
||||
" service_endpoint=\"https://inference.generativeai.us-chicago-1.oci.oraclecloud.com\",\n",
|
||||
" compartment_id=\"MY_OCID\",\n",
|
||||
" compartment_id=\"compartment_id\",\n",
|
||||
")\n",
|
||||
"\n",
|
||||
"\n",
|
||||
|
||||
@@ -42,7 +42,9 @@
|
||||
"source": [
|
||||
"### Prerequisites\n",
|
||||
"\n",
|
||||
"Ensure you have the Oracle Python Client driver installed to facilitate the integration of Langchain with Oracle AI Vector Search."
|
||||
"You'll need to install `langchain-oracledb` with `python -m pip install -U langchain-oracledb` to use this integration.\n",
|
||||
"\n",
|
||||
"The `python-oracledb` driver is installed automatically as a dependency of langchain-oracledb."
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -51,7 +53,7 @@
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"# pip install oracledb"
|
||||
"# python -m pip install -U langchain-oracledb"
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -113,7 +115,7 @@
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"from langchain_community.embeddings.oracleai import OracleEmbeddings\n",
|
||||
"from langchain_oracledb.embeddings.oracleai import OracleEmbeddings\n",
|
||||
"\n",
|
||||
"# Update the directory and file names for your ONNX model\n",
|
||||
"# make sure that you have onnx file in the system\n",
|
||||
@@ -223,7 +225,7 @@
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"from langchain_community.embeddings.oracleai import OracleEmbeddings\n",
|
||||
"from langchain_oracledb.embeddings.oracleai import OracleEmbeddings\n",
|
||||
"from langchain_core.documents import Document\n",
|
||||
"\n",
|
||||
"\"\"\"\n",
|
||||
@@ -237,10 +239,10 @@
|
||||
"\n",
|
||||
"# using huggingface\n",
|
||||
"embedder_params = {\n",
|
||||
" \"provider\": \"huggingface\", \n",
|
||||
" \"credential_name\": \"HF_CRED\", \n",
|
||||
" \"url\": \"https://api-inference.huggingface.co/pipeline/feature-extraction/\", \n",
|
||||
" \"model\": \"sentence-transformers/all-MiniLM-L6-v2\", \n",
|
||||
" \"provider\": \"huggingface\",\n",
|
||||
" \"credential_name\": \"HF_CRED\",\n",
|
||||
" \"url\": \"https://api-inference.huggingface.co/pipeline/feature-extraction/\",\n",
|
||||
" \"model\": \"sentence-transformers/all-MiniLM-L6-v2\",\n",
|
||||
" \"wait_for_model\": \"true\"\n",
|
||||
"}\n",
|
||||
"\"\"\"\n",
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user