DeepLearning.AI 강의 정리내용입니다.
예제로 살펴보자
prompt = ChatPromptTemplate.from_template(
"tell me a short joke about {topic}"
)
model = ChatOpenAI()
output_parser = StrOutputParser()
chain = prompt | model | output_parser
chain.invoke({"topic": "bears"})
# 출력
"Why don't bears wear shoes?\n\nBecause they already have bear feet!"
from langchain.embeddings import OpenAIEmbeddings
from langchain.vectorstores import DocArrayInMemorySearch
vectorstore = DocArrayInMemorySearch.from_texts(
["harrison worked at kensho", "bears like to eat honey"],
embedding=OpenAIEmbeddings()
)
retriever = vectorstore.as_retriever()
retriever.get_relevant_documents("where did harrison work?")
# 결과
[Document(page_content='harrison worked at kensho'),
Document(page_content='bears like to eat honey')]
retriever.get_relevant_documents("what do bears like to eat")
# 결과
[Document(page_content='bears like to eat honey'),
Document(page_content='harrison worked at kensho')]
# RAG 과정 -> context, 즉 retiriever로부터 fetch한 Document
template = """Answer the question based only on the following context:
{context}
Question: {question}
"""
prompt = ChatPromptTemplate.from_template(template)
# 1. Fetch relevant context
# 2. Pass 1. into the prompt
# 3. Pass 2. into a model
# 4. Pass 3. to the output parser
# 첫번째로 하나의 질문을 받아 두개(context, question)의 dictionary를 결과로 받게 Runnable 작성
from langchain.schema.runnable import RunnableMap
chain = RunnableMap({
"context": lambda x: retriever.get_relevant_documents(x["question"]),
"question": lambda x: x["question"]
)} | prompt | model | output_parser
chain.invoke({"question": "where the harrison work?"})
# 결과
'Harrison worked at Kensho.'
# 자세히 살펴보기
inputs = RunnableMap({
"context": lambda x: retriever.get_relevant_documents(x["question"]),
"question": lambda x: x["question"]
})
inputs.invoke({"question": "where did harrison work?"})
# 프롬프트 단에 들어가기 전 결과
{'context': [Document(page_content='harrison worked at kensho'),
Document(page_content='bears like to eat honey')],
'question': 'where did harrison work?'}
# 예를 들어 날씨 검색 api 를 사용하는 weather_search라는 function을 추가해보자
functions = [
{
"name": "weather_search",
"description": "Search for weather given an airport code",
"parameters": {
"type": "object",
"properties": {
"airport_code": {
"type": "string",
"description": "The airport code to get the weather for"
},
},
"required": ["airport_code"]
}
}
]
prompt = ChatPromptTemplate.from_messages(
[
("human", "{input}")
]
)
# .bind로 쉽게 function 추가!!!!
model = ChatOpenAI(temperature=0).bind(functions=functions)
runnable = prompt | model
runnable.invoke({"input": "what is the weather in sf"})
# 결과
AIMessage(content='', additional_kwargs={'function_call': {'name': 'weather_search', 'arguments': '{\n "airport_code": "SFO"\n}'}})
# 새로운 함수를 추가하고 싶을 때는 그냥 functions만 바꿔주면 업데이트 된다!!!
# 스포츠 경기 결과? 를 알려주는 함수 추가
functions = [
{
"name": "weather_search",
"description": "Search for weather given an airport code",
"parameters": {
"type": "object",
"properties": {
"airport_code": {
"type": "string",
"description": "The airport code to get the weather for"
},
},
"required": ["airport_code"]
}
},
{
"name": "sports_search",
"description": "Search for news of recent sport events",
"parameters": {
"type": "object",
"properties": {
"team_name": {
"type": "string",
"description": "The sports team to search for"
},
},
"required": ["team_name"]
}
}
]
model = model.bind(functions=functions)
runnable = prompt | model
runnable.invoke({"input": "how did the patriots do yesterday?"})
# 결과
AIMessage(content='', additional_kwargs={'function_call': {'name': 'sports_search', 'arguments': '{\n "team_name": "patriots"\n}'}})
from langchain.llms import OpenAI
import json
simple_model = OpenAI(
temperature=0,
max_tokens=1000,
model="text-davinci-001"
)
simple_chain = simple_model | json.loads
challenge = "write three poems in a json blob, where each poem is a json blob of a title, author, and first line"
simple_model.invoke(challenge)
# 결과
'\n\n["The Waste Land","T.S. Eliot","April is the cruelest month....이하 생략"]'
simple_chain.invoke(challenge) # davinci가 json이 유효하지 않기 때문에 오류 발생
model = ChatOpenAI(temperature=0)
chain = model | StrOutputParser() | json.loads
chain.invoke(challenge)
# 결과
{'poem1': {'title': 'Whispers of the Wind',
'author': 'Emily Rivers',
'first_line': 'Softly it comes, the whisper of the wind'},
'poem2': {'title': 'Silent Serenade',
'author': 'Jacob Moore',
'first_line': 'In the stillness of night, a silent serenade'},
'poem3': {'title': 'Dancing Shadows',
'author': 'Sophia Anderson',
'first_line': 'Shadows dance upon the moonlit floor'}}
# .with_fallbacks를 이용하여 원래 runnable 즉, simple_chain(json 안되는모델) 실행
# 2. 에러가 난다면 리스트 내에 있는 runnable들(여기선 하나밖에 없음)을 차례대로 성공할 때까지 수행한다.
final_chain = simple_chain.with_fallbacks([chain])
final_chain.invoke(challenge)
# 결과
{'poem1': {'title': 'Whispers of the Wind',
'author': 'Emily Rivers',
'first_line': 'Softly it comes, the whisper of the wind'},
'poem2': {'title': 'Silent Serenade',
'author': 'Jacob Moore',
'first_line': 'In the stillness of night, a silent serenade'},
'poem3': {'title': 'Dancing Shadows',
'author': 'Sophia Anderson',
'first_line': 'Shadows dance upon the moonlit floor'}}
prompt = ChatPromptTemplate.from_template(
"Tell me a short joke about {topic}"
)
model = ChatOpenAI()
output_parser = StrOutputParser()
chain = prompt | model | output_parser
# batch를 이용하여 여러 input에 대해 가능한 한 병렬적으로 처리하도록 한다.
chain.batch([{"topic": "bears"}, {"topic": "frogs"}])
# 결과
["Why don't bears wear shoes?\n\nBecause they have bear feet!",
'Why did the frog take the bus to work?\n\nBecause his car got toad away!']
# 비동기 처리도 쉽게 가능하다
# 컴포넌트 하나하나 비동기 처리 붙이는게 아닌 Runnable 에다 await 붙여주기
response = await chain.ainvoke({"topic": "bears"})
response