目录
前言
Collect (收集)
收集是什么?
Organize (组织)
组织信息
Distill (提炼)
提炼信息
Express (表达)
表达见解
Finetune调优
调整输出内容
总结一下
前言
在信息爆炸的时代,如何有效地处理和汲取大量的信息成为一个关键的挑战,尤其对于知识工作者。如果有一个知识库就像外挂大脑一样,随时可以记录信息,组织管理形成知识,需要时可以随时调用,那生产力将成倍提升数倍。
CODE是Tiago Forte在《Building a Second Brain》书中提出的一种信息处理框架,用于更有效地管理和利用个人知识。借助CODE框架来讲述如何利用RAG(Retrieval-Augmented Generation,检索增强生成)技术搭建个人的知识库。CODE框架通常指的是:
• Collect: 收集信息和数据
• Organize: 组织和分类这些信息
• Distill: 检索提炼关键信息
• Express: 表达和共享知识
作为个人知识管理(PKM)领域具有重要影响力的专家,Tiago Forte提倡将知识管理视为一个动态而有机的过程,而不是仅仅是静态地存储和检索信息。通过收集、组织、提炼和表达的循环,个人可以不断地加深对信息的理解,发现新的联系,以及应用知识于实际工作和创造性活动。这个方法旨在帮助个体更好地应对信息过载,提高工作效率,同时激发创造性思维。
Collect (收集)
收集是什么?
收集各种形式的信息。这可以包括任何觉得有价值、有趣或有潜在用途的信息。这可能是从网络上找到的文章、书籍摘录、灵感、笔记、甚至是对话中的碎片化信息。
第一步:信息抓取,传统的爬虫程序需要针对某个页面的结构,一点点提取页面的信息。利用LLM这个过程要简单得多,虽然处理的过程不是特别完美,不如手动指定节点的方式,但效率高的不是一丁半点。基于LangChain实现:
from langchain.document_loaders import AsyncChromiumLoader
from langchain.document_transformers import BeautifulSoupTransformer
# Load HTML
loader = AsyncChromiumLoader(["https://www.wsj.com"])
html = loader.load()
# Transform
bs_transformer = BeautifulSoupTransformer()
docs_transformed = bs_transformer.transform_documents(html, tags_to_extract=["span"])
html2text = Html2TextTransformer()
docs_transformed = html2text.transform_documents(docs)
docs_transformed[0].page_content[0:500]
上面示例中HTML2Text提供了将HTML内容直接转换为纯文本(带有类似Markdown的格式),而无需进行特定标签操作的简单方法。适用于那些旨在提取可读文本而无需操纵特定HTML元素的情境,用于获取文档信息的场景就很适合,非格式化数据本身不要求非常严谨。
第二步:分割和嵌入,分割文档数据不是必须的,大部分情况下需要分割。主要是两方面原因,一是对于大文档,比如说一本书,只能分割成一个个小节进行存储。另一方面是为了更精确搜索出想要的内容,相关性比较强的内容作为一个文档存储,而相关性不强的则分开存。嵌入(embedding)是一个数学概念,简单点说,就是把文档向量化,把文档抽象转化成以数字表示的一个向量,后续就能用数学计算的方式,快速判断要查询的向量与待查向量的距离,从而实现基于语义的检索。OpenAI有Embedding的API,可以直接调用,存储和检索时必须使用相同的Embedding模型。
Organize (组织)
组织信息
收集到信息后,你需要将其组织成一个有序的结构。使用标签、文件夹、关键字等方式,将信息分类并建立关联。这有助于创建一个清晰的信息体系,使你能够更轻松地定位和理解存储的内容。建立适合个人需求的组织系统,确保它是直观和可持续的。
这一环节最关键也最困难,知识有内容分类,如技术类、个人成长、新闻等,也有时间维度,长期的、短期的,以及知识之间的关联关系,如个人对信息的一些解析标注。每个人对于知识的理解是不一致的,因此该环节的工作更像是艺术,而不是科学。
一种方式是,提前把个人的知识体系用类似思维导图整理好,定义好分类和标签,再把收录的信息做分类和标签。另一种方式,则是利用NLP和聚类的算法,自动进行组织。既然LLM这么强大,能否利用LLM的能力进行组织呢,微软发布的开源框架Autogen,通过编写AI Agent自动完成任务。我准备尝试一下。
Distill (提炼)
提炼信息
将大量的原始信息转化为更有价值、更易于理解和检索的形式,更好地利用收集到的信息,为后续的学习、决策和应用提供更好的基础。通过这个过程,你不仅加深对信息的理解,还能够从中获取出对你来说最有价值的内容。
意图理解,当用户输入查询信息时,不是所有时候都是要通过信息检索就能解决。这里可以增加一个AI Agent来处理用户意图理解的问题,闲聊 -> LLM直接生成答复,数学推理 -> 调用Wolfram插件,查询数据 -> 生成SQL或者调用Code Interpreter,只有当用户是需要检索知识库的时候,才进行。
信息检索,知识在使用之前,先要准确找到它。LLM接收查询的响应作为输入,因此搜索结果的质量是成功与否的决定因素。结果以表格行集的形式呈现,其构成和结构取决于以下因素:
a.用于确定响应中包含索引部分的字段。
b.表示索引匹配项的行。
LangChain文档中可以找到 Retrieval-augmented generation (RAG)
https://python.langchain.com/docs/use_cases/question_answering
from langchain.chains import RetrievalQA
from langchain.document_loaders import TextLoader
from langchain.embeddings.openai import OpenAIEmbeddings
from langchain.llms import OpenAI
from langchain.text_splitter import CharacterTextSplitter
from langchain.vectorstores import Chroma
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()
docsearch = Chroma.from_documents(texts, embeddings)
qa = RetrievalQA.from_chain_type(llm=OpenAI(), chain_type="stuff", retriever=docsearch.as_retriever())
query = "What did the president say about Ketanji Brown Jackson"
qa.run(query)
这里检索最好使用语义(向量化)和关键词混合查询,效果要比单个查询方式好,但是比单独关键词搜索效果并没有太大的区别,为了支持语义查询做了大量的工作,有点尴尬。。。怀疑是我使用的文档类型都是某个行业新闻有关,这个还待研究。
Express (表达)
表达见解
表达阶段是将你对信息的理解、见解以及从中获得的知识表达出来的时候。这可以通过写作、绘图、演讲、制作演示文稿等方式进行。表达有助于巩固你的学习,同时也为与他人分享、合作和创造提供了平台。这个阶段是将个人学习和思考转化为实际行动和成果的关键步骤。
Prompt模版,LLM接收检索信息的返回,通过格式化模版,生成答案再返回给用户。以下是一个Prompt模版的示例,包含历史对话记录、当前问题回答、信息引用。
from langchain.prompts import ChatPromptTemplate, PromptTemplate
# Used to condense a question and chat history into a single question
condense_question_prompt_template = """Given the following conversation and a follow up question, rephrase the follow up question to be a standalone question, in its original language. If there is no chat history, just rephrase the question to be a standalone question.
Chat History:
{chat_history}
Follow Up Input: {question}
""" # noqa: E501
CONDENSE_QUESTION_PROMPT = PromptTemplate.from_template(
condense_question_prompt_template
)
# RAG Prompt to provide the context and question for LLM to answer
# We also ask the LLM to cite the source of the passage it is answering from
llm_context_prompt_template = """
Use the following passages to answer the user's question.
Each passage has a SOURCE which is the title of the document. When answering, cite source name of the passages you are answering from below the answer in a unique bullet point list.
If you don't know the answer, just say that you don't know, don't try to make up an answer.
----
{context}
----
Question: {question}
""" # noqa: E501
LLM_CONTEXT_PROMPT = ChatPromptTemplate.from_template(llm_context_prompt_template)
# Used to build a context window from passages retrieved
document_prompt_template = """
---
NAME: {name}
PASSAGE:
{page_content}
---
"""
DOCUMENT_PROMPT = PromptTemplate.from_template(document_prompt_template)
Finetune调优
调整输出内容
使用自己的数据来微调LLM,使模型适用于自己的场景、自己的任务。比如生成内容符合自己的文章风格,或者输出风格一致的教程等。
微软在AI应用动作比较快,Azure出了不少相关的应用值得参考,ChatGPT +企业数据的Demo https://github.com/Azure-Samples/azure-search-openai-demo
通过这个CODE框架,Tiago Forte提倡将知识管理视为一个动态而有机的过程,而不是仅仅是静态地存储和检索信息。通过收集、组织、提炼和表达的循环,个人可以不断地加深对信息的理解,发现新的联系,以及应用知识于实际工作和创造性活动。这个方法旨在帮助个体更好地应对信息过载,提高工作效率,同时激发创造性思维。
总结一下
RAG这个应用方向是LLM众多应用中比较直接和明确的,相应的创业公司和大厂都会有相应的产品出来,不是很适合作为创业公司ALL IN。只要是场景明确,需求统一,那大厂分分钟都能把它做成基础设施。AI应用领域创业项目最好能有这几个特点:
•离用户场景近,不管是ToB还是ToC,能直接看到效果的
•不要求严谨,比如做广告营销内容,而医疗领域就很难
•要容易算帐,帮研发提效的采购决策很慢,提升销量的决策就容易得多