일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | |||
5 | 6 | 7 | 8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 | 21 | 22 | 23 | 24 | 25 |
26 | 27 | 28 | 29 | 30 | 31 |
- Ai
- RecSys
- lcel
- toolnode
- tool_calls
- 밑바닥부터 시작하는 딥러닝
- removemessage
- 밑바닥부터시작하는딥러닝 #딥러닝 #머신러닝 #신경망
- 강화학습의 수학적 기초와 알고리듬 이해
- 강화학습의 수학적 기초와 알고리듬의 이해
- tool_binding
- chat_history
- conditional_edges
- conditional_edge
- subgraph
- langgraph
- summarize_chat_history
- humannode
- langgrpah
- Python
- 강화학습
- REACT
- LangChain
- human-in-the-loop
- pinecone
- add_subgraph
- 추천시스템
- rag
- rl
- update_state
- Today
- Total
타임트리
[LangChain] Document Loaders 본문
LLM의 input은 String type으로 넣어줘야 한다. 이를 위해 랭체인에서 제공하는 document_loaders는 pdf, notion, ppt 등의 여러 형식을 불러오고 LLM에 제공할 수 있도록 전처리를 도와준다.
기본적으로 document_loaders
의 클래스들은 load
메소드를 사용해, 여러 형태의 데이터를 알맞게 parsing해서 Document 객체를 원소로 갖는 리스트를 반환한다. 이때, Document 객체는 page_content와 metadata를 클래스 변수로 갖는다.
랭체인의 document_loaders의 클래스들이 어떤 형태로 각 문서를 처리하고 값을 반환하는지 TextLoader와 CSVLoader의 소스코드를 살펴보자.
- TextLoader
class TextLoader(BaseLoader):
def __init__(
self,
file_path: Union[str, Path],
encoding: Optional[str] = None,
autodetect_encoding: bool = False,
):
"""Initialize with file path."""
self.file_path = file_path
self.encoding = encoding
self.autodetect_encoding = autodetect_encoding
def lazy_load(self) -> Iterator[Document]:
"""Load from file path."""
text = ""
try:
with open(self.file_path, encoding=self.encoding) as f:
text = f.read()
except UnicodeDecodeError as e:
## 에러처리 ##
continue
metadata = {"source": str(self.file_path)}
yield Document(page_content=text, metadata=metadata)
TextLoader
의 lazy_load
메소드를 살펴보면, with 절로 파일 경로(file_path
)에 접근해 text를 읽어오고, dictionary type의 metadata에 source
키로 파일 경로를 주고 있다. 최종적으로는 Document type을 generator 형태로 반환한다.
TextLoader
가 상속받은 BaseLoader
에는 load
메소드가 구현되어 있는데 이 부분을 살펴보면 아래처럼 generator를 리스트 형태로 반환하는 것을 확인할 수 있다.
class BaseLoader(ABC):
def load(self) -> List[Document]:
"""Load data into Document objects."""
return list(self.lazy_load())
- CSVLoader
class CSVLoader(BaseLoader):
"""Load a `CSV` file into a list of Documents.
Output Example:
.. code-block:: txt
column1: value1
column2: value2
column3: value3
"""
def __init__(
self,
file_path: Union[str, Path],
source_column: Optional[str] = None,
metadata_columns: Sequence[str] = (),
csv_args: Optional[Dict] = None,
encoding: Optional[str] = None,
autodetect_encoding: bool = False,
):
self.file_path = file_path
self.source_column = source_column
self.metadata_columns = metadata_columns
self.encoding = encoding
self.csv_args = csv_args or {}
self.autodetect_encoding = autodetect_encoding
def lazy_load(self) -> Iterator[Document]:
try:
with open(self.file_path, newline="", encoding=self.encoding) as csvfile:
yield from self.__read_file(csvfile)
except UnicodeDecodeError as e:
if self.autodetect_encoding:
detected_encodings = detect_file_encodings(self.file_path)
for encoding in detected_encodings:
try:
with open(
self.file_path, newline="", encoding=encoding.encoding
) as csvfile:
yield from self.__read_file(csvfile)
break
except UnicodeDecodeError:
continue
else:
raise RuntimeError(f"Error loading {self.file_path}") from e
except Exception as e:
raise RuntimeError(f"Error loading {self.file_path}") from e
def __read_file(self, csvfile: TextIOWrapper) -> Iterator[Document]:
csv_reader = csv.DictReader(csvfile, **self.csv_args)
for i, row in enumerate(csv_reader):
try:
source = (
row[self.source_column]
if self.source_column is not None
else str(self.file_path)
)
except KeyError:
raise ValueError(
f"Source column '{self.source_column}' not found in CSV file."
)
content = "\n".join(
f"""{k.strip() if k is not None else k}: {v.strip()
if isinstance(v, str) else ','.join(map(str.strip, v))
if isinstance(v, list) else v}"""
for k, v in row.items()
if k not in self.metadata_columns
)
metadata = {"source": source, "row": i}
for col in self.metadata_columns:
try:
metadata[col] = row[col]
except KeyError:
raise ValueError(f"Metadata column '{col}' not found in CSV file.")
yield Document(page_content=content, metadata=metadata)
lazy_load
메소드는 csv.DictReader
로 CSV 파일을 읽고, 각 행을 순회하면서 Document 객체를 생성한다. 이때, CSV 파일의 한 행이 하나의 Document 객체가 되며, 각 행은 key-value 로 변환되어 Document의 page_content
에 저장된다.
메타데이터의 경우 기본적으로 파일 경로를 사용하며, 만약 각 행에서 source_column
이 지정된 경우 해당 컬럼의 값을 사용한다.
'LLM > LangChain' 카테고리의 다른 글
[LangChain] RAG with Pinecone (LCEL) (0) | 2024.06.21 |
---|---|
[LangChain] RAG with Pinecone (0) | 2024.06.17 |
[LangChain] AgentExecutor와 ReAct (0) | 2024.06.12 |