안녕하세요. 외부 셀프호스팅 방법 (Render, Railway etc)으로 소개해 주신 부분에 대해 질문드립니다. N8N공식 서비스를 사용하면 호스팅에 대한 지식이 전혀 없어도 간편히 사용할수 있잖아요. 그럼에도 외부 셀프호스팅 방법을 제안주신 이유는 어떤 필요에 의해서 일것 같은데 그 부분으로 짐작되는 것이 1.커뮤니티에 있는 비공식 노드들을 사용할수 있고 2.개인 로컬은 상시 ON상태를 유지하기 어렵고 3.셀프호스팅 방법에서보니.. 클릭으로 N8N환경을 자동으로 세팅해 간편해 보이기도 하고.. 이런 것이 맞을까요 ? 또는 제가 모르는 다른 필요가 있을까요 ?
안녕하세요 현재 유료 결제나 외부로 API를 연동하는 것이 사내 보안 규정 상 어려운 상황입니다. 강의에 나온 대로 langchain-core 라이브러리를 활용하는 경우 core 내부에 langsmith를 쓰는 import 가 있어 langsmith를 반드시 사용 해야하는 상황입니다. langsmith가 유료로 변경되면 API 키가 필요한 상황이라 현재 사내에서는 사용이 어려울 것 같습니다. 이런 경우 langsmith를 사용하지 않고 유사하게 기능을 구현하는 방법이 있는지 궁금합니다.
안녕하세요 강의 잘 보고있습니다. 에이전트 구현 관련해서 강의 외적으로 몇가지 질문드립니다. 에이전트를 리눅스 호스트에서 구동하며 ShellTool, PlayWright 등을 활용해서 원래 사람이 직접 리눅스와 소통하며 수행해야 했을 동작들을 에이전트로 대체하고자 합니다. 이와 관련된 좋은 Practice Example이 있을까요? 에이전트를 여러 시나리오에 대응할 수 있도록 여러 Sub StateGraph로 나누어 작업한 후에 이들을 하나의 에이전트로 합치는 구조를 생각하고 있습니다. 혹시 이렇게 될 경우 State가 Subgraph 마다 다른 것과, 메모리 등에 대해서 정확한 그림이 그려지지 않는데 이를 해결하기 위해 혹시 효과적인 설명이나 예시가 있을까요?
Upstage를 사용해도, exceeded 되었다고 에러나서요. 뭔가 최근에 토큰 제한이 줄었나봐요. 아래와 같이 batch를 주어서 반복문으로 요청후 database.add_documents(batch)하는 방식으로 해야되네요 ㅠㅠ from langchain_pinecone import PineconeVectorStore # 데이터를 처음 저장할 때 index_name = 'tax-upstage-index' # Split documents into smaller chunks text_splitter = RecursiveCharacterTextSplitter(chunk_size=1000, chunk_overlap=100) chunked_documents = text_splitter.split_documents(document_list) print(f"Chunked documents length: {len(chunked_documents)}") # Initialize the PineconeVectorStore database = PineconeVectorStore.from_documents( documents=[], # Start with an empty list embedding=embedding, index_name=index_name ) # Upload documents in batches batch_size = 100 for i in range(0, len(chunked_documents), batch_size): print(f'index: {i}, batch size: {batch_size}') batch = chunked_documents[i:i + batch_size] database.add_documents(batch) # Add documents to the existing database
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가 있는 것으로 보아 분명 '어떠한 방식'으로 등록하려는 도구들에 대한 메타 정보를 가져오는 것 같은데 그 '어떠한 방식'을 구체적으로 알고 싶습니다
제가 중국 상해에 거주하고 있습니다. SKT 사태로 유심 보호 서비스를 했고, 자동으로 해외로밍으로 핸드폰이 잠긴 상태입니다. 이런 인증의 경우가 필요해 해제를 해보려고 했지만, 핸드폰 인증이 필수 필요한 상황이라, 한국 상황만 고려, 해외에 있는 저 같은 고객은 해제 조차도 못하는 상황입니다. 공식적으로 SKT에 항의 문의와 답변을 기다리는 중입니다. 여름 휴가기간이나 되어야 한국에 나갈 것 같아.. 요청드려 봅니다. 핸드폰 인증의 절차를 요구하시는 것은 이해가 되지만, 제 강의 수강 신청 상태를 확인하시고, 제 개인 메일로 PDF와 JSON 워크플로우를 공유해 주실수는 없을까요 ? kinghm10@naver.com
안녕하세요, 강의들으면서 도움 많이 받고 있습니다. Pinecone API를 .env에 적었지만 인식을 못해서 하기와 같이 직접적으로 입력해주었습니다. 그런데 하기 부분에서 또 다시 정의가 안 되었다고 에러가 뜹니다. 어디를 수정해야할까요? 커널?을 껐다켰다하면 되는 분도 있다고 해서 따라해봤는데 잘 안 되는 것 같습니다.ㅠ
안녕하세요, 3.2 RAG구성 강의 중 하기 부분에서 막혔습니다. 조언 요청드립니다. OpenAI 대신, Upstage를 쓰고 싶어 하기와 같이 코드 수정을 하였습니다. 그런데 두번째 캡쳐 그림 부터 에러가 발생합니다. Upstage가 유효하지 않다고 하는 것 같은데... 무엇이 잘못된 것 일까요? 그리고 실습을 위해 OpenAI를 결제해야한다면 얼마정도 하면, 완강하는데 문제없을까요?! Error code: 400 - {'error': {'message': 'The requested model is invalid or no longer supported. You can find the list of available models on our models page ( https://console.upstage.ai/docs/models )', 'type': 'invalid_request_error', 'param': '', 'code': 'invalid_request_body'}}
안녕하세요 강의 보다가 헷갈리는 부분이 있어서 질문드립니다 질문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)에 반영하기 위해 사용된게 맞을까요?
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()