跳到主要內容

如何從目錄載入文件

LangChain 的 DirectoryLoader 實作了從磁碟讀取檔案到 LangChain Document 物件的功能。在此我們示範

  • 如何從檔案系統載入,包括使用萬用字元模式;
  • 如何使用多執行緒進行檔案 I/O;
  • 如何使用自訂載入器類別來解析特定檔案類型(例如,程式碼);
  • 如何處理錯誤,例如解碼造成的錯誤。
from langchain_community.document_loaders import DirectoryLoader
API 參考:DirectoryLoader

DirectoryLoader 接受 loader_cls kwarg,預設為 UnstructuredLoaderUnstructured 支援多種格式的解析,例如 PDF 和 HTML。在此我們使用它來讀取 markdown (.md) 檔案。

我們可以使用 glob 參數來控制要載入哪些檔案。請注意,此處它不會載入 .rst 檔案或 .html 檔案。

loader = DirectoryLoader("../", glob="**/*.md")
docs = loader.load()
len(docs)
20
print(docs[0].page_content[:100])
Security

LangChain has a large ecosystem of integrations with various external resources like local

顯示進度條

預設情況下,不會顯示進度條。若要顯示進度條,請安裝 tqdm 程式庫(例如 pip install tqdm),並將 show_progress 參數設定為 True

loader = DirectoryLoader("../", glob="**/*.md", show_progress=True)
docs = loader.load()
100%|█████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████| 20/20 [00:00<00:00, 54.56it/s]

使用多執行緒

預設情況下,載入發生在一個執行緒中。為了利用多個執行緒,請將 use_multithreading 標誌設定為 true。

loader = DirectoryLoader("../", glob="**/*.md", use_multithreading=True)
docs = loader.load()

變更載入器類別

預設情況下,這會使用 UnstructuredLoader 類別。若要自訂載入器,請在 loader_cls kwarg 中指定載入器類別。以下我們展示使用 TextLoader 的範例

from langchain_community.document_loaders import TextLoader

loader = DirectoryLoader("../", glob="**/*.md", loader_cls=TextLoader)
docs = loader.load()
API 參考:TextLoader
print(docs[0].page_content[:100])
# Security

LangChain has a large ecosystem of integrations with various external resources like loc

請注意,雖然 UnstructuredLoader 解析 Markdown 標頭,但 TextLoader 不會。

如果您需要載入 Python 原始碼檔案,請使用 PythonLoader

from langchain_community.document_loaders import PythonLoader

loader = DirectoryLoader("../../../../../", glob="**/*.py", loader_cls=PythonLoader)
API 參考:PythonLoader

使用 TextLoader 自動偵測檔案編碼

DirectoryLoader 可以協助管理因檔案編碼變化而造成的錯誤。以下我們將嘗試載入檔案集合,其中一個檔案包含非 UTF8 編碼。

path = "../../../libs/langchain/tests/unit_tests/examples/"

loader = DirectoryLoader(path, glob="**/*.txt", loader_cls=TextLoader)

A. 預設行為

預設情況下,我們會引發錯誤

loader.load()
Error loading file ../../../../libs/langchain/tests/unit_tests/examples/example-non-utf8.txt
---------------------------------------------------------------------------
``````output
UnicodeDecodeError Traceback (most recent call last)
``````output
File ~/repos/langchain/libs/community/langchain_community/document_loaders/text.py:43, in TextLoader.lazy_load(self)
42 with open(self.file_path, encoding=self.encoding) as f:
---> 43 text = f.read()
44 except UnicodeDecodeError as e:
``````output
File ~/.pyenv/versions/3.10.4/lib/python3.10/codecs.py:322, in BufferedIncrementalDecoder.decode(self, input, final)
321 data = self.buffer + input
--> 322 (result, consumed) = self._buffer_decode(data, self.errors, final)
323 # keep undecoded input until the next call
``````output
UnicodeDecodeError: 'utf-8' codec can't decode byte 0xca in position 0: invalid continuation byte
``````output

The above exception was the direct cause of the following exception:
``````output
RuntimeError Traceback (most recent call last)
``````output
Cell In[10], line 1
----> 1 loader.load()
``````output
File ~/repos/langchain/libs/community/langchain_community/document_loaders/directory.py:117, in DirectoryLoader.load(self)
115 def load(self) -> List[Document]:
116 """Load documents."""
--> 117 return list(self.lazy_load())
``````output
File ~/repos/langchain/libs/community/langchain_community/document_loaders/directory.py:182, in DirectoryLoader.lazy_load(self)
180 else:
181 for i in items:
--> 182 yield from self._lazy_load_file(i, p, pbar)
184 if pbar:
185 pbar.close()
``````output
File ~/repos/langchain/libs/community/langchain_community/document_loaders/directory.py:220, in DirectoryLoader._lazy_load_file(self, item, path, pbar)
218 else:
219 logger.error(f"Error loading file {str(item)}")
--> 220 raise e
221 finally:
222 if pbar:
``````output
File ~/repos/langchain/libs/community/langchain_community/document_loaders/directory.py:210, in DirectoryLoader._lazy_load_file(self, item, path, pbar)
208 loader = self.loader_cls(str(item), **self.loader_kwargs)
209 try:
--> 210 for subdoc in loader.lazy_load():
211 yield subdoc
212 except NotImplementedError:
``````output
File ~/repos/langchain/libs/community/langchain_community/document_loaders/text.py:56, in TextLoader.lazy_load(self)
54 continue
55 else:
---> 56 raise RuntimeError(f"Error loading {self.file_path}") from e
57 except Exception as e:
58 raise RuntimeError(f"Error loading {self.file_path}") from e
``````output
RuntimeError: Error loading ../../../../libs/langchain/tests/unit_tests/examples/example-non-utf8.txt

檔案 example-non-utf8.txt 使用不同的編碼,因此 load() 函數失敗,並顯示有用的訊息,指出哪個檔案解碼失敗。

使用 TextLoader 的預設行為,任何載入任何文件的失敗都會導致整個載入過程失敗,且不會載入任何文件。

B. 靜默失敗

我們可以將參數 silent_errors 傳遞給 DirectoryLoader,以跳過無法載入的檔案並繼續載入過程。

loader = DirectoryLoader(
path, glob="**/*.txt", loader_cls=TextLoader, silent_errors=True
)
docs = loader.load()
Error loading file ../../../../libs/langchain/tests/unit_tests/examples/example-non-utf8.txt: Error loading ../../../../libs/langchain/tests/unit_tests/examples/example-non-utf8.txt
doc_sources = [doc.metadata["source"] for doc in docs]
doc_sources
['../../../../libs/langchain/tests/unit_tests/examples/example-utf8.txt']

C. 自動偵測編碼

我們也可以要求 TextLoader 在失敗之前自動偵測檔案編碼,方法是將 autodetect_encoding 傳遞給載入器類別。

text_loader_kwargs = {"autodetect_encoding": True}
loader = DirectoryLoader(
path, glob="**/*.txt", loader_cls=TextLoader, loader_kwargs=text_loader_kwargs
)
docs = loader.load()
doc_sources = [doc.metadata["source"] for doc in docs]
doc_sources
['../../../../libs/langchain/tests/unit_tests/examples/example-utf8.txt',
'../../../../libs/langchain/tests/unit_tests/examples/example-non-utf8.txt']

此頁面是否有所幫助?