From ffa1b3a7581ebeec262360b4e602567c2b1e4191 Mon Sep 17 00:00:00 2001 From: Bagatur <22008038+baskaryan@users.noreply.github.com> Date: Sun, 15 Oct 2023 14:59:36 -0700 Subject: [PATCH] Add LCEL to chat model intro (#11834) --- docs/.local_build.sh | 1 + docs/docs/expression_language/interface.ipynb | 2 +- .../modules/model_io/models/chat/index.ipynb | 761 ++++++++++++++++++ .../modules/model_io/models/chat/index.mdx | 137 ---- 4 files changed, 763 insertions(+), 138 deletions(-) create mode 100644 docs/docs/modules/model_io/models/chat/index.ipynb delete mode 100644 docs/docs/modules/model_io/models/chat/index.mdx diff --git a/docs/.local_build.sh b/docs/.local_build.sh index c8a6e1a60d..bb84f2c58b 100755 --- a/docs/.local_build.sh +++ b/docs/.local_build.sh @@ -11,6 +11,7 @@ cd "${SCRIPT_DIR}" mkdir -p ../_dist cp -r . ../_dist cd ../_dist +poetry run python scripts/model_feat_table.py poetry run nbdoc_build --srcdir docs poetry run python scripts/generate_api_reference_links.py yarn install diff --git a/docs/docs/expression_language/interface.ipynb b/docs/docs/expression_language/interface.ipynb index f615b50359..3adaa916a3 100644 --- a/docs/docs/expression_language/interface.ipynb +++ b/docs/docs/expression_language/interface.ipynb @@ -925,7 +925,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.11.5" + "version": "3.9.1" } }, "nbformat": 4, diff --git a/docs/docs/modules/model_io/models/chat/index.ipynb b/docs/docs/modules/model_io/models/chat/index.ipynb new file mode 100644 index 0000000000..cc5ecd6dde --- /dev/null +++ b/docs/docs/modules/model_io/models/chat/index.ipynb @@ -0,0 +1,761 @@ +{ + "cells": [ + { + "cell_type": "raw", + "id": "c7a67d03-07ec-4c56-a5d6-8df8773e42b0", + "metadata": {}, + "source": [ + "---\n", + "sidebar_position: 1\n", + "title: Chat models\n", + "---" + ] + }, + { + "cell_type": "markdown", + "id": "a1a454a9-f963-417b-8be0-e60317cd328c", + "metadata": {}, + "source": [ + ":::info\n", + "Head to [Integrations](/docs/integrations/chat/) for documentation on built-in integrations with chat model providers.\n", + ":::\n", + "\n", + "Chat models are a variation on language models.\n", + "While chat models use language models under the hood, the interface they use is a bit different.\n", + "Rather than using a \"text in, text out\" API, they use an interface where \"chat messages\" are the inputs and outputs.\n", + "\n", + "## Get started\n", + "\n", + "### Setup\n", + "\n", + "For this example we'll need to install the OpenAI Python package:\n", + "\n", + "```bash\n", + "pip install openai\n", + "```\n", + "\n", + "Accessing the API requires an API key, which you can get by creating an account and heading [here](https://platform.openai.com/account/api-keys). Once we have a key we'll want to set it as an environment variable by running:\n", + "\n", + "```bash\n", + "export OPENAI_API_KEY=\"...\"\n", + "```\n", + "If you'd prefer not to set an environment variable you can pass the key in directly via the `openai_api_key` named parameter when initiating the OpenAI LLM class:\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "e230abb2-bc84-438b-b9ff-dd124acb1375", + "metadata": {}, + "outputs": [], + "source": [ + "from langchain.chat_models import ChatOpenAI\n", + "\n", + "chat = ChatOpenAI(openai_api_key=\"...\")" + ] + }, + { + "cell_type": "markdown", + "id": "609bbd5c-e5a1-4166-89e1-d6c52054860d", + "metadata": {}, + "source": [ + "Otherwise you can initialize without any params:" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "id": "3d9dbf70-2397-4d6b-87ec-3e6d4699f3df", + "metadata": {}, + "outputs": [], + "source": [ + "from langchain.chat_models import ChatOpenAI\n", + "\n", + "chat = ChatOpenAI()" + ] + }, + { + "cell_type": "markdown", + "id": "4ca3a777-8641-42fb-9e02-a7770a633d29", + "metadata": {}, + "source": [ + "### Messages\n", + "\n", + "The chat model interface is based around messages rather than raw text.\n", + "The types of messages currently supported in LangChain are `AIMessage`, `HumanMessage`, `SystemMessage`, `FunctionMessage` and `ChatMessage` -- `ChatMessage` takes in an arbitrary role parameter. Most of the time, you'll just be dealing with `HumanMessage`, `AIMessage`, and `SystemMessage`" + ] + }, + { + "cell_type": "markdown", + "id": "54e5088f-98dd-437e-bac8-99b750946b29", + "metadata": {}, + "source": [ + "### LCEL\n", + "\n", + "Chat models implement the [Runnable interface](/docs/expression_language/interface), the basic building block of the [LangChain Expression Language (LCEL)](/docs/expression_language/). This means they support `invoke`, `ainvoke`, `stream`, `astream`, `batch`, `abatch`, `astream_log` calls.\n", + "\n", + "Chat models accept `List[BaseMessage]` as inputs, or objects which can be coerced to messages, including `str` (converted to `HumanMessage`) and `PromptValue`." + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "id": "64ab84bc-de67-45a9-b12f-17c30da32032", + "metadata": {}, + "outputs": [], + "source": [ + "from langchain.schema.messages import HumanMessage, SystemMessage\n", + "\n", + "messages = [\n", + " SystemMessage(content=\"You're a helpful assistant\"), \n", + " HumanMessage(content=\"What is the purpose of model regularization?\")\n", + "]" + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "id": "bde21756-19ab-4e63-ab50-dfb44b5bd44d", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "AIMessage(content=\"The purpose of model regularization is to prevent overfitting in machine learning models. Overfitting occurs when a model becomes too complex and starts to fit the noise in the training data, leading to poor generalization on unseen data. Regularization techniques introduce additional constraints or penalties to the model's objective function, discouraging it from becoming overly complex and promoting simpler and more generalizable models. Regularization helps to strike a balance between fitting the training data well and avoiding overfitting, leading to better performance on new, unseen data.\")" + ] + }, + "execution_count": 11, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "chat.invoke(messages)" + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "id": "cbac65af-0003-4b63-8a88-e9bc2fc0a345", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "The purpose of model regularization is to prevent overfitting and improve the generalization of a machine learning model. Overfitting occurs when a model is too complex and learns the noise or random variations in the training data, which leads to poor performance on new, unseen data. Regularization techniques introduce additional constraints or penalties to the model's learning process, discouraging it from fitting the noise and reducing the complexity of the model. This helps to improve the model's ability to generalize well and make accurate predictions on unseen data." + ] + } + ], + "source": [ + "for chunk in chat.stream(messages):\n", + " print(chunk.content, end=\"\", flush=True)" + ] + }, + { + "cell_type": "code", + "execution_count": 13, + "id": "0661ea53-bf38-44b1-8de9-0d5c6c31c5d2", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "[AIMessage(content=\"The purpose of model regularization is to prevent overfitting in machine learning models. Overfitting occurs when a model becomes too complex and starts to learn the noise or random fluctuations in the training data, rather than the underlying patterns or relationships. Regularization techniques add a penalty term to the model's objective function, which discourages the model from becoming too complex and helps it generalize better to new, unseen data. This improves the model's ability to make accurate predictions on new data by reducing the variance and increasing the model's overall performance.\")]" + ] + }, + "execution_count": 13, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "chat.batch([messages])" + ] + }, + { + "cell_type": "code", + "execution_count": 15, + "id": "a384fa49-55af-4044-9125-28f4d322766a", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "AIMessage(content='The purpose of model regularization is to prevent overfitting in machine learning models. Overfitting occurs when a model becomes too complex and starts to memorize the training data instead of learning general patterns and relationships. This leads to poor performance on new, unseen data.\\n\\nRegularization techniques introduce additional constraints or penalties to the model during training, discouraging it from becoming overly complex. This helps to strike a balance between fitting the training data well and generalizing to new data. Regularization techniques can include adding a penalty term to the loss function, such as L1 or L2 regularization, or using techniques like dropout or early stopping. By regularizing the model, it encourages it to learn the most relevant features and reduce the impact of noise or outliers in the data.')" + ] + }, + "execution_count": 15, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "await chat.ainvoke(messages)" + ] + }, + { + "cell_type": "code", + "execution_count": 16, + "id": "276ff472-18b0-4234-98e2-6cdcfeb6c3e7", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "The purpose of model regularization is to prevent overfitting in machine learning models. Overfitting occurs when a model becomes too complex and starts to memorize the training data instead of learning the underlying patterns. Regularization techniques help in reducing the complexity of the model by adding a penalty to the loss function. This penalty encourages the model to have smaller weights or fewer features, making it more generalized and less prone to overfitting. The goal is to find the right balance between fitting the training data well and being able to generalize well to unseen data." + ] + } + ], + "source": [ + "async for chunk in chat.astream(messages):\n", + " print(chunk.content, end=\"\", flush=True)" + ] + }, + { + "cell_type": "code", + "execution_count": 17, + "id": "3037dc67-da8a-419a-a65b-44dde2365838", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "RunLogPatch({'op': 'replace',\n", + " 'path': '',\n", + " 'value': {'final_output': None,\n", + " 'id': '754c4143-2348-46c4-ad2b-3095913084c6',\n", + " 'logs': {},\n", + " 'streamed_output': []}})\n", + "RunLogPatch({'op': 'add',\n", + " 'path': '/streamed_output/-',\n", + " 'value': AIMessageChunk(content='')})\n", + "RunLogPatch({'op': 'add',\n", + " 'path': '/streamed_output/-',\n", + " 'value': AIMessageChunk(content='The')})\n", + "RunLogPatch({'op': 'add',\n", + " 'path': '/streamed_output/-',\n", + " 'value': AIMessageChunk(content=' purpose')})\n", + "RunLogPatch({'op': 'add',\n", + " 'path': '/streamed_output/-',\n", + " 'value': AIMessageChunk(content=' of')})\n", + "RunLogPatch({'op': 'add',\n", + " 'path': '/streamed_output/-',\n", + " 'value': AIMessageChunk(content=' model')})\n", + "RunLogPatch({'op': 'add',\n", + " 'path': '/streamed_output/-',\n", + " 'value': AIMessageChunk(content=' regularization')})\n", + "RunLogPatch({'op': 'add',\n", + " 'path': '/streamed_output/-',\n", + " 'value': AIMessageChunk(content=' is')})\n", + "RunLogPatch({'op': 'add',\n", + " 'path': '/streamed_output/-',\n", + " 'value': AIMessageChunk(content=' to')})\n", + "RunLogPatch({'op': 'add',\n", + " 'path': '/streamed_output/-',\n", + " 'value': AIMessageChunk(content=' prevent')})\n", + "RunLogPatch({'op': 'add',\n", + " 'path': '/streamed_output/-',\n", + " 'value': AIMessageChunk(content=' a')})\n", + "RunLogPatch({'op': 'add',\n", + " 'path': '/streamed_output/-',\n", + " 'value': AIMessageChunk(content=' machine')})\n", + "RunLogPatch({'op': 'add',\n", + " 'path': '/streamed_output/-',\n", + " 'value': AIMessageChunk(content=' learning')})\n", + "RunLogPatch({'op': 'add',\n", + " 'path': '/streamed_output/-',\n", + " 'value': AIMessageChunk(content=' model')})\n", + "RunLogPatch({'op': 'add',\n", + " 'path': '/streamed_output/-',\n", + " 'value': AIMessageChunk(content=' from')})\n", + "RunLogPatch({'op': 'add',\n", + " 'path': '/streamed_output/-',\n", + " 'value': AIMessageChunk(content=' over')})\n", + "RunLogPatch({'op': 'add',\n", + " 'path': '/streamed_output/-',\n", + " 'value': AIMessageChunk(content='fit')})\n", + "RunLogPatch({'op': 'add',\n", + " 'path': '/streamed_output/-',\n", + " 'value': AIMessageChunk(content='ting')})\n", + "RunLogPatch({'op': 'add',\n", + " 'path': '/streamed_output/-',\n", + " 'value': AIMessageChunk(content=' the')})\n", + "RunLogPatch({'op': 'add',\n", + " 'path': '/streamed_output/-',\n", + " 'value': AIMessageChunk(content=' training')})\n", + "RunLogPatch({'op': 'add',\n", + " 'path': '/streamed_output/-',\n", + " 'value': AIMessageChunk(content=' data')})\n", + "RunLogPatch({'op': 'add',\n", + " 'path': '/streamed_output/-',\n", + " 'value': AIMessageChunk(content=' and')})\n", + "RunLogPatch({'op': 'add',\n", + " 'path': '/streamed_output/-',\n", + " 'value': AIMessageChunk(content=' improve')})\n", + "RunLogPatch({'op': 'add',\n", + " 'path': '/streamed_output/-',\n", + " 'value': AIMessageChunk(content=' its')})\n", + "RunLogPatch({'op': 'add',\n", + " 'path': '/streamed_output/-',\n", + " 'value': AIMessageChunk(content=' general')})\n", + "RunLogPatch({'op': 'add',\n", + " 'path': '/streamed_output/-',\n", + " 'value': AIMessageChunk(content='ization')})\n", + "RunLogPatch({'op': 'add',\n", + " 'path': '/streamed_output/-',\n", + " 'value': AIMessageChunk(content=' ability')})\n", + "RunLogPatch({'op': 'add',\n", + " 'path': '/streamed_output/-',\n", + " 'value': AIMessageChunk(content='.')})\n", + "RunLogPatch({'op': 'add',\n", + " 'path': '/streamed_output/-',\n", + " 'value': AIMessageChunk(content=' Over')})\n", + "RunLogPatch({'op': 'add',\n", + " 'path': '/streamed_output/-',\n", + " 'value': AIMessageChunk(content='fit')})\n", + "RunLogPatch({'op': 'add',\n", + " 'path': '/streamed_output/-',\n", + " 'value': AIMessageChunk(content='ting')})\n", + "RunLogPatch({'op': 'add',\n", + " 'path': '/streamed_output/-',\n", + " 'value': AIMessageChunk(content=' occurs')})\n", + "RunLogPatch({'op': 'add',\n", + " 'path': '/streamed_output/-',\n", + " 'value': AIMessageChunk(content=' when')})\n", + "RunLogPatch({'op': 'add',\n", + " 'path': '/streamed_output/-',\n", + " 'value': AIMessageChunk(content=' a')})\n", + "RunLogPatch({'op': 'add',\n", + " 'path': '/streamed_output/-',\n", + " 'value': AIMessageChunk(content=' model')})\n", + "RunLogPatch({'op': 'add',\n", + " 'path': '/streamed_output/-',\n", + " 'value': AIMessageChunk(content=' becomes')})\n", + "RunLogPatch({'op': 'add',\n", + " 'path': '/streamed_output/-',\n", + " 'value': AIMessageChunk(content=' too')})\n", + "RunLogPatch({'op': 'add',\n", + " 'path': '/streamed_output/-',\n", + " 'value': AIMessageChunk(content=' complex')})\n", + "RunLogPatch({'op': 'add',\n", + " 'path': '/streamed_output/-',\n", + " 'value': AIMessageChunk(content=' and')})\n", + "RunLogPatch({'op': 'add',\n", + " 'path': '/streamed_output/-',\n", + " 'value': AIMessageChunk(content=' learns')})\n", + "RunLogPatch({'op': 'add',\n", + " 'path': '/streamed_output/-',\n", + " 'value': AIMessageChunk(content=' to')})\n", + "RunLogPatch({'op': 'add',\n", + " 'path': '/streamed_output/-',\n", + " 'value': AIMessageChunk(content=' fit')})\n", + "RunLogPatch({'op': 'add',\n", + " 'path': '/streamed_output/-',\n", + " 'value': AIMessageChunk(content=' the')})\n", + "RunLogPatch({'op': 'add',\n", + " 'path': '/streamed_output/-',\n", + " 'value': AIMessageChunk(content=' noise')})\n", + "RunLogPatch({'op': 'add',\n", + " 'path': '/streamed_output/-',\n", + " 'value': AIMessageChunk(content=' or')})\n", + "RunLogPatch({'op': 'add',\n", + " 'path': '/streamed_output/-',\n", + " 'value': AIMessageChunk(content=' random')})\n", + "RunLogPatch({'op': 'add',\n", + " 'path': '/streamed_output/-',\n", + " 'value': AIMessageChunk(content=' fluctuations')})\n", + "RunLogPatch({'op': 'add',\n", + " 'path': '/streamed_output/-',\n", + " 'value': AIMessageChunk(content=' in')})\n", + "RunLogPatch({'op': 'add',\n", + " 'path': '/streamed_output/-',\n", + " 'value': AIMessageChunk(content=' the')})\n", + "RunLogPatch({'op': 'add',\n", + " 'path': '/streamed_output/-',\n", + " 'value': AIMessageChunk(content=' training')})\n", + "RunLogPatch({'op': 'add',\n", + " 'path': '/streamed_output/-',\n", + " 'value': AIMessageChunk(content=' data')})\n", + "RunLogPatch({'op': 'add',\n", + " 'path': '/streamed_output/-',\n", + " 'value': AIMessageChunk(content=',')})\n", + "RunLogPatch({'op': 'add',\n", + " 'path': '/streamed_output/-',\n", + " 'value': AIMessageChunk(content=' instead')})\n", + "RunLogPatch({'op': 'add',\n", + " 'path': '/streamed_output/-',\n", + " 'value': AIMessageChunk(content=' of')})\n", + "RunLogPatch({'op': 'add',\n", + " 'path': '/streamed_output/-',\n", + " 'value': AIMessageChunk(content=' capturing')})\n", + "RunLogPatch({'op': 'add',\n", + " 'path': '/streamed_output/-',\n", + " 'value': AIMessageChunk(content=' the')})\n", + "RunLogPatch({'op': 'add',\n", + " 'path': '/streamed_output/-',\n", + " 'value': AIMessageChunk(content=' underlying')})\n", + "RunLogPatch({'op': 'add',\n", + " 'path': '/streamed_output/-',\n", + " 'value': AIMessageChunk(content=' patterns')})\n", + "RunLogPatch({'op': 'add',\n", + " 'path': '/streamed_output/-',\n", + " 'value': AIMessageChunk(content=' and')})\n", + "RunLogPatch({'op': 'add',\n", + " 'path': '/streamed_output/-',\n", + " 'value': AIMessageChunk(content=' relationships')})\n", + "RunLogPatch({'op': 'add',\n", + " 'path': '/streamed_output/-',\n", + " 'value': AIMessageChunk(content='.')})\n", + "RunLogPatch({'op': 'add',\n", + " 'path': '/streamed_output/-',\n", + " 'value': AIMessageChunk(content=' Regular')})\n", + "RunLogPatch({'op': 'add',\n", + " 'path': '/streamed_output/-',\n", + " 'value': AIMessageChunk(content='ization')})\n", + "RunLogPatch({'op': 'add',\n", + " 'path': '/streamed_output/-',\n", + " 'value': AIMessageChunk(content=' techniques')})\n", + "RunLogPatch({'op': 'add',\n", + " 'path': '/streamed_output/-',\n", + " 'value': AIMessageChunk(content=' introduce')})\n", + "RunLogPatch({'op': 'add',\n", + " 'path': '/streamed_output/-',\n", + " 'value': AIMessageChunk(content=' a')})\n", + "RunLogPatch({'op': 'add',\n", + " 'path': '/streamed_output/-',\n", + " 'value': AIMessageChunk(content=' penalty')})\n", + "RunLogPatch({'op': 'add',\n", + " 'path': '/streamed_output/-',\n", + " 'value': AIMessageChunk(content=' term')})\n", + "RunLogPatch({'op': 'add',\n", + " 'path': '/streamed_output/-',\n", + " 'value': AIMessageChunk(content=' to')})\n", + "RunLogPatch({'op': 'add',\n", + " 'path': '/streamed_output/-',\n", + " 'value': AIMessageChunk(content=' the')})\n", + "RunLogPatch({'op': 'add',\n", + " 'path': '/streamed_output/-',\n", + " 'value': AIMessageChunk(content=' model')})\n", + "RunLogPatch({'op': 'add',\n", + " 'path': '/streamed_output/-',\n", + " 'value': AIMessageChunk(content=\"'s\")})\n", + "RunLogPatch({'op': 'add',\n", + " 'path': '/streamed_output/-',\n", + " 'value': AIMessageChunk(content=' objective')})\n", + "RunLogPatch({'op': 'add',\n", + " 'path': '/streamed_output/-',\n", + " 'value': AIMessageChunk(content=' function')})\n", + "RunLogPatch({'op': 'add',\n", + " 'path': '/streamed_output/-',\n", + " 'value': AIMessageChunk(content=',')})\n", + "RunLogPatch({'op': 'add',\n", + " 'path': '/streamed_output/-',\n", + " 'value': AIMessageChunk(content=' which')})\n", + "RunLogPatch({'op': 'add',\n", + " 'path': '/streamed_output/-',\n", + " 'value': AIMessageChunk(content=' discour')})\n", + "RunLogPatch({'op': 'add',\n", + " 'path': '/streamed_output/-',\n", + " 'value': AIMessageChunk(content='ages')})\n", + "RunLogPatch({'op': 'add',\n", + " 'path': '/streamed_output/-',\n", + " 'value': AIMessageChunk(content=' the')})\n", + "RunLogPatch({'op': 'add',\n", + " 'path': '/streamed_output/-',\n", + " 'value': AIMessageChunk(content=' model')})\n", + "RunLogPatch({'op': 'add',\n", + " 'path': '/streamed_output/-',\n", + " 'value': AIMessageChunk(content=' from')})\n", + "RunLogPatch({'op': 'add',\n", + " 'path': '/streamed_output/-',\n", + " 'value': AIMessageChunk(content=' becoming')})\n", + "RunLogPatch({'op': 'add',\n", + " 'path': '/streamed_output/-',\n", + " 'value': AIMessageChunk(content=' too')})\n", + "RunLogPatch({'op': 'add',\n", + " 'path': '/streamed_output/-',\n", + " 'value': AIMessageChunk(content=' complex')})\n", + "RunLogPatch({'op': 'add',\n", + " 'path': '/streamed_output/-',\n", + " 'value': AIMessageChunk(content='.')})\n", + "RunLogPatch({'op': 'add',\n", + " 'path': '/streamed_output/-',\n", + " 'value': AIMessageChunk(content=' This')})\n", + "RunLogPatch({'op': 'add',\n", + " 'path': '/streamed_output/-',\n", + " 'value': AIMessageChunk(content=' helps')})\n", + "RunLogPatch({'op': 'add',\n", + " 'path': '/streamed_output/-',\n", + " 'value': AIMessageChunk(content=' to')})\n", + "RunLogPatch({'op': 'add',\n", + " 'path': '/streamed_output/-',\n", + " 'value': AIMessageChunk(content=' control')})\n", + "RunLogPatch({'op': 'add',\n", + " 'path': '/streamed_output/-',\n", + " 'value': AIMessageChunk(content=' the')})\n", + "RunLogPatch({'op': 'add',\n", + " 'path': '/streamed_output/-',\n", + " 'value': AIMessageChunk(content=' model')})\n", + "RunLogPatch({'op': 'add',\n", + " 'path': '/streamed_output/-',\n", + " 'value': AIMessageChunk(content=\"'s\")})\n", + "RunLogPatch({'op': 'add',\n", + " 'path': '/streamed_output/-',\n", + " 'value': AIMessageChunk(content=' complexity')})\n", + "RunLogPatch({'op': 'add',\n", + " 'path': '/streamed_output/-',\n", + " 'value': AIMessageChunk(content=' and')})\n", + "RunLogPatch({'op': 'add',\n", + " 'path': '/streamed_output/-',\n", + " 'value': AIMessageChunk(content=' reduces')})\n", + "RunLogPatch({'op': 'add',\n", + " 'path': '/streamed_output/-',\n", + " 'value': AIMessageChunk(content=' the')})\n", + "RunLogPatch({'op': 'add',\n", + " 'path': '/streamed_output/-',\n", + " 'value': AIMessageChunk(content=' risk')})\n", + "RunLogPatch({'op': 'add',\n", + " 'path': '/streamed_output/-',\n", + " 'value': AIMessageChunk(content=' of')})\n", + "RunLogPatch({'op': 'add',\n", + " 'path': '/streamed_output/-',\n", + " 'value': AIMessageChunk(content=' over')})\n", + "RunLogPatch({'op': 'add',\n", + " 'path': '/streamed_output/-',\n", + " 'value': AIMessageChunk(content='fit')})\n", + "RunLogPatch({'op': 'add',\n", + " 'path': '/streamed_output/-',\n", + " 'value': AIMessageChunk(content='ting')})\n", + "RunLogPatch({'op': 'add',\n", + " 'path': '/streamed_output/-',\n", + " 'value': AIMessageChunk(content=',')})\n", + "RunLogPatch({'op': 'add',\n", + " 'path': '/streamed_output/-',\n", + " 'value': AIMessageChunk(content=' leading')})\n", + "RunLogPatch({'op': 'add',\n", + " 'path': '/streamed_output/-',\n", + " 'value': AIMessageChunk(content=' to')})\n", + "RunLogPatch({'op': 'add',\n", + " 'path': '/streamed_output/-',\n", + " 'value': AIMessageChunk(content=' better')})\n", + "RunLogPatch({'op': 'add',\n", + " 'path': '/streamed_output/-',\n", + " 'value': AIMessageChunk(content=' performance')})\n", + "RunLogPatch({'op': 'add',\n", + " 'path': '/streamed_output/-',\n", + " 'value': AIMessageChunk(content=' on')})\n", + "RunLogPatch({'op': 'add',\n", + " 'path': '/streamed_output/-',\n", + " 'value': AIMessageChunk(content=' unseen')})\n", + "RunLogPatch({'op': 'add',\n", + " 'path': '/streamed_output/-',\n", + " 'value': AIMessageChunk(content=' data')})\n", + "RunLogPatch({'op': 'add',\n", + " 'path': '/streamed_output/-',\n", + " 'value': AIMessageChunk(content='.')})\n", + "RunLogPatch({'op': 'add',\n", + " 'path': '/streamed_output/-',\n", + " 'value': AIMessageChunk(content='')})\n", + "RunLogPatch({'op': 'replace',\n", + " 'path': '/final_output',\n", + " 'value': {'generations': [[{'generation_info': {'finish_reason': 'stop'},\n", + " 'message': AIMessageChunk(content=\"The purpose of model regularization is to prevent a machine learning model from overfitting the training data and improve its generalization ability. Overfitting occurs when a model becomes too complex and learns to fit the noise or random fluctuations in the training data, instead of capturing the underlying patterns and relationships. Regularization techniques introduce a penalty term to the model's objective function, which discourages the model from becoming too complex. This helps to control the model's complexity and reduces the risk of overfitting, leading to better performance on unseen data.\"),\n", + " 'text': 'The purpose of model regularization is '\n", + " 'to prevent a machine learning model '\n", + " 'from overfitting the training data and '\n", + " 'improve its generalization ability. '\n", + " 'Overfitting occurs when a model becomes '\n", + " 'too complex and learns to fit the noise '\n", + " 'or random fluctuations in the training '\n", + " 'data, instead of capturing the '\n", + " 'underlying patterns and relationships. '\n", + " 'Regularization techniques introduce a '\n", + " \"penalty term to the model's objective \"\n", + " 'function, which discourages the model '\n", + " 'from becoming too complex. This helps '\n", + " \"to control the model's complexity and \"\n", + " 'reduces the risk of overfitting, '\n", + " 'leading to better performance on unseen '\n", + " 'data.'}]],\n", + " 'llm_output': None,\n", + " 'run': None}})\n" + ] + } + ], + "source": [ + "async for chunk in chat.astream_log(messages):\n", + " print(chunk)" + ] + }, + { + "cell_type": "markdown", + "id": "7b289727-3983-43f7-a8b2-dd5582d49b6a", + "metadata": {}, + "source": [ + "### `__call__`\n", + "#### Messages in -> message out\n", + "\n", + "For convenience you can also treat chat models as callables. You can get chat completions by passing one or more messages to the chat model. The response will be a message." + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "id": "e3d59f6f-176c-4d63-9b0e-8f3018810ecd", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "AIMessage(content=\"J'adore la programmation.\")" + ] + }, + "execution_count": 2, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "from langchain.schema import (\n", + " AIMessage,\n", + " HumanMessage,\n", + " SystemMessage\n", + ")\n", + "\n", + "chat([HumanMessage(content=\"Translate this sentence from English to French: I love programming.\")])" + ] + }, + { + "cell_type": "markdown", + "id": "ffa2968e-3a7e-4139-a13f-5364e6525d2a", + "metadata": {}, + "source": [ + "OpenAI's chat model supports multiple messages as input. See [here](https://platform.openai.com/docs/guides/chat/chat-vs-completions) for more information. Here is an example of sending a system and user message to the chat model:" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "id": "89227e01-8d59-4aa2-8530-c1b28a5c4beb", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "AIMessage(content=\"J'adore la programmation.\")" + ] + }, + "execution_count": 3, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "messages = [\n", + " SystemMessage(content=\"You are a helpful assistant that translates English to French.\"),\n", + " HumanMessage(content=\"I love programming.\")\n", + "]\n", + "chat(messages)\n" + ] + }, + { + "cell_type": "markdown", + "id": "2b996c69-fd5d-4889-af4a-19dfd2833021", + "metadata": {}, + "source": [ + "### `generate`\n", + "#### Batch calls, richer outputs\n", + "\n", + "You can go one step further and generate completions for multiple sets of messages using `generate`. This returns an `LLMResult` with an additional `message` parameter. This will include additional information about each generation beyond the returned message (e.g. the finish reason) and additional information about the full API call (e.g. total tokens used)." + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "id": "9b610194-5ccd-4c41-8125-24aa7d50ed38", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "LLMResult(generations=[[ChatGeneration(text=\"J'adore programmer.\", generation_info={'finish_reason': 'stop'}, message=AIMessage(content=\"J'adore programmer.\"))], [ChatGeneration(text=\"J'adore l'intelligence artificielle.\", generation_info={'finish_reason': 'stop'}, message=AIMessage(content=\"J'adore l'intelligence artificielle.\"))]], llm_output={'token_usage': {'prompt_tokens': 53, 'completion_tokens': 18, 'total_tokens': 71}, 'model_name': 'gpt-3.5-turbo'}, run=[RunInfo(run_id=UUID('077917a9-026c-47c4-b308-77b37c3a3bfa')), RunInfo(run_id=UUID('0a70a0bf-c599-4f51-932a-c7d42202c984'))])" + ] + }, + "execution_count": 4, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "batch_messages = [\n", + " [\n", + " SystemMessage(content=\"You are a helpful assistant that translates English to French.\"),\n", + " HumanMessage(content=\"I love programming.\")\n", + " ],\n", + " [\n", + " SystemMessage(content=\"You are a helpful assistant that translates English to French.\"),\n", + " HumanMessage(content=\"I love artificial intelligence.\")\n", + " ],\n", + "]\n", + "result = chat.generate(batch_messages)\n", + "result" + ] + }, + { + "cell_type": "markdown", + "id": "c3c289a4-9e1b-483c-a7f8-7f430da74b1e", + "metadata": {}, + "source": [ + "You can recover things like token usage from this LLMResult:" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "id": "2ecf2c7e-935f-42c8-9c5f-9ca08e214f40", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "{'token_usage': {'prompt_tokens': 53,\n", + " 'completion_tokens': 18,\n", + " 'total_tokens': 71},\n", + " 'model_name': 'gpt-3.5-turbo'}" + ] + }, + "execution_count": 5, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "result.llm_output" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "poetry-venv", + "language": "python", + "name": "poetry-venv" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.9.1" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/docs/docs/modules/model_io/models/chat/index.mdx b/docs/docs/modules/model_io/models/chat/index.mdx deleted file mode 100644 index f6d7f1e95c..0000000000 --- a/docs/docs/modules/model_io/models/chat/index.mdx +++ /dev/null @@ -1,137 +0,0 @@ ---- -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 use is a bit different. -Rather than using a "text in, text out" API, they use 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. - -## Get started - -### Setup - -To start we'll need to install the OpenAI Python package: - -```bash -pip install openai -``` - -Accessing the API requires an API key, which you can get by creating an account and heading [here](https://platform.openai.com/account/api-keys). Once we have a key we'll want to set it as an environment variable by running: - -```bash -export OPENAI_API_KEY="..." -``` -If you'd prefer not to set an environment variable you can pass the key in directly via the `openai_api_key` named parameter when initiating the OpenAI LLM class: - -```python -from langchain.chat_models import ChatOpenAI - -chat = ChatOpenAI(openai_api_key="...") -``` - -Otherwise you can initialize without any params: -```python -from langchain.chat_models import ChatOpenAI - -chat = ChatOpenAI() -``` - -### Messages - -The chat model interface is based around messages rather than raw text. -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` - -### `__call__` -#### Messages in -> message out - -You can get chat completions by passing one or more messages to the chat model. The response will be a message. - -```python -from langchain.schema import ( - AIMessage, - HumanMessage, - SystemMessage -) - -chat([HumanMessage(content="Translate this sentence from English to French: I love programming.")]) -``` - - - -``` - AIMessage(content="J'aime programmer.", additional_kwargs={}) -``` - - - -OpenAI's chat model supports multiple messages as input. See [here](https://platform.openai.com/docs/guides/chat/chat-vs-completions) for more information. Here is an example of sending a system and user message to the chat model: - - -```python -messages = [ - SystemMessage(content="You are a helpful assistant that translates English to French."), - HumanMessage(content="I love programming.") -] -chat(messages) -``` - - - -``` - AIMessage(content="J'aime programmer.", additional_kwargs={}) -``` - - - -### `generate` -#### Batch calls, richer outputs - -You can go one step further and generate completions for multiple sets of messages using `generate`. This returns an `LLMResult` with an additional `message` parameter. - -```python -batch_messages = [ - [ - SystemMessage(content="You are a helpful assistant that translates English to French."), - HumanMessage(content="I love programming.") - ], - [ - SystemMessage(content="You are a helpful assistant that translates English to French."), - HumanMessage(content="I love artificial intelligence.") - ], -] -result = chat.generate(batch_messages) -result -``` - - - -``` - LLMResult(generations=[[ChatGeneration(text="J'aime programmer.", generation_info=None, message=AIMessage(content="J'aime programmer.", additional_kwargs={}))], [ChatGeneration(text="J'aime l'intelligence artificielle.", generation_info=None, message=AIMessage(content="J'aime l'intelligence artificielle.", additional_kwargs={}))]], llm_output={'token_usage': {'prompt_tokens': 57, 'completion_tokens': 20, 'total_tokens': 77}}) -``` - - - -You can recover things like token usage from this LLMResult: - - -```python -result.llm_output -``` - - - -``` - {'token_usage': {'prompt_tokens': 57, - 'completion_tokens': 20, - 'total_tokens': 77}} -``` - - -