langchain使用自定義example?selector示例解析
簡介
在之前的文章中,我們提到了可以在跟大模型交互的時候,給大模型提供一些具體的例子內容,方便大模型從這些內容中獲取想要的答案。這種方便的機制在langchain中叫做FewShotPromptTemplate。
如果例子內容少的話,其實無所謂,我們可以把所有的例子都發(fā)送給大語言模型進行處理。
但是如果例子太多的話,每次都發(fā)送如此多的內容,會讓我們的錢包承受不住。畢竟那些第三方的大語言模型是按token收費的。
怎么辦呢? 能不能找到一個經濟又有效的方法來完成我們的工作呢?
答案就是使用example selector。
使用和自定義example selector
我們回想一下在使用FewShotPromptTemplate的時候,實際上是可以同時傳入example_selector和examples。
prompt = FewShotPromptTemplate( example_selector=example_selector, example_prompt=example_prompt, suffix="Question: {input}", input_variables=["input"] )
這里我們使用了一個example_selector,那么什么是example_selector呢?
從名字上看他的主要作用就是從給定的examples中選擇需要的examples出來,提供給大模型使用,從而減少會話的token數(shù)目。
langchain中提供了這樣的example_selector的實現(xiàn),我們先來看下它的基礎類的定義是怎么樣的:
class BaseExampleSelector(ABC): """Interface for selecting examples to include in prompts.""" @abstractmethod def add_example(self, example: Dict[str, str]) -> Any: """Add new example to store for a key.""" @abstractmethod def select_examples(self, input_variables: Dict[str, str]) -> List[dict]: """Select which examples to use based on the inputs."""
可以看到BaseExampleSelector繼承自ABC,并且定義了兩個需要實現(xiàn)的抽象方法。
一個方法叫做add_example。目的是向selector中添加一個example。
一個方法叫做select_examples,主要目的就是根據input,從examples中找出要select出來的內容。
那么什么是ABC呢?
ABC當然就是你了解到的ABC,但是他還有一些額外的含義。ABC的全稱叫做Abstract Base Class,也叫做抽象基類。主要用于在Python程序中創(chuàng)建抽象基類。
他提供了一些@abstractmethod,@abstarctproperty這些裝飾方法,來表明具體類的特征。
所以,如果我們想自定義一個ExampleSelector,只需要繼承自BaseExampleSelector,然后實現(xiàn)這兩個抽象方法即可。
langchain中的ExampleSelector實現(xiàn)
除了自定義實現(xiàn)之外,langchain已經為我們提供了幾個常用的ExampleSelector實現(xiàn),一起來看看吧。
LengthBasedExampleSelector
LengthBasedExampleSelector是根據example的長度來進行選擇的選擇器。
我們看下它的具體實現(xiàn):
def add_example(self, example: Dict[str, str]) -> None: """Add new example to list.""" self.examples.append(example) string_example = self.example_prompt.format(**example) self.example_text_lengths.append(self.get_text_length(string_example))
add_example的邏輯是先把example添加到examples這個list中。
然后使用example_prompt對example進行格式化,得到最終的輸出。
最后再把最后輸出的text長度添加到example_text_lengths數(shù)組中。
def select_examples(self, input_variables: Dict[str, str]) -> List[dict]: """Select which examples to use based on the input lengths.""" inputs = " ".join(input_variables.values()) remaining_length = self.max_length - self.get_text_length(inputs) i = 0 examples = [] while remaining_length > 0 and i < len(self.examples): new_length = remaining_length - self.example_text_lengths[i] if new_length < 0: break else: examples.append(self.examples[i]) remaining_length = new_length i += 1 return examples
select_examples方法實際上就是用max_length減去輸入text的長度,然后再去匹配example_text的長度,匹配一個減去一個,最終得到特定長度的examples。
這個selector的最主要作用就是防止耗盡context window。因為對于大多數(shù)大語言模型來說,用戶的輸入是有長度限制的。
如果超出了輸入長度,會產生意想不到的結果。
這個selector使用起來很簡單,下面是具體的例子:
examples = [ {"input": "happy", "output": "sad"}, {"input": "tall", "output": "short"}, {"input": "energetic", "output": "lethargic"}, {"input": "sunny", "output": "gloomy"}, {"input": "windy", "output": "calm"}, example_prompt = PromptTemplate( input_variables=["input", "output"], template="Input: {input}\nOutput: {output}", ) example_selector = LengthBasedExampleSelector( examples=examples, example_prompt=example_prompt, max_length=25, )
SemanticSimilarityExampleSelector和MaxMarginalRelevanceExampleSelector
這兩個selector是根據相似度來進行example的查找的。
其中MaxMarginalRelevanceExampleSelector是SemanticSimilarityExampleSelector的字類,他是對SemanticSimilarityExampleSelector進行了一些算法上的優(yōu)化。所以這里我們把他們兩個放在一起介紹。
這兩個selector和之前介紹的selector有所不同。因為他們用到了向量數(shù)據庫。
向量數(shù)據庫是干什么用的呢?它的主要目的是把輸入轉換成各種向量然后存儲起來。向量數(shù)據庫可以方便的進行輸入相識度的計算。
我們先來看下他們的add_example方法:
def add_example(self, example: Dict[str, str]) -> str: """Add new example to vectorstore.""" if self.input_keys: string_example = " ".join( sorted_values({key: example[key] for key in self.input_keys}) ) else: string_example = " ".join(sorted_values(example)) ids = self.vectorstore.add_texts([string_example], metadatas=[example]) return ids[0]
這個方法先把example的key加入到input_keys中,然后進行排序。最后通過調用vectorstore的add_texts,把key和value加入到向量數(shù)據庫中。
這兩個selector的add_example都是一樣的。只有select_examples的方法不同。
其中SemanticSimilarityExampleSelector調用了vectorstore的similarity_search方法來實現(xiàn)相似度的搜索。
而MaxMarginalRelevanceExampleSelector則是調用vectorstore的max_marginal_relevance_search方法來實現(xiàn)搜索的。
兩者的搜索算法不太一樣。
因為使用了向量數(shù)據庫,所以他們的調用方法和其他的也不太一樣:
examples = [ {"input": "happy", "output": "sad"}, {"input": "tall", "output": "short"}, {"input": "energetic", "output": "lethargic"}, {"input": "sunny", "output": "gloomy"}, {"input": "windy", "output": "calm"}, ] example_selector = SemanticSimilarityExampleSelector.from_examples( examples, # 使用的ebeddings OpenAIEmbeddings(), # 向量數(shù)據庫 Chroma, # 要返回的數(shù)目 k=1 )
NGramOverlapExampleSelector
最后一個要介紹的是NGramOverlapExampleSelector。這個selector使用的是ngram 重疊矩陣來選擇相似的輸入。
具體的實現(xiàn)算法和原理這里就不介紹了。大家有興趣的可以自行探索。
這個selector也不需要使用向量數(shù)據庫。
使用起來是這樣的:
example_selector = NGramOverlapExampleSelector( examples=examples, example_prompt=example_prompt, threshold=-1.0, )
這里有個不太一樣的參數(shù)叫做threshold。
對于負閾值:Selector按ngram重疊分數(shù)對示例進行排序,不排除任何示例。
對于大于1.0的閾值:選擇器排除所有示例,并返回一個空列表。
對于等于0.0的閾值:選擇器根據ngram重疊分數(shù)對示例進行排序,并且排除與輸入沒有ngram重疊的那些。
總結
有了這些selector我們就可以在提供的examples中進行特定的選擇,然后再把選擇的結果輸入給大語言模型。從而有效的減少token的浪費。
以上就是langchain使用自定義example selector示例解析的詳細內容,更多關于langchain自定義example selector的資料請關注腳本之家其它相關文章!
相關文章
python中np.zeros_like函數(shù)用法詳解
這篇文章主要介紹了python中np.zeros_like函數(shù)用法的相關資料,np.zeros_like是?NumPy?庫中的一個函數(shù),用于創(chuàng)建一個與給定數(shù)組形狀和類型相同的新數(shù)組,文中通過代碼介紹的非常詳細,需要的朋友可以參考下2025-04-04Python爬取商家聯(lián)系電話以及各種數(shù)據的方法
今天小編就為大家分享一篇Python爬取商家聯(lián)系電話以及各種數(shù)據的方法,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2018-11-11Python如何解決secure_filename對中文不支持問題
最近使用到了secure_filename,然后悲劇的發(fā)現(xiàn)中文居然不展示出來,本文就詳細的介紹一下解決方法,感興趣的可以了解一下2021-07-07