[PYTHON/LANGCHAIN] StructuredTool 클래스 : invoke 메소드에서 AIMessage 객체의 tool_calls 속성값을 사용해 ToolMessage 객체 구하기
■ StructuredTool 클래스의 invoke 메소드에서 AIMessage 객체의 tool_calls 속성 값을 사용해 ToolMessage 객체를 구하는 방법을 보여준다. ※ OPENAI_API_KEY 환경 변수 값은 .env
■ StructuredTool 클래스의 invoke 메소드에서 AIMessage 객체의 tool_calls 속성 값을 사용해 ToolMessage 객체를 구하는 방법을 보여준다. ※ OPENAI_API_KEY 환경 변수 값은 .env
■ RunnableBindable 클래스의 invoke 메소드를 사용해 모델에서 도구를 호출하는 방법을 보여준다. ※ OPENAI_API_KEY 환경 변수 값은 .env 파일에 정의한다. ▶ main.py
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 |
import random from dotenv import load_dotenv from langchain_core.tools import tool from typing import Tuple from typing import List from langchain_openai import ChatOpenAI load_dotenv() @tool(response_format = "content_and_artifact") def generateRandomIntegerValues(minimumValue : int, maximumValue : int, count : int) -> Tuple[str, List[int]]: """Generate size random ints in the range [minimumValue, maximumValue].""" array = [random.randint(minimumValue, maximumValue) for _ in range(count)] content = f"Successfully generated array of {count} random ints in [{minimumValue}, {maximumValue}]." return content, array chatOpenAI = ChatOpenAI(model = "gpt-4o-mini") runnableBindable = chatOpenAI.bind_tools([generateRandomIntegerValues]) responseAIMessage = runnableBindable.invoke("generate 6 positive ints less than 25") print(responseAIMessage.tool_calls) """ [{'name': 'generateRandomIntegerValues', 'args': {'minimumValue': 1, 'maximumValue': 24, 'count': 6}, 'id': 'call_F9ZZFBIsd6HXz30bb0yZTWgl', 'type': 'tool_call'}] """ |
■ ChatOpenAI 클래스의 bind_tools 메소드에서 parallel_tool_calls 인자를 사용해 병렬 도구 호출을 비활성화하는 방법을 보여준다. ※ OPENAI_API_KEY 환경 변수 값은 .env 파일에 정의한다.
■ chatOpenAI 클래스의 bind_tools 메소드에서 tool_choice 인자를 사용해 도구 호출을 강제하는 방법을 보여준다. ※ OPENAI_API_KEY 환경 변수 값은 .env 파일에 정의한다. ▶
■ 도구 실행 오류시 재실행하는 방법을 보여준다. ※ OPENAI_API_KEY 환경 변수 값은 .env 파일에 정의한다. ▶ main.py
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 |
from dotenv import load_dotenv from langchain_core.tools import tool from langchain_core.messages import ToolCall from langchain_core.messages import AIMessage from langchain_core.runnables import RunnableConfig from langchain_core.runnables import Runnable from langchain_core.messages import ToolMessage from langchain_core.messages import HumanMessage from langchain_core.prompts import ChatPromptTemplate from langchain_openai import ChatOpenAI load_dotenv() @tool def complexTool(integerValue : int, floatValue : float, dictionaryValue : dict) -> int: """Do something complex with a complex tool.""" return integerValue * floatValue class CustomToolException(Exception): """Custom LangChain tool exception.""" def __init__(self, toolCall : ToolCall, exception : Exception) -> None: super().__init__() self.tool_call = toolCall self.exception = exception def complexToolWithCustomException(aiMessage : AIMessage, config : RunnableConfig) -> Runnable: try: return complexTool.invoke(aiMessage.tool_calls[0]["args"], config = config) except Exception as exception: raise CustomToolException(aiMessage.tool_calls[0], exception) def getInputDictionary(inputDictionary : dict) -> dict: exception = inputDictionary.pop("exception") messageList = [ AIMessage(content = "", tool_calls = [exception.tool_call]), ToolMessage(tool_call_id = exception.tool_call["id"], content = str(exception.exception)), HumanMessage(content = "The last tool call raised an exception. Try calling the tool again with corrected arguments. Do not repeat mistakes.") ] inputDictionary["last_output"] = messageList return inputDictionary # 우리는 프롬프트에 last_output MessagesPlaceholder를 추가한다. # 이 메시지는 전달되지 않으면 프롬프트에 전혀 영향을 미치지 않지만 필요한 경우 임의의 메시지 목록을 프롬프트에 삽입할 수 있는 옵션을 제공한다. # 이를 재시도 시 사용하여 오류 메시지를 삽입한다. chatPromptTemplate = ChatPromptTemplate.from_messages( [ ("human" , "{input}" ), ("placeholder", "{last_output}") ] ) chatOpenAI = ChatOpenAI(model="gpt-4o-mini") runnableBindable = chatOpenAI.bind_tools([complexTool]) runnableSequence = chatPromptTemplate | runnableBindable | complexToolWithCustomException selfCorrectingRunnableSequence = runnableSequence.with_fallbacks([getInputDictionary | runnableSequence], exception_key = "exception") responseValue = selfCorrectingRunnableSequence.invoke({"input" : "use complex tool. the args are 5, 2.1, empty dictionary. don't forget dictionaryValue"}) print(responseValue) |
▶ requirements.txt
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 |
annotated-types==0.7.0 anyio==4.6.0 certifi==2024.8.30 charset-normalizer==3.3.2 colorama==0.4.6 distro==1.9.0 h11==0.14.0 httpcore==1.0.5 httpx==0.27.2 idna==3.10 jiter==0.5.0 jsonpatch==1.33 jsonpointer==3.0.0 langchain-core==0.3.5 langchain-openai==0.2.0 langsmith==0.1.128 openai==1.47.1 orjson==3.10.7 packaging==24.1 pydantic==2.9.2 pydantic_core==2.23.4 python-dotenv==1.0.1 PyYAML==6.0.2 regex==2024.9.11 requests==2.32.3 sniffio==1.3.1 tenacity==8.5.0 tiktoken==0.7.0 tqdm==4.66.5 typing_extensions==4.12.2 urllib3==2.2.3 |
※
■ RunnableSequence 클래스의 with_fallbacks 메소드를 사용해 도구 오류시 대체 모델을 사용하는 방법을 보여준다. ※ OPENAI_API_KEY 환경 변수 값은 .env 파일에 정의한다. ▶
■ try … except 구문을 사용해 도구 사용시 오류를 처리하는 방법을 보여준다. ※ OPENAI_API_KEY 환경 변수 값은 .env 파일에 정의한다. ▶ main.py
■ RunnableSequence 클래스의 batch 메소드에서 config 인자를 사용해 동시 작업 수를 설정하는 방법을 보여준다. ※ OPENAI_API_KEY 환경 변수 값은 .env 파일에 정의한다.
■ PromptTemplate 클래스의 from_template 정적 메소드를 사용해 PromptTemplate 객체를 만드는 방법을 보여준다. ※ OPENAI_API_KEY 환경 변수 값은 .env 파일에 정의한다. ▶ main.py
■ RunnableSequence 클래스의 invoke 메소드를 사용해 LCEL 체인을 실행하는 방법을 보여준다. ※ OPENAI_API_KEY 환경 변수 값은 .env 파일에 정의한다. ▶ main.py
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
from dotenv import load_dotenv from langchain_core.prompts import PromptTemplate from langchain_openai import ChatOpenAI load_dotenv() templateString = "{country}의 수도는 어디입니까?" promptTemplate = PromptTemplate.from_template(templateString) chatOpenAI = ChatOpenAI( model_name = "gpt-4o-mini", # 모델명 max_tokens = 2048, # 최대 토큰 수 temperature = 0.1, # 창의성 (0.0 ~ 2.0) ) runnableSequence = promptTemplate | chatOpenAI responseAIMessage = runnableSequence.invoke({"country" : "미국"}) print(responseAIMessage.content) """ 미국의 수도는 워싱턴 D.C.입니다. """ |
■ ChatOpenAI 클래스의 bind 메소드에서 logprobs 인자를 사용해 주어진 토큰 확률 로그 값을 받는 방법을 보여준다. ※ OPENAI_API_KEY 환경 변수 값은 .env
■ ChatOpenAI 클래스의 invoke 메소드를 사용해 질문하는 방법을 보여준다. ※ OPENAI_API_KEY 환경 변수 값은 .env 파일에 정의한다. ▶ main.py
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
from dotenv import load_dotenv from langchain_openai import ChatOpenAI load_dotenv() chatOpenAI = ChatOpenAI( model_name = "gpt-4o-mini", # 모델명 temperature = 0.1 # 창의성 (0.0 ~ 2.0) ) requestString = "대한민국의 수도는 어디입니까?" responseAIMessage = chatOpenAI.invoke(requestString) print(responseAIMessage.content) |
▶ requirements.txt
■ 도구 호출시 오류를 처리하는 방법을 보여준다. ※ OPENAI_API_KEY 환경 변수 값은 .env 파일에 정의한다. ▶ main.py
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 |
from dotenv import load_dotenv from langchain_core.tools import tool from langchain_core.runnables import RunnableConfig from langchain_core.runnables import Runnable from langchain_openai import ChatOpenAI load_dotenv() @tool def _execute(integerValue : int, floatValue : float, dictionary1 : dict) -> int: """Do something complex with a complex tool.""" return integerValue * floatValue def execute(tool_args : dict, config : RunnableConfig) -> Runnable: try: _execute.invoke(tool_args, config = config) except Exception as e: return f"Calling tool with arguments:\n\n{tool_args}\n\nraised the following error:\n\n{type(e)}: {e}" chatOpenAI = ChatOpenAI(model = "gpt-4o-mini") runnableBindable = chatOpenAI.bind_tools([_execute]) runnableSequence = runnableBindable | (lambda aiMessage : aiMessage.tool_calls[0]["args"]) | execute resultValue = runnableSequence.invoke("use complex tool. the args are 5, 2.1, empty dictionary. don't forget dictionary1") print(resultValue) """ Calling tool with arguments: {'integerValue': 5, 'floatValue': 2.1} raised the following error: <class 'pydantic_core._pydantic_core.ValidationError'>: 1 validation error for _execute dictionary1 Field required [type=missing, input_value={'integerValue': 5, 'floatValue': 2.1}, input_type=dict] For further information visit https://errors.pydantic.dev/2.9/v/missing """ |
▶ requirements.txt
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 |
annotated-types==0.7.0 anyio==4.6.0 certifi==2024.8.30 charset-normalizer==3.3.2 colorama==0.4.6 distro==1.9.0 h11==0.14.0 httpcore==1.0.5 httpx==0.27.2 idna==3.10 jiter==0.5.0 jsonpatch==1.33 jsonpointer==3.0.0 langchain-core==0.3.5 langchain-openai==0.2.0 langsmith==0.1.125 openai==1.47.0 orjson==3.10.7 packaging==24.1 pydantic==2.9.2 pydantic_core==2.23.4 python-dotenv==1.0.1 PyYAML==6.0.2 regex==2024.9.11 requests==2.32.3 sniffio==1.3.1 tenacity==8.5.0 tiktoken==0.7.0 tqdm==4.66.5 typing_extensions==4.12.2 urllib3==2.2.3 |
※
■ 도구 호출시 사용자 승인 절차를 추가하는 방법을 보여준다. ※ OPENAI_API_KEY 환경 변수 값은 .env 파일에 정의한다. ▶ main.py
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 |
import json from dotenv import load_dotenv from langchain_core.tools import tool from langchain_openai import ChatOpenAI from langchain_core.messages import AIMessage from typing import Dict from typing import List load_dotenv() @tool def countEmail(lastDayCount : int) -> int: """Dummy function to count number of e-mails. Returns 2 * last_n_days.""" return lastDayCount * 2 @tool def sendEmail(message : str, recipient : str) -> str: """Dummy function for sending an e-mail.""" return f"Successfully sent email to {recipient}." toolList = [countEmail, sendEmail] chatOpenAI = ChatOpenAI(model = "gpt-4o-mini") runnableBinding = chatOpenAI.bind_tools(toolList) def callTool(aiMessage : AIMessage) -> List[Dict]: """Simple sequential tool calling helper.""" toolMapDictionary = {tool.name : tool for tool in toolList} toolCallList = aiMessage.tool_calls.copy() for toolCall in toolCallList: toolCall["output"] = toolMapDictionary[toolCall["name"]].invoke(toolCall["args"]) return toolCallList class NotApproved(Exception): """Custom exception.""" def approve(aiMessage : AIMessage) -> AIMessage: """Responsible for passing through its input or raising an exception. Args: aiMessage : output from the chat model Returns: aiMessage : original output from the msg """ toolCallListJSON = "\n\n".join(json.dumps(toolCall, indent = 2) for toolCall in aiMessage.tool_calls) inputString = f"Do you approve of the following tool invocations\n\n{toolCallListJSON}\n\nAnything except 'Y'/'Yes' (case-insensitive) will be treated as a no.\n >>>" outputString = input(inputString) if outputString.lower() not in ("yes", "y"): raise NotApproved(f"Tool invocations not approved:\n\n{toolCallListJSON}") return aiMessage runnableSequence = runnableBinding | approve | callTool try: toolCallList = runnableSequence.invoke("how many emails did i get in the last 5 days?") print(toolCallList) except NotApproved as e: print() print(e) |
▶ requirements.txt
■ InjectedToolArg 클래스를 사용해 도구에 런타임 값을 전달하는 방법을 보여준다. ※ 런타임에만 알려진 도구에 값을 바인딩해야 할 수도 있다. ※ 예를 들어,
■ ChatOpenAI 클래스의 bind_tools 메소드를 사용해 도구 출력을 채팅 모델에 전달하는 방법을 보여준다. ※ OPENAI_API_KEY 환경 변수 값은 .env 파일에 정의한다. ▶
■ PydanticToolsParser 클래스의 생성자에서 tools 인자를 사용해 도구 호출 정보를 반환하는 방법을 보여준다. ※ OPENAI_API_KEY 환경 변수 값은 .env 파일에 정의한다. ▶
■ ChatOpenAI 클래스dml bind_tools 메소드를 사용해 도구 호출 메시지를 반환하는 방법을 보여준다. ※ OPENAI_API_KEY 환경 변수 값은 .env 파일에 정의한다. ▶ main.py
■ TimeWeightedVectorStoreRetriever 클래스에서 mock_now 함수를 사용해 가상 시간을 설정하는 방법을 보여준다. ▶ main.py
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 |
import faiss from langchain_openai import OpenAIEmbeddings from langchain_community.docstore import InMemoryDocstore from langchain_community.vectorstores import FAISS from langchain.retrievers import TimeWeightedVectorStoreRetriever from datetime import datetime from datetime import timedelta from langchain_core.documents import Document from langchain_core.utils import mock_now openAIEmbeddings = OpenAIEmbeddings() embeddingSize = 1536 indexFlatL2 = faiss.IndexFlatL2(embeddingSize) inMemoryDocstore = InMemoryDocstore({}) faiss = FAISS(openAIEmbeddings, indexFlatL2, inMemoryDocstore, {}) timeWeightedVectorStoreRetriever = TimeWeightedVectorStoreRetriever(vectorstore = faiss, decay_rate = 0.999, k = 1) yesterday = datetime.now() - timedelta(days = 1) timeWeightedVectorStoreRetriever.add_documents([Document(page_content = "hello world", metadata = {"last_accessed_at" : yesterday})]) timeWeightedVectorStoreRetriever.add_documents([Document(page_content = "hello foo")]) with mock_now(datetime(2024, 9, 16, 10, 11)): resultDocumentList = timeWeightedVectorStoreRetriever.get_relevant_documents("hello world") for resultDocument in resultDocumentList: print(resultDocument) |
▶ requirements.txt
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 |
aiohappyeyeballs==2.4.0 aiohttp==3.10.5 aiosignal==1.3.1 annotated-types==0.7.0 anyio==4.4.0 attrs==24.2.0 certifi==2024.8.30 charset-normalizer==3.3.2 colorama==0.4.6 dataclasses-json==0.6.7 distro==1.9.0 faiss-cpu==1.8.0.post1 frozenlist==1.4.1 greenlet==3.1.0 h11==0.14.0 httpcore==1.0.5 httpx==0.27.2 idna==3.10 jiter==0.5.0 jsonpatch==1.33 jsonpointer==3.0.0 langchain==0.3.0 langchain-community==0.3.0 langchain-core==0.3.0 langchain-openai==0.2.0 langchain-text-splitters==0.3.0 langsmith==0.1.121 marshmallow==3.22.0 multidict==6.1.0 mypy-extensions==1.0.0 numpy==1.26.4 openai==1.45.1 orjson==3.10.7 packaging==24.1 pydantic==2.9.1 pydantic-settings==2.5.2 pydantic_core==2.23.3 python-dotenv==1.0.1 PyYAML==6.0.2 regex==2024.9.11 requests==2.32.3 sniffio==1.3.1 SQLAlchemy==2.0.35 tenacity==8.5.0 tiktoken==0.7.0 tqdm==4.66.5 typing-inspect==0.9.0 typing_extensions==4.12.2 urllib3==2.2.3 yarl==1.11.1 |
※ pip install langchain-community langchain-openai
■ TimeWeightedVectorStoreRetriever 클래스를 사용해 높은 감쇠율로 문서를 검색하는 방법을 보여준다. ※ 높은 감소율(예 : 9가 여러 개)에서는 최근성 점수가 빠르게 0으로 떨어진다!
■ TimeWeightedVectorStoreRetriever 클래스를 사용해 낮은 감쇠율로 문서를 검색하는 방법을 보여준다. ※ 낮은 감쇠율(여기서는 극단적으로 0에 가깝게 설정했다)은 기억이 더 오랫동안 "기억"된다는 것을
■ TimeWeightedVectorStoreRetriever 클래스의 생성자에서 vectorstore/decay_rate 인자를 사용해 TimeWeightedVectorStoreRetriever 객체를 만드는 방법을 보여준다. ▶ main.py
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
import faiss from langchain_openai import OpenAIEmbeddings from langchain_community.docstore import InMemoryDocstore from langchain_community.vectorstores import FAISS from langchain.retrievers import TimeWeightedVectorStoreRetriever openAIEmbeddings = OpenAIEmbeddings() embeddingSize = 1536 indexFlatL2 = faiss.IndexFlatL2(embeddingSize) inMemoryDocstore = InMemoryDocstore({}) faiss = FAISS(openAIEmbeddings, indexFlatL2, inMemoryDocstore, {}) timeWeightedVectorStoreRetriever = TimeWeightedVectorStoreRetriever(vectorstore = faiss, decay_rate = 0.0000000000000000000000001, k = 1) |
▶ requirements.txt
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 |
aiohappyeyeballs==2.4.0 aiohttp==3.10.5 aiosignal==1.3.1 annotated-types==0.7.0 anyio==4.4.0 attrs==24.2.0 certifi==2024.8.30 charset-normalizer==3.3.2 colorama==0.4.6 dataclasses-json==0.6.7 distro==1.9.0 faiss-cpu==1.8.0.post1 frozenlist==1.4.1 greenlet==3.1.0 h11==0.14.0 httpcore==1.0.5 httpx==0.27.2 idna==3.10 jiter==0.5.0 jsonpatch==1.33 jsonpointer==3.0.0 langchain==0.3.0 langchain-community==0.3.0 langchain-core==0.3.0 langchain-openai==0.2.0 langchain-text-splitters==0.3.0 langsmith==0.1.121 marshmallow==3.22.0 multidict==6.1.0 mypy-extensions==1.0.0 numpy==1.26.4 openai==1.45.1 orjson==3.10.7 packaging==24.1 pydantic==2.9.1 pydantic-settings==2.5.2 pydantic_core==2.23.3 python-dotenv==1.0.1 PyYAML==6.0.2 regex==2024.9.11 requests==2.32.3 sniffio==1.3.1 SQLAlchemy==2.0.35 tenacity==8.5.0 tiktoken==0.7.0 tqdm==4.66.5 typing-inspect==0.9.0 typing_extensions==4.12.2 urllib3==2.2.3 yarl==1.11.1 |
※ pip install langchain-community
■ SelfQueryRetriever 클래스의 생성자에서 query_constructor 인자를 사용해 LCEL을 설정하는 방법을 보여준다. ※ OPENAI_API_KEY 환경 변수 값은 .env 파일에 정의한다. ▶ main.py
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 |
from dotenv import load_dotenv from langchain_core.documents import Document from langchain_openai import OpenAIEmbeddings from langchain_chroma import Chroma from langchain.chains.query_constructor.base import AttributeInfo from langchain.chains.query_constructor.base import get_query_constructor_prompt from langchain.chains.query_constructor.base import StructuredQueryOutputParser from langchain_openai import ChatOpenAI from langchain.retrievers.self_query.base import SelfQueryRetriever from langchain_community.query_constructors.chroma import ChromaTranslator load_dotenv() documentList = [ Document( page_content = "A bunch of scientists bring back dinosaurs and mayhem breaks loose", metadata = {"year" : 1993, "rating" : 7.7, "genre" : "science fiction"} ), Document( page_content = "Leo DiCaprio gets lost in a dream within a dream within a dream within a ...", metadata = {"year" : 2010, "director" : "Christopher Nolan", "rating" : 8.2} ), Document( page_content = "A psychologist / detective gets lost in a series of dreams within dreams within dreams and Inception reused the idea", metadata = {"year" : 2006, "director" : "Satoshi Kon", "rating" : 8.6} ), Document( page_content = "A bunch of normal-sized women are supremely wholesome and some men pine after them", metadata = {"year" : 2019, "director" : "Greta Gerwig", "rating" : 8.3} ), Document( page_content = "Toys come alive and have a blast doing so", metadata = {"year" : 1995, "genre" : "animated"} ), Document( page_content = "Three men walk into the Zone, three men walk out of the Zone", metadata = {"year" : 1979, "director" : "Andrei Tarkovsky", "genre" : "thriller", "rating" : 9.9} ) ] openAIEmbeddings = OpenAIEmbeddings() chroma = Chroma.from_documents(documentList, openAIEmbeddings) attributeInfoList = [ AttributeInfo( name = "genre", description = "The genre of the movie. One of ['science fiction', 'comedy', 'drama', 'thriller', 'romance', 'action', 'animated']", type = "string" ), AttributeInfo( name = "year", description = "The year the movie was released", type = "integer" ), AttributeInfo( name = "director", description = "The name of the movie director", type = "string" ), AttributeInfo( name = "rating", description = "A 1-10 rating for the movie", type = "float" ) ] documentContentDescription = "Brief summary of a movie" fewShotPromptTemplate = get_query_constructor_prompt( documentContentDescription, attributeInfoList ) structuredQueryOutputParser = StructuredQueryOutputParser.from_components() chatOpenAI = ChatOpenAI(temperature = 0) runnableSequence = fewShotPromptTemplate | chatOpenAI | structuredQueryOutputParser selfQueryRetriever = SelfQueryRetriever( query_constructor = runnableSequence, vectorstore = chroma, structured_query_translator = ChromaTranslator(), ) resultDocumentList = selfQueryRetriever.invoke("What's a movie after 1990 but before 2005 that's all about toys, and preferably is animated") for resultDocument in resultDocumentList: print(resultDocument) |
■ SelfQueryRetriever 클래스의 from_llm 정적 메소드에서 enable_limit 인자를 사용해 SelfQueryRetriever 객체를 만드는 방법을 보여준다. ※ OPENAI_API_KEY 환경 변수 값은 .env 파일에 정의한다.