内容审核# – LangChain中文网

6大核心模块（Modules)链（Chains)示例（Examples）审查（Moderation）

内容审核#
本文档介绍如何使用内容审核链，以及几种常见的使用方式。内容审核链可用于检测可能具有仇恨、暴力等内容的文本。这对于对用户输入以及语言模型的输出都很有用。一些API提供商（如OpenAI)明确禁止 (opens in a new tab)您或您的最终用户生成某些类型的有害内容。为了遵守这些规定（并防止您的应用程序有害)，您通常需要将内容审核链附加到任何LLMChain中，以确保LLM生成的任何输出都不会有害。
如果传入内容审核链的内容有害，处理它可能没有最佳的方法，这可能取决于您的应用程序。有时您可能想在链中抛出一个错误（并让您的应用程序处理它)。其他时候，您可能想向用户返回一些解释说该文本是有害的。甚至可能有其他处理方式！本文档将涵盖所有这些方式。
本文档将展示：

如何通过内容审核链运行任何文本片段。

如何将内容审核链附加到LLMChain中。

```code
from langchain.llms import OpenAI
from langchain.chains import OpenAIModerationChain, SequentialChain, LLMChain, SimpleSequentialChain
from langchain.prompts import PromptTemplate

```

如何使用Moderation Chain#
以下是一个使用默认设置的Moderation Chain的示例（将返回一个解释已被标记的字符串)。

```code
moderation_chain = OpenAIModerationChain()

```

```code
moderation_chain.run("This is okay")

```

```code
'This is okay'

```

```code
moderation_chain.run("I will kill you")

```

```code
"Text was found that violates OpenAI's content policy."

```

以下是一个使用Moderation Chain抛出错误的示例。

```code
moderation_chain_error = OpenAIModerationChain(error=True)

```

```code
moderation_chain_error.run("This is okay")

```

```code
'This is okay'

```

```code
moderation_chain_error.run("I will kill you")

```

```code
---------------------------------------------------------------------------
ValueError Traceback (most recent call last)
Cell In[7], line 1
----> 1 moderation_chain_error.run("I will kill you")

File ~/workplace/langchain/langchain/chains/base.py:138, in Chain.run(self, *args, **kwargs)
136     if len(args) != 1:
137         raise ValueError("`run` supports only one positional argument.")
--> 138     return self(args[0])[self.output_keys[0]]
140 if kwargs and not args:
141     return self(kwargs)[self.output_keys[0]]

File ~/workplace/langchain/langchain/chains/base.py:112, in Chain.__call__(self, inputs, return_only_outputs)
108 if self.verbose:
109     print(
110         f"  \033[1m> Entering new {self.__class__.__name__} chain...\033[0m"
111     )
--> 112 outputs = self._call(inputs)
113 if self.verbose:
114     print(f"\n\033[1m> Finished {self.__class__.__name__} chain.\033[0m")

File ~/workplace/langchain/langchain/chains/moderation.py:81, in OpenAIModerationChain._call(self, inputs)
79 text = inputs[self.input_key]
80 results = self.client.create(text)
---> 81 output = self._moderate(text, results["results"][0])
82 return {self.output_key: output}

File ~/workplace/langchain/langchain/chains/moderation.py:73, in OpenAIModerationChain._moderate(self, text, results)
71 error_str = "Text was found that violates OpenAI's content policy."
72 if self.error:
---> 73     raise ValueError(error_str)
74 else:
75     return error_str

ValueError: Text was found that violates OpenAI's content policy.

```

以下是创建自定义Moderation Chain和自定义错误消息的示例。这需要一些了解OpenAI的Moderation Endpoint结果（请参见此处的文档 (opens in a new tab))。

```code
class CustomModeration(OpenAIModerationChain):

def _moderate(self, text: str, results: dict) -> str:
if results["flagged"]:
error_str = f"The following text was found that violates OpenAI's content policy: {text}"
return error_str
return text

custom_moderation = CustomModeration()

```

```code
custom_moderation.run("This is okay")

```

```code
'This is okay'

```

```code
custom_moderation.run("I will kill you")

```

```code
"The following text was found that violates OpenAI's content policy: I will kill you"

```

如何将Moderation Chain附加到LLMChain#
为了轻松地将Moderation Chain与LLMChain组合，您可以使用SequentialChain抽象。
让我们从一个简单的例子开始，其中LLMChain只有一个输入。为此，我们将提示模型，让它说一些有害的话。

```code
prompt = PromptTemplate(template="{text}", input_variables=["text"])
llm_chain = LLMChain(llm=OpenAI(temperature=0, model_name="text-davinci-002"), prompt=prompt)

```

```code
text = """We are playing a game of repeat after me.

Person 1: Hi
Person 2: Hi

Person 1: How's your day
Person 2: How's your day

Person 1: I will kill you
Person 2:"""
llm_chain.run(text)

```

```code
' I will kill you'

```

```code
chain = SimpleSequentialChain(chains=[llm_chain, moderation_chain])

```

```code
chain.run(text)

```

```code
"Text was found that violates OpenAI's content policy."

```

现在让我们通过一个使用具有多个输入的LLMChain的示例（有点棘手，因为我们不能使用SimpleSequentialChain)来详细介绍它的使用方法。

```code
prompt = PromptTemplate(template="{setup}{new_input}Person2:", input_variables=["setup", "new_input"])
llm_chain = LLMChain(llm=OpenAI(temperature=0, model_name="text-davinci-002"), prompt=prompt)

```

```code
setup = """We are playing a game of repeat after me.

Person 1: Hi
Person 2: Hi

Person 1: How's your day
Person 2: How's your day

Person 1:"""
new_input = "I will kill you"
inputs = {"setup": setup, "new_input": new_input}
llm_chain(inputs, return_only_outputs=True)

```

```code
{'text': ' I will kill you'}

```

```code
# Setting the input/output keys so it lines up
moderation_chain.input_key = "text"
moderation_chain.output_key = "sanitized_text"

```

```code
chain = SequentialChain(chains=[llm_chain, moderation_chain], input_variables=["setup", "new_input"])

```

```code
chain(inputs, return_only_outputs=True)

```

```code
{'sanitized_text': "Text was found that violates OpenAI's content policy."}

```
LLM 摘要检查器（LLM Summarization Checker）OpenAPI


PAL# – LangChain中文网

6大核心模块（Modules)链（Chains)示例（Examples）PAL

PAL#
实现了程序辅助的语言模型，例如 https://arxiv.org/pdf/2211.10435.pdf。 (opens in a new tab)

```code
from langchain.chains import PALChain
from langchain import OpenAI

```

```code
llm = OpenAI(temperature=0, max_tokens=512)

```

数学提示#

```code
pal_chain = PALChain.from_math_prompt(llm, verbose=True)

```

```code
question = "Jan has three times the number of pets as Marcia. Marcia has two more pets than Cindy. If Cindy has four pets, how many total pets do the three have?"

```

```code
pal_chain.run(question)

```

```code
> Entering new PALChain chain...
def solution():
"""Jan has three times the number of pets as Marcia. Marcia has two more pets than Cindy. If Cindy has four pets, how many total pets do the three have?"""
cindy_pets = 4
marcia_pets = cindy_pets + 2
jan_pets = marcia_pets * 3
total_pets = cindy_pets + marcia_pets + jan_pets
result = total_pets
return result

> Finished chain.

```

```code
'28'

```

彩色物体#

```code
pal_chain = PALChain.from_colored_object_prompt(llm, verbose=True)

```

```code
question = "On the desk, you see two blue booklets, two purple booklets, and two yellow pairs of sunglasses. If I remove all the pairs of sunglasses from the desk, how many purple items remain on it?"

```

```code
pal_chain.run(question)

```

```code
> Entering new PALChain chain...
# Put objects into a list to record ordering
objects = []
objects += [('booklet', 'blue')] * 2
objects += [('booklet', 'purple')] * 2
objects += [('sunglasses', 'yellow')] * 2

# Remove all pairs of sunglasses
objects = [object for object in objects if object[0] != 'sunglasses']

# Count number of purple objects
num_purple = len([object for object in objects if object[1] == 'purple'])
answer = num_purple

> Finished PALChain chain.

```

```code
'2'

```

中间步骤#
你还可以使用中间步骤标志来返回生成答案的代码。

```code
pal_chain = PALChain.from_colored_object_prompt(llm, verbose=True, return_intermediate_steps=True)

```

```code
question = "On the desk, you see two blue booklets, two purple booklets, and two yellow pairs of sunglasses. If I remove all the pairs of sunglasses from the desk, how many purple items remain on it?"

```

```code
result = pal_chain({"question": question})

```

```code
> Entering new PALChain chain...
# Put objects into a list to record ordering
objects = []
objects += [('booklet', 'blue')] * 2
objects += [('booklet', 'purple')] * 2
objects += [('sunglasses', 'yellow')] * 2

# Remove all pairs of sunglasses
objects = [object for object in objects if object[0] != 'sunglasses']

# Count number of purple objects
num_purple = len([object for object in objects if object[1] == 'purple'])
answer = num_purple

> Finished chain.

```

```code
result['intermediate_steps']

```

```code
"# Put objects into a list to record ordering\nobjects = []\nobjects += [('booklet', 'blue')] * 2\nobjects += [('booklet', 'purple')] * 2\nobjects += [('sunglasses', 'yellow')] * 2  # Remove all pairs of sunglasses\nobjects = [object for object in objects if object[0] != 'sunglasses']  # Count number of purple objects\nnum_purple = len([object for object in objects if object[1] == 'purple'])\nanswer = num_purple"

```
OpenAPISQLite


用 SQLDatabaseChain 对数据库进行问答 – LangChain中文网

6大核心模块（Modules)链（Chains)示例（Examples）SQLite

用
```code
SQLDatabaseChain
```
对数据库进行问答
此示例演示了使用
```code
SQLDatabaseChain
```
对数据库进行问答。
在后台，LangChain 使用 SQLAlchemy 连接 SQL 数据库。因此，
```code
SQLDatabaseChain
```
可以与 SQLAlchemy 支持的任何 SQL 方言一起使用，例如 MS SQL、MySQL、MariaDB、PostgreSQL、Oracle SQL 和 SQLite。请参阅 SQLAlchemy 文档，了解有关连接到数据库的要求的更多信息。例如，连接到 MySQL 需要适当的连接器，如 PyMySQL。MySQL 连接的 URI 可能如下所示：
```code
mysql+pymysql://user:pass@some_mysql_db_address/db_name
```

此演示使用 SQLite 和示例 Chinook 数据库。
要设置它，请按照 https://database.guide/2-sample-databases-sqlite/ (opens in a new tab) 上的说明，在此存储库的根目录下的 notebooks 文件夹中放置
```code
.db
```
文件。

```code
from langchain import OpenAI, SQLDatabase, SQLDatabaseChain

```

```code
db = SQLDatabase.from_uri("sqlite:///../../../../notebooks/Chinook.db")
llm = OpenAI(temperature=0)

```

NOTE: For data-sensitive projects, you can specify
```code
return_direct=True
```
in the
```code
SQLDatabaseChain
```
initialization to directly return the output of the SQL query without any additional formatting. This prevents the LLM from seeing any contents within the database. Note, however, the LLM still has access to the database scheme (i.e. dialect, table and key names) by default.

```code
db_chain = SQLDatabaseChain.from_llm(llm, db, verbose=True)

```

```code
db_chain.run("How many employees are there?")

```

```code
> Entering new SQLDatabaseChain chain...
How many employees are there?
SQLQuery:

```

```code
/Users/harrisonchase/workplace/langchain/langchain/sql_database.py:120: SAWarning: Dialect sqlite+pysqlite does *not* support Decimal objects natively, and SQLAlchemy must convert from floating point - rounding errors and other issues may occur. Please consider storing Decimal numbers as strings or integers on this platform for lossless storage.
sample_rows = connection.execute(command)

```

```code
SELECT COUNT(*) FROM Employee;
SQLResult: [(8,)]
Answer: There are 8 employees.
> Finished chain.

```

```code
' There are 8 employees.'

```

Customize Prompt#
You can also customize the prompt that is used. Here is an example prompting it to understand that foobar is the same as the Employee table

```code
from langchain.prompts.prompt import PromptTemplate

_DEFAULT_TEMPLATE = """Given an input question, first create a syntactically correct {dialect} query to run, then look at the results of the query and return the answer.
Use the following format:

Question: "Question here"
SQLQuery: "SQL Query to run"
SQLResult: "Result of the SQLQuery"
Answer: "Final answer here"

Only use the following tables:

{table_info}

If someone asks for the table foobar, they really mean the employee table.

Question: {input}"""
PROMPT = PromptTemplate(
input_variables=["input", "table_info", "dialect"], template=_DEFAULT_TEMPLATE
)

```

```code
db_chain = SQLDatabaseChain.from_llm(llm, db, prompt=PROMPT, verbose=True)

```

```code
db_chain.run("How many employees are there in the foobar table?")

```

```code
> Entering new SQLDatabaseChain chain...
How many employees are there in the foobar table?
SQLQuery: SELECT COUNT(*) FROM Employee;
SQLResult: [(8,)]
Answer: There are 8 employees in the foobar table.
> Finished chain.

```

```code
' There are 8 employees in the foobar table.'

```

Return Intermediate Steps#
You can also return the intermediate steps of the SQLDatabaseChain. This allows you to access the SQL statement that was generated, as well as the result of running that against the SQL Database.

```code
db_chain = SQLDatabaseChain.from_llm(llm, db, prompt=PROMPT, verbose=True, return_intermediate_steps=True)

```

```code
result = db_chain("How many employees are there in the foobar table?")
result["intermediate_steps"]

```

```code
> Entering new SQLDatabaseChain chain...
How many employees are there in the foobar table?
SQLQuery: SELECT COUNT(*) FROM Employee;
SQLResult: [(8,)]
Answer: There are 8 employees in the foobar table.
> Finished chain.

```

```code
[' SELECT COUNT(*) FROM Employee;', '[(8,)]']

```

Choosing how to limit the number of rows returned#
If you are querying for several rows of a table you can select the maximum number of results you want to get by using the ‘top_k’ parameter (default is 10). This is useful for avoiding query results that exceed the prompt max length or consume tokens unnecessarily.

```code
db_chain = SQLDatabaseChain.from_llm(llm, db, verbose=True, top_k=3)

```

```code
db_chain.run("What are some example tracks by composer Johann Sebastian Bach?")

```

```code
> Entering new SQLDatabaseChain chain...
What are some example tracks by composer Johann Sebastian Bach?
SQLQuery: SELECT Name, Composer FROM Track WHERE Composer LIKE '%Johann Sebastian Bach%' LIMIT 3;
SQLResult: [('Concerto for 2 Violins in D Minor, BWV 1043: I. Vivace', 'Johann Sebastian Bach'), ('Aria Mit 30 Veränderungen, BWV 988 "Goldberg Variations": Aria', 'Johann Sebastian Bach'), ('Suite for Solo Cello No. 1 in G Major, BWV 1007: I. Prélude', 'Johann Sebastian Bach')]
Answer: Some example tracks by composer Johann Sebastian Bach are 'Concerto for 2 Violins in D Minor, BWV 1043: I. Vivace', 'Aria Mit 30 Veränderungen, BWV 988 "Goldberg Variations": Aria', and 'Suite for Solo Cello No. 1 in G Major, BWV 1007: I. Prélude'.
> Finished chain.

```

```code
' Some example tracks by composer Johann Sebastian Bach are \'Concerto for 2 Violins in D Minor, BWV 1043: I. Vivace\', \'Aria Mit 30 Veränderungen, BWV 988 "Goldberg Variations": Aria\', and \'Suite for Solo Cello No. 1 in G Major, BWV 1007: I. Prélude\'.'

```

Adding example rows from each table#
Sometimes, the format of the data is not obvious and it is optimal to include a sample of rows from the tables in the prompt to allow the LLM to understand the data before providing a final query. Here we will use this feature to let the LLM know that artists are saved with their full names by providing two rows from the
```code
Track
```
table.

```code
db = SQLDatabase.from_uri(
"sqlite:///../../../../notebooks/Chinook.db",
include_tables=['Track'], # we include only one table to save tokens in the prompt :)
sample_rows_in_table_info=2)

```

The sample rows are added to the prompt after each corresponding table’s column information:

```code
print(db.table_info)

```

```code
CREATE TABLE "Track" (
"TrackId" INTEGER NOT NULL,
"Name" NVARCHAR(200) NOT NULL,
"AlbumId" INTEGER,
"MediaTypeId" INTEGER NOT NULL,
"GenreId" INTEGER,
"Composer" NVARCHAR(220),
"Milliseconds" INTEGER NOT NULL,
"Bytes" INTEGER,
"UnitPrice" NUMERIC(10, 2) NOT NULL,
PRIMARY KEY ("TrackId"),
FOREIGN KEY("MediaTypeId") REFERENCES "MediaType" ("MediaTypeId"),
FOREIGN KEY("GenreId") REFERENCES "Genre" ("GenreId"),
FOREIGN KEY("AlbumId") REFERENCES "Album" ("AlbumId")
)
/*
2 rows from Track table:
TrackIdNameAlbumIdMediaTypeIdGenreIdComposerMillisecondsBytesUnitPrice
1For Those About To Rock (We Salute You)111Angus Young, Malcolm Young, Brian Johnson343719111703340.99
2Balls to the Wall221None34256255104240.99
*/

```

```code
/home/jon/projects/langchain/langchain/sql_database.py:135: SAWarning: Dialect sqlite+pysqlite does *not* support Decimal objects natively, and SQLAlchemy must convert from floating point - rounding errors and other issues may occur. Please consider storing Decimal numbers as strings or integers on this platform for lossless storage.
sample_rows = connection.execute(command)

```

```code
db_chain = SQLDatabaseChain.from_llm(llm, db, verbose=True)

```

```code
db_chain.run("What are some example tracks by Bach?")

```

```code
> Entering new SQLDatabaseChain chain...
What are some example tracks by Bach?
SQLQuery: SELECT Name FROM Track WHERE Composer LIKE '%Bach%' LIMIT 5;
SQLResult: [('American Woman',), ('Concerto for 2 Violins in D Minor, BWV 1043: I. Vivace',), ('Aria Mit 30 Veränderungen, BWV 988 "Goldberg Variations": Aria',), ('Suite for Solo Cello No. 1 in G Major, BWV 1007: I. Prélude',), ('Toccata and Fugue in D Minor, BWV 565: I. Toccata',)]
Answer: Some example tracks by Bach are 'American Woman', 'Concerto for 2 Violins in D Minor, BWV 1043: I. Vivace', 'Aria Mit 30 Veränderungen, BWV 988 "Goldberg Variations": Aria', 'Suite for Solo Cello No. 1 in G Major, BWV 1007: I. Prélude', and 'Toccata and Fugue in D Minor, BWV 565: I. Toccata'.
> Finished chain.

```

```code
' Some example tracks by Bach are \'American Woman\', \'Concerto for 2 Violins in D Minor, BWV 1043: I. Vivace\', \'Aria Mit 30 Veränderungen, BWV 988 "Goldberg Variations": Aria\', \'Suite for Solo Cello No. 1 in G Major, BWV 1007: I. Prélude\', and \'Toccata and Fugue in D Minor, BWV 565: I. Toccata\'.'

```

Custom Table Info#
In some cases, it can be useful to provide custom table information instead of using the automatically generated table definitions and the first
```code
sample_rows_in_table_info
```
sample rows. For example, if you know that the first few rows of a table are uninformative, it could help to manually provide example rows that are more diverse or provide more information to the model. It is also possible to limit the columns that will be visible to the model if there are unnecessary columns.
可以将此信息作为字典提供，其中表名为键，表信息为值。例如，让我们为只有几列的 Track 表提供自定义定义和示例行：

```code
custom_table_info = {
"Track": """CREATE TABLE Track (
"TrackId" INTEGER NOT NULL,
"Name" NVARCHAR(200) NOT NULL,
"Composer" NVARCHAR(220),
PRIMARY KEY ("TrackId")
)
/*
3 rows from Track table:
TrackId Name Composer
1 For Those About To Rock (We Salute You) Angus Young, Malcolm Young, Brian Johnson
2 Balls to the Wall None
3 My favorite song ever The coolest composer of all time
*/"""
}

```

```code
db = SQLDatabase.from_uri(
"sqlite:///../../../../notebooks/Chinook.db",
include_tables=['Track', 'Playlist'],
sample_rows_in_table_info=2,
custom_table_info=custom_table_info)

print(db.table_info)

```

```code
CREATE TABLE "Playlist" (
"PlaylistId" INTEGER NOT NULL,
"Name" NVARCHAR(120),
PRIMARY KEY ("PlaylistId")
)
/*
2 rows from Playlist table:
PlaylistIdName
1Music
2Movies
*/

CREATE TABLE Track (
"TrackId" INTEGER NOT NULL,
"Name" NVARCHAR(200) NOT NULL,
"Composer" NVARCHAR(220),
PRIMARY KEY ("TrackId")
)
/*
3 rows from Track table:
TrackIdNameComposer
1For Those About To Rock (We Salute You)Angus Young, Malcolm Young, Brian Johnson
2Balls to the WallNone
3My favorite song everThe coolest composer of all time
*/

```

注意，我们自定义的 Track 表定义和示例行覆盖了 sample_rows_in_table_info 参数。未被 custom_table_info 覆盖的表，在本例中为 Playlist，将像往常一样自动收集其表信息。

```code
db_chain = SQLDatabaseChain.from_llm(llm, db, verbose=True)
db_chain.run("What are some example tracks by Bach?")

```

```code
> Entering new SQLDatabaseChain chain...
What are some example tracks by Bach?
SQLQuery: SELECT Name, Composer FROM Track WHERE Composer LIKE '%Bach%' LIMIT 5;
SQLResult: [('American Woman', 'B. Cummings/G. Peterson/M.J. Kale/R. Bachman'), ('Concerto for 2 Violins in D Minor, BWV 1043: I. Vivace', 'Johann Sebastian Bach'), ('Aria Mit 30 Veränderungen, BWV 988 "Goldberg Variations": Aria', 'Johann Sebastian Bach'), ('Suite for Solo Cello No. 1 in G Major, BWV 1007: I. Prélude', 'Johann Sebastian Bach'), ('Toccata and Fugue in D Minor, BWV 565: I. Toccata', 'Johann Sebastian Bach')]
Answer: Some example tracks by Bach are 'American Woman', 'Concerto for 2 Violins in D Minor, BWV 1043: I. Vivace', 'Aria Mit 30 Veränderungen, BWV 988 "Goldberg Variations": Aria', 'Suite for Solo Cello No. 1 in G Major, BWV 1007: I. Prélude', and 'Toccata and Fugue in D Minor, BWV 565: I. Toccata'.
> Finished chain.

```

```code
' Some example tracks by Bach are \'American Woman\', \'Concerto for 2 Violins in D Minor, BWV 1043: I. Vivace\', \'Aria Mit 30 Veränderungen, BWV 988 "Goldberg Variations": Aria\', \'Suite for Solo Cello No. 1 in G Major, BWV 1007: I. Prélude\', and \'Toccata and Fugue in D Minor, BWV 565: I. Toccata\'.'

```

SQLDatabaseSequentialChain#
用于查询 SQL 数据库的顺序链。
链如下：

```code
1. Based on the query, determine which tables to use.
2. Based on those tables, call the normal SQL database chain.

```

在数据库中表的数量很多的情况下，这非常有用。

```code
from langchain.chains import SQLDatabaseSequentialChain
db = SQLDatabase.from_uri("sqlite:///../../../../notebooks/Chinook.db")

```

```code
chain = SQLDatabaseSequentialChain.from_llm(llm, db, verbose=True)

```

```code
chain.run("How many employees are also customers?")

```

```code
> Entering new SQLDatabaseSequentialChain chain...
Table names to use:
['Customer', 'Employee']

> Entering new SQLDatabaseChain chain...
How many employees are also customers?
SQLQuery: SELECT COUNT(*) FROM Employee INNER JOIN Customer ON Employee.EmployeeId = Customer.SupportRepId;
SQLResult: [(59,)]
Answer: 59 employees are also customers.
> Finished chain.

> Finished chain.

```

```code
' 59 employees are also customers.'

```
PALMulti Prompt Router


路由器链：使用MultiPromptChain从多个提示中选择# – LangChain中文网

6大核心模块（Modules)链（Chains)示例（Examples）Multi Prompt Router

路由器链：使用MultiPromptChain从多个提示中选择#
本教程演示了如何使用RouterChain范例创建一个链，它动态地选择用于给定输入的提示。具体来说，我们展示了如何使用MultiPromptChain创建一个问答链，该链选择与给定问题最相关的提示，然后使用该提示回答问题。

```code
from langchain.chains.router import MultiPromptChain
from langchain.llms import OpenAI

```

```code
physics_template = """You are a very smart physics professor. \
You are great at answering questions about physics in a concise and easy to understand manner. \
When you don't know the answer to a question you admit that you don't know.

Here is a question:
{input}"""

math_template = """You are a very good mathematician. You are great at answering math questions. \
You are so good because you are able to break down hard problems into their component parts, \
answer the component parts, and then put them together to answer the broader question.

Here is a question:
{input}"""

```

```code
prompt_infos = [
{
"name": "physics",
"description": "Good for answering questions about physics",
"prompt_template": physics_template
},
{
"name": "math",
"description": "Good for answering math questions",
"prompt_template": math_template
}
]

```

```code
chain = MultiPromptChain.from_prompts(OpenAI(), prompt_infos, verbose=True)

```

```code
print(chain.run("What is black body radiation?"))

```

```code
> Entering new MultiPromptChain chain...
physics: {'input': 'What is black body radiation?'}
> Finished chain.

Black body radiation is the emission of electromagnetic radiation from a body due to its temperature. It is a type of thermal radiation that is emitted from the surface of all objects that are at a temperature above absolute zero. It is a spectrum of radiation that is influenced by the temperature of the body and is independent of the composition of the emitting material.

```

```code
print(chain.run("What is the first prime number greater than 40 such that one plus the prime number is divisible by 3"))

```

```code
> Entering new MultiPromptChain chain...
math: {'input': 'What is the first prime number greater than 40 such that one plus the prime number is divisible by 3'}
> Finished chain.
?

The first prime number greater than 40 such that one plus the prime number is divisible by 3 is 43. To solve this problem, we can break down the question into two parts: finding the first prime number greater than 40, and then finding a number that is divisible by 3.

The first step is to find the first prime number greater than 40. A prime number is a number that is only divisible by 1 and itself. The next prime number after 40 is 41.

The second step is to find a number that is divisible by 3. To do this, we can add 1 to 41, which gives us 42. Now, we can check if 42 is divisible by 3. 42 divided by 3 is 14, so 42 is divisible by 3.

Therefore, the answer to the question is 43.

```

```code
print(chain.run("What is the name of the type of cloud that rins"))

```

```code
> Entering new MultiPromptChain chain...
None: {'input': 'What is the name of the type of cloud that rains?'}
> Finished chain.
The type of cloud that typically produces rain is called a cumulonimbus cloud. This type of cloud is characterized by its large vertical extent and can produce thunderstorms and heavy precipitation. Is there anything else you'd like to know?

```
SQLiteMulti Retrieval Qa Router


路由器链：使用MultiRetrievalQAChain从多个提示中选择# – LangChain中文网

6大核心模块（Modules)链（Chains)示例（Examples）Multi Retrieval Qa Router

路由器链：使用MultiRetrievalQAChain从多个提示中选择#
本教程演示如何使用
```code
RouterChain
```
范例创建一个动态选择使用哪个检索系统的链。具体而言，我们展示了如何使用
```code
MultiRetrievalQAChain
```
创建一个问答链，该链选择对于给定问题最相关的检索QA链，然后使用它回答问题。

```code
from langchain.chains.router import MultiRetrievalQAChain
from langchain.llms import OpenAI

```

```code
from langchain.embeddings import OpenAIEmbeddings
from langchain.document_loaders import TextLoader
from langchain.vectorstores import FAISS

sou_docs = TextLoader('../../state_of_the_union.txt').load_and_split()
sou_retriever = FAISS.from_documents(sou_docs, OpenAIEmbeddings()).as_retriever()

pg_docs = TextLoader('../../paul_graham_essay.txt').load_and_split()
pg_retriever = FAISS.from_documents(pg_docs, OpenAIEmbeddings()).as_retriever()

personal_texts = [
"I love apple pie",
"My favorite color is fuchsia",
"My dream is to become a professional dancer",
"I broke my arm when I was 12",
"My parents are from Peru",
]
personal_retriever = FAISS.from_texts(personal_texts, OpenAIEmbeddings()).as_retriever()

```

```code
retriever_infos = [
{
"name": "state of the union",
"description": "Good for answering questions about the 2023 State of the Union address",
"retriever": sou_retriever
},
{
"name": "pg essay",
"description": "Good for answer quesitons about Paul Graham's essay on his career",
"retriever": pg_retriever
},
{
"name": "personal",
"description": "Good for answering questions about me",
"retriever": personal_retriever
}
]

```

```code
chain = MultiRetrievalQAChain.from_retrievers(OpenAI(), retriever_infos, verbose=True)

```

```code
print(chain.run("What did the president say about the economy?"))

```

```code
> Entering new MultiRetrievalQAChain chain...
state of the union: {'query': 'What did the president say about the economy in the 2023 State of the Union address?'}
> Finished chain.
The president said that the economy was stronger than it had been a year prior, and that the American Rescue Plan helped create record job growth and fuel economic relief for millions of Americans. He also proposed a plan to fight inflation and lower costs for families, including cutting the cost of prescription drugs and energy, providing investments and tax credits for energy efficiency, and increasing access to child care and Pre-K.

```

```code
print(chain.run("What is something Paul Graham regrets about his work?"))

```

```code
> Entering new MultiRetrievalQAChain chain...
pg essay: {'query': 'What is something Paul Graham regrets about his work?'}
> Finished chain.
Paul Graham regrets that he did not take a vacation after selling his company, instead of immediately starting to paint.

```

```code
print(chain.run("What is my background?"))

```

```code
> Entering new MultiRetrievalQAChain chain...
personal: {'query': 'What is my background?'}
> Finished chain.
Your background is Peruvian.

```

```code
print(chain.run("What year was the Internet created in?"))

```

```code
> Entering new MultiRetrievalQAChain chain...
None: {'query': 'What year was the Internet created in?'}
> Finished chain.
The Internet was created in 1969 through a project called ARPANET, which was funded by the United States Department of Defense. However, the World Wide Web, which is often confused with the Internet, was created in 1989 by British computer scientist Tim Berners-Lee.

```
Multi Prompt Router异步链（Async Chain）


Async Chain – LangChain中文网

6大核心模块（Modules)链（Chains)通用功能（Generic）异步链（Async Chain）

链的异步API
LangChain通过利用asyncio库为链提供异步支持。
目前LLMChain（通过arun、apredict、acall)、LLMMathChain（通过arun和acall)、ChatVectorDBChain以及QA chains支持异步方法。其他链的异步支持正在路线图中。

```code
import asyncio
import time

from langchain.llms import OpenAI
from langchain.prompts import PromptTemplate
from langchain.chains import LLMChain

def generate_serially():
llm = OpenAI(temperature=0.9)
prompt = PromptTemplate(
input_variables=["product"],
template="What is a good name for a company that makes {product}?",
)
chain = LLMChain(llm=llm, prompt=prompt)
for _ in range(5):
resp = chain.run(product="toothpaste")
print(resp)

async def async_generate(chain):
resp = await chain.arun(product="toothpaste")
print(resp)

async def generate_concurrently():
llm = OpenAI(temperature=0.9)
prompt = PromptTemplate(
input_variables=["product"],
template="What is a good name for a company that makes {product}?",
)
chain = LLMChain(llm=llm, prompt=prompt)
tasks = [async_generate(chain) for _ in range(5)]
await asyncio.gather(\*tasks)

s = time.perf_counter()
# If running this outside of Jupyter, use asyncio.run(generate_concurrently())
await generate_concurrently()
elapsed = time.perf_counter() - s
print('\033[1m' + f"Concurrent executed in {elapsed:0.2f} seconds." + '\033[0m')

s = time.perf_counter()
generate_serially()
elapsed = time.perf_counter() - s
print('\033[1m' + f"Serial executed in {elapsed:0.2f} seconds." + '\033[0m')

```

```code
BrightSmile Toothpaste Company

BrightSmile Toothpaste Co.

BrightSmile Toothpaste

Gleaming Smile Inc.

SparkleSmile Toothpaste
Concurrent executed in 1.54 seconds.

BrightSmile Toothpaste Co.

MintyFresh Toothpaste Co.

SparkleSmile Toothpaste.

Pearly Whites Toothpaste Co.

BrightSmile Toothpaste.
Serial executed in 6.38 seconds.

```
Multi Retrieval Qa Router从 Hub（From Hub）


从LangChainHub加载＃ – LangChain中文网

6大核心模块（Modules)链（Chains)通用功能（Generic）从 Hub（From Hub）

从LangChainHub加载＃
本笔记涵盖了如何从LangChainHub (opens in a new tab)加载链。

```code
from langchain.chains import load_chain

chain = load_chain("lc://chains/llm-math/chain.json")

```

```code
chain.run("whats 2 raised to .12")

```

```code
> Entering new LLMMathChain chain...
whats 2 raised to .12
Answer: 1.0791812460476249
> Finished chain.

```

```code
'Answer: 1.0791812460476249'

```

有时，链会需要额外的参数，这些参数没有与链一起序列化。例如，对于在向量数据库上进行问题回答的链，将需要一个向量数据库。

```code
from langchain.embeddings.openai import OpenAIEmbeddings
from langchain.vectorstores import Chroma
from langchain.text_splitter import CharacterTextSplitter
from langchain import OpenAI, VectorDBQA

```

```code
from langchain.document_loaders import TextLoader
loader = TextLoader('../../state_of_the_union.txt')
documents = loader.load()
text_splitter = CharacterTextSplitter(chunk_size=1000, chunk_overlap=0)
texts = text_splitter.split_documents(documents)

embeddings = OpenAIEmbeddings()
vectorstore = Chroma.from_documents(texts, embeddings)

```

```code
Running Chroma using direct local API.
Using DuckDB in-memory for database. Data will be transient.

```

```code
chain = load_chain("lc://chains/vector-db-qa/stuff/chain.json", vectorstore=vectorstore)

```

```code
query = "What did the president say about Ketanji Brown Jackson"
chain.run(query)

```

```code
" The president said that Ketanji Brown Jackson is a Circuit Court of Appeals Judge, one of the nation's top legal minds, a former top litigator in private practice, a former federal public defender, has received a broad range of support from the Fraternal Order of Police to former judges appointed by Democrats and Republicans, and will continue Justice Breyer's legacy of excellence."

```
异步链（Async Chain）LLM 链（LLM Chain）


从字符串初始化# – LangChain中文网

6大核心模块（Modules)链（Chains)通用功能（Generic）LLM 链（LLM Chain）

LLM Chain#

```code
LLMChain
```
可能是查询 LLM 对象最流行的方式之一。它使用提供的输入键值（以及可用的内存键值)格式化提示模板，将格式化后的字符串传递给 LLM 并返回 LLM 输出。下面我们展示了
```code
LLMChain
```
类的其他功能。

```code
from langchain import PromptTemplate, OpenAI, LLMChain

prompt_template = "What is a good name for a company that makes {product}?"

llm = OpenAI(temperature=0)
llm_chain = LLMChain(
llm=llm,
prompt=PromptTemplate.from_template(prompt_template)
)
llm_chain("colorful socks")

```

```code
{'product': 'colorful socks', 'text': '  Socktastic!'}

```

运行 LLM Chain 的其他方法#
除了所有
```code
Chain
```
对象共享的
```code
__call__
```
和
```code
run
```
方法（请参见入门指南了解更多信息)，
```code
LLMChain
```
还提供了几种调用链逻辑的方法：

```code
apply
```
允许您对输入列表运行链：

```code
input_list = [
{"product": "socks"},
{"product": "computer"},
{"product": "shoes"}
]

llm_chain.apply(input_list)

```

```code
[{'text': '  Socktastic!'},
{'text': '  TechCore Solutions.'},
{'text': '  Footwear Factory.'}]

```

```code
generate
```
与
```code
apply
```
类似，不同之处在于它返回一个
```code
LLMResult
```
而不是字符串。
```code
LLMResult
```
通常包含有用的生成信息，例如标记使用和完成原因。

```code
llm_chain.generate(input_list)

```

```code
LLMResult(generations=[[Generation(text='  Socktastic!', generation_info={'finish_reason': 'stop', 'logprobs': None})], [Generation(text='  TechCore Solutions.', generation_info={'finish_reason': 'stop', 'logprobs': None})], [Generation(text='  Footwear Factory.', generation_info={'finish_reason': 'stop', 'logprobs': None})]], llm_output={'token_usage': {'prompt_tokens': 36, 'total_tokens': 55, 'completion_tokens': 19}, 'model_name': 'text-davinci-003'})

```

```code
predict
```
与
```code
run
```
方法类似，不同之处在于输入键是关键字参数而不是Python字典。

```code
# Single input example
llm_chain.predict(product="colorful socks")

```

```code
'  Socktastic!'

```

```code
# Multiple inputs example

template = """Tell me a {adjective} joke about {subject}."""
prompt = PromptTemplate(template=template, input_variables=["adjective", "subject"])
llm_chain = LLMChain(prompt=prompt, llm=OpenAI(temperature=0))

llm_chain.predict(adjective="sad", subject="ducks")

```

```code
'  Q: What did the duck say when his friend died?\nA: Quack, quack, goodbye.'

```

解析输出#
默认情况下，即使底层
```code
prompt
```
对象具有输出解析器，
```code
LLMChain
```
也不会解析输出。如果您想在LLM输出上应用该输出解析器，请使用
```code
predict_and_parse
```
代替
```code
predict
```
和
```code
apply_and_parse
```
代替
```code
apply
```
。
使用
```code
predict
```
：

```code
from langchain.output_parsers import CommaSeparatedListOutputParser

output_parser = CommaSeparatedListOutputParser()
template = """List all the colors in a rainbow"""
prompt = PromptTemplate(template=template, input_variables=[], output_parser=output_parser)
llm_chain = LLMChain(prompt=prompt, llm=llm)

llm_chain.predict()

```

```code
'  Red, orange, yellow, green, blue, indigo, violet'

```

使用
```code
predict_and_parser
```
：

```code
llm_chain.predict_and_parse()

```

```code
['Red', 'orange', 'yellow', 'green', 'blue', 'indigo', 'violet']

```

从字符串初始化#
您还可以直接从字符串模板构建LLMChain。

```code
template = """Tell me a {adjective} joke about {subject}."""
llm_chain = LLMChain.from_string(llm=llm, template=template)

```

```code
llm_chain.predict(adjective="sad", subject="ducks")

```

```code
'  Q: What did the duck say when his friend died?\nA: Quack, quack, goodbye.'

```
从 Hub（From Hub）顺序链（Sequential Chains）


Sequential Chains# – LangChain中文网

6大核心模块（Modules)链（Chains)通用功能（Generic）顺序链（Sequential Chains）

Sequential Chains#
调用语言模型后的下一步是做一系列的调用。当您想要将一个调用的输出作为另一个调用的输入时，这是特别有用的。
在本教程中，我们将演示如何使用顺序链来完成一些示例。顺序链被定义为一系列链，按确定的顺序调用。有两种类型的顺序链：

```code
SimpleSequentialChain
```
：最简单的顺序链形式，每个步骤都有一个单一的输入/输出，一个步骤的输出是下一个步骤的输入。

```code
SequentialChain
```
：更一般的顺序链形式，允许多个输入/输出。

SimpleSequentialChain#
在这个链式结构中，每个链只有一个输入和一个输出，一个步骤的输出作为下一个步骤的输入。
我们来看一个玩具例子，第一个链接收一个虚构剧本的标题，然后生成该剧本的概要，第二个链接收该剧本的概要，然后生成一个虚构评论。

```code
from langchain.llms import OpenAI
from langchain.chains import LLMChain
from langchain.prompts import PromptTemplate

```

```code
# This is an LLMChain to write a synopsis given a title of a play.
llm = OpenAI(temperature=.7)
template = """You are a playwright. Given the title of play, it is your job to write a synopsis for that title.

Title: {title}
Playwright: This is a synopsis for the above play:"""
prompt_template = PromptTemplate(input_variables=["title"], template=template)
synopsis_chain = LLMChain(llm=llm, prompt=prompt_template)

```

```code
# This is an LLMChain to write a review of a play given a synopsis.
llm = OpenAI(temperature=.7)
template = """You are a play critic from the New York Times. Given the synopsis of play, it is your job to write a review for that play.

Play Synopsis:
{synopsis}
Review from a New York Times play critic of the above play:"""
prompt_template = PromptTemplate(input_variables=["synopsis"], template=template)
review_chain = LLMChain(llm=llm, prompt=prompt_template)

```

```code
# This is the overall chain where we run these two chains in sequence.
from langchain.chains import SimpleSequentialChain
overall_chain = SimpleSequentialChain(chains=[synopsis_chain, review_chain], verbose=True)

```

```code
review = overall_chain.run("Tragedy at sunset on the beach")

```

```code
> Entering new SimpleSequentialChain chain...

Tragedy at Sunset on the Beach is a story of a young couple, Jack and Sarah, who are in love and looking forward to their future together. On the night of their anniversary, they decide to take a walk on the beach at sunset. As they are walking, they come across a mysterious figure, who tells them that their love will be tested in the near future.

The figure then tells the couple that the sun will soon set, and with it, a tragedy will strike. If Jack and Sarah can stay together and pass the test, they will be granted everlasting love. However, if they fail, their love will be lost forever.

The play follows the couple as they struggle to stay together and battle the forces that threaten to tear them apart. Despite the tragedy that awaits them, they remain devoted to one another and fight to keep their love alive. In the end, the couple must decide whether to take a chance on their future together or succumb to the tragedy of the sunset.

Tragedy at Sunset on the Beach is an emotionally gripping story of love, hope, and sacrifice. Through the story of Jack and Sarah, the audience is taken on a journey of self-discovery and the power of love to overcome even the greatest of obstacles.

The play's talented cast brings the characters to life, allowing us to feel the depths of their emotion and the intensity of their struggle. With its compelling story and captivating performances, this play is sure to draw in audiences and leave them on the edge of their seats.

The play's setting of the beach at sunset adds a touch of poignancy and romanticism to the story, while the mysterious figure serves to keep the audience enthralled. Overall, Tragedy at Sunset on the Beach is an engaging and thought-provoking play that is sure to leave audiences feeling inspired and hopeful.

> Finished chain.

```

```code
print(review)

```

```code
Tragedy at Sunset on the Beach is an emotionally gripping story of love, hope, and sacrifice. Through the story of Jack and Sarah, the audience is taken on a journey of self-discovery and the power of love to overcome even the greatest of obstacles.

The play's talented cast brings the characters to life, allowing us to feel the depths of their emotion and the intensity of their struggle. With its compelling story and captivating performances, this play is sure to draw in audiences and leave them on the edge of their seats.

The play's setting of the beach at sunset adds a touch of poignancy and romanticism to the story, while the mysterious figure serves to keep the audience enthralled. Overall, Tragedy at Sunset on the Beach is an engaging and thought-provoking play that is sure to leave audiences feeling inspired and hopeful.

```

顺序链#
当然，并不是所有的顺序链都像传递单个字符串参数并获取单个字符串输出那样简单。在下一个示例中，我们将尝试更复杂的链，涉及多个输入，以及多个最终输出。
特别重要的是如何命名输入/输出变量名。在上面的例子中，我们不必考虑这个问题，因为我们只是将一个链的输出直接作为下一个链的输入传递，但在这里，我们必须考虑这个问题，因为我们有多个输入。

```code
# This is an LLMChain to write a synopsis given a title of a play and the era it is set in.
llm = OpenAI(temperature=.7)
template = """You are a playwright. Given the title of play and the era it is set in, it is your job to write a synopsis for that title.

Title: {title}
Era: {era}
Playwright: This is a synopsis for the above play:"""
prompt_template = PromptTemplate(input_variables=["title", 'era'], template=template)
synopsis_chain = LLMChain(llm=llm, prompt=prompt_template, output_key="synopsis")

```

```code
# This is an LLMChain to write a review of a play given a synopsis.
llm = OpenAI(temperature=.7)
template = """You are a play critic from the New York Times. Given the synopsis of play, it is your job to write a review for that play.

Play Synopsis:
{synopsis}
Review from a New York Times play critic of the above play:"""
prompt_template = PromptTemplate(input_variables=["synopsis"], template=template)
review_chain = LLMChain(llm=llm, prompt=prompt_template, output_key="review")

```

```code
# This is the overall chain where we run these two chains in sequence.
from langchain.chains import SequentialChain
overall_chain = SequentialChain(
chains=[synopsis_chain, review_chain],
input_variables=["era", "title"],
# Here we return multiple variables
output_variables=["synopsis", "review"],
verbose=True)

```

```code
overall_chain({"title":"Tragedy at sunset on the beach", "era": "Victorian England"})

```

```code
> Entering new SequentialChain chain...

> Finished chain.

```

```code
{'title': 'Tragedy at sunset on the beach',
'era': 'Victorian England',
'synopsis': "  The play follows the story of John, a young man from a wealthy Victorian family, who dreams of a better life for himself. He soon meets a beautiful young woman named Mary, who shares his dream. The two fall in love and decide to elope and start a new life together.  On their journey, they make their way to a beach at sunset, where they plan to exchange their vows of love. Unbeknownst to them, their plans are overheard by John's father, who has been tracking them. He follows them to the beach and, in a fit of rage, confronts them.   A physical altercation ensues, and in the struggle, John's father accidentally stabs Mary in the chest with his sword. The two are left in shock and disbelief as Mary dies in John's arms, her last words being a declaration of her love for him.  The tragedy of the play comes to a head when John, broken and with no hope of a future, chooses to take his own life by jumping off the cliffs into the sea below.   The play is a powerful story of love, hope, and loss set against the backdrop of 19th century England.",
'review': "  The latest production from playwright X is a powerful and heartbreaking story of love and loss set against the backdrop of 19th century England. The play follows John, a young man from a wealthy Victorian family, and Mary, a beautiful young woman with whom he falls in love. The two decide to elope and start a new life together, and the audience is taken on a journey of hope and optimism for the future.  Unfortunately, their dreams are cut short when John's father discovers them and in a fit of rage, fatally stabs Mary. The tragedy of the play is further compounded when John, broken and without hope, takes his own life. The storyline is not only realistic, but also emotionally compelling, drawing the audience in from start to finish.  The acting was also commendable, with the actors delivering believable and nuanced performances. The playwright and director have successfully crafted a timeless tale of love and loss that will resonate with audiences for years to come. Highly recommended."}

```

顺序链中的记忆#
有时您可能想传递一些上下文以在链的每个步骤或链的后面部分中使用，但维护和链接输入/输出变量可能会很快变得混乱。使用
```code
SimpleMemory
```
是一种方便的方式来管理这个问题并清理您的链。
举个例子，假设你使用之前介绍过的playwright SequentialChain，你想要在剧本中添加一些关于日期、时间和地点的上下文信息，并且使用生成的简介和评论来创建一些社交媒体发布文本。你可以将这些新的上下文变量添加为
```code
input_variables
```
，或者我们可以添加一个
```code
SimpleMemory
```
到链中来管理这个上下文：

```code
from langchain.chains import SequentialChain
from langchain.memory import SimpleMemory

llm = OpenAI(temperature=.7)
template = """You are a social media manager for a theater company. Given the title of play, the era it is set in, the date,time and location, the synopsis of the play, and the review of the play, it is your job to write a social media post for that play.

Here is some context about the time and location of the play:
Date and Time: {time}
Location: {location}

Play Synopsis:
{synopsis}
Review from a New York Times play critic of the above play:
{review}

Social Media Post:
"""
prompt_template = PromptTemplate(input_variables=["synopsis", "review", "time", "location"], template=template)
social_chain = LLMChain(llm=llm, prompt=prompt_template, output_key="social_post_text")

overall_chain = SequentialChain(
memory=SimpleMemory(memories={"time": "December 25th, 8pm PST", "location": "Theater in the Park"}),
chains=[synopsis_chain, review_chain, social_chain],
input_variables=["era", "title"],
# Here we return multiple variables
output_variables=["social_post_text"],
verbose=True)

overall_chain({"title":"Tragedy at sunset on the beach", "era": "Victorian England"})

```

```code
> Entering new SequentialChain chain...

> Finished chain.

```

```code
{'title': 'Tragedy at sunset on the beach',
'era': 'Victorian England',
'time': 'December 25th, 8pm PST',
'location': 'Theater in the Park',
'social_post_text': "\nSpend your Christmas night with us at Theater in the Park and experience the heartbreaking story of love and loss that is 'A Walk on the Beach'. Set in Victorian England, this romantic tragedy follows the story of Frances and Edward, a young couple whose love is tragically cut short. Don't miss this emotional and thought-provoking production that is sure to leave you in tears. #AWalkOnTheBeach #LoveAndLoss #TheaterInThePark #VictorianEngland"}

```
LLM 链（LLM Chain）序列化（Serialization）


序列化# – LangChain中文网

6大核心模块（Modules)链（Chains)通用功能（Generic）序列化（Serialization）

序列化#
该教程涵盖了如何将链序列化到磁盘并从磁盘反序列化。我们使用的序列化格式是json或yaml。目前仅有一些链支持此类型的序列化。我们将逐步增加支持的链数。
将链保存到磁盘#
首先，让我们了解如何将链保存到磁盘。这可以通过
```code
.save
```
方法完成，并指定一个具有json或yaml扩展名的文件路径。

```code
from langchain import PromptTemplate, OpenAI, LLMChain
template = """Question: {question}

Answer: Let's think step by step."""
prompt = PromptTemplate(template=template, input_variables=["question"])
llm_chain = LLMChain(prompt=prompt, llm=OpenAI(temperature=0), verbose=True)

```

```code
llm_chain.save("llm_chain.json")

```

现在让我们来看看保存的文件中的内容

```code
!cat llm_chain.json

```

```code
{
"memory": null,
"verbose": true,
"prompt": {
"input_variables": [
"question"
],
"output_parser": null,
"template": "Question: {question}  Answer: Let's think step by step.",
"template_format": "f-string"
},
"llm": {
"model_name": "text-davinci-003",
"temperature": 0.0,
"max_tokens": 256,
"top_p": 1,
"frequency_penalty": 0,
"presence_penalty": 0,
"n": 1,
"best_of": 1,
"request_timeout": null,
"logit_bias": {},
"_type": "openai"
},
"output_key": "text",
"_type": "llm_chain"
}

```

从磁盘加载链#
我们可以使用
```code
load_chain
```
方法从磁盘加载链。

```code
from langchain.chains import load_chain

```

```code
chain = load_chain("llm_chain.json")

```

```code
chain.run("whats 2 + 2")

```

```code
> Entering new LLMChain chain...
Prompt after formatting:
Question: whats 2 + 2

Answer: Let's think step by step.

> Finished chain.

```

```code
' 2 + 2 = 4'

```

分别保存组件#
在上面的例子中，我们可以看到提示和llm配置信息保存在与整个链相同的json中。或者，我们可以将它们拆分并分别保存。这通常有助于使保存的组件更加模块化。为了做到这一点，我们只需要指定
```code
llm_path
```
而不是
```code
llm
```
组件，以及
```code
prompt_path
```
而不是
```code
prompt
```
组件。

```code
llm_chain.prompt.save("prompt.json")

```

```code
!cat prompt.json

```

```code
{
"input_variables": [
"question"
],
"output_parser": null,
"template": "Question: {question}  Answer: Let's think step by step.",
"template_format": "f-string"
}

```

```code
llm_chain.llm.save("llm.json")

```

```code
!cat llm.json

```

```code
{
"model_name": "text-davinci-003",
"temperature": 0.0,
"max_tokens": 256,
"top_p": 1,
"frequency_penalty": 0,
"presence_penalty": 0,
"n": 1,
"best_of": 1,
"request_timeout": null,
"logit_bias": {},
"_type": "openai"
}

```

```code
config = {
"memory": None,
"verbose": True,
"prompt_path": "prompt.json",
"llm_path": "llm.json",
"output_key": "text",
"_type": "llm_chain"
}
import json
with open("llm_chain_separate.json", "w") as f:
json.dump(config, f, indent=2)

```

```code
!cat llm_chain_separate.json

```

```code
{
"memory": null,
"verbose": true,
"prompt_path": "prompt.json",
"llm_path": "llm.json",
"output_key": "text",
"_type": "llm_chain"
}

```

然后我们可以以相同的方式加载它。

```code
chain = load_chain("llm_chain_separate.json")

```

```code
chain.run("whats 2 + 2")

```

```code
> Entering new LLMChain chain...
Prompt after formatting:
Question: whats 2 + 2

Answer: Let's think step by step.

> Finished chain.

```

```code
' 2 + 2 = 4'

```
顺序链（Sequential Chains）转换（Transformation）


转换链# – LangChain中文网

6大核心模块（Modules)链（Chains)通用功能（Generic）转换（Transformation）

转换链#
本笔记展示了使用通用转换链。
以一个示例为例，我们将创建一个虚拟的转换，将一个超长文本过滤为仅前3段，并将其传递到LLMChain以对其进行摘要。

```code
from langchain.chains import TransformChain, LLMChain, SimpleSequentialChain
from langchain.llms import OpenAI
from langchain.prompts import PromptTemplate

```

```code
with open("../../state_of_the_union.txt") as f:
state_of_the_union = f.read()

```

```code
def transform_func(inputs: dict) -> dict:
text = inputs["text"]
shortened_text = "  ".join(text.split("  ")[:3])
return {"output_text": shortened_text}

transform_chain = TransformChain(input_variables=["text"], output_variables=["output_text"], transform=transform_func)

```

```code
template = """Summarize this text:

{output_text}

Summary:"""
prompt = PromptTemplate(input_variables=["output_text"], template=template)
llm_chain = LLMChain(llm=OpenAI(), prompt=prompt)

```

```code
sequential_chain = SimpleSequentialChain(chains=[transform_chain, llm_chain])

```

```code
sequential_chain.run(state_of_the_union)

```

```code
' The speaker addresses the nation, noting that while last year they were kept apart due to COVID-19, this year they are together again. They are reminded that regardless of their political affiliations, they are all Americans.'

```
序列化（Serialization）Custom Chain


创建自定义链# – LangChain中文网

6大核心模块（Modules)链（Chains)通用功能（Generic）Custom Chain

创建自定义链#
要实现自己的自定义链，您可以从
```code
Chain
```
子类化，并实现以下方法：

```code
from __future__ import annotations

from typing import Any, Dict, List, Optional

from pydantic import Extra

from langchain.base_language import BaseLanguageModel
from langchain.callbacks.manager import (
AsyncCallbackManagerForChainRun,
CallbackManagerForChainRun,
)
from langchain.chains.base import Chain
from langchain.prompts.base import BasePromptTemplate

class MyCustomChain(Chain):
"""
An example of a custom chain.
"""

prompt: BasePromptTemplate
"""Prompt object to use."""
llm: BaseLanguageModel
output_key: str = "text"  #: :meta private:

class Config:
"""Configuration for this pydantic object."""

extra = Extra.forbid
arbitrary_types_allowed = True

@property
def input_keys(self) -> List[str]:
"""Will be whatever keys the prompt expects.

:meta private:
"""
return self.prompt.input_variables

@property
def output_keys(self) -> List[str]:
"""Will always return text key.

:meta private:
"""
return [self.output_key]

def _call(
self,
inputs: Dict[str, Any],
run_manager: Optional[CallbackManagerForChainRun] = None,
) -> Dict[str, str]:
# Your custom chain logic goes here
# This is just an example that mimics LLMChain
prompt_value = self.prompt.format_prompt(**inputs)

# Whenever you call a language model, or another chain, you should pass
# a callback manager to it. This allows the inner run to be tracked by
# any callbacks that are registered on the outer run.
# You can always obtain a callback manager for this by calling
# `run_manager.get_child()` as shown below.
response = self.llm.generate_prompt(
[prompt_value],
callbacks=run_manager.get_child() if run_manager else None
)

# If you want to log something about this run, you can do so by calling
# methods on the `run_manager`, as shown below. This will trigger any
# callbacks that are registered for that event.
if run_manager:
run_manager.on_text("Log something about this run")

return {self.output_key: response.generations[0][0].text}

async def _acall(
self,
inputs: Dict[str, Any],
run_manager: Optional[AsyncCallbackManagerForChainRun] = None,
) -> Dict[str, str]:
# Your custom chain logic goes here
# This is just an example that mimics LLMChain
prompt_value = self.prompt.format_prompt(**inputs)

# Whenever you call a language model, or another chain, you should pass
# a callback manager to it. This allows the inner run to be tracked by
# any callbacks that are registered on the outer run.
# You can always obtain a callback manager for this by calling
# `run_manager.get_child()` as shown below.
response = await self.llm.agenerate_prompt(
[prompt_value],
callbacks=run_manager.get_child() if run_manager else None
)

# If you want to log something about this run, you can do so by calling
# methods on the `run_manager`, as shown below. This will trigger any
# callbacks that are registered for that event.
if run_manager:
await run_manager.on_text("Log something about this run")

return {self.output_key: response.generations[0][0].text}

@property
def _chain_type(self) -> str:
return "my_custom_chain"

```

```code
from langchain.callbacks.stdout import StdOutCallbackHandler
from langchain.chat_models.openai import ChatOpenAI
from langchain.prompts.prompt import PromptTemplate

chain = MyCustomChain(
prompt=PromptTemplate.from_template('tell us a joke about {topic}'),
llm=ChatOpenAI()
)

chain.run({'topic': 'callbacks'}, callbacks=[StdOutCallbackHandler()])

```

```code
> Entering new MyCustomChain chain...
Log something about this run
> Finished chain.

```

```code
'Why did the callback function feel lonely? Because it was always waiting for someone to call it back!'

```
转换（Transformation）入门（Getting Started）


开始 – LangChain中文网

6大核心模块（Modules)链（Chains)入门（Getting Started）

开始
在本教程中，我们将学习如何在 LangChain 创建简单的连锁店。我们将学习如何创建一个链，向其添加组件，并运行它。
在本教程中，我们将介绍:

使用简单的 LLM 链
创建连续链
创建定制链

为什么我们需要锁链？
链允许我们将多个组件组合在一起，创建一个单一的、一致的应用程序。例如，我们可以创建一个链，该链接接受用户输入，使用 PromptTemplate 对其进行格式化，然后将格式化后的响应传递给 LLM。我们可以通过将多个链组合在一起，或者通过将链与其他组件组合在一起，来构建更复杂的链。
快速开始: 使用
```code
LLMChain
```

LLMChain 是一个简单的链，它接受一个提示模板，使用用户输入对其进行格式化，并从 LLM 返回响应。
要使用 LLMChain，首先创建一个提示模板。

```code
from langchain.prompts import PromptTemplate
from langchain.llms import OpenAI

llm = OpenAI(temperature=0.9)
prompt = PromptTemplate(
input_variables=["product"],
template="What is a good name for a company that makes {product}?",
)

```

现在我们可以创建一个非常简单的链，它将接受用户输入，用它格式化提示符，然后将其发送到 LLM。

```code
from langchain.chains import LLMChain
chain = LLMChain(llm=llm, prompt=prompt)

# Run the chain only specifying the input variable.
print(chain.run("colorful socks"))

```

```code
SockSplash!

```

你也可以在 LLMChain 中使用聊天模型:

```code
from langchain.chat_models import ChatOpenAI
from langchain.prompts.chat import (
ChatPromptTemplate,
HumanMessagePromptTemplate,
)
human_message_prompt = HumanMessagePromptTemplate(
prompt=PromptTemplate(
template="What is a good name for a company that makes {product}?",
input_variables=["product"],
)
)
chat_prompt_template = ChatPromptTemplate.from_messages([human_message_prompt])
chat = ChatOpenAI(temperature=0.9)
chain = LLMChain(llm=chat, prompt=chat_prompt_template)
print(chain.run("colorful socks"))

```

```code
Rainbow Sox Co.

```

调用链的不同方式
从 Chain 继承的所有类都提供了一些运行链逻辑的方法。最直接的方法是使用

```code
__call__
```

:

```code
chat = ChatOpenAI(temperature=0)
prompt_template = "Tell me a {adjective} joke"
llm_chain = LLMChain(
llm=chat,
prompt=PromptTemplate.from_template(prompt_template)
)

llm_chain(inputs={"adjective":"corny"})

```

```code
{'adjective': 'corny',
'text': 'Why did the tomato turn red? Because it saw the salad dressing!'}

```

默认情况下，
```code
_ _ call _ _
```
返回输入和输出键值。通过将
```code
return _ only _ output
```
设置为
```code
True
```
，可以将其配置为只返回输出键值。

```code
llm_chain("corny", return_only_outputs=True)

```

```code
{'text': 'Why did the tomato turn red? Because it saw the salad dressing!'}

```

如果 Chain 只输出一个输出键(即在 output _ key 中只有一个元素) ，则可以使用 run 方法。注意 run 输出的是字符串而不是字典。

```code
# llm_chain only has one output key, so we can use run
llm_chain.output_keys

```

```code
['text']

```

```code
llm_chain.run({"adjective":"corny"})

```

```code
'Why did the tomato turn red? Because it saw the salad dressing!'

```

对于一个输入键，您可以直接输入字符串，而无需指定输入映射。

```code
# These two are equivalent
llm_chain.run({"adjective":"corny"})
llm_chain.run("corny")

# These two are also equivalent
llm_chain("corny")
llm_chain({"adjective":"corny"})

```

```code
{'adjective': 'corny',
'text': 'Why did the tomato turn red? Because it saw the salad dressing!'}

```

提示: 您可以通过 run 方法轻松地将 Chain 对象作为工具集成到您的 Agent 中。这里有一个例子。
here
.
向链中添加内存
Chain 支持将 BaseMemory 对象作为其内存参数，允许 Chain 对象跨多个调用持久存储数据。换句话说，它使 Chain 成为一个有状态对象。

```code
from langchain.chains import ConversationChain
from langchain.memory import ConversationBufferMemory

conversation = ConversationChain(
llm=chat,
memory=ConversationBufferMemory()
)

conversation.run("Answer briefly. What are the first 3 colors of a rainbow?")
# -> The first three colors of a rainbow are red, orange, and yellow.
conversation.run("And the next 4?")
# -> The next four colors of a rainbow are green, blue, indigo, and violet.

```

```code
'The next four colors of a rainbow are green, blue, indigo, and violet.'

```

实际上，BaseMemory 定义了一个长链存储内存的接口。它允许通过 load _ memory _ variable 方法读取存储的数据，并通过 save _ context 方法存储新数据。你可以在内存部分了解更多。
Memory
调试链
因为大多数 Chain 对象都涉及大量的输入提示预处理和 LLM 输出后处理，所以很难单独从它的输出调试 Chain 对象。如果详细设置为 True，将在 Chain 对象运行时打印出它的一些内部状态。

```code
conversation = ConversationChain(
llm=chat,
memory=ConversationBufferMemory(),
verbose=True
)
conversation.run("What is ChatGPT?")

```

```code
> Entering new ConversationChain chain...
Prompt after formatting:
The following is a friendly conversation between a human and an AI. The AI is talkative and provides lots of specific details from its context. If the AI does not know the answer to a question, it truthfully says it does not know.

Current conversation:

Human: What is ChatGPT?
AI:

> Finished chain.

```

```code
'ChatGPT is an AI language model developed by OpenAI. It is based on the GPT-3 architecture and is capable of generating human-like responses to text prompts. ChatGPT has been trained on a massive amount of text data and can understand and respond to a wide range of topics. It is often used for chatbots, virtual assistants, and other conversational AI applications.'

```

Combine chains with the

```code
SequentialChain
```

调用语言模型之后的下一步是对语言模型进行一系列调用。我们可以使用序列链来实现这一点，序列链是按照预定义的顺序执行链接的链。具体来说，我们将使用 SimpleSequentialChain。这是最简单的顺序链类型，其中每个步骤都有一个输入/输出，一个步骤的输出是下一个步骤的输入。
在本教程中，我们的顺序链将:
首先，为产品创建一个公司名称。我们将重用之前初始化的 LLMChain 来创建这个公司名称。
然后，为产品创建一个口号。我们将初始化一个新的 LLMChain 来创建这个口号，如下所示。

```code
second_prompt = PromptTemplate(
input_variables=["company_name"],
template="Write a catchphrase for the following company: {company_name}",
)
chain_two = LLMChain(llm=llm, prompt=second_prompt)

```

现在我们可以组合这两个 LLMChains，这样我们就可以在一个步骤中创建一个公司名称和一个口号。

```code
from langchain.chains import SimpleSequentialChain
overall_chain = SimpleSequentialChain(chains=[chain, chain_two], verbose=True)

# Run the chain specifying only the input variable for the first chain.
catchphrase = overall_chain.run("colorful socks")
print(catchphrase)

```

```code
> Entering new SimpleSequentialChain chain...
Rainbow Socks Co.

"Step into Color with Rainbow Socks!"

> Finished chain.

"Step into Color with Rainbow Socks!"

```

类创建自定义链
```code
Chain
```
类
LangChain 提供了很多现成的链接，但是有时候您可能想要为您的特定用例创建一个自定义链接。对于此示例，我们将创建一个自定义链，用于连接2个 LLMChains 的输出。
为了创建自定义链:
首先从 Chain 类的子类化开始,
填写 input _ key 和 output _ key 属性,
添加显示如何执行链的 _ call 方法。
下面的例子说明了这些步骤:

```code
from langchain.chains import LLMChain
from langchain.chains.base import Chain

from typing import Dict, List

class ConcatenateChain(Chain):
chain_1: LLMChain
chain_2: LLMChain

@property
def input_keys(self) -> List[str]:
# Union of the input keys of the two chains.
all_input_vars = set(self.chain_1.input_keys).union(set(self.chain_2.input_keys))
return list(all_input_vars)

@property
def output_keys(self) -> List[str]:
return ['concat_output']

def _call(self, inputs: Dict[str, str]) -> Dict[str, str]:
output_1 = self.chain_1.run(inputs)
output_2 = self.chain_2.run(inputs)
return {'concat_output': output_1 + output_2}

```

就是这样! 想了解更多关于如何使用链条做一些很酷的事情的细节，请查看链条使用指南。

```code
prompt_1 = PromptTemplate(
input_variables=["product"],
template="What is a good name for a company that makes {product}?",
)
chain_1 = LLMChain(llm=llm, prompt=prompt_1)

prompt_2 = PromptTemplate(
input_variables=["product"],
template="What is a good slogan for a company that makes {product}?",
)
chain_2 = LLMChain(llm=llm, prompt=prompt_2)

concat_chain = ConcatenateChain(chain_1=chain_1, chain_2=chain_2)
concat_output = concat_chain.run("colorful socks")
print(f"Concatenated output:\n{concat_output}")

```

```code
Concatenated output:

Socktastic Colors.

"Put Some Color in Your Step!"

```

That’s it! For more details about how to do cool things with Chains, check out the
how-to guide
for chains.Custom Chain如何指南（How-to Guides）


How to Guides – LangChain中文网

6大核心模块（Modules)链（Chains)如何指南（How-to Guides）

使用指南
链是由链接组成的，它可以是原语或其他链。原语可以是提示、模型、任意函数或其他链。这里的示例分为三个部分：
通用功能
涵盖了通用链（在各种应用程序中都有用的链)以及与这些链相关的通用功能。

链的异步API
创建自定义链
从LangChainHub加载
LLM Chain
运行LLM Chain的其他方式
解析输出
从字符串初始化
顺序链
序列化
转换链

与索引相关的链
与处理索引有关的链。

分析文档
在文档上聊天并查看历史记录
图形问答
假设情况下的文档嵌入
使用来源的问答
问答
总结
检索问答
检索问答并使用来源
向量数据库文本生成

其他所有类型的链
其他所有类型的链！

API 链
带宪法人工智能的自我批判链
BashChain
LLMCheckerChain
LLM 数学
LLMRequestsChain
LLMSummarizationCheckerChain
审核
OpenAPI 链
PAL
SQL 链示例
入门（Getting Started）分析文档（Analyze Document）


分析文档# – LangChain中文网

6大核心模块（Modules)链（Chains)索引示例（Index Examples）分析文档（Analyze Document）

分析文档#
分析文档链更像是一个结束链。该链接收单个文档，将其拆分，然后通过合并文档链运行它。这可以用作更多的端到端链。

```code
with open("../../state_of_the_union.txt") as f:
state_of_the_union = f.read()

```

总结#
让我们看看它在下面的示例中的使用，使用它来总结一个长文档。

```code
from langchain import OpenAI
from langchain.chains.summarize import load_summarize_chain

llm = OpenAI(temperature=0)
summary_chain = load_summarize_chain(llm, chain_type="map_reduce")

```

```code
from langchain.chains import AnalyzeDocumentChain

```

```code
summarize_document_chain = AnalyzeDocumentChain(combine_docs_chain=summary_chain)

```

```code
summarize_document_chain.run(state_of_the_union)

```

```code
" In this speech, President Biden addresses the American people and the world, discussing the recent aggression of Russia's Vladimir Putin in Ukraine and the US response. He outlines economic sanctions and other measures taken to hold Putin accountable, and announces the US Department of Justice's task force to go after the crimes of Russian oligarchs. He also announces plans to fight inflation and lower costs for families, invest in American manufacturing, and provide military, economic, and humanitarian assistance to Ukraine. He calls for immigration reform, protecting the rights of women, and advancing the rights of LGBTQ+ Americans, and pays tribute to military families. He concludes with optimism for the future of America."

```

问答#
让我们使用问答链来看看它。

```code
from langchain.chains.question_answering import load_qa_chain

```

```code
qa_chain = load_qa_chain(llm, chain_type="map_reduce")

```

```code
qa_document_chain = AnalyzeDocumentChain(combine_docs_chain=qa_chain)

```

```code
qa_document_chain.run(input_document=state_of_the_union, question="what did the president say about justice breyer?")

```

```code
' The president thanked Justice Breyer for his service.'

```
如何指南（How-to Guides）聊天向量数据库（Chat Vector DB）


在文档中聊天，带有聊天记录 – LangChain中文网

6大核心模块（Modules)链（Chains)索引示例（Index Examples）聊天向量数据库（Chat Vector DB）

在文档中聊天，带有聊天记录
本教程演示了如何使用
```code
ConversationalRetrievalChain
```
设置聊天过程中带有聊天历史的链。与RetrievalQAChain唯一的区别是，这个链允许传入聊天历史，以便进行后续提问。

```code
from langchain.embeddings.openai import OpenAIEmbeddings
from langchain.vectorstores import Chroma
from langchain.text_splitter import CharacterTextSplitter
from langchain.llms import OpenAI
from langchain.chains import ConversationalRetrievalChain

```

加载文档。您可以将其替换为您想要的任何类型的数据加载程序

```code
from langchain.document_loaders import TextLoader
loader = TextLoader("../../state_of_the_union.txt")
documents = loader.load()

```

如果您有多个加载程序需要组合，可以执行以下操作：

```code
# loaders = [....]
# docs = []
# for loader in loaders:
# docs.extend(loader.load())

```

现在我们将文档拆分、创建嵌入并将它们放入向量存储中。这使我们可以在它们之间进行语义搜索。

```code
text_splitter = CharacterTextSplitter(chunk_size=1000, chunk_overlap=0)
documents = text_splitter.split_documents(documents)

embeddings = OpenAIEmbeddings()
vectorstore = Chroma.from_documents(documents, embeddings)

```

```code
Using embedded DuckDB without persistence: data will be transient

```

现在我们可以创建一个内存对象，用于跟踪输入/输出并进行对话。

```code
from langchain.memory import ConversationBufferMemory
memory = ConversationBufferMemory(memory_key="chat_history", return_messages=True)

```

现在我们初始化
```code
ConversationalRetrievalChain
```

```code
qa = ConversationalRetrievalChain.from_llm(OpenAI(temperature=0), vectorstore.as_retriever(), memory=memory)

```

```code
query = "What did the president say about Ketanji Brown Jackson"
result = qa({"question": query})

```

```code
result["answer"]

```

```code
" The president said that Ketanji Brown Jackson is one of the nation's top legal minds, a former top litigator in private practice, a former federal public defender, and from a family of public school educators and police officers. He also said that she is a consensus builder and has received a broad range of support from the Fraternal Order of Police to former judges appointed by Democrats and Republicans."

```

```code
query = "Did he mention who she suceeded"
result = qa({"question": query})

```

```code
result['answer']

```

```code
' Ketanji Brown Jackson succeeded Justice Stephen Breyer on the United States Supreme Court.'

```

传入聊天历史
在上面的示例中，我们使用Memory对象来跟踪聊天历史。我们也可以直接传递它。为此，我们需要初始化一个没有任何内存对象的链。

```code
qa = ConversationalRetrievalChain.from_llm(OpenAI(temperature=0), vectorstore.as_retriever())

```

这里是一个没有聊天记录的提问示例

```code
chat_history = []
query = "What did the president say about Ketanji Brown Jackson"
result = qa({"question": query, "chat_history": chat_history})

```

```code
result["answer"]

```

```code
" The president said that Ketanji Brown Jackson is one of the nation's top legal minds, a former top litigator in private practice, a former federal public defender, and from a family of public school educators and police officers. He also said that she is a consensus builder and has received a broad range of support from the Fraternal Order of Police to former judges appointed by Democrats and Republicans."

```

这里是一个有一些聊天记录的提问示例

```code
chat_history = [(query, result["answer"])]
query = "Did he mention who she suceeded"
result = qa({"question": query, "chat_history": chat_history})

```

```code
result['answer']

```

```code
' Ketanji Brown Jackson succeeded Justice Stephen Breyer on the United States Supreme Court.'

```

返回源文件#
您还可以轻松地从ConversationalRetrievalChain返回源文档。这对于您想要检查哪些文档被返回时非常有用。

```code
qa = ConversationalRetrievalChain.from_llm(OpenAI(temperature=0), vectorstore.as_retriever(), return_source_documents=True)

```

```code
chat_history = []
query = "What did the president say about Ketanji Brown Jackson"
result = qa({"question": query, "chat_history": chat_history})

```

```code
result['source_documents'][0]

```

```code
Document(page_content='Tonight. I call on the Senate to: Pass the Freedom to Vote Act. Pass the John Lewis Voting Rights Act. And while you’re at it, pass the Disclose Act so Americans can know who is funding our elections.   Tonight, I’d like to honor someone who has dedicated his life to serve this country: Justice Stephen Breyer—an Army veteran, Constitutional scholar, and retiring Justice of the United States Supreme Court. Justice Breyer, thank you for your service.   One of the most serious constitutional responsibilities a President has is nominating someone to serve on the United States Supreme Court.   And I did that 4 days ago, when I nominated Circuit Court of Appeals Judge Ketanji Brown Jackson. One of our nation’s top legal minds, who will continue Justice Breyer’s legacy of excellence.', metadata={'source': '../../state_of_the_union.txt'})

```

带有
```code
search_distance
```
的ConversationalRetrievalChain#
如果您正在使用支持按搜索距离过滤的向量存储，则可以添加阈值参数。

```code
vectordbkwargs = {"search_distance": 0.9}

```

```code
qa = ConversationalRetrievalChain.from_llm(OpenAI(temperature=0), vectorstore.as_retriever(), return_source_documents=True)
chat_history = []
query = "What did the president say about Ketanji Brown Jackson"
result = qa({"question": query, "chat_history": chat_history, "vectordbkwargs": vectordbkwargs})

```

带有
```code
map_reduce
```
的ConversationalRetrievalChain#
我们还可以使用不同类型的组合文档链与ConversationalRetrievalChain链。

```code
from langchain.chains import LLMChain
from langchain.chains.question_answering import load_qa_chain
from langchain.chains.conversational_retrieval.prompts import CONDENSE_QUESTION_PROMPT

```

```code
llm = OpenAI(temperature=0)
question_generator = LLMChain(llm=llm, prompt=CONDENSE_QUESTION_PROMPT)
doc_chain = load_qa_chain(llm, chain_type="map_reduce")

chain = ConversationalRetrievalChain(
retriever=vectorstore.as_retriever(),
question_generator=question_generator,
combine_docs_chain=doc_chain,
)

```

```code
chat_history = []
query = "What did the president say about Ketanji Brown Jackson"
result = chain({"question": query, "chat_history": chat_history})

```

```code
result['answer']

```

```code
" The president said that Ketanji Brown Jackson is one of the nation's top legal minds, a former top litigator in private practice, a former federal public defender, from a family of public school educators and police officers, a consensus builder, and has received a broad range of support from the Fraternal Order of Police to former judges appointed by Democrats and Republicans."

```

带有源问题的ConversationalRetrievalChain问答#
你也可以将这个链与带有来源的问答链一起使用。

```code
from langchain.chains.qa_with_sources import load_qa_with_sources_chain

```

```code
llm = OpenAI(temperature=0)
question_generator = LLMChain(llm=llm, prompt=CONDENSE_QUESTION_PROMPT)
doc_chain = load_qa_with_sources_chain(llm, chain_type="map_reduce")

chain = ConversationalRetrievalChain(
retriever=vectorstore.as_retriever(),
question_generator=question_generator,
combine_docs_chain=doc_chain,
)

```

```code
chat_history = []
query = "What did the president say about Ketanji Brown Jackson"
result = chain({"question": query, "chat_history": chat_history})

```

```code
result['answer']

```

```code
" The president said that Ketanji Brown Jackson is one of the nation's top legal minds, a former top litigator in private practice, a former federal public defender, from a family of public school educators and police officers, a consensus builder, and has received a broad range of support from the Fraternal Order of Police to former judges appointed by Democrats and Republicans. \nSOURCES: ../../state_of_the_union.txt"

```

ConversationalRetrievalChain 与流式输出到
```code
stdout
```
#
在这个例子中，链的输出会被逐个 token 地流式输出到
```code
stdout
```
。

```code
from langchain.chains.llm import LLMChain
from langchain.callbacks.streaming_stdout import StreamingStdOutCallbackHandler
from langchain.chains.conversational_retrieval.prompts import CONDENSE_QUESTION_PROMPT, QA_PROMPT
from langchain.chains.question_answering import load_qa_chain

# Construct a ConversationalRetrievalChain with a streaming llm for combine docs
# and a separate, non-streaming llm for question generation
llm = OpenAI(temperature=0)
streaming_llm = OpenAI(streaming=True, callbacks=[StreamingStdOutCallbackHandler()], temperature=0)

question_generator = LLMChain(llm=llm, prompt=CONDENSE_QUESTION_PROMPT)
doc_chain = load_qa_chain(streaming_llm, chain_type="stuff", prompt=QA_PROMPT)

qa = ConversationalRetrievalChain(
retriever=vectorstore.as_retriever(), combine_docs_chain=doc_chain, question_generator=question_generator)

```

```code
chat_history = []
query = "What did the president say about Ketanji Brown Jackson"
result = qa({"question": query, "chat_history": chat_history})

```

```code
The president said that Ketanji Brown Jackson is one of the nation's top legal minds, a former top litigator in private practice, a former federal public defender, and from a family of public school educators and police officers. He also said that she is a consensus builder and has received a broad range of support from the Fraternal Order of Police to former judges appointed by Democrats and Republicans.

```

```code
chat_history = [(query, result["answer"])]
query = "Did he mention who she suceeded"
result = qa({"question": query, "chat_history": chat_history})

```

```code
Ketanji Brown Jackson succeeded Justice Stephen Breyer on the United States Supreme Court.

```

get_chat_history 函数#
你也可以指定一个
```code
get_chat_history
```
函数，用于格式化聊天历史字符串。

```code
def get_chat_history(inputs) -> str:
res = []
for human, ai in inputs:
res.append(f"Human:{human}\nAI:{ai}")
return "\n".join(res)
qa = ConversationalRetrievalChain.from_llm(OpenAI(temperature=0), vectorstore.as_retriever(), get_chat_history=get_chat_history)

```

```code
chat_history = []
query = "What did the president say about Ketanji Brown Jackson"
result = qa({"question": query, "chat_history": chat_history})

```

```code
result['answer']

```

```code
" The president said that Ketanji Brown Jackson is one of the nation's top legal minds, a former top litigator in private practice, a former federal public defender, and from a family of public school educators and police officers. He also said that she is a consensus builder and has received a broad range of support from the Fraternal Order of Police to former judges appointed by Democrats and Republicans."

```
分析文档（Analyze Document）图形问答（Graph QA）


图问题回答# – LangChain中文网

6大核心模块（Modules)链（Chains)索引示例（Index Examples）图形问答（Graph QA）

图问题回答#
本教程介绍如何在图数据结构上进行问题回答。
创建图#
在本节中，我们构建一个示例图。目前，这适用于小段文本。

```code
from langchain.indexes import GraphIndexCreator
from langchain.llms import OpenAI
from langchain.document_loaders import TextLoader

```

```code
index_creator = GraphIndexCreator(llm=OpenAI(temperature=0))

```

```code
with open("../../state_of_the_union.txt") as f:
all_text = f.read()

```

我们只使用一个小片段，因为提取知识三元组稍微有些费力。

```code
text = "\n".join(all_text.split("  ")[105:108])

```

```code
text

```

```code
'It won’t look like much, but if you stop and look closely, you’ll see a “Field of dreams,” the ground on which America’s future will be built. \nThis is where Intel, the American company that helped build Silicon Valley, is going to build its $20 billion semiconductor “mega site”. \nUp to eight state-of-the-art factories in one place. 10,000 new good-paying jobs. '

```

```code
graph = index_creator.from_text(text)

```

我们可以查看创建的图。

```code
graph.get_triples()

```

```code
[('Intel', '$20 billion semiconductor "mega site"', 'is going to build'),
('Intel', 'state-of-the-art factories', 'is building'),
('Intel', '10,000 new good-paying jobs', 'is creating'),
('Intel', 'Silicon Valley', 'is helping build'),
('Field of dreams',
"America's future will be built",
'is the ground on which')]

```

查询图#
现在我们可以使用图QA链来问图的问题

```code
from langchain.chains import GraphQAChain

```

```code
chain = GraphQAChain.from_llm(OpenAI(temperature=0), graph=graph, verbose=True)

```

```code
chain.run("what is Intel going to build?")

```

```code
> Entering new GraphQAChain chain...
Entities Extracted:
Intel
Full Context:
Intel is going to build $20 billion semiconductor "mega site"
Intel is building state-of-the-art factories
Intel is creating 10,000 new good-paying jobs
Intel is helping build Silicon Valley

> Finished chain.

```

```code
' Intel is going to build a $20 billion semiconductor "mega site" with state-of-the-art factories, creating 10,000 new good-paying jobs and helping to build Silicon Valley.'

```

保存图#
我们也可以保存和加载图。

```code
graph.write_to_gml("graph.gml")

```

```code
from langchain.indexes.graph import NetworkxEntityGraph

```

```code
loaded_graph = NetworkxEntityGraph.from_gml("graph.gml")

```

```code
loaded_graph.get_triples()

```

```code
[('Intel', '$20 billion semiconductor "mega site"', 'is going to build'),
('Intel', 'state-of-the-art factories', 'is building'),
('Intel', '10,000 new good-paying jobs', 'is creating'),
('Intel', 'Silicon Valley', 'is helping build'),
('Field of dreams',
"America's future will be built",
'is the ground on which')]

```
聊天向量数据库（Chat Vector DB）海德（Hyde）


HyDE – LangChain中文网

6大核心模块（Modules)链（Chains)索引示例（Index Examples）海德（Hyde）

HyDE
本笔记介绍如何使用假设性文档嵌入（HyDE)，如本文 (opens in a new tab)所述。
在高层次上，HyDE是一种嵌入技术，它接收查询，生成假设的答案，然后嵌入生成的文档，并将其用作最终示例。
为了使用HyDE，因此我们需要提供一个基本嵌入模型，以及一个可以用于生成这些文档的LLMChain。默认情况下，HyDE类带有一些默认提示（有关详细信息，请参见本文)，但我们也可以创建自己的提示。

```code
from langchain.llms import OpenAI
from langchain.embeddings import OpenAIEmbeddings
from langchain.chains import LLMChain, HypotheticalDocumentEmbedder
from langchain.prompts import PromptTemplate

```

```code
base_embeddings = OpenAIEmbeddings()
llm = OpenAI()

```

```code
# Load with `web_search` prompt
embeddings = HypotheticalDocumentEmbedder.from_llm(llm, base_embeddings, "web_search")

```

```code
# Now we can use it as any embedding class!
result = embeddings.embed_query("Where is the Taj Mahal?")

```

多次生成#
我们也可以生成多个文档，然后组合这些文档的嵌入。默认情况下，我们通过取平均值来组合这些文档。我们可以通过更改用于生成文档的LLM来实现此目的，从而返回多个内容。

```code
multi_llm = OpenAI(n=4, best_of=4)

```

```code
embeddings = HypotheticalDocumentEmbedder.from_llm(multi_llm, base_embeddings, "web_search")

```

```code
result = embeddings.embed_query("Where is the Taj Mahal?")

```

使用自己的提示#
Besides using preconfigured prompts, we can also easily construct our own prompts and use those in the LLMChain that is generating the documents. This can be useful if we know the domain our queries will be in, as we can condition the prompt to generate text more similar to that.
In the example below, let’s condition it to generate text about a state of the union address (because we will use that in the next example).

```code
prompt_template = """Please answer the user's question about the most recent state of the union address
Question: {question}
Answer:"""
prompt = PromptTemplate(input_variables=["question"], template=prompt_template)
llm_chain = LLMChain(llm=llm, prompt=prompt)

```

```code
embeddings = HypotheticalDocumentEmbedder(llm_chain=llm_chain, base_embeddings=base_embeddings)

```

```code
result = embeddings.embed_query("What did the president say about Ketanji Brown Jackson")

```

Using HyDE#
Now that we have HyDE, we can use it as we would any other embedding class! Here is using it to find similar passages in the state of the union example.

```code
from langchain.text_splitter import CharacterTextSplitter
from langchain.vectorstores import Chroma

with open("../../state_of_the_union.txt") as f:
state_of_the_union = f.read()
text_splitter = CharacterTextSplitter(chunk_size=1000, chunk_overlap=0)
texts = text_splitter.split_text(state_of_the_union)

```

```code
docsearch = Chroma.from_texts(texts, embeddings)

query = "What did the president say about Ketanji Brown Jackson"
docs = docsearch.similarity_search(query)

```

```code
Running Chroma using direct local API.
Using DuckDB in-memory for database. Data will be transient.

```

```code
print(docs[0].page_content)

```

```code
In state after state, new laws have been passed, not only to suppress the vote, but to subvert entire elections.

We cannot let this happen.

Tonight. I call on the Senate to: Pass the Freedom to Vote Act. Pass the John Lewis Voting Rights Act. And while you’re at it, pass the Disclose Act so Americans can know who is funding our elections.

Tonight, I’d like to honor someone who has dedicated his life to serve this country: Justice Stephen Breyer—an Army veteran, Constitutional scholar, and retiring Justice of the United States Supreme Court. Justice Breyer, thank you for your service.

One of the most serious constitutional responsibilities a President has is nominating someone to serve on the United States Supreme Court.

And I did that 4 days ago, when I nominated Circuit Court of Appeals Judge Ketanji Brown Jackson. One of our nation’s top legal minds, who will continue Justice Breyer’s legacy of excellence.

```
图形问答（Graph QA）问答与来源（Q&A with Sources）