

# 将 DynamoDB 与 LangChain 结合使用
<a name="ddb-langchain"></a>

[LangChain](https://www.langchain.com/) 是一个用于通过大语言模型（LLM）构建应用程序的框架。有两个 LangChain 集成使用 DynamoDB：`DynamoDBChatMessageHistory` 类用于存储对话历史记录，使模型能够跨会话与用户来回进行对话；`DynamoDBVectorStore` 类则在 DynamoDB 向量索引上实现 LangChain 向量存储接口来进行相似性搜索。

## 聊天消息历史记录
<a name="langchain-chat-history"></a>

`DynamoDBChatMessageHistory` 类位于适用于 Python 的 `langchain-community` 程序包和适用于 JavaScript 的 `@langchain/community` 程序包中，用于将聊天消息持久化存储在 DynamoDB 表中。该类需要一个已存在的表，其分区键是名为 `SessionId` 的字符串属性（可通过 `primary_key_name` 进行配置）。使用 Amazon CLI 创建表：

```
aws dynamodb create-table \
  --table-name SessionTable \
  --attribute-definitions AttributeName=SessionId,AttributeType=S \
  --key-schema AttributeName=SessionId,KeyType=HASH \
  --billing-mode PAY_PER_REQUEST
```

安装软件包，然后以会话 ID 为键读取和写入历史记录：

```
pip install langchain-community boto3
```

```
from langchain_community.chat_message_histories import DynamoDBChatMessageHistory

history = DynamoDBChatMessageHistory(
    table_name="SessionTable",
    session_id="user-42",
)

history.add_user_message("Hello!")
history.add_ai_message("How can I help you today?")

print(history.messages)
```

每个聊天会话的消息都存储在其 `session_id` 下，因此回访用户可以从中断处继续对话。构造函数还支持复合键，用于按应用程序详细信息 [例如用户 ID (`key`)、旧会话基于生存时间的过期 (`ttl`) 以及存储消息数量上限 (`history_size`)] 隔离历史记录。有关完整 API，请参阅 [Python 参考](https://reference.langchain.com/python/langchain-community/chat_message_histories/dynamodb/DynamoDBChatMessageHistory)和 [JavaScript 参考](https://reference.langchain.com/javascript/langchain-community/stores/message/dynamodb)。

## 由向量索引支持的向量存储
<a name="langchain-vector-store"></a>

`langchain-aws` 程序包中的 `DynamoDBVectorStore` 类使用 DynamoDB 向量索引实现 LangChain 向量存储接口（请参阅[在 DynamoDB 中使用向量索引](VectorSearch.md)）。文档以常规 DynamoDB 项目的形式存储，并通过 `SearchVectors` API 在表的向量索引中进行搜索，因此 LangChain 检索器和 RAG 链可直接对存放数据的表执行相似性搜索。

安装程序包：

```
pip install langchain-aws boto3
```

提供表名称和嵌入函数。如果表和向量索引不存在，则会在第一次写入时创建：

```
from langchain_aws.embeddings import BedrockEmbeddings
from langchain_aws.vectorstores.dynamodb import DynamoDBVectorStore

vector_store = DynamoDBVectorStore.from_texts(
    ["hello", "developer", "wife"],
    embedding=BedrockEmbeddings(model_id="amazon.titan-embed-text-v2:0"),
    table_name="my-documents",
)

docs = vector_store.similarity_search("greeting", k=2)
```

要限定搜索范围，请在构造存储时传递 `partition_attribute`。随后，系统会使用该文档元数据字段上的搜索架构分区键创建向量索引，并且每次搜索仅检查该字段的某一个值（例如集合、类别或租户），而非扫描整个语料库。然后，每次搜索都会通过 `filter={partition_attribute: value}` 或存储级别的 `default_partition_value` 提供值。分区键是索引架构的一部分，在创建索引后无法更改。

记住以下内容：
+ 与全局二级索引一样，向量索引是最终一致的：紧接在 `add_texts` 之后发出的搜索可能不包含刚写入的文档，直到索引追上进度。
+ 对于每次查询，`SearchVectors` 最多返回前 100 个匹配项，因此存储的 `k` 参数上限为 100。
+ 索引的维度、距离函数和搜索架构在创建时固定。存储会根据现有索引对它们进行验证，而不是在不匹配的情况下继续处理。

有关完整的 API，请参阅 [langchain-aws 存储库中的 DynamoDBVectorStore](https://github.com/langchain-ai/langchain-aws/tree/main/libs/aws/langchain_aws/vectorstores/dynamodb)。

## 其他资源
<a name="langchain-additional-resources"></a>
+ [DynamoDBChatMessageHistory Python 参考](https://reference.langchain.com/python/langchain-community/chat_message_histories/dynamodb/DynamoDBChatMessageHistory)
+ [DynamoDBChatMessageHistory JavaScript 参考](https://reference.langchain.com/javascript/langchain-community/stores/message/dynamodb)
+ [GitHub 上的 langchain-aws](https://github.com/langchain-ai/langchain-aws)
+ [Build a scalable, context-aware chatbot with Amazon DynamoDB, Amazon Bedrock, and LangChain](https://www.amazonaws.cn/blogs/database/build-a-scalable-context-aware-chatbot-with-amazon-dynamodb-amazon-bedrock-and-langchain/)