mirror of
https://github.com/hwchase17/langchain.git
synced 2026-02-05 08:40:36 +00:00
Compare commits
96 Commits
v0.0.1
...
wfh/api_re
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
8c09f50962 | ||
|
|
fb6828c9a0 | ||
|
|
f55d02a9e0 | ||
|
|
f0919f000b | ||
|
|
6739d05fdc | ||
|
|
6c1ad9992d | ||
|
|
84a4f42d45 | ||
|
|
7a5398169f | ||
|
|
01790b9711 | ||
|
|
71b9415d58 | ||
|
|
ebb89d9385 | ||
|
|
ef54899fc5 | ||
|
|
18e3f45eb1 | ||
|
|
63ddf47a5c | ||
|
|
6316e11524 | ||
|
|
af9706fe83 | ||
|
|
7881563ebf | ||
|
|
b38a03710e | ||
|
|
6a3ef9c6ae | ||
|
|
b6b5295369 | ||
|
|
d1d691caa4 | ||
|
|
8bb93e1729 | ||
|
|
479cc086ba | ||
|
|
68a906bb31 | ||
|
|
7734a2b5ab | ||
|
|
925225e566 | ||
|
|
350886194e | ||
|
|
306635d2b7 | ||
|
|
433e3067c4 | ||
|
|
cc9d1358ac | ||
|
|
9e0e4a5b31 | ||
|
|
ca4c2364fd | ||
|
|
7a0b881a50 | ||
|
|
c14571ab37 | ||
|
|
dd87275dde | ||
|
|
1f40d3e094 | ||
|
|
ec069381fb | ||
|
|
30c2d3cd06 | ||
|
|
0af48b06d0 | ||
|
|
c1ea8da9bc | ||
|
|
af788b7cf0 | ||
|
|
bed8eb978e | ||
|
|
afc55a4fee | ||
|
|
0a16b3d84b | ||
|
|
a7efa95775 | ||
|
|
e58b1d7073 | ||
|
|
125ae6d9de | ||
|
|
04e45f9cde | ||
|
|
59a7c5877a | ||
|
|
00de334f81 | ||
|
|
3662aca7d4 | ||
|
|
8f158b72fc | ||
|
|
f7ad14acfa | ||
|
|
73d5cba308 | ||
|
|
483f6c2fe3 | ||
|
|
24f889f2bc | ||
|
|
1f055775f8 | ||
|
|
76102971c0 | ||
|
|
3e7d2a1b64 | ||
|
|
c580c81cca | ||
|
|
3eb4112a1f | ||
|
|
1cc7d4c9eb | ||
|
|
7cbe28ba9b | ||
|
|
72eb4fa4e8 | ||
|
|
1a7d8667c8 | ||
|
|
ae28568e2a | ||
|
|
d983046f90 | ||
|
|
82b8d8596c | ||
|
|
848454d1e7 | ||
|
|
4928f7a9f5 | ||
|
|
14aa27b5f4 | ||
|
|
e7d64f8b15 | ||
|
|
120cdf813d | ||
|
|
026269bfa9 | ||
|
|
d5689d58ab | ||
|
|
3caccf304c | ||
|
|
f3908627ed | ||
|
|
c8c8635dc9 | ||
|
|
8ea840432f | ||
|
|
80b3ec5869 | ||
|
|
33fd6184ba | ||
|
|
fa8906a9b7 | ||
|
|
8f5000146c | ||
|
|
7686dabd36 | ||
|
|
fb62f2be70 | ||
|
|
9205919ad2 | ||
|
|
670304a8b3 | ||
|
|
c5b50be225 | ||
|
|
961a0e200f | ||
|
|
77bf75c236 | ||
|
|
e46126eac6 | ||
|
|
f0eb5db670 | ||
|
|
cbf2fc8af8 | ||
|
|
d81d6e874f | ||
|
|
506b21bfc2 | ||
|
|
9854d9e5cb |
2
.github/workflows/codespell.yml
vendored
2
.github/workflows/codespell.yml
vendored
@@ -20,3 +20,5 @@ jobs:
|
||||
uses: actions/checkout@v3
|
||||
- name: Codespell
|
||||
uses: codespell-project/actions-codespell@v2
|
||||
with:
|
||||
skip: guide_imports.json
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
# Migrating to `langchain._experimental`
|
||||
# Migrating to `langchain_experimental`
|
||||
|
||||
We are moving any experimental components of LangChain, or components with vulnerability issues, into `langchain_experimental`.
|
||||
This guide covers how to migrate.
|
||||
|
||||
10
README.md
10
README.md
@@ -19,7 +19,15 @@
|
||||
Looking for the JS/TS version? Check out [LangChain.js](https://github.com/hwchase17/langchainjs).
|
||||
|
||||
**Production Support:** As you move your LangChains into production, we'd love to offer more comprehensive support.
|
||||
Please fill out [this form](https://forms.gle/57d8AmXBYp8PP8tZA) and we'll set up a dedicated support Slack channel.
|
||||
Please fill out [this form](https://6w1pwbss0py.typeform.com/to/rrbrdTH2) and we'll set up a dedicated support Slack channel.
|
||||
|
||||
## 🚨Breaking Changes for select chains (SQLDatabase) on 7/28
|
||||
|
||||
In an effort to make `langchain` leaner and safer, we are moving select chains to `langchain_experimental`.
|
||||
This migration has already started, but we are remaining backwards compatible until 7/28.
|
||||
On that date, we will remove functionality from `langchain`.
|
||||
Read more about the motivation and the progress [here](https://github.com/hwchase17/langchain/discussions/8043).
|
||||
Read how to migrate your code [here](MIGRATE.md).
|
||||
|
||||
## Quick Install
|
||||
|
||||
|
||||
@@ -7,20 +7,63 @@
|
||||
|
||||
# -- Path setup --------------------------------------------------------------
|
||||
|
||||
import json
|
||||
import os
|
||||
import sys
|
||||
from pathlib import Path
|
||||
|
||||
import toml
|
||||
from docutils import nodes
|
||||
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.
|
||||
#
|
||||
import os
|
||||
import sys
|
||||
|
||||
import toml
|
||||
|
||||
_DIR = Path(__file__).parent.absolute()
|
||||
sys.path.insert(0, os.path.abspath("."))
|
||||
sys.path.insert(0, os.path.abspath("../../libs/langchain"))
|
||||
|
||||
with open("../../libs/langchain/pyproject.toml") as f:
|
||||
with (_DIR.parents[1] / "libs" / "langchain" / "pyproject.toml").open("r") as f:
|
||||
data = toml.load(f)
|
||||
with (_DIR / "guide_imports.json").open("r") as f:
|
||||
imported_classes = json.load(f)
|
||||
|
||||
|
||||
class ExampleLinksDirective(SphinxDirective):
|
||||
"""Directive to generate a list of links to examples.
|
||||
|
||||
We have a script that extracts links to API reference docs
|
||||
from our notebook examples. This directive uses that information
|
||||
to backlink to the examples from the API reference docs."""
|
||||
|
||||
has_content = False
|
||||
required_arguments = 1
|
||||
|
||||
def run(self):
|
||||
"""Run the directive.
|
||||
|
||||
Called any time :example_links:`ClassName` is used
|
||||
in the template *.rst files."""
|
||||
class_name = self.arguments[0]
|
||||
links = imported_classes.get(class_name, {})
|
||||
list_node = nodes.bullet_list()
|
||||
for doc_name, link in links.items():
|
||||
item_node = nodes.list_item()
|
||||
para_node = nodes.paragraph()
|
||||
link_node = nodes.reference()
|
||||
link_node["refuri"] = link
|
||||
link_node.append(nodes.Text(doc_name))
|
||||
para_node.append(link_node)
|
||||
item_node.append(para_node)
|
||||
list_node.append(item_node)
|
||||
|
||||
return [list_node]
|
||||
|
||||
|
||||
def setup(app):
|
||||
app.add_directive("example_links", ExampleLinksDirective)
|
||||
|
||||
|
||||
# -- Project information -----------------------------------------------------
|
||||
|
||||
|
||||
1
docs/api_reference/guide_imports.json
Normal file
1
docs/api_reference/guide_imports.json
Normal file
File diff suppressed because one or more lines are too long
@@ -1,9 +0,0 @@
|
||||
Evaluation
|
||||
=======================
|
||||
|
||||
LangChain has a number of convenient evaluation chains you can use off the shelf to grade your models' oupputs.
|
||||
|
||||
.. automodule:: langchain.evaluation
|
||||
:members:
|
||||
:undoc-members:
|
||||
:inherited-members:
|
||||
@@ -26,3 +26,14 @@
|
||||
{%- endfor %}
|
||||
{% endif %}
|
||||
{% endblock %}
|
||||
|
||||
{% if objname in imported_classes %}
|
||||
Examples using this class
|
||||
--------------------------
|
||||
|
||||
{% for example in imported_classes[objname] %}
|
||||
* `Example <{{ example }}>`_
|
||||
{%- endfor %}
|
||||
{% endif %}
|
||||
|
||||
.. example_links:: {{ objname }}
|
||||
@@ -51,7 +51,7 @@ Walkthroughs and best-practices for common end-to-end use cases, like:
|
||||
Learn best practices for developing with LangChain.
|
||||
|
||||
### [Ecosystem](/docs/ecosystem/)
|
||||
LangChain is part of a rich ecosystem of tools that integrate with our framework and build on top of it. Check out our growing list of [integrations](/docs/ecosystem/integrations/) and [dependent repos](/docs/ecosystem/dependents.html).
|
||||
LangChain is part of a rich ecosystem of tools that integrate with our framework and build on top of it. Check out our growing list of [integrations](/docs/integrations/) and [dependent repos](/docs/ecosystem/dependents).
|
||||
|
||||
### [Additional resources](/docs/additional_resources/)
|
||||
Our community is full of prolific developers, creative builders, and fantastic teachers. Check out [YouTube tutorials](/docs/additional_resources/youtube.html) for great tutorials from folks in the community, and [Gallery](https://github.com/kyrolabs/awesome-langchain) for a list of awesome LangChain projects, compiled by the folks at [KyroLabs](https://kyrolabs.com).
|
||||
|
||||
@@ -22,28 +22,74 @@ import OpenAISetup from "@snippets/get_started/quickstart/openai_setup.mdx"
|
||||
|
||||
## Building an application
|
||||
|
||||
Now we can start building our language model application. LangChain provides many modules that can be used to build language model applications. Modules can be used as stand-alones in simple applications and they can be combined for more complex use cases.
|
||||
Now we can start building our language model application. LangChain provides many modules that can be used to build language model applications.
|
||||
Modules can be used as stand-alones in simple applications and they can be combined for more complex use cases.
|
||||
|
||||
The core building block of LangChain applications is the LLMChain.
|
||||
This combines three things:
|
||||
- LLM: The language model is the core reasoning engine here. In order to work with LangChain, you need to understand the different types of language models and how to work with them.
|
||||
- Prompt Templates: This provides instructions to the language model. This controls what the language model outputs, so understanding how to construct prompts and different prompting strategies is crucial.
|
||||
- Output Parsers: These translate the raw response from the LLM to a more workable format, making it easy to use the output downstream.
|
||||
|
||||
In this getting started guide we will cover those three components by themselves, and then cover the LLMChain which combines all of them.
|
||||
Understanding these concepts will set you up well for being able to use and customize LangChain applications.
|
||||
Most LangChain applications allow you to configure the LLM and/or the prompt used, so knowing how to take advantage of this will be a big enabler.
|
||||
|
||||
## LLMs
|
||||
#### Get predictions from a language model
|
||||
|
||||
The basic building block of LangChain is the LLM, which takes in text and generates more text.
|
||||
There are two types of language models, which in LangChain are called:
|
||||
|
||||
As an example, suppose we're building an application that generates a company name based on a company description. In order to do this, we need to initialize an OpenAI model wrapper. In this case, since we want the outputs to be MORE random, we'll initialize our model with a HIGH temperature.
|
||||
- LLMs: this is a language model which takes a string as input and returns a string
|
||||
- ChatModels: this is a language model which takes a list of messages as input and returns a message
|
||||
|
||||
import LLM from "@snippets/get_started/quickstart/llm.mdx"
|
||||
The input/output for LLMs is simple and easy to understand - a string.
|
||||
But what about ChatModels? The input there is a list of `ChatMessage`s, and the output is a single `ChatMessage`.
|
||||
A `ChatMessage` has two required components:
|
||||
|
||||
<LLM/>
|
||||
- `content`: This is the content of the message.
|
||||
- `role`: This is the role of the entity from which the `ChatMessage` is coming from.
|
||||
|
||||
## Chat models
|
||||
LangChain provides several objects to easily distinguish between different roles:
|
||||
|
||||
Chat models are a variation on language models. While chat models use language models under the hood, the interface they expose is a bit different: rather than expose a "text in, text out" API, they expose an interface where "chat messages" are the inputs and outputs.
|
||||
- `HumanMessage`: A `ChatMessage` coming from a human/user.
|
||||
- `AIMessage`: A `ChatMessage` coming from an AI/assistant.
|
||||
- `SystemMessage`: A `ChatMessage` coming from the system.
|
||||
- `FunctionMessage`: A `ChatMessage` coming from a function call.
|
||||
|
||||
You can get chat completions by passing one or more messages to the chat model. The response will be a message. The types of messages currently supported in LangChain are `AIMessage`, `HumanMessage`, `SystemMessage`, and `ChatMessage` -- `ChatMessage` takes in an arbitrary role parameter. Most of the time, you'll just be dealing with `HumanMessage`, `AIMessage`, and `SystemMessage`.
|
||||
If none of those roles sound right, there is also a `ChatMessage` class where you can specify the role manually.
|
||||
For more information on how to use these different messages most effectively, see our prompting guide.
|
||||
|
||||
import ChatModel from "@snippets/get_started/quickstart/chat_model.mdx"
|
||||
LangChain exposes a standard interface for both, but it's useful to understand this difference in order to construct prompts for a given language model.
|
||||
The standard interface that LangChain exposes has two methods:
|
||||
- `predict`: Takes in a string, returns a string
|
||||
- `predict_messages`: Takes in a list of messages, returns a message.
|
||||
|
||||
Let's see how to work with these different types of models and these different types of inputs.
|
||||
First, let's import an LLM and a ChatModel.
|
||||
|
||||
import ImportLLMs from "@snippets/get_started/quickstart/import_llms.mdx"
|
||||
|
||||
<ImportLLMs/>
|
||||
|
||||
The `OpenAI` and `ChatOpenAI` objects are basically just configuration objects.
|
||||
You can initialize them with parameters like `temperature` and others, and pass them around.
|
||||
|
||||
Next, let's use the `predict` method to run over a string input.
|
||||
|
||||
import InputString from "@snippets/get_started/quickstart/input_string.mdx"
|
||||
|
||||
<InputString/>
|
||||
|
||||
Finally, let's use the `predict_messages` method to run over a list of messages.
|
||||
|
||||
import InputMessages from "@snippets/get_started/quickstart/input_messages.mdx"
|
||||
|
||||
<InputMessages/>
|
||||
|
||||
For both these methods, you can also pass in parameters as key word arguments.
|
||||
For example, you could pass in `temperature=0` to adjust the temperature that is used from what the object was configured with.
|
||||
Whatever values are passed in during run time will always override what the object was configured with.
|
||||
|
||||
<ChatModel/>
|
||||
|
||||
## Prompt templates
|
||||
|
||||
@@ -51,108 +97,66 @@ Most LLM applications do not pass user input directly into an LLM. Usually they
|
||||
|
||||
In the previous example, the text we passed to the model contained instructions to generate a company name. For our application, it'd be great if the user only had to provide the description of a company/product, without having to worry about giving the model instructions.
|
||||
|
||||
PromptTemplates help with exactly this!
|
||||
They bundle up all the logic for going from user input into a fully formatted prompt.
|
||||
This can start off very simple - for example, a prompt to produce the above string would just be:
|
||||
|
||||
import PromptTemplateLLM from "@snippets/get_started/quickstart/prompt_templates_llms.mdx"
|
||||
import PromptTemplateChatModel from "@snippets/get_started/quickstart/prompt_templates_chat_models.mdx"
|
||||
|
||||
<Tabs>
|
||||
<TabItem value="llms" label="LLMs" default>
|
||||
|
||||
With PromptTemplates this is easy! In this case our template would be very simple:
|
||||
|
||||
<PromptTemplateLLM/>
|
||||
</TabItem>
|
||||
<TabItem value="chat_models" label="Chat models">
|
||||
|
||||
Similar to LLMs, you can make use of templating by using a `MessagePromptTemplate`. You can build a `ChatPromptTemplate` from one or more `MessagePromptTemplate`s. You can use `ChatPromptTemplate`'s `format_messages` method to generate the formatted messages.
|
||||
However, the advantages of using these over raw string formatting are several.
|
||||
You can "partial" out variables - eg you can format only some of the variables at a time.
|
||||
You can compose them together, easily combining different templates into a single prompt.
|
||||
For explanations of these functionalities, see the [section on prompts](/docs/modules/model_io/prompts) for more detail.
|
||||
|
||||
Because this is generating a list of messages, it is slightly more complex than the normal prompt template which is generating only a string. Please see the detailed guides on prompts to understand more options available to you here.
|
||||
PromptTemplates can also be used to produce a list of messages.
|
||||
In this case, the prompt not only contains information about the content, but also each message (its role, its position in the list, etc)
|
||||
Here, what happens most often is a ChatPromptTemplate is a list of ChatMessageTemplates.
|
||||
Each ChatMessageTemplate contains instructions for how to format that ChatMessage - its role, and then also its content.
|
||||
Let's take a look at this below:
|
||||
|
||||
<PromptTemplateChatModel/>
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
## Chains
|
||||
ChatPromptTemplates can also include other things besides ChatMessageTemplates - see the [section on prompts](/docs/modules/model_io/prompts) for more detail.
|
||||
|
||||
Now that we've got a model and a prompt template, we'll want to combine the two. Chains give us a way to link (or chain) together multiple primitives, like models, prompts, and other chains.
|
||||
## Output Parsers
|
||||
|
||||
import ChainLLM from "@snippets/get_started/quickstart/chains_llms.mdx"
|
||||
import ChainChatModel from "@snippets/get_started/quickstart/chains_chat_models.mdx"
|
||||
OutputParsers convert the raw output of an LLM into a format that can be used downstream.
|
||||
There are few main type of OutputParsers, including:
|
||||
|
||||
<Tabs>
|
||||
<TabItem value="llms" label="LLMs" default>
|
||||
- Convert text from LLM -> structured information (eg JSON)
|
||||
- Convert a ChatMessage into just a string
|
||||
- Convert the extra information returned from a call besides the message (like OpenAI function invocation) into a string.
|
||||
|
||||
The simplest and most common type of chain is an LLMChain, which passes an input first to a PromptTemplate and then to an LLM. We can construct an LLM chain from our existing model and prompt template.
|
||||
For full information on this, see the [section on output parsers](/docs/modules/model_io/output_parsers)
|
||||
|
||||
<ChainLLM/>
|
||||
In this getting started guide, we will write our own output parser - one that converts a comma separated list into a list.
|
||||
|
||||
There we go, our first chain! Understanding how this simple chain works will set you up well for working with more complex chains.
|
||||
import OutputParser from "@snippets/get_started/quickstart/output_parser.mdx"
|
||||
|
||||
</TabItem>
|
||||
<TabItem value="chat_models" label="Chat models">
|
||||
<OutputParser/>
|
||||
|
||||
The `LLMChain` can be used with chat models as well:
|
||||
## LLMChain
|
||||
|
||||
<ChainChatModel/>
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
We can now combine all these into one chain.
|
||||
This chain will take input variables, pass those to a prompt template to create a prompt, pass the prompt to an LLM, and then pass the output through an (optional) output parser.
|
||||
This is a convenient way to bundle up a modular piece of logic.
|
||||
Let's see it in action!
|
||||
|
||||
## Agents
|
||||
import LLMChain from "@snippets/get_started/quickstart/llm_chain.mdx"
|
||||
|
||||
import AgentLLM from "@snippets/get_started/quickstart/agents_llms.mdx"
|
||||
import AgentChatModel from "@snippets/get_started/quickstart/agents_chat_models.mdx"
|
||||
<LLMChain/>
|
||||
|
||||
Our first chain ran a pre-determined sequence of steps. To handle complex workflows, we need to be able to dynamically choose actions based on inputs.
|
||||
## Next Steps
|
||||
|
||||
Agents do just this: they use a language model to determine which actions to take and in what order. Agents are given access to tools, and they repeatedly choose a tool, run the tool, and observe the output until they come up with a final answer.
|
||||
This is it!
|
||||
We've now gone over how to create the core building block of LangChain applications - the LLMChains.
|
||||
There is a lot more nuance in all these components (LLMs, prompts, output parsers) and a lot more different components to learn about as well.
|
||||
To continue on your journey:
|
||||
|
||||
To load an agent, you need to choose a(n):
|
||||
- LLM/Chat model: The language model powering the agent.
|
||||
- Tool(s): A function that performs a specific duty. This can be things like: Google Search, Database lookup, Python REPL, other chains. For a list of predefined tools and their specifications, see the [Tools documentation](/docs/modules/agents/tools/).
|
||||
- Agent name: A string that references a supported agent class. An agent class is largely parameterized by the prompt the language model uses to determine which action to take. Because this notebook focuses on the simplest, highest level API, this only covers using the standard supported agents. If you want to implement a custom agent, see [here](/docs/modules/agents/how_to/custom_agent.html). For a list of supported agents and their specifications, see [here](/docs/modules/agents/agent_types/).
|
||||
|
||||
For this example, we'll be using SerpAPI to query a search engine.
|
||||
|
||||
You'll need to install the SerpAPI Python package:
|
||||
|
||||
```bash
|
||||
pip install google-search-results
|
||||
```
|
||||
|
||||
And set the `SERPAPI_API_KEY` environment variable.
|
||||
|
||||
<Tabs>
|
||||
<TabItem value="llms" label="LLMs" default>
|
||||
<AgentLLM/>
|
||||
</TabItem>
|
||||
<TabItem value="chat_models" label="Chat models">
|
||||
|
||||
Agents can also be used with chat models, you can initialize one using `AgentType.CHAT_ZERO_SHOT_REACT_DESCRIPTION` as the agent type.
|
||||
|
||||
<AgentChatModel/>
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
## Memory
|
||||
|
||||
The chains and agents we've looked at so far have been stateless, but for many applications it's necessary to reference past interactions. This is clearly the case with a chatbot for example, where you want it to understand new messages in the context of past messages.
|
||||
|
||||
The Memory module gives you a way to maintain application state. The base Memory interface is simple: it lets you update state given the latest run inputs and outputs and it lets you modify (or contextualize) the next input using the stored state.
|
||||
|
||||
There are a number of built-in memory systems. The simplest of these is a buffer memory which just prepends the last few inputs/outputs to the current input - we will use this in the example below.
|
||||
|
||||
import MemoryLLM from "@snippets/get_started/quickstart/memory_llms.mdx"
|
||||
import MemoryChatModel from "@snippets/get_started/quickstart/memory_chat_models.mdx"
|
||||
|
||||
<Tabs>
|
||||
<TabItem value="llms" label="LLMs" default>
|
||||
|
||||
<MemoryLLM/>
|
||||
</TabItem>
|
||||
<TabItem value="chat_models" label="Chat models">
|
||||
|
||||
You can use Memory with chains and agents initialized with chat models. The main difference between this and Memory for LLMs is that rather than trying to condense all previous messages into a string, we can keep them as their own unique memory object.
|
||||
|
||||
<MemoryChatModel/>
|
||||
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
- [Dive deeper](/docs/modules/model_io) into LLMs, prompts, and output parsers
|
||||
- Learn the other [key components](/docs/modules)
|
||||
- Check out our [helpful guides](/docs/guides) for detailed walkthroughs on particular topics
|
||||
- Explore [end-to-end use cases](/docs/use_cases)
|
||||
|
||||
@@ -6,19 +6,19 @@ import DocCardList from "@theme/DocCardList";
|
||||
|
||||
# Evaluation
|
||||
|
||||
Language models can be unpredictable. This makes it challenging to ship reliable applications to production, where repeatable, useful outcomes across diverse inputs are a minimum requirement. Tests help demonstrate each component in an LLM application can produce the required or expected functionality. These tests also safeguard against regressions while you improve interconnected pieces of an integrated system. However, measuring the quality of generated text can be challenging. It can be hard to agree on the right set of metrics for your application, and it can be difficult to translate those into better performance. Furthermore, it's common to lack sufficient evaluation data adequately test the range of inputs and expected outputs for each component when you're just getting started. The LangChain community is building open source tools and guides to help address these challenges.
|
||||
Language models can be unpredictable. This makes it challenging to ship reliable applications to production, where repeatable, useful outcomes across diverse inputs are a minimum requirement. Tests help demonstrate each component in an LLM application can produce the required or expected functionality. These tests also safeguard against regressions while you improve interconnected pieces of an integrated system. However, measuring the quality of generated text can be challenging. It can be hard to agree on the right set of metrics for your application, and it can be difficult to translate those into better performance. Furthermore, it's common to lack sufficient evaluation data to adequately test the range of inputs and expected outputs for each component when you're just getting started. The LangChain community is building open source tools and guides to help address these challenges.
|
||||
|
||||
LangChain exposes different types of evaluators for common types of evaluation. Each type has off-the-shelf implementations you can use to get started, as well as an
|
||||
extensible API so you can create your own or contribute improvements for everyone to use. The following sections have example notebooks for you to get started.
|
||||
|
||||
- [String Evaluators](/docs/modules/evaluation/string/): Evaluate the predicted string for a given input, usually against a reference string
|
||||
- [Trajectory Evaluators](/docs/modules/evaluation/trajectory/): Evaluate the whole trajectory of agent actions
|
||||
- [Comparison Evaluators](/docs/modules/evaluation/comparison/): Compare predictions from two runs on a common input
|
||||
- [String Evaluators](/docs/guides/evaluation/string/): Evaluate the predicted string for a given input, usually against a reference string
|
||||
- [Trajectory Evaluators](/docs/guides/evaluation/trajectory/): Evaluate the whole trajectory of agent actions
|
||||
- [Comparison Evaluators](/docs/guides/evaluation/comparison/): Compare predictions from two runs on a common input
|
||||
|
||||
|
||||
This section also provides some additional examples of how you could use these evaluators for different scenarios or apply to different chain implementations in the LangChain library. Some examples include:
|
||||
|
||||
- [Preference Scoring Chain Outputs](/docs/modules/evaluation/examples/comparisons): An example using a comparison evaluator on different models or prompts to select statistically significant differences in aggregate preference scores
|
||||
- [Preference Scoring Chain Outputs](/docs/guides/evaluation/examples/comparisons): An example using a comparison evaluator on different models or prompts to select statistically significant differences in aggregate preference scores
|
||||
|
||||
|
||||
## Reference Docs
|
||||
@@ -3,46 +3,80 @@ sidebar_position: 4
|
||||
---
|
||||
# Agents
|
||||
|
||||
Some applications require a flexible chain of calls to LLMs and other tools based on user input. The **Agent** interface provides the flexibility for such applications. An agent has access to a suite of tools, and determines which ones to use depending on the user input. Agents can use multiple tools, and use the output of one tool as the input to the next.
|
||||
The core idea of agents is to use an LLM to choose a sequence of actions to take.
|
||||
In chains, a sequence of actions is hardcoded (in code).
|
||||
In agents, a language model is used as a reasoning engine to determine which actions to take and in which order.
|
||||
|
||||
There are two main types of agents:
|
||||
There are several key components here:
|
||||
|
||||
- **Action agents**: at each timestep, decide on the next action using the outputs of all previous actions
|
||||
- **Plan-and-execute agents**: decide on the full sequence of actions up front, then execute them all without updating the plan
|
||||
## Agent
|
||||
|
||||
Action agents are suitable for small tasks, while plan-and-execute agents are better for complex or long-running tasks that require maintaining long-term objectives and focus. Often the best approach is to combine the dynamism of an action agent with the planning abilities of a plan-and-execute agent by letting the plan-and-execute agent use action agents to execute plans.
|
||||
This is the class responsible for deciding what step to take next.
|
||||
This is powered by a language model and a prompt.
|
||||
This prompt can include things like:
|
||||
|
||||
For a full list of agent types see [agent types](/docs/modules/agents/agent_types/). Additional abstractions involved in agents are:
|
||||
- [**Tools**](/docs/modules/agents/tools/): the actions an agent can take. What tools you give an agent highly depend on what you want the agent to do
|
||||
- [**Toolkits**](/docs/modules/agents/toolkits/): wrappers around collections of tools that can be used together a specific use case. For example, in order for an agent to
|
||||
interact with a SQL database it will likely need one tool to execute queries and another to inspect tables
|
||||
1. The personality of the agent (useful for having it respond in a certain way)
|
||||
2. Background context for the agent (useful for giving it more context on the types of tasks it's being asked to do)
|
||||
3. Prompting strategies to invoke better reasoning (the most famous/widely used being [ReAct](https://arxiv.org/abs/2210.03629))
|
||||
|
||||
## Action agents
|
||||
LangChain provides a few different types of agents to get started.
|
||||
Even then, you will likely want to customize those agents with parts (1) and (2).
|
||||
For a full list of agent types see [agent types](/docs/modules/agents/agent_types/)
|
||||
|
||||
At a high-level an action agent:
|
||||
1. Receives user input
|
||||
2. Decides which tool, if any, to use and the tool input
|
||||
3. Calls the tool and records the output (also known as an "observation")
|
||||
4. Decides the next step using the history of tools, tool inputs, and observations
|
||||
5. Repeats 3-4 until it determines it can respond directly to the user
|
||||
## Tools
|
||||
|
||||
Action agents are wrapped in **agent executors**, which are responsible for calling the agent, getting back an action and action input, calling the tool that the action references with the generated input, getting the output of the tool, and then passing all that information back into the agent to get the next action it should take.
|
||||
Tools are functions that an agent calls.
|
||||
There are two important considerations here:
|
||||
|
||||
Although an agent can be constructed in many ways, it typically involves these components:
|
||||
1. Giving the agent access to the right tools
|
||||
2. Describing the tools in a way that is most helpful to the agent
|
||||
|
||||
- **Prompt template**: Responsible for taking the user input and previous steps and constructing a prompt
|
||||
to send to the language model
|
||||
- **Language model**: Takes the prompt with use input and action history and decides what to do next
|
||||
- **Output parser**: Takes the output of the language model and parses it into the next action or a final answer
|
||||
Without both, the agent you are trying to build will not work.
|
||||
If you don't give the agent access to a correct set of tools, it will never be able to accomplish the objective.
|
||||
If you don't describe the tools properly, the agent won't know how to properly use them.
|
||||
|
||||
## Plan-and-execute agents
|
||||
LangChain provides a wide set of tools to get started, but also makes it easy to define your own (including custom descriptions).
|
||||
For a full list of tools, see [here](/docs/modules/agents/tools/)
|
||||
|
||||
At a high-level a plan-and-execute agent:
|
||||
1. Receives user input
|
||||
2. Plans the full sequence of steps to take
|
||||
3. Executes the steps in order, passing the outputs of past steps as inputs to future steps
|
||||
## Toolkits
|
||||
|
||||
The most typical implementation is to have the planner be a language model, and the executor be an action agent. Read more [here](/docs/modules/agents/agent_types/plan_and_execute.html).
|
||||
Often the set of tools an agent has access to is more important than a single tool.
|
||||
For this LangChain provides the concept of toolkits - groups of tools needed to accomplish specific objectives.
|
||||
There are generally around 3-5 tools in a toolkit.
|
||||
|
||||
LangChain provides a wide set of toolkits to get started.
|
||||
For a full list of toolkits, see [here](/docs/modules/agents/toolkits/)
|
||||
|
||||
## AgentExecutor
|
||||
|
||||
The agent executor is the runtime for an agent.
|
||||
This is what actually calls the agent and executes the actions it chooses.
|
||||
Pseudocode for this runtime is below:
|
||||
|
||||
```python
|
||||
next_action = agent.get_action(...)
|
||||
while next_action != AgentFinish:
|
||||
observation = run(next_action)
|
||||
next_action = agent.get_action(..., next_action, observation)
|
||||
return next_action
|
||||
```
|
||||
|
||||
While this may seem simple, there are several complexities this runtime handles for you, including:
|
||||
|
||||
1. Handling cases where the agent selects a non-existent tool
|
||||
2. Handling cases where the tool errors
|
||||
3. Handling cases where the agent produces output that cannot be parsed into a tool invocation
|
||||
4. Logging and observability at all levels (agent decisions, tool calls) either to stdout or [LangSmith](https://smith.langchain.com).
|
||||
|
||||
## Other types of agent runtimes
|
||||
|
||||
The `AgentExecutor` class is the main agent runtime supported by LangChain.
|
||||
However, there are other, more experimental runtimes we also support.
|
||||
These include:
|
||||
|
||||
- [Plan-and-execute Agent](/docs/modules/agents/agent_types/plan_and_execute.html)
|
||||
- [Baby AGI](/docs/use_cases/autonomous_agents/baby_agi.html)
|
||||
- [Auto GPT](/docs/use_cases/autonomous_agents/autogpt.html)
|
||||
|
||||
## Get started
|
||||
|
||||
|
||||
@@ -3,8 +3,8 @@ sidebar_position: 3
|
||||
---
|
||||
# Toolkits
|
||||
|
||||
:::info
|
||||
Head to [Integrations](/docs/integrations/toolkits/) for documentation on built-in toolkit integrations.
|
||||
:::
|
||||
|
||||
Toolkits are collections of tools that are designed to be used together for specific tasks and have convenience loading methods.
|
||||
|
||||
import DocCardList from "@theme/DocCardList";
|
||||
|
||||
<DocCardList />
|
||||
|
||||
@@ -1,2 +0,0 @@
|
||||
label: 'How-to'
|
||||
position: 0
|
||||
@@ -3,6 +3,10 @@ sidebar_position: 2
|
||||
---
|
||||
# Tools
|
||||
|
||||
:::info
|
||||
Head to [Integrations](/docs/integrations/tools/) for documentation on built-in tool integrations.
|
||||
:::
|
||||
|
||||
Tools are interfaces that an agent can use to interact with the world.
|
||||
|
||||
## Get started
|
||||
|
||||
@@ -1 +0,0 @@
|
||||
label: 'Integrations'
|
||||
@@ -1,2 +0,0 @@
|
||||
label: 'How-to'
|
||||
position: 0
|
||||
@@ -3,6 +3,10 @@ sidebar_position: 5
|
||||
---
|
||||
# Callbacks
|
||||
|
||||
:::info
|
||||
Head to [Integrations](/docs/integrations/callbacks/) for documentation on built-in callbacks integrations with 3rd-party tools.
|
||||
:::
|
||||
|
||||
LangChain provides a callbacks system that allows you to hook into the various stages of your LLM application. This is useful for logging, monitoring, streaming, and other tasks.
|
||||
|
||||
import GetStarted from "@snippets/modules/callbacks/get_started.mdx"
|
||||
|
||||
@@ -1 +0,0 @@
|
||||
label: 'Integrations'
|
||||
@@ -1,2 +0,0 @@
|
||||
label: 'How-to'
|
||||
position: 0
|
||||
@@ -3,6 +3,10 @@ sidebar_position: 0
|
||||
---
|
||||
# Document loaders
|
||||
|
||||
:::info
|
||||
Head to [Integrations](/docs/integrations/document_loaders/) for documentation on built-in document loader integrations with 3rd-party tools.
|
||||
:::
|
||||
|
||||
Use document loaders to load data from a source as `Document`'s. A `Document` is a piece of text
|
||||
and associated metadata. For example, there are document loaders for loading a simple `.txt` file, for loading the text
|
||||
contents of any web page, or even for loading a transcript of a YouTube video.
|
||||
|
||||
@@ -1 +0,0 @@
|
||||
label: 'Integrations'
|
||||
@@ -3,6 +3,10 @@ sidebar_position: 1
|
||||
---
|
||||
# Document transformers
|
||||
|
||||
:::info
|
||||
Head to [Integrations](/docs/integrations/document_transformers/) for documentation on built-in document transformer integrations with 3rd-party tools.
|
||||
:::
|
||||
|
||||
Once you've loaded documents, you'll often want to transform them to better suit your application. The simplest example
|
||||
is you may want to split a long document into smaller chunks that can fit into your model's context window. LangChain
|
||||
has a number of built-in document transformers that make it easy to split, combine, filter, and otherwise manipulate documents.
|
||||
|
||||
@@ -1,2 +0,0 @@
|
||||
label: 'How-to'
|
||||
position: 0
|
||||
@@ -3,6 +3,10 @@ sidebar_position: 4
|
||||
---
|
||||
# Retrievers
|
||||
|
||||
:::info
|
||||
Head to [Integrations](/docs/integrations/retrievers/) for documentation on built-in retriever integrations with 3rd-party tools.
|
||||
:::
|
||||
|
||||
A retriever is an interface that returns documents given an unstructured query. It is more general than a vector store.
|
||||
A retriever does not need to be able to store documents, only to return (or retrieve) it. Vector stores can be used
|
||||
as the backbone of a retriever, but there are other types of retrievers as well.
|
||||
|
||||
@@ -3,6 +3,10 @@ sidebar_position: 2
|
||||
---
|
||||
# Text embedding models
|
||||
|
||||
:::info
|
||||
Head to [Integrations](/docs/integrations/text_embedding/) for documentation on built-in integrations with text embedding model providers.
|
||||
:::
|
||||
|
||||
The Embeddings class is a class designed for interfacing with text embedding models. There are lots of embedding model providers (OpenAI, Cohere, Hugging Face, etc) - this class is designed to provide a standard interface for all of them.
|
||||
|
||||
Embeddings create a vector representation of a piece of text. This is useful because it means we can think about text in the vector space, and do things like semantic search where we look for pieces of text that are most similar in the vector space.
|
||||
|
||||
@@ -1 +0,0 @@
|
||||
label: 'Integrations'
|
||||
@@ -3,6 +3,10 @@ sidebar_position: 3
|
||||
---
|
||||
# Vector stores
|
||||
|
||||
:::info
|
||||
Head to [Integrations](/docs/integrations/vectorstores/) for documentation on built-in integrations with 3rd-party vector stores.
|
||||
:::
|
||||
|
||||
One of the most common ways to store and search over unstructured data is to embed it and store the resulting embedding
|
||||
vectors, and then at query time to embed the unstructured query and retrieve the embedding vectors that are
|
||||
'most similar' to the embedded query. A vector store takes care of storing embedded data and performing vector search
|
||||
|
||||
@@ -1 +0,0 @@
|
||||
label: 'Integrations'
|
||||
@@ -1,2 +0,0 @@
|
||||
label: 'How-to'
|
||||
position: 0
|
||||
@@ -6,6 +6,10 @@ sidebar_position: 3
|
||||
|
||||
🚧 _Docs under construction_ 🚧
|
||||
|
||||
:::info
|
||||
Head to [Integrations](/docs/integrations/memory/) for documentation on built-in memory integrations with 3rd-party tools.
|
||||
:::
|
||||
|
||||
By default, Chains and Agents are stateless,
|
||||
meaning that they treat each incoming query independently (like the underlying LLMs and chat models themselves).
|
||||
In some applications, like chatbots, it is essential
|
||||
|
||||
@@ -1 +0,0 @@
|
||||
label: 'Integrations'
|
||||
@@ -1,2 +0,0 @@
|
||||
label: 'How-to'
|
||||
position: 0
|
||||
@@ -3,18 +3,16 @@ sidebar_position: 1
|
||||
---
|
||||
# Chat models
|
||||
|
||||
:::info
|
||||
Head to [Integrations](/docs/integrations/chat/) for documentation on built-in integrations with chat model providers.
|
||||
:::
|
||||
|
||||
Chat models are a variation on language models.
|
||||
While chat models use language models under the hood, the interface they expose is a bit different.
|
||||
Rather than expose a "text in, text out" API, they expose an interface where "chat messages" are the inputs and outputs.
|
||||
|
||||
Chat model APIs are fairly new, so we are still figuring out the correct abstractions.
|
||||
|
||||
The following sections of documentation are provided:
|
||||
|
||||
- **How-to guides**: Walkthroughs of core functionality, like streaming, creating chat prompts, etc.
|
||||
|
||||
- **Integrations**: How to use different chat model providers (OpenAI, Anthropic, etc).
|
||||
|
||||
## Get started
|
||||
|
||||
import GetStarted from "@snippets/modules/model_io/models/chat/get_started.mdx"
|
||||
|
||||
@@ -1 +0,0 @@
|
||||
label: 'Integrations'
|
||||
@@ -1,2 +0,0 @@
|
||||
label: 'How-to'
|
||||
position: 0
|
||||
@@ -3,14 +3,12 @@ sidebar_position: 0
|
||||
---
|
||||
# LLMs
|
||||
|
||||
:::info
|
||||
Head to [Integrations](/docs/integrations/llms/) for documentation on built-in integrations with LLM providers.
|
||||
:::
|
||||
|
||||
Large Language Models (LLMs) are a core component of LangChain.
|
||||
LangChain does not serve it's own LLMs, but rather provides a standard interface for interacting with many different LLMs.
|
||||
|
||||
For more detailed documentation check out our:
|
||||
|
||||
- **How-to guides**: Walkthroughs of core functionality, like streaming, async, etc.
|
||||
|
||||
- **Integrations**: How to use different LLM providers (OpenAI, Anthropic, etc.)
|
||||
LangChain does not serve its own LLMs, but rather provides a standard interface for interacting with many different LLMs.
|
||||
|
||||
## Get started
|
||||
|
||||
|
||||
@@ -1 +0,0 @@
|
||||
label: 'Integrations'
|
||||
150
docs/docs_skeleton/generate_api_reference_links.py
Normal file
150
docs/docs_skeleton/generate_api_reference_links.py
Normal file
@@ -0,0 +1,150 @@
|
||||
import importlib
|
||||
import inspect
|
||||
import json
|
||||
import logging
|
||||
import os
|
||||
import re
|
||||
from pathlib import Path
|
||||
|
||||
logging.basicConfig(level=logging.INFO)
|
||||
logger = logging.getLogger(__name__)
|
||||
# Base URL for all class documentation
|
||||
_BASE_URL = "https://api.python.langchain.com/en/latest/"
|
||||
|
||||
# Regular expression to match Python code blocks
|
||||
code_block_re = re.compile(r"^(```python\n)(.*?)(```\n)", re.DOTALL | re.MULTILINE)
|
||||
# Regular expression to match langchain import lines
|
||||
_IMPORT_RE = re.compile(r"(from\s+(langchain\.\w+(\.\w+)*?)\s+import\s+)(\w+)")
|
||||
|
||||
_CURRENT_PATH = Path(__file__).parent.absolute()
|
||||
# Directory where generated markdown files are stored
|
||||
_DOCS_DIR = _CURRENT_PATH / "docs"
|
||||
_JSON_PATH = _CURRENT_PATH.parent / "api_reference" / "guide_imports.json"
|
||||
|
||||
|
||||
def find_files(path):
|
||||
"""Find all MDX files in the given path"""
|
||||
for root, _, files in os.walk(path):
|
||||
for file in files:
|
||||
if file.endswith(".mdx") or file.endswith(".md"):
|
||||
yield os.path.join(root, file)
|
||||
|
||||
|
||||
def get_full_module_name(module_path, class_name):
|
||||
"""Get full module name using inspect"""
|
||||
module = importlib.import_module(module_path)
|
||||
class_ = getattr(module, class_name)
|
||||
return inspect.getmodule(class_).__name__
|
||||
|
||||
|
||||
def main():
|
||||
"""Main function"""
|
||||
global_imports = {}
|
||||
|
||||
for file in find_files(_DOCS_DIR):
|
||||
print(f"Adding links for imports in {file}")
|
||||
|
||||
# replace_imports now returns the import information rather than writing it to a file
|
||||
file_imports = replace_imports(file)
|
||||
|
||||
if file_imports:
|
||||
# Use relative file path as key
|
||||
relative_path = os.path.relpath(file, _DOCS_DIR)
|
||||
doc_url = f"https://python.langchain.com/docs/{relative_path.replace('.mdx', '').replace('.md', '')}"
|
||||
for import_info in file_imports:
|
||||
doc_title = import_info["title"]
|
||||
class_name = import_info["imported"]
|
||||
if class_name not in global_imports:
|
||||
global_imports[class_name] = {}
|
||||
global_imports[class_name][doc_title] = doc_url
|
||||
|
||||
# Write the global imports information to a JSON file
|
||||
with _JSON_PATH.open("w") as f:
|
||||
json.dump(global_imports, f)
|
||||
|
||||
|
||||
def _get_doc_title(data: str, file_name: str) -> str:
|
||||
try:
|
||||
return re.findall(r"^#\s+(.*)", data, re.MULTILINE)[0]
|
||||
except IndexError:
|
||||
pass
|
||||
# Parse the rst-style titles
|
||||
try:
|
||||
return re.findall(r"^(.*)\n=+\n", data, re.MULTILINE)[0]
|
||||
except IndexError:
|
||||
return file_name
|
||||
|
||||
|
||||
def replace_imports(file):
|
||||
"""Replace imports in each Python code block with links to their documentation and append the import info in a comment"""
|
||||
all_imports = []
|
||||
with open(file, "r") as f:
|
||||
data = f.read()
|
||||
|
||||
file_name = os.path.basename(file)
|
||||
_DOC_TITLE = _get_doc_title(data, file_name)
|
||||
|
||||
def replacer(match):
|
||||
# Extract the code block content
|
||||
code = match.group(2)
|
||||
# Replace if any import comment exists
|
||||
# TODO: Use our own custom <code> component rather than this
|
||||
# injection method
|
||||
existing_comment_re = re.compile(r"^<!--IMPORTS:.*?-->\n", re.MULTILINE)
|
||||
code = existing_comment_re.sub("", code)
|
||||
|
||||
# Process imports in the code block
|
||||
imports = []
|
||||
for import_match in _IMPORT_RE.finditer(code):
|
||||
class_name = import_match.group(4)
|
||||
try:
|
||||
module_path = get_full_module_name(import_match.group(2), class_name)
|
||||
except AttributeError as e:
|
||||
logger.warning(f"Could not find module for {class_name}, {e}")
|
||||
continue
|
||||
except ImportError as e:
|
||||
# Some CentOS OpenSSL issues can cause this to fail
|
||||
logger.warning(f"Failed to load for class {class_name}, {e}")
|
||||
continue
|
||||
|
||||
url = (
|
||||
_BASE_URL
|
||||
+ "/"
|
||||
+ module_path.split(".")[1]
|
||||
+ "/"
|
||||
+ module_path
|
||||
+ "."
|
||||
+ class_name
|
||||
+ ".html"
|
||||
)
|
||||
|
||||
# Add the import information to our list
|
||||
imports.append(
|
||||
{
|
||||
"imported": class_name,
|
||||
"source": import_match.group(2),
|
||||
"docs": url,
|
||||
"title": _DOC_TITLE,
|
||||
}
|
||||
)
|
||||
|
||||
if imports:
|
||||
all_imports.extend(imports)
|
||||
# Create a unique comment containing the import information
|
||||
import_comment = f"<!--IMPORTS:{json.dumps(imports)}-->"
|
||||
# Inject the import comment at the start of the code block
|
||||
return match.group(1) + import_comment + "\n" + code + match.group(3)
|
||||
else:
|
||||
# If there are no imports, return the original match
|
||||
return match.group(0)
|
||||
|
||||
# Use re.sub to replace each Python code block
|
||||
data = code_block_re.sub(replacer, data)
|
||||
|
||||
with open(file, "w") as f:
|
||||
f.write(data)
|
||||
return all_imports
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
@@ -21,7 +21,7 @@ function Imports({ imports }) {
|
||||
</h4>
|
||||
<ul style={{ paddingBottom: "1rem" }}>
|
||||
{imports.map(({ imported, source, docs }) => (
|
||||
<li>
|
||||
<li key={imported}>
|
||||
<a href={docs}>
|
||||
<span>{imported}</span>
|
||||
</a>{" "}
|
||||
@@ -34,14 +34,25 @@ function Imports({ imports }) {
|
||||
}
|
||||
|
||||
export default function CodeBlockWrapper({ children, ...props }) {
|
||||
// Initialize imports as an empty array
|
||||
let imports = [];
|
||||
|
||||
// Check if children is a string
|
||||
if (typeof children === "string") {
|
||||
return <CodeBlock {...props}>{children}</CodeBlock>;
|
||||
// Search for an IMPORTS comment in the code
|
||||
const match = /<!--IMPORTS:(.*?)-->\n/.exec(children);
|
||||
if (match) {
|
||||
imports = JSON.parse(match[1]);
|
||||
children = children.replace(match[0], "");
|
||||
}
|
||||
} else if (children.imports) {
|
||||
imports = children.imports;
|
||||
}
|
||||
|
||||
return (
|
||||
<>
|
||||
<CodeBlock {...props}>{children.content}</CodeBlock>
|
||||
<Imports imports={children.imports} />
|
||||
<CodeBlock {...props}>{children}</CodeBlock>
|
||||
{imports.length > 0 && <Imports imports={imports} />}
|
||||
</>
|
||||
);
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,10 +1,38 @@
|
||||
#!/bin/bash
|
||||
yum -y update
|
||||
yum remove openssl-devel -y
|
||||
yum install gcc bzip2-devel libffi-devel zlib-devel wget tar -y
|
||||
# Make sure openssl11 is installed before Python compilation
|
||||
yum install openssl11 -y
|
||||
yum install openssl11-devel -y
|
||||
|
||||
# Locate openssl 1.1.1 library and headers
|
||||
# OPENSSL_LIB_PATH=$(dirname $(find / -name 'libssl.so.*' | grep 'openssl11'))
|
||||
# OPENSSL_INCLUDE_PATH=$(dirname $(find / -name 'openssl' | grep 'openssl11'))
|
||||
|
||||
echo "OPENSSL VERSION"
|
||||
openssl11 version
|
||||
|
||||
# Install python 3.11 to connect with openSSL 1.1.1
|
||||
wget https://www.python.org/ftp/python/3.11.4/Python-3.11.4.tgz
|
||||
tar xzf Python-3.11.4.tgz
|
||||
cd Python-3.11.4
|
||||
./configure
|
||||
#--with-openssl=${OPENSSL_LIB_PATH} CPPFLAGS="-I${OPENSSL_INCLUDE_PATH}"
|
||||
make altinstall
|
||||
|
||||
# Check python version
|
||||
echo "Python Version"
|
||||
python3.11 --version
|
||||
cd ..
|
||||
python3 --version
|
||||
python3 -m venv .venv
|
||||
|
||||
# Install nbdev and generate docs
|
||||
cd ..
|
||||
python3.11 -m venv .venv
|
||||
source .venv/bin/activate
|
||||
python3 -m pip install -r vercel_requirements.txt
|
||||
python3.11 -m pip install --upgrade pip
|
||||
python3.11 -m pip install -r vercel_requirements.txt
|
||||
cp -r extras/* docs_skeleton/docs
|
||||
cd docs_skeleton
|
||||
nbdoc_build
|
||||
python3.11 generate_api_reference_links.py
|
||||
|
||||
@@ -31,7 +31,7 @@ There isn't any special setup for it.
|
||||
|
||||
## LLM
|
||||
|
||||
See a [usage example](/docs/modules/model_io/models/llms/integrations/INCLUDE_REAL_NAME.html).
|
||||
See a [usage example](/docs/integrations/llms/INCLUDE_REAL_NAME).
|
||||
|
||||
```python
|
||||
from langchain.llms import integration_class_REPLACE_ME
|
||||
@@ -40,7 +40,7 @@ from langchain.llms import integration_class_REPLACE_ME
|
||||
|
||||
## Text Embedding Models
|
||||
|
||||
See a [usage example](/docs/modules/data_connection/text_embedding/integrations/INCLUDE_REAL_NAME.html)
|
||||
See a [usage example](/docs/integrations/text_embedding/INCLUDE_REAL_NAME)
|
||||
|
||||
```python
|
||||
from langchain.embeddings import integration_class_REPLACE_ME
|
||||
@@ -49,7 +49,7 @@ from langchain.embeddings import integration_class_REPLACE_ME
|
||||
|
||||
## Chat Models
|
||||
|
||||
See a [usage example](/docs/modules/model_io/models/chat/integrations/INCLUDE_REAL_NAME.html)
|
||||
See a [usage example](/docs/integrations/chat/INCLUDE_REAL_NAME)
|
||||
|
||||
```python
|
||||
from langchain.chat_models import integration_class_REPLACE_ME
|
||||
@@ -57,7 +57,7 @@ from langchain.chat_models import integration_class_REPLACE_ME
|
||||
|
||||
## Document Loader
|
||||
|
||||
See a [usage example](/docs/modules/data_connection/document_loaders/integrations/INCLUDE_REAL_NAME.html).
|
||||
See a [usage example](/docs/integrations/document_loaders/INCLUDE_REAL_NAME).
|
||||
|
||||
```python
|
||||
from langchain.document_loaders import integration_class_REPLACE_ME
|
||||
|
||||
@@ -29,7 +29,7 @@
|
||||
"source": [
|
||||
"from langchain.evaluation import load_evaluator\n",
|
||||
"\n",
|
||||
"evaluator = load_evaluator(\"pairwise_string\", requires_reference=True)"
|
||||
"evaluator = load_evaluator(\"labeled_pairwise_string\")"
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -43,7 +43,7 @@
|
||||
{
|
||||
"data": {
|
||||
"text/plain": [
|
||||
"{'reasoning': 'Response A provides an incorrect answer by stating there are three dogs in the park, while the reference answer indicates there are four. Response B, on the other hand, provides the correct answer, matching the reference answer. Although Response B is less detailed, it is accurate and directly answers the question. \\n\\nTherefore, the better response is [[B]].\\n',\n",
|
||||
"{'reasoning': 'Response A is incorrect as it states there are three dogs in the park, which contradicts the reference answer of four. Response B, on the other hand, is accurate as it matches the reference answer. Although Response B is not as detailed or elaborate as Response A, it is more important that the response is accurate. \\n\\nFinal Decision: [[B]]\\n',\n",
|
||||
" 'value': 'B',\n",
|
||||
" 'score': 0}"
|
||||
]
|
||||
@@ -90,7 +90,7 @@
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 5,
|
||||
"execution_count": 4,
|
||||
"id": "7f56c76e-a39b-4509-8b8a-8a2afe6c3da1",
|
||||
"metadata": {
|
||||
"tags": []
|
||||
@@ -104,7 +104,7 @@
|
||||
" 'score': 0}"
|
||||
]
|
||||
},
|
||||
"execution_count": 5,
|
||||
"execution_count": 4,
|
||||
"metadata": {},
|
||||
"output_type": "execute_result"
|
||||
}
|
||||
@@ -129,7 +129,7 @@
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 6,
|
||||
"execution_count": 5,
|
||||
"id": "de84a958-1330-482b-b950-68bcf23f9e35",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
@@ -138,12 +138,12 @@
|
||||
"\n",
|
||||
"llm = ChatAnthropic(temperature=0)\n",
|
||||
"\n",
|
||||
"evaluator = load_evaluator(\"pairwise_string\", llm=llm, requires_reference=True)"
|
||||
"evaluator = load_evaluator(\"labeled_pairwise_string\", llm=llm)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 7,
|
||||
"execution_count": 6,
|
||||
"id": "e162153f-d50a-4a7c-a033-019dabbc954c",
|
||||
"metadata": {
|
||||
"tags": []
|
||||
@@ -152,12 +152,12 @@
|
||||
{
|
||||
"data": {
|
||||
"text/plain": [
|
||||
"{'reasoning': 'Response A provides a specific number but is inaccurate based on the reference answer. Response B provides the correct number but lacks detail or explanation. Overall, Response B is more helpful and accurate in directly answering the question, despite lacking depth or creativity.\\n\\n[[B]]\\n',\n",
|
||||
"{'reasoning': 'Here is my assessment:\\n\\nResponse B is better because it directly answers the question by stating the number \"4\", which matches the ground truth reference answer. Response A provides an incorrect number of dogs, stating there are three dogs when the reference says there are four. \\n\\nResponse B is more helpful, relevant, accurate and provides the right level of detail by simply stating the number that was asked for. Response A provides an inaccurate number, so is less helpful and accurate.\\n\\nIn summary, Response B better followed the instructions and answered the question correctly per the reference answer.\\n\\n[[B]]',\n",
|
||||
" 'value': 'B',\n",
|
||||
" 'score': 0}"
|
||||
]
|
||||
},
|
||||
"execution_count": 7,
|
||||
"execution_count": 6,
|
||||
"metadata": {},
|
||||
"output_type": "execute_result"
|
||||
}
|
||||
@@ -185,7 +185,7 @@
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 12,
|
||||
"execution_count": 7,
|
||||
"id": "fb817efa-3a4d-439d-af8c-773b89d97ec9",
|
||||
"metadata": {
|
||||
"tags": []
|
||||
@@ -210,13 +210,13 @@
|
||||
"\"\"\"\n",
|
||||
")\n",
|
||||
"evaluator = load_evaluator(\n",
|
||||
" \"pairwise_string\", prompt=prompt_template, requires_reference=True\n",
|
||||
" \"labeled_pairwise_string\", prompt=prompt_template\n",
|
||||
")"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 13,
|
||||
"execution_count": 8,
|
||||
"id": "d40aa4f0-cfd5-4cb4-83c8-8d2300a04c2f",
|
||||
"metadata": {
|
||||
"tags": []
|
||||
@@ -237,7 +237,7 @@
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 14,
|
||||
"execution_count": 9,
|
||||
"id": "9467bb42-7a31-4071-8f66-9ed2c6f06dcd",
|
||||
"metadata": {
|
||||
"tags": []
|
||||
@@ -246,12 +246,12 @@
|
||||
{
|
||||
"data": {
|
||||
"text/plain": [
|
||||
"{'reasoning': \"Option A is most similar to the reference label. Both the reference label and option A state that the dog's name is Fido. Option B, on the other hand, gives a different name for the dog. Therefore, option A is the most similar to the reference label. \\n\",\n",
|
||||
"{'reasoning': 'Option A is more similar to the reference label because it mentions the same dog\\'s name, \"fido\". Option B mentions a different name, \"spot\". Therefore, A is more similar to the reference label. \\n',\n",
|
||||
" 'value': 'A',\n",
|
||||
" 'score': 1}"
|
||||
]
|
||||
},
|
||||
"execution_count": 14,
|
||||
"execution_count": 9,
|
||||
"metadata": {},
|
||||
"output_type": "execute_result"
|
||||
}
|
||||
@@ -30,7 +30,12 @@
|
||||
"source": [
|
||||
"from langchain.evaluation import load_evaluator\n",
|
||||
"\n",
|
||||
"evaluator = load_evaluator(\"criteria\", criteria=\"conciseness\")"
|
||||
"evaluator = load_evaluator(\"criteria\", criteria=\"conciseness\")\n",
|
||||
"\n",
|
||||
"# This is equivalent to loading using the enum\n",
|
||||
"from langchain.evaluation import EvaluatorType\n",
|
||||
"\n",
|
||||
"evaluator = load_evaluator(EvaluatorType.CRITERIA, criteria=\"conciseness\")"
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -45,7 +50,7 @@
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"{'reasoning': 'The criterion is conciseness. This means the submission should be brief and to the point. \\n\\nLooking at the submission, the answer to the task is included, but there is additional commentary that is not necessary to answer the question. The phrase \"That\\'s an elementary question\" and \"The answer you\\'re looking for is\" could be removed and the answer would still be clear and correct. \\n\\nTherefore, the submission is not concise and does not meet the criterion. \\n\\nN', 'value': 'N', 'score': 0}\n"
|
||||
"{'reasoning': 'The criterion is conciseness, which means the submission should be brief and to the point. \\n\\nLooking at the submission, the answer to the question \"What\\'s 2+2?\" is indeed \"four\". However, the respondent has added extra information, stating \"That\\'s an elementary question.\" This statement does not contribute to answering the question and therefore makes the response less concise.\\n\\nTherefore, the submission does not meet the criterion of conciseness.\\n\\nN', 'value': 'N', 'score': 0}\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
@@ -59,7 +64,45 @@
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "43397a9f-ccca-4f91-b0e1-df0cada2efb1",
|
||||
"id": "c40b1ac7-8f95-48ed-89a2-623bcc746461",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## Using Reference Labels\n",
|
||||
"\n",
|
||||
"Some criteria (such as correctness) require reference labels to work correctly. To do this, initialuse the `labeled_criteria` evaluator and call the evaluator with a `reference` string."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 3,
|
||||
"id": "20d8a86b-beba-42ce-b82c-d9e5ebc13686",
|
||||
"metadata": {
|
||||
"tags": []
|
||||
},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"With ground truth: 1\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"evaluator = load_evaluator(\"labeled_criteria\", criteria=\"correctness\")\n",
|
||||
"\n",
|
||||
"# We can even override the model's learned knowledge using ground truth labels\n",
|
||||
"eval_result = evaluator.evaluate_strings(\n",
|
||||
" input=\"What is the capital of the US?\",\n",
|
||||
" prediction=\"Topeka, KS\",\n",
|
||||
" reference=\"The capital of the US is Topeka, KS, where it permanently moved from Washington D.C. on May 16, 2023\",\n",
|
||||
")\n",
|
||||
"print(f'With ground truth: {eval_result[\"score\"]}')"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "e05b5748-d373-4ff8-85d9-21da4641e84c",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"**Default Criteria**\n",
|
||||
@@ -70,77 +113,36 @@
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 3,
|
||||
"id": "8c4ec9dd-6557-4f23-8480-c822eb6ec552",
|
||||
"metadata": {
|
||||
"tags": []
|
||||
},
|
||||
"execution_count": 4,
|
||||
"id": "47de7359-db3e-4cad-bcfa-4fe834dea893",
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
"text/plain": [
|
||||
"['conciseness',\n",
|
||||
" 'relevance',\n",
|
||||
" 'correctness',\n",
|
||||
" 'coherence',\n",
|
||||
" 'harmfulness',\n",
|
||||
" 'maliciousness',\n",
|
||||
" 'helpfulness',\n",
|
||||
" 'controversiality',\n",
|
||||
" 'mysogyny',\n",
|
||||
" 'criminality',\n",
|
||||
" 'insensitive']"
|
||||
"[<Criteria.CONCISENESS: 'conciseness'>,\n",
|
||||
" <Criteria.RELEVANCE: 'relevance'>,\n",
|
||||
" <Criteria.CORRECTNESS: 'correctness'>,\n",
|
||||
" <Criteria.COHERENCE: 'coherence'>,\n",
|
||||
" <Criteria.HARMFULNESS: 'harmfulness'>,\n",
|
||||
" <Criteria.MALICIOUSNESS: 'maliciousness'>,\n",
|
||||
" <Criteria.HELPFULNESS: 'helpfulness'>,\n",
|
||||
" <Criteria.CONTROVERSIALITY: 'controversiality'>,\n",
|
||||
" <Criteria.MISOGYNY: 'misogyny'>,\n",
|
||||
" <Criteria.CRIMINALITY: 'criminality'>,\n",
|
||||
" <Criteria.INSENSITIVITY: 'insensitivity'>]"
|
||||
]
|
||||
},
|
||||
"execution_count": 3,
|
||||
"execution_count": 4,
|
||||
"metadata": {},
|
||||
"output_type": "execute_result"
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"from langchain.evaluation import CriteriaEvalChain\n",
|
||||
"from langchain.evaluation import Criteria\n",
|
||||
"\n",
|
||||
"# For a list of other default supported criteria, try calling `supported_default_criteria`\n",
|
||||
"CriteriaEvalChain.get_supported_default_criteria()"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "c40b1ac7-8f95-48ed-89a2-623bcc746461",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## Using Reference Labels\n",
|
||||
"\n",
|
||||
"Some criteria (such as correctness) require reference labels to work correctly. To do this, initialize with `requires_reference=True` and call the evaluator with a `reference` string."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 4,
|
||||
"id": "20d8a86b-beba-42ce-b82c-d9e5ebc13686",
|
||||
"metadata": {
|
||||
"tags": []
|
||||
},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"With ground truth: 1\n",
|
||||
"Without ground truth: 0\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"evaluator = load_evaluator(\"criteria\", criteria=\"correctness\", requires_reference=True)\n",
|
||||
"\n",
|
||||
"# We can even override the model's learned knowledge using ground truth labels\n",
|
||||
"eval_result = evaluator.evaluate_strings(\n",
|
||||
" input=\"What is the capital of the US?\",\n",
|
||||
" prediction=\"Topeka, KS\",\n",
|
||||
" reference=\"The capital of the US is Topeka, KS, where it permanently moved from Washington D.C. on May 16, 2023\",\n",
|
||||
")\n",
|
||||
"print(f'With ground truth: {eval_result[\"score\"]}')"
|
||||
"list(Criteria)"
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -157,7 +159,7 @@
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 6,
|
||||
"execution_count": 8,
|
||||
"id": "bafa0a11-2617-4663-84bf-24df7d0736be",
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
@@ -165,18 +167,19 @@
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"{'reasoning': 'The criterion is asking if the output contains numeric information. The submission does mention the \"late 16th century,\" which is a numeric information. Therefore, the submission meets the criterion.\\n\\nY', 'value': 'Y', 'score': 1}\n"
|
||||
"{'reasoning': 'The criterion asks if the output contains numeric or mathematical information. \\n\\nThe submission is a joke that says, \"I ate some square pie but I don\\'t know the square of pi.\" \\n\\nIn this joke, there is a reference to the mathematical term \"square\" and the mathematical constant \"pi\". \\n\\nTherefore, the submission does contain numeric or mathematical information, and it meets the criterion. \\n\\nY', 'value': 'Y', 'score': 1}\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"custom_criterion = {\"numeric\": \"Does the output contain numeric information?\"}\n",
|
||||
"custom_criterion = {\"numeric\": \"Does the output contain numeric or mathematical information?\"}\n",
|
||||
"\n",
|
||||
"eval_chain = load_evaluator(\n",
|
||||
" EvaluatorType.CRITERIA,\n",
|
||||
" llm=eval_llm,\n",
|
||||
" criteria=custom_criterion,\n",
|
||||
")\n",
|
||||
"query = \"Tell me a joke\"\n",
|
||||
"prediction = \"I ate some square pie but I don't know the square of pi.\"\n",
|
||||
"eval_result = eval_chain.evaluate_strings(prediction=prediction, input=query)\n",
|
||||
"print(eval_result)"
|
||||
]
|
||||
@@ -194,7 +197,7 @@
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 7,
|
||||
"execution_count": 9,
|
||||
"id": "99e3c242-5b12-4bd5-b487-64990a159655",
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
@@ -220,7 +223,7 @@
|
||||
" ConstitutionalPrinciple(critique_request='Discuss the assistant’s last response to the human and whether it is in any way insensitive, sexist, racist, or socially inappropriate.', revision_request='Revise the assistant’s last response to remove content that is in any way insensitive, sexist, racist, or socially inappropriate.', name='insensitive'))]"
|
||||
]
|
||||
},
|
||||
"execution_count": 7,
|
||||
"execution_count": 9,
|
||||
"metadata": {},
|
||||
"output_type": "execute_result"
|
||||
}
|
||||
@@ -234,28 +237,23 @@
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 8,
|
||||
"execution_count": 12,
|
||||
"id": "f4061bc0-a88a-4d1c-88a0-8003bba084c7",
|
||||
"metadata": {
|
||||
"tags": []
|
||||
},
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
"text/plain": [
|
||||
"{'reasoning': 'The criterion asks to identify if the assistant\\'s response is harmful, unethical, racist, sexist, toxic, dangerous, or illegal.\\n\\nThe assistant\\'s response is \"I say that man is a lilly-livered nincompoop\". This is a negative statement about a person named Will. \\n\\nThe term \"lilly-livered\" is an old-fashioned term meaning cowardly, and \"nincompoop\" is a term meaning a foolish or stupid person. \\n\\nWhile this is a negative and potentially insulting statement, it does not appear to be harmful in a physical sense, unethical, racist, sexist, toxic, dangerous, or illegal. \\n\\nIt could be argued that the statement is harmful in a psychological or emotional sense, as it is insulting. However, without further context, it\\'s hard to definitively say if this meets the criteria of being harmful.\\n\\nN',\n",
|
||||
" 'value': 'N',\n",
|
||||
" 'score': 0}"
|
||||
]
|
||||
},
|
||||
"execution_count": 8,
|
||||
"metadata": {},
|
||||
"output_type": "execute_result"
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"{'reasoning': 'The criterion asks to identify if the assistant\\'s response is harmful, unethical, racist, sexist, toxic, dangerous, or illegal.\\n\\nLooking at the assistant\\'s response, it is clear that it is not racist or sexist as it does not discriminate or stereotype based on race or gender. \\n\\nThe response is also not illegal as it does not involve any criminal activity or encourage any form of illegal behavior.\\n\\nThe response is not dangerous as it does not pose a physical threat or risk to anyone\\'s safety.\\n\\nHowever, the assistant\\'s response can be considered harmful and toxic as it uses derogatory language (\"lilly-livered nincompoop\") to describe \\'Will\\'. This can be seen as a form of verbal abuse or insult, which can cause emotional harm.\\n\\nThe response can also be seen as unethical, as it is generally considered inappropriate to insult or belittle someone in this manner.\\n\\nN', 'value': 'N', 'score': 0}\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"eval_chain = load_evaluator(\n",
|
||||
" EvaluatorType.CRITERIA, llm=eval_llm, criteria=PRINCIPLES[\"harmful1\"]\n",
|
||||
"evaluator = load_evaluator(\n",
|
||||
" EvaluatorType.CRITERIA, criteria=PRINCIPLES[\"harmful1\"]\n",
|
||||
")\n",
|
||||
"eval_result = evaluator.evaluate_strings(\n",
|
||||
" prediction=\"I say that man is a lilly-livered nincompoop\",\n",
|
||||
@@ -278,7 +276,7 @@
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 10,
|
||||
"execution_count": 13,
|
||||
"id": "1717162d-f76c-4a14-9ade-168d6fa42b7a",
|
||||
"metadata": {
|
||||
"tags": []
|
||||
@@ -291,7 +289,7 @@
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 11,
|
||||
"execution_count": 14,
|
||||
"id": "8727e6f4-aaba-472d-bb7d-09fc1a0f0e2a",
|
||||
"metadata": {
|
||||
"tags": []
|
||||
@@ -306,7 +304,7 @@
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 12,
|
||||
"execution_count": 15,
|
||||
"id": "3f6f0d8b-cf42-4241-85ae-35b3ce8152a0",
|
||||
"metadata": {
|
||||
"tags": []
|
||||
@@ -316,7 +314,7 @@
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"{'reasoning': 'Here is my step-by-step reasoning for each criterion:\\n\\nconciseness: The submission is not concise. It contains unnecessary words and phrases like \"That\\'s an elementary question\" and \"you\\'re looking for\". The answer could have simply been stated as \"4\" to be concise.\\n\\nN', 'value': 'N', 'score': 0}\n"
|
||||
"{'reasoning': 'Step 1) Analyze the conciseness criterion: Is the submission concise and to the point?\\nStep 2) The submission provides extraneous information beyond just answering the question directly. It characterizes the question as \"elementary\" and provides reasoning for why the answer is 4. This additional commentary makes the submission not fully concise.\\nStep 3) Therefore, based on the analysis of the conciseness criterion, the submission does not meet the criteria.\\n\\nN', 'value': 'N', 'score': 0}\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
@@ -340,7 +338,7 @@
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 13,
|
||||
"execution_count": 16,
|
||||
"id": "22e57704-682f-44ff-96ba-e915c73269c0",
|
||||
"metadata": {
|
||||
"tags": []
|
||||
@@ -364,13 +362,13 @@
|
||||
"prompt = PromptTemplate.from_template(fstring)\n",
|
||||
"\n",
|
||||
"evaluator = load_evaluator(\n",
|
||||
" \"criteria\", criteria=\"correctness\", prompt=prompt, requires_reference=True\n",
|
||||
" \"labeled_criteria\", criteria=\"correctness\", prompt=prompt\n",
|
||||
")"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 14,
|
||||
"execution_count": 17,
|
||||
"id": "5d6b0eca-7aea-4073-a65a-18c3a9cdb5af",
|
||||
"metadata": {
|
||||
"tags": []
|
||||
@@ -380,7 +378,7 @@
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"{'reasoning': 'Correctness: No, the submission is not correct. The expected response was \"It\\'s 17 now.\" but the response given was \"What\\'s 2+2? That\\'s an elementary question. The answer you\\'re looking for is that two and two is four.\"', 'value': 'N', 'score': 0}\n"
|
||||
"{'reasoning': 'Correctness: No, the response is not correct. The expected response was \"It\\'s 17 now.\" but the response given was \"What\\'s 2+2? That\\'s an elementary question. The answer you\\'re looking for is that two and two is four.\"', 'value': 'N', 'score': 0}\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
@@ -53,7 +53,7 @@
|
||||
{
|
||||
"data": {
|
||||
"text/plain": [
|
||||
"{'score': 12}"
|
||||
"{'score': 0.11555555555555552}"
|
||||
]
|
||||
},
|
||||
"execution_count": 3,
|
||||
@@ -79,7 +79,7 @@
|
||||
{
|
||||
"data": {
|
||||
"text/plain": [
|
||||
"{'score': 4}"
|
||||
"{'score': 0.0724999999999999}"
|
||||
]
|
||||
},
|
||||
"execution_count": 4,
|
||||
@@ -143,7 +143,7 @@
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"jaro_evaluator = load_evaluator(\n",
|
||||
" \"string_distance\", distance=StringDistance.JARO, requires_reference=True\n",
|
||||
" \"string_distance\", distance=StringDistance.JARO\n",
|
||||
")"
|
||||
]
|
||||
},
|
||||
9
docs/extras/integrations/callbacks/index.mdx
Normal file
9
docs/extras/integrations/callbacks/index.mdx
Normal file
@@ -0,0 +1,9 @@
|
||||
---
|
||||
sidebar_position: 0
|
||||
---
|
||||
|
||||
# Callbacks
|
||||
|
||||
import DocCardList from "@theme/DocCardList";
|
||||
|
||||
<DocCardList />
|
||||
@@ -11,7 +11,7 @@
|
||||
"\n",
|
||||
"[PromptLayer](https://promptlayer.com) is a an LLM observability platform that lets you visualize requests, version prompts, and track usage. In this guide we will go over how to setup the `PromptLayerCallbackHandler`. \n",
|
||||
"\n",
|
||||
"While PromptLayer does have LLMs that integrate directly with LangChain (eg [`PromptLayerOpenAI`](https://python.langchain.com/docs/modules/model_io/models/llms/integrations/promptlayer_openai)), this callback is the recommended way to integrate PromptLayer with LangChain.\n",
|
||||
"While PromptLayer does have LLMs that integrate directly with LangChain (eg [`PromptLayerOpenAI`](https://python.langchain.com/docs/integrations/llms/promptlayer_openai)), this callback is the recommended way to integrate PromptLayer with LangChain.\n",
|
||||
"\n",
|
||||
"See [our docs](https://docs.promptlayer.com/languages/langchain) for more information."
|
||||
]
|
||||
9
docs/extras/integrations/chat/index.mdx
Normal file
9
docs/extras/integrations/chat/index.mdx
Normal file
@@ -0,0 +1,9 @@
|
||||
---
|
||||
sidebar_position: 0
|
||||
---
|
||||
|
||||
# Chat models
|
||||
|
||||
import DocCardList from "@theme/DocCardList";
|
||||
|
||||
<DocCardList />
|
||||
134
docs/extras/integrations/chat/llama_api.ipynb
Normal file
134
docs/extras/integrations/chat/llama_api.ipynb
Normal file
@@ -0,0 +1,134 @@
|
||||
{
|
||||
"cells": [
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "90a1faf2",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"# Llama API\n",
|
||||
"\n",
|
||||
"This notebook shows how to use LangChain with [LlamaAPI](https://llama-api.com/) - a hosted version of Llama2 that adds in support for function calling."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "f5b652cf",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"!pip install -U llamaapi"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 2,
|
||||
"id": "bfd385fd",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"from llamaapi import LlamaAPI\n",
|
||||
"\n",
|
||||
"# Replace 'Your_API_Token' with your actual API token\n",
|
||||
"llama = LlamaAPI('Your_API_Token')"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 4,
|
||||
"id": "632eb3e5",
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stderr",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"/Users/harrisonchase/.pyenv/versions/3.9.1/envs/langchain/lib/python3.9/site-packages/deeplake/util/check_latest_version.py:32: UserWarning: A newer version of deeplake (3.6.12) is available. It's recommended that you update to the latest version using `pip install -U deeplake`.\n",
|
||||
" warnings.warn(\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"from langchain_experimental.llms import ChatLlamaAPI"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 5,
|
||||
"id": "6f850e82",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"model = ChatLlamaAPI(client=llama)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 6,
|
||||
"id": "975c2bf4",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"from langchain.chains import create_tagging_chain\n",
|
||||
"\n",
|
||||
"schema = {\n",
|
||||
" \"properties\": {\n",
|
||||
" \"sentiment\": {\"type\": \"string\", 'description': 'the sentiment encountered in the passage'},\n",
|
||||
" \"aggressiveness\": {\"type\": \"integer\", 'description': 'a 0-10 score of how aggressive the passage is'},\n",
|
||||
" \"language\": {\"type\": \"string\", 'description': 'the language of the passage'},\n",
|
||||
" }\n",
|
||||
"}\n",
|
||||
"\n",
|
||||
"chain = create_tagging_chain(schema, model)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 7,
|
||||
"id": "ef9638c3",
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
"text/plain": [
|
||||
"{'sentiment': 'aggressive', 'aggressiveness': 8}"
|
||||
]
|
||||
},
|
||||
"execution_count": 7,
|
||||
"metadata": {},
|
||||
"output_type": "execute_result"
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"chain.run(\"give me your money\")"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "238b4f62",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": []
|
||||
}
|
||||
],
|
||||
"metadata": {
|
||||
"kernelspec": {
|
||||
"display_name": "Python 3 (ipykernel)",
|
||||
"language": "python",
|
||||
"name": "python3"
|
||||
},
|
||||
"language_info": {
|
||||
"codemirror_mode": {
|
||||
"name": "ipython",
|
||||
"version": 3
|
||||
},
|
||||
"file_extension": ".py",
|
||||
"mimetype": "text/x-python",
|
||||
"name": "python",
|
||||
"nbconvert_exporter": "python",
|
||||
"pygments_lexer": "ipython3",
|
||||
"version": "3.9.1"
|
||||
}
|
||||
},
|
||||
"nbformat": 4,
|
||||
"nbformat_minor": 5
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user