用LangChain教AI模仿你的写作风格:详细教程
近年来,大型语言模型(LLMs)在各类任务中的应用如雨后春笋般涌现。然而,如何让这些模型准确地模仿个人的写作风格仍是一个挑战。在本文中,我们将通过LangChain的工具链,向大家展示如何构建一个能模仿你写作风格的LLM。你将学习如何提取、处理文档,生成嵌入,以及创建一个高效的检索生成(RAG)管道,进而让AI更好地帮助你完成写作。
核心原理
1. 文档提取与分块:通过LangChain的 Documents
对象加载原始文本,并将其分块以适配LLM的上下文窗口。这一步确保模型能有效处理大量内容,同时剔除冗余信息,提取关键文字。2. 嵌入生成:利用嵌入模型(如OpenAI Embeddings)将文本转化为数值向量,构建可供检索的语义索引。这些嵌入捕捉了文本的语义信息,为检索和生成提供精准的语义匹配。 3. 高效检索:通过向量数据库(如ChromaDB),结合父子文档结构,实现对大文档的精准片段检索,确保模型生成的内容与原始写作风格保持一致。 4. 上下文驱动生成:基于检索到的文档上下文,让LLM在保持风格一致性的同时生成新的内容。这种方法为模型提供了参考语料,从而增强生成内容的个性化与连贯性。 5. 模仿写作风格:将作者过往的文字作为参考,提供给AI,让AI学会模仿特定的写作风格。通过将这些参考文本作为上下文,模型能够捕捉作者语言的独特节奏、用词和语调,生成高度相似的文本。
通过以上步骤,模型能够将作者的写作特点内化并体现在生成的内容中,使AI成为真正意义上的“写作助手”。
为什么选择LangChain?
LangChain是一款功能强大的RAG库,它支持Python和JavaScript。RAG技术通过结合外部文档增强LLM的生成能力,无需对模型进行繁琐的微调,是解决生成不可靠文本的利器。
虽然很多时候提示词已经够用,但结合RAG可以进一步增强模型的生成能力,特别是当需要生成更高质量和个性化内容时。探索LangChain的初衷正是希望用LLM辅助写作,通过增强上下文信息来获得更优质的生成效果。
步骤1:提取文档
LangChain的Documents
对象让加载文本数据变得简单。这些文档可以轻松拆分后加入到生成链中。
首先,准备好你需要的文档(如博客文章)。以下代码展示了如何将存储在目录中的HTML文档加载到LangChain的Documents
对象中:
from os import listdir
from os.path import isfile, join
mypath = 'project_directory'
onlyfiles = [f for f in listdir(mypath) if isfile(join(mypath, f))]
onlyfiles = [x for x in onlyfiles if 'htm' in x]
接着,使用LangChain的HTML解析器将这些文件转换为可用的文档:
from langchain_community.document_loaders import UnstructuredHTMLLoader
data = {}
for i, file in enumerate(onlyfiles):
loader = UnstructuredHTMLLoader(file)
data[i] = loader.load()
每个文档包括内容(page_content
)和元数据(如标题)。由于LLM的上下文窗口有限(例如ChatGPT-3.5的窗口大小为4096个tokens),需要对文档进行分块以提高处理效率。
from langchain.text_splitter import TokenTextSplitter
text_splitter = TokenTextSplitter(chunk_size=1000, chunk_overlap=25)
texts = {data[i][0].metadata['source']: text_splitter.split_documents(data[i]) for i in range(len(data))}
步骤2:生成嵌入
嵌入(Embeddings)是将文本转换为向量的一种方式,是RAG管道的核心。在这里,我们使用OpenAI的嵌入模型,并将向量存储在本地的ChromaDB中。
from langchain_community.vectorstores import Chroma
from langchain_openai.embeddings import OpenAIEmbeddings
for i, key in enumerate(texts.keys()):
vectordb = Chroma.from_documents(
texts[key],
embedding=OpenAIEmbeddings(api_key='your_open_ai_key'),
persist_directory='./LLM_train_embedding/Doc'
)
vectordb.persist()
步骤3:实现文档检索
为了让LLM能够基于上下文生成内容,我们需要一个高效的检索机制。以下代码展示了如何使用ChromaDB的检索功能:
retriever = vectordb.as_retriever(search_type='mmr', search_kwargs={'k': 1})
retriever.get_relevant_documents('What is a Sankey?')
此外,我们还可以实现父文档检索,通过将大文档拆分为父子文档,提高检索的精确度:
from langchain.retrievers import ParentDocumentRetriever
from langchain.storage import InMemoryStore
from langchain.text_splitter import TokenTextSplitter
child_splitter = TokenTextSplitter(chunk_size=250, chunk_overlap=10)
parent_splitter = TokenTextSplitter(chunk_size=1000, chunk_overlap=50)
vectorstore = Chroma(
collection_name="full_documents",
embedding_function=OpenAIEmbeddings(api_key='your_api_key')
)
store = InMemoryStore()
retriever = ParentDocumentRetriever(
vectorstore=vectorstore,
docstore=store,
child_splitter=child_splitter,
parent_splitter=parent_splitter
)
for i inrange(len(data)):
retriever.add_documents(data[i])
retriever.get_relevant_documents('What is a Sankey?')
步骤4:生成文本
最后,我们利用检索到的文档作为上下文,让LLM生成模仿你写作风格的文本。以下是一个使用LangChain RetrievalQA
链的实现示例:
from langchain_core.output_parsers import StrOutputParser
from langchain_core.prompts import ChatPromptTemplate
from langchain_openai import ChatOpenAI
template = """Mimic the writing style in the context:
{context} and produce a blog on the topic
Topic: {topic}
"""
prompt = ChatPromptTemplate.from_template(template)
model = ChatOpenAI(api_key='your_api_key')
chain = (
{
"context": retriever,
"topic": lambda x: x["topic"]
}
| prompt
| model
| StrOutputParser()
)
output = chain.invoke({"topic": "Pakistan"})
print(output)
总结
通过以上步骤,你已经掌握了如何使用LangChain构建一个模仿你写作风格的LLM。从文档提取、嵌入生成,到检索与内容生成,每一步都至关重要。
结合RAG技术,LLM不仅能生成高质量内容,还能精准模仿你的写作风格,为你的创作带来更多可能性。
如果您想要让大模型写出优质的短篇小说,以及对其他内容感兴趣,也欢迎点击下面的链接,效果不错哦。