묻고 답해요
156만명의 커뮤니티!! 함께 토론해봐요.
인프런 TOP Writers
-
해결됨LangGraph를 활용한 AI Agent 개발 (feat. MCP)
안녕하세요.
안녕하세요.기획자로 일하고 있는 직장인입니다. 강의를 듣던중 갑자기 궁금한 것이 있는데,강사님께서 Claude Code대신 Cursor를 이용하시는 이유를 여쭤볼 수 있을까요? 감사합니다.
-
미해결AI 에이전트로 구현하는 RAG 시스템(w. LangGraph)
강의 46에서 노드의 병렬 수행시 Thread-Safety 문제는 없을까요?
강의 46 듣고 질문드립니다.여러 노드가 병렬로 수행 되면서 동일한 ToolSearchState를 접근해서 데이터를 수정하게 되면 thread-safety 문제가 발생할 텐데 이런 부분에 대한 설명이 명시적이지 않아서 어떻게 처리 되는 건지 궁금합니다. Langchain에서 State 클래스는 이미 thread-safety를 보장하는 것인가요? 아니면 강의 예제에는 없었지만 실 구현시에는 사용자가 직접 thread-safety에 대한 고려를 해서 코딩해야 하는 건가요?
-
미해결AI 에이전트로 구현하는 RAG 시스템(w. LangGraph)
similarity_search 후 왜 다시 LLM을 통해 grade를 측정 하나요?
안녕하세요.Self RAG 에이전트 구현하기 강좌에 대한 질문이 있습니다. 중간 중간에 결과 평가하는 것 중 검색된 문서와 질문에 대한 관련성을 평가하는 부분이 있는데요, 검색 자체를 embedding된 vector에서 similarity search를 하여 뽑아 낸 것들이고, 이 방식 자체가 질문과 유사한 문서를 뽑아 내는 기술인데 굳이 LLM으로 하여 다시 평가를 하게 하는 이유는 뭘까요? 벡터 embedding 과 유사도 검색에 대한 기술이 LLM에 맏기는 것 보다 유사도 검색에 있어 더 정확해야 하는 것이 아닌가 하는 생각이 들어서요. LLM이 하는 유사도 평가가 더 정확하다면 굳이 벡터 embedding 같은 기술을 쓸 필요가 있을까 싶어서 질문 드립니다.
-
미해결AI 에이전트로 구현하는 RAG 시스템(w. LangGraph)
agent_executor 실행시 JSONDecodeError에러가 발생해요.
문제가 발생하는 코드 ㄴ LLM모델만 gemini-2.5-pro로 사용하고 있고 다른 부분은 다른게 없는데 아래의 에러가 발생하네요...혹시 도와주실 수 있을까요? # AgentExecutor 실행 query = "시그니처 스테이크의 가격과 특징은 무엇인가요? 그리고 스테이크와 어울리는 와인 추천도 해주세요." agent_response = agent_executor.invoke({"input": query})에러로그 Entering new AgentExecutor chain... Invoking: search_menu with {'query': 'Signature Steak'} [Document(metadata={'menu_name': '시그니처 스테이크', 'menu_number': 1, 'source': './data/restaurant_menu.txt'}, page_content='1. 시그니처 스테이크\n • 가격: ₩35,000\n • 주요 식재료: 최상급 한우 등심, 로즈메리 감자, 그릴드 아스파라거스\n • 설명: 셰프의 특제 시그니처 메뉴로, 21일간 건조 숙성한 최상급 한우 등심을 사용합니다. 미디엄 레어로 조리하여 육즙을 최대한 보존하며, 로즈메리 향의 감자와 아삭한 그릴드 아스파라거스가 곁들여집니다. 레드와인 소스와 함께 제공되어 풍부한 맛을 더합니다.'), Document(metadata={'menu_name': '안심 스테이크 샐러드', 'menu_number': 8, 'source': './data/restaurant_menu.txt'}, page_content='8. 안심 스테이크 샐러드\n • 가격: ₩26,000\n • 주요 식재료: 소고기 안심, 루꼴라, 체리 토마토, 발사믹 글레이즈\n • 설명: 부드러운 안심 스테이크를 얇게 슬라이스하여 신선한 루꼴라 위에 올린 메인 요리 샐러드입니다. 체리 토마토와 파마산 치즈 플레이크로 풍미를 더하고, 발사믹 글레이즈로 마무리하여 고기의 풍미를 한층 끌어올렸습니다.')] Invoking: search_wine with {'query': 'steak'} [Document(metadata={'menu_name': '사시카이아 2018', 'menu_number': 3, 'source': './data/restaurant_wine.txt'}, page_content='3. 사시카이아 2018\n • 가격: ₩420,000\n • 주요 품종: 카베르네 소비뇽, 카베르네 프랑, 메를로\n • 설명: 이탈리아 토스카나의 슈퍼 투스칸 와인입니다. 블랙베리, 카시스의 강렬한 과실향과 함께 허브, 가죽, 스파이스 노트가 복잡성을 더합니다. 풀바디이지만 우아한 타닌과 신선한 산도가 균형을 잡아줍니다. 오크 숙성으로 인한 바닐라, 초콜릿 향이 은은하게 느껴집니다.'), Document(metadata={'menu_name': '샤토 디켐 2015', 'menu_number': 9, 'source': './data/restaurant_wine.txt'}, page_content='9. 샤토 디켐 2015\n • 가격: ₩800,000 (375ml)\n • 주요 품종: 세미용, 소비뇽 블랑\n • 설명: 보르도 소테른 지역의 legendary 디저트 와인입니다. 아프리콧, 복숭아, 파인애플의 농축된 과실향과 함께 꿀, 사프란, 바닐라의 복잡한 향이 어우러집니다. 놀라운 농축도와 균형 잡힌 산도, 긴 여운이 특징이며, 100년 이상 숙성 가능한 와인으로 알려져 있습니다.')]--------------------------------------------------------------------------- JSONDecodeError Traceback (most recent call last) Cell In[163], line 4 1 # AgentExecutor 실행 3 query = "시그니처 스테이크의 가격과 특징은 무엇인가요? 그리고 스테이크와 어울리는 와인 추천도 해주세요." ----> 4 agent_response = agent_executor.invoke({"input": query}) File c:\Users\jangi\AppData\Local\pypoetry\Cache\virtualenvs\langgraph-agent-AGzdf7hx-py3.11\Lib\site-packages\langchain\chains\base.py:170, in Chain.invoke(self, input, config, kwargs) 168 except BaseException as e: 169 run_manager.on_chain_error(e) --> 170 raise e 171 run_manager.on_chain_end(outputs) 173 if include_run_info: File c:\Users\jangi\AppData\Local\pypoetry\Cache\virtualenvs\langgraph-agent-AGzdf7hx-py3.11\Lib\site-packages\langchain\chains\base.py:160, in Chain.invoke(self, input, config, kwargs) 157 try: 158 self._validate_inputs(inputs) 159 outputs = ( --> 160 self._call(inputs, run_manager=run_manager) 161 if new_arg_supported 162 else self._call(inputs) 163 ) 165 final_outputs: Dict[str, Any] = self.prep_outputs( 166 inputs, outputs, return_only_outputs 167 )... 339 if end != len(s): --> 340 raise JSONDecodeError("Extra data", s, end) 341 return obj JSONDecodeError: Extra data: line 1 column 29 (char 28)Output is truncated. View as a scrollable element or open in a text editor. Adjust cell output settings...
-
미해결모두를 위한 대규모 언어 모델 LLM Part 5 - LangGraph로 나만의 AI 에이전트 만들기
비동기 방식으로 agent를 구성할 필요성이 궁금합니다.
안녕하세요, 강의 감사히 잘 보고 있습니다.Plan-and-Execute 강의 코드 보다가 궁금한 점이 있는데요,다른 agent 구성에서는 동기 방식으로 def를 정의했었는데,여기에서는 async와 await, .ainvoke의 비동기 방식으로 agent를 정의하는 것 같아 왜 여기서는 비동기 방식으로 정의하는지 여쭤봅니다.plan -> execute -> replan 자체도 순차적으로 실행되는 것 같은데(RAG와 같이), 비동기 방식이 어떤 이유로 필요한 것인지 질문드립니다.감사합니다.
-
미해결모두를 위한 대규모 언어 모델 LLM Part 5 - LangGraph로 나만의 AI 에이전트 만들기
Structured outputs ppt 강의자료 다운로드 가능 위치 문의
안녕하세요, 강의 잘 듣고 있습니다.강의자료 관련하여Structured outputs 관련 자료는 '강의 슬라이드 다운로드'를 통한 다운로드에도 포함되어 있지 않고 강의 화면에서 아래로 스크롤을 내려서도 확인할 수 없는데,어디서 받을 수 있는지 답변주시면 감사드리겠습니다.
-
미해결AI 에이전트로 구현하는 RAG 시스템(w. LangGraph)
툴의 숫자가 많을때 동작
안녕하세요.강의들 듣다가 질문이 생겨서 문의 드립니다. 첫번째, 툴이 너무 많은경우 어떤 식으로 처리해야 하나요? 즉, 사용할수 있는 툴이 천개 정도 된다면 LLM 호출시 마다 모든 툴에 대한 description 등을 같이 보내서 알맞은 툴을 선택하라고 할 수 없을 것 같은데 좋은 방법이 있을 까요?두번째, 툴들 중 비슷한 역할을 하거나 중복되는 툴이 있을 때는 어떻게 처리해야 하나요? 사용자 정의 툴들을 등록하다 보면 기존에 있었던 것과 동일하지만 이름만 다르거나 아예 중복되는 툴들이 생길 수 있는데 이럴때 처리 방법이 궁금합니다.
-
미해결LangGraph를 활용한 AI Agent 개발 (feat. MCP)
키워드 사전 강의
안녕하세요 강의 7분 30초 쯤에 키워드 사전을 통해서 답변의 퀄리티를 높힌다고 하셨는데 그 강의가 RAG를 활용한 LLM Application 개발 (feat. LangChain) 일까요??
-
미해결LangGraph를 활용한 AI Agent 개발 (feat. MCP)
2.2 PDF 전처리 강의에서 문의가 있습니다.
강의에서 구성한 그래프를 보면 retriever로 조회한 document들을 그대로 context로 넣는것으로 보이는데요.여기에서 document의 page_content만 추출하는 과정은 필요 없나요?lang smith를 보면 아래와 같이 프롬프트가 구성되어있는데 page_content만 넣도록 해야하는것이 아닌가 의문이 들었습니다.
-
미해결LangGraph를 활용한 AI Agent 개발 (feat. MCP)
2.2 PDF 전처리 > PDF Loader
안녕하세요.강의에선 zeorx로 PDF -> Markdown 변환 후 UnstructuredMarkdownLoader로 split해서 document chunk를 얻는데요 혹시 UnstructuredPDFLoader를 통해서 한번에 load_and_split 하는것과는 어떤 차이가 있을까요? UnstructuredLoader에서 요구하는 것이 패키지 외에도 pdf2image 모듈등이 있는것 같아서 실제로 시도해보지는 못했습니다.
-
미해결LangGraph를 활용한 AI Agent 개발 (feat. MCP)
LlamaIndex
혹시 LlamaIndex 관련한 강의는 없는지 또는 계획은 없으신지 궁금합니다
-
미해결LangGraph를 활용한 AI Agent 개발 (feat. MCP)
PDF 청킹 문의
안녕하세요. 강의 잘 수강하고 있습니다.자체적으로 텍스트, 표, 시계열꺽은선그래프로 주로 구성된 pdf를 임베딩해서 RAG 기반의 LLM 서비스를 만들어 보고 싶은데요표의 경우는 md 파일을 txt로 변환해서 저장하는 방법을 잘 알려주셨습니다만, 혹시 꺾은선그래프를 이미지처럼 저장해서 서비스에 활용할 수 있는 방법이 있을까요? 참고할만한 기술이나 좋은 아이디어 있으면 공유 혹은 조언해주시면 감사하겠습니다.
-
미해결AI 에이전트로 구현하는 RAG 시스템(w. LangGraph)
안녕하세요 후속강의 듣고 싶은데, 비용이 부담되어서..
혹시 할인계획이 있으신지요?
-
미해결LangGraph를 활용한 AI Agent 개발 (feat. MCP)
커널 재실행 후 Run all 할 경우 에러
커널 재실행 직후 run all 하면 토큰 수 제한 에러가 뜹니다. 다시 run all하면 잘 실행되구요. websearch 후 generate의 query 찍어보면 토큰 수 제한 걸릴일이 없는 문장인데 왜이럴까요? websearch 후 generate의 query 값이 "쿼리입니다 === " 이 부분입니다.
-
해결됨LangGraph를 활용한 AI Agent 개발 (feat. MCP)
create_react_agent, retriever요약 문제점
안녕하십니까 선생님 강의 잘 듣고있습니다.만약 create_react_agent에 tool이 vectordb retriever를 수행 할 때 retriever의 문서의 내용이 너무 많은 context를 가지고 있다면 llm이 리트리버한 결과를 바탕으로 질문에 대한 답변을 하지 않고 리트리버 문서를 요약해서 답변으로 출력합니다. 왜 그런건지 궁금합니다. from langgraph.prebuilt import create_react_agent @tool def retriever_tool(query: str)->List[Document]: """ 이 도구는 HR 데이터베이스에서 정보를 검색합니다. """ return retriever.invoke(query) tools = [retriever_tool] research_agent = create_react_agent( model = llm, tools = tools, prompt=(""), )
-
미해결LangGraph를 활용한 AI Agent 개발 (feat. MCP)
Agent로 리눅스 제어
안녕하세요 강의 잘 보고있습니다. 에이전트 구현 관련해서 강의 외적으로 몇가지 질문드립니다. 에이전트를 리눅스 호스트에서 구동하며 ShellTool, PlayWright 등을 활용해서 원래 사람이 직접 리눅스와 소통하며 수행해야 했을 동작들을 에이전트로 대체하고자 합니다. 이와 관련된 좋은 Practice Example이 있을까요?에이전트를 여러 시나리오에 대응할 수 있도록 여러 Sub StateGraph로 나누어 작업한 후에 이들을 하나의 에이전트로 합치는 구조를 생각하고 있습니다. 혹시 이렇게 될 경우 State가 Subgraph 마다 다른 것과, 메모리 등에 대해서 정확한 그림이 그려지지 않는데 이를 해결하기 위해 혹시 효과적인 설명이나 예시가 있을까요?
-
해결됨LangGraph를 활용한 AI Agent 개발 (feat. MCP)
agent가 tool을 선택하는 방법?
from langchain_core.messages import HumanMessage from langgraph.prebuilt import create_react_agent from langchain_mcp_adapters.client import MultiServerMCPClient async with MultiServerMCPClient( { "house_tax": { "command": "python", "args": ["./mcp_stdio_server.py"], "transport": "stdio", }, } ) as client: ##### AGENT ##### tool_list = client.get_tools() agent = create_react_agent(llm, tool_list) query = '5억짜리 집 1채, 10억짜리 집 1채, 20억짜리 집 1채를 가지고 있을 때 세금을 얼마나 내나요?' system_prompt = client.get_prompt(server_name="house_tax", prompt_name="house_tax_system_prompt", arguments={}) messages = await system_prompt + [HumanMessage(content=query)] print("=====RESPONSE=====") stream_generator = agent.astream({'messages': messages}) all_chunks = await process_stream(stream_generator) if all_chunks: final_result = all_chunks[-1] print("\nFinal result:", final_result)안녕하세요, mcp 쪽 공부하다가 궁금한 점이 생겨서 질문드립니다. MultiServerMCPClient를 이용해서 react_agent를 생성하면, query에 적합한 tool들을 알아서 선별해서 query가 요청하는 태스크를 실행해주는 방식이란 점은 잘 이해가 됩니다. 하지만, 어떤 방식으로 tool들의 메타 정보(description, 필수 argument 정보)등을 가져오고 인식하는 지 공식 문서로 정리된 점이 있나요? 강의 자료에서는 local python 파일을 이용해서 tool을 등록했지만, 아래의 방식처럼 smithery를 통해 tool을 등록하는 방법도 있는 것으로 알고 있습니다. 이렇게 tool을 등록하는 방식이 다양한데 MultiServerMCPClient가 어떤 식으로 tool들의 정보와 사용법에 대한 정보를 얻어서, 태스크에 적절한 tool들을 할당할 수 있는 지에 대해 여쭤보고 싶습니다"Gmail": { "transport": "sse", "enabled": True, "command": "npx", "args": [ "-y", "supergateway", "--sse", "https://" ], https://github.com/langchain-ai/langchain-mcp-adapters/tree/main 에서 MultiServerMCPClient 코드들을 조회해봤을 때 get_prompt나 get_resources가 있는 것으로 보아 분명 '어떠한 방식'으로 등록하려는 도구들에 대한 메타 정보를 가져오는 것 같은데 그 '어떠한 방식'을 구체적으로 알고 싶습니다
-
해결됨LangGraph를 활용한 AI Agent 개발 (feat. MCP)
멀티턴, MemorySaver,MessagesState 질문 입니다
안녕하세요 강의 보다가 헷갈리는 부분이 있어서 질문드립니다 질문1. 3.3 LangGraph에서 도구(tool) 활용 방법아래 agent 함수는 여러번 호출되는데 리턴하는 부분에서 새로운 배열을 만드는것 처럼 보이지만 add_messages에 의해 자동으로 누적되어 멀티턴 대화가 된다고 이해하면 맞을까요? def agent(state: MessagesState) -> MessagesState: """ 에이전트 함수는 주어진 상태에서 메시지를 가져와 LLM과 도구를 사용하여 응답 메시지를 생성합니다. Args: state (MessagesState): 메시지 상태를 포함하는 state. Returns: MessagesState: 응답 메시지를 포함하는 새로운 state. """ # 상태에서 메시지를 추출합니다. messages = state['messages'] # LLM과 도구를 사용하여 메시지를 처리하고 응답을 생성합니다. response = llm_with_tools.invoke(messages) # 응답 메시지를 새로운 상태로 반환합니다. return {'messages': [response]} 질문2. 3.5 Agent의 히스토리를 관리하는 방법MemorySaver()의 목적은 주피터 노트북 각 블록을 사용하는데 있어 그 전에 실행해서 얻은 message를 메모리에 저장후 다음 요청 (update_query)에 반영하기 위해 사용된게 맞을까요?
-
미해결LangGraph를 활용한 AI Agent 개발 (feat. MCP)
새로운 메시지에 summary 추적 질문드립니다.
from langchain_core.messages import SystemMessage def agent(state: AgentState) -> AgentState: """ 주어진 `state`에서 메시지를 가져와 LLM과 도구를 사용하여 응답 메시지를 생성합니다. Args: state (AgentState): 메시지 기록과 요약을 포함하는 state. Returns: MessagesState: 응답 메시지를 포함하는 새로운 state. """ # 메시지와 요약을 state에서 가져옵니다. messages = state['messages'] summary = state['summary'] # 요약이 비어있지 않으면, 요약을 메시지 앞에 추가합니다. if summary != '': messages = [SystemMessage(content=f'Here is the summary of the earlier conversation: {summary}')] + messages # LLM과 도구를 사용하여 메시지에 대한 응답을 생성합니다. response = llm_with_tools.invoke(messages) # 응답 메시지를 포함하는 새로운 state를 반환합니다. return {'messages': [response]}부분에summary = state['summary']agent시작하자마자 summary를 넣게되는데 해당 소스부분은 몇 번을 질문해도 처음에는 빈값이 들어가는게 맞나요?summary를 연속질문에 처음 시작 부터 적용하기 위해서는 아래처럼 session정보를 받아서 처리해야하는지 궁금합니다.from langchain_core.messages import HumanMessage query = '안녕' for chunk in graph.stream({'messages': [HumanMessage(query)], 'summary': graph.get_state(config).values['summary']}, config=config, stream_mode='values'): chunk['messages'][-1].pretty_print()
-
미해결모두를 위한 대규모 언어 모델 LLM Part 5 - LangGraph로 나만의 AI 에이전트 만들기
STORM 관련 ipynb 소스에서
안녕하세요.. 수업노트에 있는 storm colab 파일을 따라 하는데..import json from langchain_core.runnables import RunnableConfig async def gen_answer( state: InterviewState, config: Optional[RunnableConfig] = None, name: str = "Subject_Matter_Expert", max_str_len: int = 15000, ): swapped_state = swap_roles(state, name) # Convert all other AI messages # 쿼리 생성 queries = await gen_queries_chain.ainvoke(swapped_state) query_results = await search_engine.abatch( queries["parsed"].queries, config, return_exceptions=True ) successful_results = [ res for res in query_results if not isinstance(res, Exception) ] # url와 콘텐츠 추출 all_query_results = { res["url"]: res["content"] for results in successful_results for res in results } # We could be more precise about handling max token length if we wanted to here dumped = json.dumps(all_query_results)[:max_str_len] ai_message: AIMessage = queries["raw"] tool_call = queries["raw"].tool_calls[0] tool_id = tool_call["id"] tool_message = ToolMessage(tool_call_id=tool_id, content=dumped) swapped_state["messages"].extend([ai_message, tool_message]) # Only update the shared state with the final answer to avoid # polluting the dialogue history with intermediate messages generated = await gen_answer_chain.ainvoke(swapped_state) cited_urls = set(generated["parsed"].cited_urls) # Save the retrieved information to a the shared state for future reference cited_references = {k: v for k, v in all_query_results.items() if k in cited_urls} formatted_message = AIMessage(name=name, content=generated["parsed"].as_str) return {"messages": [formatted_message], "references": cited_references}이 부분에서 궁금한 것이 생겼습니다. 중간에 tool_call = queries["raw"].tool_calls[0] tool_id = tool_call["id"] 중간에 tool_calls 관련 정보를 호출하는데..그럴려면 gen_queries_chain이 체인에 tool_bind된 llm이 사용되어야 하는 것 아닌가요? duckduckgo 관련 search_engine함수를 @tool을 이용해서 tool로 선언한 것 같은데.. 해당 퉁을 llm에 바인딩하는 것을 못보아서.. tool index 부분에서 Cell In[46], line 30, in gen_answer(state, config, name, max_str_len) 28 dumped = json.dumps(all_query_results)[:max_str_len] 29 ai_message: AIMessage = queries["raw"] ---> 30 tool_call = queries["raw"].tool_calls[0] 31 tool_id = tool_call["id"] 32 tool_message = ToolMessage(tool_call_id=tool_id, content=dumped) IndexError: list index out of range가 발생하는 것 같습니다. 어떻게 수정하면 되는지 알려주세요..