Jinja 템플릿
Jinja 템플릿 (Jinja Templates)
Jinja 템플릿은 Haystack 컴포넌트에서 어떻게 작동하는지 알아볼게요. 동적 콘텐츠를 만들 때 유용한 도구라서, 개념과 주의할 점을 함께 설명합니다.
출처: 공식문서
Jinja 템플릿이란?
Jinja 템플릿은 동적 콘텐츠를 생성하기 위한 자리표시자(placeholder)를 담고 있는 텍스트 구조예요. 템플릿이 렌더링될 때 그 자리표시자들이 값으로 채워집니다. Jinja2의 전체 기능 목록은 원본 문서에서 확인할 수 있어요.
Hayskack에서 이 템플릿은 Builders, OutputAdapter, ConditionalRouter 컴포넌트에서 쓸 수 있습니다.
문서 배열에서 첫 번째 문서의 content 필드만 출력하는 짧은 Jinja 템플릿을 OutputAdapter에 적용한 예를 볼게요:
from haystack import Document
from haystack.components.converters import OutputAdapter
adapter = OutputAdapter(
template="{{ documents[0].content }}",
output_type=str,
)
input_data = {"documents": [Document(content="Test content")]}
expected_output = {"output": "Test content"}
assert adapter.run(**input_data) == expected_output
Python f-string과 함께 쓰기
Jinja 자리표시자를 Python f-string 안에 넣을 때는, Jinja의 {와 }를 두 배로 늘려(escape) 줘야 해요. 즉 {{ var }}는 {{{{ var }}}}가 됩니다. 그렇지 않으면 Python이 중괄호를 먼저 소비해버려서 Jinja 변수를 찾지 못합니다.
권장하는 템플릿:
template = """
Language: {{ language }}
Question: {{ question }}
"""
# pass both variables when rendering
굳이 f-string을 써야 한다면 (중괄호 이스케이프):
language = "en"
template = f"""
Language: {language}
Question: {{{{ question }}}}
"""
안전 (Safety) 기능
Haystack이 일부 컴포넌트에서 Jinja를 사용하는 방식 때문에, 염두에 둬야 할 보안 고려사항이 있어요. Jinja는 템플릿에 포함된 코드를 실행하는 방식으로 작동하므로, 템플릿이 신뢰할 수 있는 소스에서 나온 것임이 아주 중요합니다. 최종 사용자가 템플릿을 커스터마이즈할 수 있다면, 원격 코드 실행(remote code execution)으로 이어질 위험이 있거든요.
이 위험을 줄이기 위해 Jinja 템플릿은 샌드박스 환경에서 실행·렌더링됩니다. 이 방식은 안전하지만 그만큼 유연성은 떨어져서 템플릿의 표현력이 제한돼요.
Jinja 템플릿의 더 고급 기능이 필요하다면, Jinja를 쓰는 컴포넌트들이 unsafe init 파라미터를 제공합니다. unsafe를 False로 설정하면 샌드박스 환경을 끄고 안전하지 않은 템플릿 렌더링을 활성화할 수 있어요. (원문 기준, unsafe=True로 설정해야 샌드박스가 꺼집니다 — 자세한 동작은 해당 컴포넌트 문서를 확인하세요.)
안전하지 않은 템플릿 렌더링을 쓰면, OutputAdapter와 ConditionalRouter 컴포넌트가 output_type을 ChatMessage, Document, Answer 같은 Haystack 데이터 클래스 중 하나로 설정할 수 있게 됩니다.