[랭체인 기본 문법]
목차
학습 목표
랭체인의 기본 원리에 대해서 학습한다.
랭체인의 기본 구성
1. 모델 IO:
- 프롬프트, 언어모델, 출력파서
2. 데이터 연결
- 문서 읽기, 문서 변환, 문서 임베딩, 벡터 DB, 검색기
3. 체인
4. 메모리
5. 에이전트 + 툴
1. 모델 IO
: 프롬프트, 언어모델, 출력파서로 구성
- 프롬프트: LLM 모델에 전달될 프롬프트 생성
- 언어모델: 답변을 받기 위한 LLM API 호출
- 출력 파서(Output parser): 답변을 출력할 형식을 모델에게 전달한다.
PromptTemplate()와 PromptTemplate.from_template() 차이는 무엇인가?
프롬프트 생성
언어 모델: OPEN AI, 허깅 페이스 등 활용할 수 있음.
출력 파서
출력 형식 지정
체인
프롬프트, 모델, 아웃풋 파서 등의 여러 구성 요소를 조합하여 하나의 파이프 라인을 구성해주는 역할을 한다.
| 연산자: 각 요소를 체인으로 연결하는 역할을 한다.
{} 연산자: 딕셔너리 연산자 (key & value)
나만의 커스텀 체인 정의 하기
어떤 작업을 할 것인가?
1. 대본 시놉시스 쓰기 (title -> 연극 시놉시스 쓰기)
2. 시놉시스에 대한 리뷰 작성(1의 결과인 연극 시놉시스 -> 리뷰 작성)
구현하기
1. 먼저 각 작업에 대한 prompttemplate을 작성한다.
synopsis_prompt = PromptTemplate.from_template(
"너는 극작가야.너는 주어진 연극의 이름에 따라 알맞은 시놉시스를 쓰는것이야!\n\n 제목: {title}\n 내용 : 위 극의 시놉시스를 작성해:"
)
review_prompt = PromptTemplate.from_template(
"너는 연극 잡지의 비평가야. 주어진 극의 시놉시스에 리뷰를 써야해 \n\n시놉시스:\n{synopsis}\n 평론가로서 평가해줘"
)
2. 각 작업을 체인으로 엮기
chain = (
{"synopsis": synopsis_prompt | llm | StrOutputParser()}
| review_prompt | llm | StrOutputParser()
)
chain
각 부분을 해석해보자
chain = ( {"synopsis": synopsis_prompt | llm | StrOutputParser()} | review_prompt | llm | StrOutputParser() )
: '()' 안에 필요한 요소들을 정의한다. 이때 각 요소들은 | 연산자로 묶는다.
chain = ( {"synopsis": synopsis_prompt | llm | StrOutputParser()} | review_prompt | llm | StrOutputParser() )
: 딕셔너리 형태로 여러 요소들을 synopsis에 매칭한다.
synopsis라는 이름키에 synopsis_prompt & llm & StrOutputParser() 체인을 매핑한 것이라고 보면 된다.
Q. 딕셔너리에서 "synopsis"라는 키로 설정한 이유?
A. 리뷰 프롬프트에서 input 변수 이름을 'synopsis'로 전달 받기 때문이다.
즉 sysnopsis_prompt > llm > stroutputparser()를 통해 나온 시놉시스 텍스트가 "synopsis"라는 이름으로 review_prompt에 전달된다.
chain = ({"synopsis": synopsis_prompt | llm | StrOutputParser()} | review_prompt | llm | StrOutputParser() )
: review_prompt > llm > StrOutputParser를 거쳐서 비평 텍스트가 전달되게 된다.
또 다른 예시를 보기
template = """Use the following pieces of context to answer the question at the end.
If you don't know the answer, just say that you don't know, don't try to make up an answer.
Use three sentences maximum and keep the answer as concise as possible.
Always say "thanks for asking!" at the end of the answer.
{context}
Question: {question}
Helpful Answer:"""
custom_rag_prompt = PromptTemplate.from_template(template)
rag_chain = (
{"context": retriever | format_docs, "question": RunnablePassthrough()}
| custom_rag_prompt
| llm
| StrOutputParser()
)
rag_chain을 보면, context와 question을 custom_rag_prompt에 전달하고 있다.
- context: retriever > format_docs 체인을 포함함. 즉 RAG 검색 결과를 의미한다.
- question: 사용자 질문이다. 사용자 입력을 그대로 전달하는 RunnablePassthrough()를 사용
즉 rag 검색 결과와 원래 사용자 질문 question 을 custom rag_prompt에 전달하게 된다.
그러면 custom rag_prompt에서는 context를 기반으로 question에 응답할 수 있는지 없는지를 판단한다.
Reference
chain설명 예시
[langchain공부] langchain 핵심 - 1 (체인 만들기)
langchain의 핵심~!!!! 이름 그대로 chain을 만들어봅시다!! 그런데!!! 왜 체인이 필요할까요!!?? GPT를 활용, 연결되고 연결되는 결과물을 얻기 위해서입니다!! 예를들어!! 여러분은 한 연극의 제목에 대
drfirst.tistory.com