使用LangChain、DeepInfra逆向工程Twitter算法
譯文作者 | Mike Young
譯者 | 李睿
審校 | 重樓
在這個指南中,將對Twitter的推薦算法進行逆向工程,以更好地理解代碼庫,并提供見解,以制作更好的內容。
想象一下,如果非編程人員能夠借助工具編寫一個能夠理解、協助甚至生成代碼的軟件該有多好,就像經驗豐富的開發人員所做的那樣。
這對LangChain來說是可能實現的。利用VectorStores、Conversational RetrieverChain和LLM等高級模型,LangChain可以讓非編程人員在代碼理解和生成方面達到更高的水平。
在這一指南中,將對Twitter的推薦算法進行逆向工程,以更好地理解代碼庫,并提供見解,以制作更好的內容。在這里將使用OpenAI公司的嵌入技術和一個名為Activeloop的工具來使代碼易于理解,并在DeepInfra上托管一個名為Dolly的LLM來與代碼進行對話。
在完成之后,能夠通過讓人工智能回答最緊迫的問題來減少理解算法所需的困難工作,而不是花幾周時間進行篩選。
1、采用LangChain理解代碼的概念
LangChain是一個非常有用的工具,可以分析GitHub上的代碼庫。它匯集了三個重要部分:VectorStores、Conversationa RetrieverChain和LLM,以幫助人們理解代碼,在場景中回答有關代碼的問題,甚至在GitHub存儲庫中生成新代碼。
Conversational RetrieverChain系統有助于從VectorStore中查找和檢索有用的信息。它使用智能技術,例如場景感知過濾和排名,來確定哪些代碼片段和信息與用戶的特定問題或查詢最相關。其與眾不同之處在于,它考慮了對話的歷史和提問的背景。這意味著它可以為用戶提供高質量和相關的結果,專門滿足用戶的需求。簡單地說,這就像有一個智能助手,它能理解問題的場景,并根據場景給出最好的答案。
現在,了解一下LangChain的工作流,看看它是如何在高層次上工作的:
(1)為代碼庫編制索引
第一步是克隆要分析的目標存儲庫。加載存儲庫中的所有文件,將它們分成更小的塊,并啟動索引過程。如果已經有了索引數據集,可以跳過這一步驟。
(2)嵌入和代碼存儲
為了使代碼片段更容易理解,LangChain采用了代碼感知嵌入模型。該模型有助于捕獲代碼的本質,并將嵌入的代碼片段存儲在VectorStore中,以便在將來查詢時可以隨時訪問它們。
簡而言之,LangChain使用一種稱為代碼感知嵌入的特殊技術,使代碼片段更容易理解。它有一個可以分析代碼并捕獲其重要特征的模型。然后,它將這些分析過的代碼片段存儲在VectorStore中,這就像一個易于訪問的存儲場所。這樣,代碼片段就被組織起來,可以在將來有查詢或問題時進行快速檢索。
(3)理解查詢
這是LLM發揮作用的地方。可以使用像databricks/dolly-v2-12b這樣的模型來處理查詢。該模型分析用戶的查詢,并通過考慮場景和提取重要信息來理解它們的含義。通過這樣做,該模型可以幫助LangChain準確地解釋其查詢,并為用戶提供精確且相關的結果。
(4)構建檢索器
一旦提出的問題或查詢是明確的,Conversational RetrieverChain開始發揮作用。它通過VectorStore這一存儲代碼片段的地方,找到與用戶的查詢最相關的代碼片段。這個搜索過程非常靈活,可以根據用戶的需求進行定制。用戶可以調整設置并應用特定于其需要的過濾器,以確保獲得最準確和最有用的查詢結果。
一旦設置好了檢索器,就是建立對話鏈的時候了。這一步包括調整檢索器的設置以更好地滿足用戶的需求,并應用可能需要的任何其他過濾器。通過這樣做,用戶可以縮小搜索范圍,并確保收到最精確、準確和相關的查詢結果。從本質上來說,它允許用戶微調檢索過程,以獲得對其最有用的信息。
(5)提問
用戶可以使用Conversational RetrieverChain詢問有關代碼庫的問題。它將為用戶生成全面的和場景相關的答案。用戶的LLM作為會話鏈的一部分,考慮到檢索的代碼片段和會話歷史,為用戶提供詳細和準確的答案。
遵循這一工作流程,用戶可以有效地使用LangChain來更深入地了解代碼,為其問題獲得場景感知的答案,甚至在GitHub存儲庫中生成代碼片段。現在逐步地了解其實際效果。
2、分步指南
以下深入了解實際的實現。
(1)獲取密鑰
在開始時,必須在各自的網站注冊,并獲得Activeloop、DeepInfra和OpenAI的API密鑰。
(2)設置Indexer.py文件
創建一個Python文件(例如indexer.py)來索引數據。導入必要的模塊,并將API密鑰設置為環境變量:
Python
import os
from langchain.document_loaders import TextLoader
from langchain.embeddings.openai import OpenAIEmbeddings
from langchain.vectorstores import DeepLake
os.environ['OPENAI_API_KEY'] = 'YOUR KEY HERE'
os.environ['ACTIVELOOP_TOKEN'] = 'YOUR KEY HERE'
embeddings = OpenAIEmbeddings(disallowed_special=())
簡單地說,嵌入是文本的表示,它捕獲不同文本字符串的含義和相關性。它們是數字向量或數字列表,用于度量不同文本輸入之間的相似性或距離。
嵌入通常用于各種任務,例如搜索、聚類、推薦、異常檢測、多樣性測量和分類。在搜索中,嵌入有助于對搜索結果與查詢的相關性進行排序。在聚類中,嵌入將相似的文本字符串分組在一起。
推薦利用嵌入來推薦具有相關文本字符串的項目。異常檢測使用嵌入來識別關聯度小的異常值。多樣性測量包括分析文本字符串之間的相似性分布。分類利用嵌入將文本字符串分配給最相似的標簽。
兩個嵌入向量之間的距離表示相應文本字符串的相關或相似程度。較小的距離表明親緣關系高,而較大的距離表明親緣關系低。
(3)克隆和索引目標存儲庫
接下來,將克隆Twitter算法存儲庫,加載、拆分和索引文檔。可以從此鏈接(https://github.com/twitter/the-algorithm)克隆這一算法。
這段代碼遍歷一個目錄及其子目錄(os.walk(root_dir))。對于遇到的每個文件(文件名),它嘗試執行以下步驟:
Python
root_dir = './the-algorithm'
docs = []
for dirpath, dirnames, filenames in os.walk(root_dir):
for file in filenames:
try:
loader = TextLoader(os.path.join(dirpath, file), encoding='utf-8')
docs.extend(loader.load_and_split())
except Exception as e:
pass
- 它創建一個TextLoader對象,指定當前正在處理的文件的路徑(os.path.join(dirpath, file)),并將編碼設置為UTF-8。
- 然后調用TextLoader對象的load_and_split()方法,該方法可能讀取文件的內容,執行一些處理或拆分操作并返回結果文本數據。
- 然后使用extend()方法將獲得的文本數據添加到一個名為docs的現有列表中。
- 如果在這個過程中發生任何異常,則由try-except塊捕獲并簡單地忽略(' pass ')。
這個代碼片段遞歸地遍歷一個目錄,從文件中加載和分割文本數據,并將結果數據添加到一個名為docs的列表中。
(4)嵌入代碼片段
接下來,使用OpenAI嵌入來嵌入代碼片段。然后將這些嵌入存儲在VectorStore中,這將允許執行有效的相似性搜索:
Python
from langchain.text_splitter import CharacterTextSplitter
text_splitter = CharacterTextSplitter(chunk_size=1000, chunk_overlap=0)
texts = text_splitter.split_documents(docs)
username = "mikelabs" # replace with your username from app.activeloop.ai
db = DeepLake(dataset_path=f"hub://{username}/twitter-algorithm", embedding_functinotallow=embeddings, public=True) #dataset would be publicly available
db.add_documents(texts)print(“done”)
這段代碼導入CharacterTextSplitter類,并初始化它的一個實例,其塊大小為1000個字符且沒有重疊。然后,它使用split_documents方法將提供的文檔分成更小的文本塊,并將它們存儲在文本變量中。
接下來,它設置用戶名(用于注冊Activeloop!)。它創建了一個名為db的DeepLake實例,該實例的數據集路徑指向以指定用戶名托管在“app.activeloop.ai”上的公共數據集。embedding_function處理所需的嵌入。
最后,它使用add_documents方法將文本添加到數據庫中,可能是為了存儲或進一步處理。
運行該文件,然后等待幾分鐘(它可能會掛起一段時間,通常不超過5分鐘)。然后,進入下一步。
(5)使用dolly-v2-12b來處理和理解用戶查詢
現在設置另一個Python文件question.py,以使用DeepInfra平臺中可用的語言模型dolly-v2-12b來處理和理解用戶查詢。
(6)構建檢索器
使用前面創建的VectorStore構建一個檢索器。
Python
db = DeepLake(dataset_path="hub://mikelabs/twitter-algorithm", read_notallow=True, embedding_functinotallow=embeddings) #use your username
retriever = db.as_retriever()
retriever.search_kwargs['distance_metric'] = 'cos'
retriever.search_kwargs['fetch_k'] = 100
retriever.search_kwargs['maximal_marginal_relevance'] = True
retriever.search_kwargs['k'] = 10
以下是代碼正在執行的操作:
該代碼初始化一個名為db的DeepLake對象。它從指定為“hub://mikelabs/twitter-algorithm”的路徑讀取數據集。值得注意的是,需要將“mikelabs”替換為自己的用戶名!
然后使用as_retriver()方法將db對象轉換為檢索器。這一步驟允許對存儲在VectorStore中的數據執行搜索操作。
一些搜索選項可以通過修改檢索器自定義多個retriever.search_kwargs字典:
distance _ metric被設置為“cos”,表示余弦相似度將用于測量文本輸入之間的相似度。假設有兩個向量來表示不同的文本片段,例如句子或文檔。余弦相似性是衡量這兩段文本的相似程度或相關性的一種方法。
通過觀察兩個向量之間的夾角來計算余弦相似度。如果向量指向相同的方向或者彼此非常接近,余弦相似度將接近于1。這意味著文本片段彼此非常相似。
另一方面,如果向量指向相反的方向或相距很遠,余弦相似度將接近于-1。這表明文本片段非常不同或不相似。余弦相似度為0意味著兩個向量彼此垂直或成90度角。在這種情況下,文本片段之間沒有相似性。
在上面的代碼中,余弦相似度被用作比較文本輸入之間相似度的度量。它有助于確定兩個文本片段的關聯程度。使用余弦相似度,代碼可以與給定查詢最相似的頂級匹配進行排序和檢索。
fetch_k參數設置為100,這意味著檢索器將根據余弦相似度檢索前100個最接近的匹配項。
maximal_marginal_relevance設置為True,這表明檢索器將優先考慮不同的結果,而不是返回高度相似的匹配。
參數k設置為10,表示檢索器將為每個查詢返回10個結果。
(7)構建會話鏈
使用Conversational RetrievalChain來連接檢索器和語言模型。這使系統能夠處理用戶查詢并生成場景感知的響應:
Python
model = DeepInfra(model_id="databricks/dolly-v2-12b")
qa = ConversationalRetrievalChain.from_llm(model,retriever=retriever)
Conversational RetrievalChain充當檢索器和語言模型之間的連接。該連接允許系統處理用戶查詢并生成場景感知的響應。
(8)提問
現在可以問關于Twitter算法代碼庫的問題。Conversational RetrievalChain提供的答案是場景感知的,并且直接基于代碼庫。
以下是得到的一個樣本答案:
Python
questions = ["What does favCountParams do?", ...]
chat_history = []
for question in questions:
result = qa({"question": question, "chat_history": chat_history})
chat_history.append((question, result['answer']))
print(f"-> **Question**: {question} \n")
print(f"**Answer**: {result['answer']} \n")
以下是一些摘自LangChain文檔的示例問題:
Python 1 questions = [
2 "What does favCountParams do?",
3 "is it Likes + Bookmarks, or not clear from the code?",
4 "What are the major negative modifiers that lower your linear ranking parameters?",
5 "How do you get assigned to SimClusters?",
6 "What is needed to migrate from one SimClusters to another SimClusters?",
7 "How much do I get boosted within my cluster?",
8 "How does Heavy ranker work. what are it’s main inputs?",
9 "How can one influence Heavy ranker?",
10 "why threads and long tweets do so well on the platform?",
11 "Are thread and long tweet creators building a following that reacts to only threads?",
12 "Do you need to follow different strategies to get most followers vs to get most likes and bookmarks per tweet?",
13 "Content meta data and how it impacts virality (e.g. ALT in images).",
14 "What are some unexpected fingerprints for spam factors?",
15 "Is there any difference between company verified checkmarks and blue verified individual checkmarks?",
16 ]
以下是得到的一個樣本答案:
Python
**Question**: What does favCountParams do?
**Answer**: FavCountParams helps count your favorite videos in a way that is friendlier to the video hosting ser
3、有用的資源
這里有一些額外的資源,可能會有用:
- Activeloop documentation
(https://docs.activeloop.ai/)
- AIModels.fyi
(http://aimodels.fyi/)
- LangChain guides
(https://notes.aimodels.fyi/tag/langchain/)
- OpenAI embeddings documentation
(https://platform.openai.com/docs/guides/embeddings)
4、結論
在這一指南中,探索了使用LangChain對Twitter的推薦算法進行逆向工程。通過利用人工智能功能,節省了寶貴的時間和精力,用自動查詢響應取代了人工代碼檢查。
LangChain是一個強大的工具,它徹底改變了代碼的理解和生成。使用VectorStores、Conversational Retriverchain等高級模型,以及托管在DeepInfra等服務上的LLM, LangChain使開發人員能夠有效地分析代碼庫,提供場景感知的答案,并生成新代碼。
LangChain的工作流程包括索引代碼庫、嵌入代碼片段、使用語言模型處理用戶查詢,以及利用Conversational RetrieverChain檢索相關代碼片段。通過自定義檢索器并構建會話鏈,開發人員可以微調檢索過程以獲得精確的結果。
按照分步指南,可以利用LangChain來增強代碼理解能力,獲得場景感知的答案,甚至在GitHub存儲庫中生成代碼片段。LangChain為生產力和理解開辟了新的可能性。那么人們會采用它建造什么?
原文鏈接:https://dzone.com/articles/a-plain-english-guide-to-reverse-engineering-the-t