작성
·
12
·
수정됨
0
자체 예제를 만들어서 진행해보고 있는데,
사용자가 입력한 정보에서 배송지와 연락처를 추출한다는 상황을 가정하였습니다.
여기서 프롬프트를
from langchain_core.prompts import PromptTemplate
purpose_prompt = PromptTemplate.from_template("""
당신은 사용자의 입력값에 배송지와 연락처가 존재하는지 판단해서, 배송지와 연락처를 정확히 파싱하는 전문가입니다.
예를 들어 입력값이 '판교역로 123번지 23 01022345843'이라면, 배송지는 판교역로 123번지 23이고, 연락처는 01022345843입니다.
만약 배송지와 연락처가 모두 파악되면, message에는 '해당 정보가 맞습니까?'를 입력해주고 data에는 'delivery_address: {{message}}, phone_number: {{phone_number}}'라고 출력하고,
하나만 파악되면, 없는 쪽에 대해 '연락처를 (또는 배송지를) 다시 한 번 입력해주세요.'라고 message에 작성해주세요.
둘 다 파악하지 못했으면 '배송지와 연락처 정보를 다시 한 번 입력해주세요.'라고 message에 출력고 data는 빈 딕셔너리로 반환해주세요.
사용자의 입력값:
{{query}}
반환값 포맷:
{
"message": {{message}},
"data": {
"delivery_address": {{delivery_address}},
"phone_number": {{phone_number}}
}
}
""")
이런식으로 짰는데
KeyError: '\n "delivery_address"' During task with name 'generate' and id
이런 에러가 납니다. state를
from typing_extensions import TypedDict
class AgentState(TypedDict):
question: str
message: str
data: dict
from langchain_core.output_parsers import StrOutputParser
def generate(state: AgentState) -> AgentState:
"""사용자의 입력값을 기반으로 배송지와 연락처 정보를 추출하고, 추출된 결과를 JSON 형식으로 반환합니다."""
query = state['question']
rag_chain = purpose_prompt | llm | StrOutputParser()
response = rag_chain.invoke(query)
print(response)
return {'answer': response}
initial_state = {'question': '대왕판교로 1234 201동 앞에 01022384938'}
graph.invoke(initial_state)
이렇게 구성해봤는데 어디가 문제인지 모르겠습니다..
generate() 중간에 response를 찍어보려해도 더 이전에 에러가 나서 보이지 않는데.. 어디가 문제인지 알 수 있을까요?
또 output_par
답변 3
0
안녕하세요! 좋은 질문 감사합니다.
에러가 나는 원인은 프롬프트 포맷이 맞습니다. string안에 {}
로 감싸진 부분을 변수로 판단하기 때문에, 중괄호 안에 있는 변수들은 .invoke()
나 .stream()
을 호출할 때 변수로 넣어서 호출해야 합니다. 예를들면 사용자의 입력값의 경우에도 아래와 같이 작성하셔야 합니다.
"""
...생략
사용자의 입력값:
{query}
...생략
"""
그리고 invoke()
하는 시점에 .invoke({'query': '대왕판교로 1234 201동 앞에 01022384938'})
이런식으로 넣으셔야 합니다. 작성하신 코드의 포맷과 맞추려면 이런식이 되겠네요
response = rag_chain.invoke({'query': query})
중괄호를 겹쳐서 사용하는 경우에는, 해당 값이 변수가 아니라 dict라는 것을 나타내는데, 그런 경우에는 전체를 모두 이중으로 겹쳐서 아래와 같이 작성해야 합니다
"""
...생략
반환값 포맷:
{{
"message": {{message}},
"data": {{
"delivery_address": {{delivery_address}},
"phone_number": {{phone_number}}
}}
}}
...생략
"""
그래서 작성하신 코드를 수정해서 다시 실행해보자면, 아래와 같은 구조로 작성하셔야 정상적으로 돌아갑니다
from langchain_core.prompts import PromptTemplate
purpose_prompt = PromptTemplate.from_template("""
당신은 사용자의 입력값에 배송지와 연락처가 존재하는지 판단해서, 배송지와 연락처를 정확히 파싱하는 전문가입니다.
예를 들어 입력값이 '판교역로 123번지 23 01022345843'이라면, 배송지는 판교역로 123번지 23이고, 연락처는 01022345843입니다.
만약 배송지와 연락처가 모두 파악되면, message에는 '해당 정보가 맞습니까?'를 입력해주고 data에는 'delivery_address: {{message}}, phone_number: {{phone_number}}'라고 출력하고,
하나만 파악되면, 없는 쪽에 대해 '연락처를 (또는 배송지를) 다시 한 번 입력해주세요.'라고 message에 작성해주세요.
둘 다 파악하지 못했으면 '배송지와 연락처 정보를 다시 한 번 입력해주세요.'라고 message에 출력고 data는 빈 딕셔너리로 반환해주세요.
사용자의 입력값:
{query}
반환값 포맷:
{{
"message": {{message}},
"data": {{
"delivery_address": {{delivery_address}},
"phone_number": {{phone_number}}
}}
}}
""")
from langchain_core.output_parsers import StrOutputParser
from langchain_openai import ChatOpenAI
llm = ChatOpenAI(model="gpt-5-nano")
query = '대왕판교로 1234 201동 앞에 01022384938'
rag_chain = purpose_prompt | llm | StrOutputParser()
response = rag_chain.invoke({'query':query})
print(response)
이렇게 실행하시면 아래처럼 나옵니다!
0
프롬프트 포맷 및 중괄호 사용:
LangChain의 프롬프트에서 중괄호 {{}}
를 사용할 때는 보간을 위해 사용하는데, JSON 내에서 사용하려면 이중으로 사용해야 합니다. 한번 더 확인해보세요.
Typo 또는 이름 불일치:
중간에 변수 사용이나 반환 값에서 delivery_address
와 같은 키가 선언되어 있어야 합니다. 프롬프트 내에서 잘못 기재되었는지 점검해보세요.
해당 의견을 반영하면 어떻게 되어야 하는지 예시를 볼 수 있을까요?
기존에
반환값 포맷:
{
"message": {{message}},
"data": {
"delivery_address": {{delivery_address}},
"phone_number": {{phone_number}}
}
}
""")
에서
반환값 포맷:
{{{
"message": {{message}},
"data": {
"delivery_address": {{delivery_address}},
"phone_number": {{phone_number}}
}
}}}
""")
이렇게 하면 되는 건가요?
또 리턴값에 delivery_address
가 선언되어야 한다고 했는데 어디에서 선언해야 하는건지요? state에 선언되어야 하는건가요?
from typing_extensions import TypedDict
class DataState(TypedDict):
delivery_address: str
phone_number: str
class AgentState(TypedDict):
question: str
message: str
data: DataState
이렇게 선언해두고 자시 실행해봐도
KeyError Traceback (most recent call last) Cell In[12], line 2 1 initial_state = {'question': '대왕판교로 1234 201동 앞에 01022384938'} ----> 2 graph.invoke(initial_state) File ~/miniconda3/envs/ai/lib/python3.11/site-packages/langgraph/pregel/main.py:3026, in Pregel.invoke(self, input, config, context, stream_mode, print_mode, output_keys, interrupt_before, interrupt_after, durability, kwargs) 3023 chunks: list[dict[str, Any] | Any] = [] 3024 interrupts: list[Interrupt] = [] -> 3026 for chunk in self.stream( 3027 input, 3028 config, 3029 context=context, 3030 stream_mode=["updates", "values"] 3031 if stream_mode == "values" 3032 else stream_mode, 3033 print_mode=print_mode, 3034 output_keys=output_keys, 3035 interrupt_before=interrupt_before, 3036 interrupt_after=interrupt_after, 3037 durability=durability, 3038 kwargs, 3039 ): 3040 if stream_mode == "values": 3041 if len(chunk) == 2:
...
255 else: --> 256 return kwargs[key] KeyError: '\n "delivery_address"' During task with name 'generate' and id '800f8345-efd6-2e9b-4ae5-e8bbabce0b7b'
이런 키에러가 납니다..
0
안녕하세요, 인프런 AI 인턴입니다. support님께서 질문하신 내용은 LangChain을 활용하여 RAG 응답에 대한 커스텀(JSON)을 구성하는 과정에서 KeyError가 발생한 문제입니다. 이 문제를 해결하기 위해 몇 가지 점검 사항을 안내해드리겠습니다.
프롬프트 포맷 및 중괄호 사용:
{{}}
를 사용할 때는 보간을 위해 사용하는데, JSON 내에서 사용하려면 이중으로 사용해야 합니다. 한번 더 확인해보세요.응답 처리 로직:
purpose_prompt
의 반환 형식과 generate
함수 내 로직이 잘못 매핑될 때 이와 유사한 오류가 발생할 수 있습니다.Typo 또는 이름 불일치:
delivery_address
와 같은 키가 선언되어 있어야 합니다. 프롬프트 내에서 잘못 기재되었는지 점검해보세요.프롬프트 내용 확인
프롬프트 내 JSON 구조에 대한 변수 이름이 잘 맞는지 확인해야 합니다. {{}}
로 보간되거나 선언되지 않은 변수가 없는지 점검하십시오.
위의 프롬프트에 정의된 delivery_address
, phone_number
등이 정확히 템플릿 내부의 다른 곳에서도 선언되고 매핑되어야 합니다.
코드 로직 점검
response = rag_chain.invoke(query)
호출 후 response
의 구조를 예상해야 합니다. 이 response
가 의도한대로 generate
에서 사용될 수 있는 형태인지 확인해 보세요.디버깅 추가
generate
함수가 호출되기 전후를 print()
로 출력하여 각 단계에서 state 또는 응답값의 형태를 확인할 수 있도록 합니다.**해결을 위한 예제:
None
을 정의하는 것도 고려해볼 수 있습니다.관련 유사 질문 링크:
- 해당 내용이 설명된 유사 링크를 추가할 수 있습니다: 프롬프트에서 발생하는 데이터 매핑 오류에 대한 일반적 해결 사례를 참고하세요.
구성하신 코드가 예상대로 작동할 수 있도록 위의 점검 사항들을 참고하여 진행해 보시기 바랍니다. 질문에 대한 추가 문제가 생기면, 이어서 더 상세히 질문해 주세요.
저는 질문자님의 이해를 돕고자 지식공유자님의 기존 답변을 참고하여 유사한 답변 링크를 추천해드리고 있습니다. 현재 베타 기능으로 답변이 만족스럽지 않을 수 있는 점 양해 부탁드립니다. 🙏 추가적으로 궁금한 점이 있으시면, 이어서 질문해 주세요. 곧 지식공유자께서 답변해 주실 것입니다.