문서 정의 및 커스터마이징
문서 정의 및 커스터마이징 (Defining and Customizing Documents)
Document를 데이터 로더로 자동 생성하거나 수동으로 만드는 방법, 그리고 메타데이터·id·포맷 등을 커스터마이즈하는 방법을 알아봐요.
출처: 문서
본문
문서 정의하기
Documents는 데이터 로더를 통해 자동으로 만들거나 수동으로 만들 수 있어요.
기본적으로 우리의 모든 data loaders는 load_data 함수를 통해 Document 객체를 반환해요.
from llama_index.core import SimpleDirectoryReader
documents = SimpleDirectoryReader("./data").load_data()
문서를 수동으로 만드는 것도 선택할 수 있어요. LlamaIndex는 Document 구조를 노출해요.
from llama_index.core import Document
text_list = [text1, text2, ...]
documents = [Document(text=t) for t in text_list]
프로토타이핑과 개발 속도를 높이려면 몇 가지 기본 텍스트로 문서를 빠르게 만들 수도 있어요:
document = Document.example()
문서 커스터마이징
이 섹션은 Document 객체를 커스터마이즈하는 다양한 방법을 다뤄요. Document 객체는 우리의 TextNode 객체의 서브클래스이므로, 이 모든 설정과 세부 사항은 TextNode 객체 클래스에도 동일하게 적용돼요.
메타데이터
Documents는 유용한 메타데이터를 포함할 기회도 제공해요. 각 문서의 metadata 딕셔너리를 사용해 응답을 안내하고 쿼리 응답의 소스를 추적하는 데 도움이 되는 추가 정보를 포함할 수 있어요. 이 정보는 파일 이름이나 카테고리 같은 어떤 것이든 가능해요. 벡터 데이터베이스와 통합한다면 일부 벡터 DB는 키가 문자열이어야 하고 값이 평면형(str, float 또는 int)이어야 한다는 점을 명심하세요.
각 문서의 metadata 딕셔너리에 설정한 정보는 해당 문서에서 만들어진 각 소스 노드의 metadata에 나타나요. 또한 이 정보는 노드에 포함되어 인덱스가 쿼리와 응답에 활용할 수 있게 해요. 기본적으로 메타데이터는 임베딩과 LLM 모델 호출 모두를 위해 텍스트에 주입돼요.
이 딕셔너리를 설정하는 몇 가지 방법이 있어요:
- 문서 생성자에서:
document = Document(
text="text",
metadata={"filename": "<doc_file_name>", "category": "<category>"},
)
- 문서를 만든 후:
document.metadata = {"filename": "<doc_file_name>"}
SimpleDirectoryReader와file_metadata훅을 사용해 파일 이름을 자동으로 설정. 각 문서에 훅을 자동으로 실행해metadata필드를 설정해요:
from llama_index.core import SimpleDirectoryReader
filename_fn = lambda filename: {"file_name": filename}
# automatically sets the metadata of each document according to filename_fn
documents = SimpleDirectoryReader(
"./data", file_metadata=filename_fn
).load_data()
id 커스터마이징
Document Management 섹션에서 자세히 설명했듯이 doc_id는 인덱스에서 문서를 효율적으로 새로고침하는 데 사용돼요. SimpleDirectoryReader를 사용할 때 각 문서의 전체 경로로 doc doc_id를 자동 설정할 수 있어요:
from llama_index.core import SimpleDirectoryReader
documents = SimpleDirectoryReader("./data", filename_as_id=True).load_data()
print([x.doc_id for x in documents])
어떤 Document의 doc_id를 직접 설정할 수도 있어요!
document.doc_id = "My new document id!"
참고: id는 TextNode 객체와 유사하게 Document 객체의 node_id 또는 id_ 프로퍼티로도 설정할 수 있어요.
고급 - 메타데이터 커스터마이징
위에서 언급한 핵심 세부 사항은, 기본적으로 설정한 메타데이터가 임베딩 생성과 LLM에 포함된다는 거예요.
LLM 메타데이터 텍스트 커스터마이징
보통 문서에는 메타데이터 키가 많지만, 응답 합성 중에 모든 키를 LLM이 보게 하고 싶지는 않을 거예요. 위 예시에서 우리는 LLM이 우리 문서의 file_name을 읽는 걸 원하지 않을 수 있어요. 하지만 file_name은 더 나은 임베딩을 생성하는 데 도움이 되는 정보를 포함할 수도 있어요. 이렇게 하는 핵심 장점은 LLM이 결국 읽게 될 내용을 바꾸지 않으면서 검색을 위한 임베딩을 편향시킬 수 있다는 거예요.
다음과 같이 제외할 수 있어요:
document.excluded_llm_metadata_keys = ["file_name"]
그런 다음 get_content() 함수와 MetadataMode.LLM을 지정해 LLM이 실제로 읽게 될 내용을 테스트할 수 있어요:
from llama_index.core.schema import MetadataMode
print(document.get_content(metadata_mode=MetadataMode.LLM))
임베딩 메타데이터 텍스트 커스터마이징
LLM에 보이는 메타데이터를 커스터마이즈하는 것과 유사하게, 임베딩에 보이는 메타데이터도 커스터마이즈할 수 있어요. 이 경우 특정 텍스트가 임베딩을 편향시키길 원하지 않으면 임베딩 모델에 보이는 메타데이터를 구체적으로 제외할 수 있어요.
document.excluded_embed_metadata_keys = ["file_name"]
그런 다음 get_content() 함수와 MetadataMode.EMBED를 지정해 임베딩 모델이 실제로 읽게 될 내용을 테스트할 수 있어요:
from llama_index.core.schema import MetadataMode
print(document.get_content(metadata_mode=MetadataMode.EMBED))
메타데이터 포맷 커스터마이징
지금쯤 알겠지만 메타데이터는 LLM이나 임베딩 모델로 보낼 때 각 문서/노드의 실제 텍스트에 주입돼요. 기본적으로 이 메타데이터의 형식은 세 가지 속성으로 제어돼요:
Document.metadata_seperator-> 기본값 ="\n"
메타데이터의 모든 키/값 필드를 연결할 때 이 필드는 각 키/값 쌍 사이의 구분자를 제어해요.
Document.metadata_template-> 기본값 ="{key}: {value}"
이 속성은 메타데이터의 각 키/값 쌍이 어떻게 형식화되는지 제어해요. key와 value 두 문자열 키가 필요해요.
Document.text_template-> 기본값 ={metadata_str}\n\n{content}
메타데이터가 metadata_seperator와 metadata_template을 사용해 문자열로 변환되면, 이 템플릿이 문서/노드의 텍스트 콘텐츠와 결합될 때 메타데이터가 어떻게 보이는지 제어해요. metadata와 content 문자열 키가 필요해요.
요약 (Summary)
이 모든 것을 알았으니, 이 모든 힘을 사용하는 짧은 예시를 만들어 보죠:
from llama_index.core import Document
from llama_index.core.schema import MetadataMode
document = Document(
text="This is a super-customized document",
metadata={
"file_name": "super_secret_document.txt",
"category": "finance",
"author": "LlamaIndex",
},
excluded_llm_metadata_keys=["file_name"],
metadata_seperator="::",
metadata_template="{key}=>{value}",
text_template="Metadata: {metadata_str}\n-----\nContent: {content}",
)
print(
"The LLM sees this: \n",
document.get_content(metadata_mode=MetadataMode.LLM),
)
print(
"The Embedding model sees this: \n",
document.get_content(metadata_mode=MetadataMode.EMBED),
)
고급 - 자동 메타데이터 추출
LLM 자체를 사용해 메타데이터 추출을 수행하는 초기 예시가 있어요.