Llama 모델이 답변을 생성할 때 컨텍스트, 질문, 답변을 모두 포함하여 반환하는 문제가 발생했습니다. 필요한 것은 답변 부분만 추출하는 것입니다.
해결 방법
정규 표현식을 사용한 문자열 파싱 함수를 작성하여 문제를 해결했습니다.
구현 코드
1
2
3
4
5
6
7
8
9
10
11
12
13
importredefextract_origin_text(data:str)->str:"""
결과 텍스트에서 원본 텍스트를 추출합니다
result_text: str
"""result_text=data# 원본 텍스트 추출
match=re.search(r"(\n\nOrigin:.*?\n\n)",result_text,re.DOTALL)ifmatch:returnmatch.group(1).strip()return""
코드 분석
정규 표현식 설명
1
r"(\n\nOrigin:.*?\n\n)"
\n\n: 두 개의 줄바꿈으로 시작
Origin:: “Origin:” 문자열
.*?: 최소 매칭 (non-greedy)
\n\n: 두 개의 줄바꿈으로 종료
re.DOTALL: .이 줄바꿈 문자도 포함하도록 설정
match.group(1)
괄호로 묶인 첫 번째 그룹 반환
strip(): 앞뒤 공백 제거
사용 예시
입력 데이터
1
2
3
4
5
6
7
8
9
10
11
12
13
llama_output="""
Context: 사용자가 질문을 했습니다.
Question: 날씨가 어때요?
Origin: 오늘 날씨는 맑습니다.
Additional Info: ...
"""result=extract_origin_text(llama_output)print(result)# 출력: "Origin: 오늘 날씨는 맑습니다."
개선된 버전
여러 패턴 지원
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
importredefextract_answer(data:str,pattern:str="Origin")->str:"""
다양한 패턴의 답변 추출
data: str - 전체 텍스트
pattern: str - 추출할 섹션 이름
"""# 패턴에 맞는 섹션 추출
regex=rf"({pattern}:.*?)(?=\n\n[A-Z]|\Z)"match=re.search(regex,data,re.DOTALL)ifmatch:returnmatch.group(1).strip()return""# 사용 예시
result=extract_answer(llama_output,"Origin")
다중 섹션 추출
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
defextract_all_sections(data:str)->dict:"""모든 섹션을 딕셔너리로 추출"""sections={}pattern=r"([A-Z][a-z]+):\s*(.*?)(?=\n\n[A-Z]|\Z)"formatchinre.finditer(pattern,data,re.DOTALL):section_name=match.group(1)section_content=match.group(2).strip()sections[section_name]=section_contentreturnsections# 사용 예시
sections=extract_all_sections(llama_output)print(sections["Origin"])
에러 핸들링
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
defextract_origin_text_safe(data:str)->str:"""안전한 텍스트 추출"""try:ifnotdataornotisinstance(data,str):return""match=re.search(r"(\n\nOrigin:.*?\n\n)",data,re.DOTALL)ifmatch:returnmatch.group(1).strip()# 대안 패턴 시도
match=re.search(r"Origin:(.*?)(?=\n\n|\Z)",data,re.DOTALL)ifmatch:returnmatch.group(1).strip()return""exceptExceptionase:print(f"텍스트 추출 중 오류: {e}")return""
성능 최적화
컴파일된 정규 표현식 사용
1
2
3
4
5
6
7
8
9
10
11
importre# 모듈 레벨에서 컴파일
ORIGIN_PATTERN=re.compile(r"(\n\nOrigin:.*?\n\n)",re.DOTALL)defextract_origin_text_fast(data:str)->str:"""최적화된 텍스트 추출"""match=ORIGIN_PATTERN.search(data)ifmatch:returnmatch.group(1).strip()return""