이번 포스팅에서도 랭체인의 컴포넌트에 대해 알아볼거에요.
랭체인의 컴포넌트에는 Model I/O, Retrieval, Composition, Memory, Callbacks 등이 있어요.
이번에는 Composition에 대해서 학습해볼게요.
Composition에는 Tool, Agents, Chains 등의 컴포넌트가 있어요.
이 고수준의 컴포넌트들을 다른 임의의 시스템(ex. 외부 API, 서비스 등) 또는
랭체인의 기본 요소들과 결합해요.
Composition을 구성하고 있는 컴포넌트들이 어떤 역할을 담당하는지 살펴볼게요.
# Tool
Tool은 LLM 및 기타 구성 요소가 다른 시스템과 상호작용을 할 수 있도록
인터페이스를 제공해요!
Tool에는 Wikipedia나 PythonREPL 등이 있어요.
Tool은 Agents, Chains, LLM이 세상과 상호작용할 수 있도록 지원하는 인터페이스에요.
대표적으로 Wikipedia나 PythonRepl 등이 있는데요.
Tool을 사용하면 아래 정보를 기본적으로 제공해줘요.
- 도구의 이름
- 도구가 무엇인지에 대한 설명
- 도구가 무엇을 어떻게 입력해야 하는지 작성된 JSON 스키마
- 호출할 함수의 정보
- 도구의 결과를 사용자에게 직접 반환해야 하는지 여부
Tool을 이용하는 Component에게 이 모든 정보를 제공하는 것이 좋아요.
제공된 정보를 사용해서 Action-taking System(액션 수행 시스템)을 구축할 수 있기 때문이죠.
이름, 설명, JSON 스키마를 제공하면 LLM에 프롬프트를 표시하여
어떤 액션을 수행할지 지정하는 방법을 알 수 있어요.
호출할 함수 정보를 제공하면 어떤 함수를 통해 액션을 수행해야 하는지도 알 수 있답니다.
그리고 Tool에 대한 입력이 간단할수록 LLM이 Tool을 더 쉽게 사용할 수 있어요.
그래서 많은 Agents는 단일 문자열을 입력으로 받는 Tool로만 작업한다고 해요.
Tool에서 가장 중요한 점은 이럼, 설명, JSON 스키마가 모두 프롬프트에 사용된다는 것이에요.
그렇기 때문에 이 정보들을 정확히, 그리고 명확히 설명하는 것이 정말 중요해요.
LLM이 Tool 사용 방법을 이해하지 못하면 제대로 된 결과가 나오지 않거든요!
그리고 결과 정보를 직접 수정해야 하는 불상사도 생기죠...
이제 LangChain의 공식 문서에 작성된 예제를 통해 Tool을 어떻게 사용하는지 알아볼게요!
Default Tools
먼저 내장된 Tool을 이용해서 공부해볼게요!
1 from langchain_community.tools import WikipediaQueryRun
2 from langchain_community.utilities import WikipediaAPIWrapper
3
4 # top_k_results, doc_content_chars_max 정보를 제공하여 Tool을 초기화
5 api_wrapper = WikipediaAPIWrapper(top_k_results=1, doc_content_chars_max=100)
6 tool = WikipediaQueryRun(api_wrapper=api_wrapper)
내장된 WikipediaAPIWrapper에 top_k_results, doc_content_chars_max 정보를 제공하고,
WikipediaQueryRun에 Wrapper를 전달하여 초기화된 Tool을 생성했어요.
참고로 WikipediaQueryRun에는 꼭 WikipediaAPIWrapper가 전달되어야 하는 점을 명심하세요~
- top_k_results : 상위 k 결과의 페이지 요약을 반환하도록 하는 파라미터
- doc_content_chars_max : 문서의 내용을 제한하는 파라미터
7 tool.name
# 결과
'Wikipedia'
생성된 Tool의 이름을 확인해보니 'Wikipedia'네요
8 tool.description
# 결과
'A wrapper around Wikipedia. Useful for when you need to answer general questions about people, places, companies, facts, historical events, or other subjects. Input should be a search query.'
tool.description을 통해 Tool이 어떤 역할을 하는지 알 수 있어요.
Wikipedia Tool의 역할은 일반적인 검색어(질문)에 대해 답변해주는 역할이네요.
9 tool.args
# 결과
{'query': {'title': 'Query', 'type': 'string'}}
그리고 tool.args를 통해 Tool에 어떻게 입력해야 하는지 방법을 알 수 있어요.
JSON 구조를 간단히 설명하자면...
입력은 'query'라는 Key를 사용하여 전달해야 되요.
'query'라는 Key의 타이틀은 'Query'이고 데이터 형식은 문자열(string)이네요.
설명만으로는 이해하기 어렵죠?
아래 작성된 소스코드를 봐주세요!
10 tool.run({"query": "langchain"})
# 결과
'Page: LangChain\nSummary: LangChain is a framework designed to simplify the creation of applications'
10번 줄에 작성된 소스코드를 보면
"query"라는 이름(Key) 안에 입력 값이 작성되어 있고,
작성된 입력 값은 "langchain"이라는 문자열(string)이라는 것을 알 수 있어요.
run 함수를 통해 검색어를 전달하니 LangChain에 대해 설명해주네요!
11 tool.return_direct
# 결과
False
마지막으로 Tool.return_direct를 통해 사용자에게 결과를 직접 반환하는지 확인할 수 있어요.
지금까지 기본 제공되는 Tool의 정보와 질문을 입력하는 방법에 대해 알아봤어요!
하지만 기본 제공되는 Tool은 제가 원하는 역할을 수행하지 않네요...
그럼 어떻게 할까요?
WikipediaAPIWrapper와 WikipediaQueryRun과 같은 소스코드를 직접 만들어서 새로운 Tool을 생성해야 할까요?
물론! 시간과 노력을 충분히 투자할 수 있다면 그렇게 해도 되요.
다시 질문할게요.
그럼 어떻게 해야할까요...?
바로 기존에 제공되는 Tool을 사용자 입맛에 맞게 변형(Custom)하면 되요!
WikipediaQueryRun에 여러 파라미터를 전달하여 Custom하는 방법에 대해 알아볼게요!
Customizing Default Tools
1 from langchain_core.pydantic_v1 import BaseModel, Field
2
3
4 class WikiInputs(BaseModel):
5 """Inputs to the wikipedia tool."""
6
7 query: str = Field(
8 description="query to look up in Wikipedia, should be 3 or less words"
9 )
10
11 # Wikipedia Tool Customizing
12 tool = WikipediaQueryRun(
13 name="wiki-tool",
14 description="look up things in wikipedia",
15 args_schema=WikiInputs,
16 api_wrapper=api_wrapper,
17 return_direct=True,
18 )
19
20 tool.name
21 # 결과 : 'wiki-tool'
먼저 WikiInputs 클래스를 만들어 입력 정보를 작성했어요.
그리고 WikipediaQueryRun에 Tool의 이름, 설명(역할), 입력 정보(JSON), WikipediaAPIWrapper(api_wrapper),
반환 여부(return_direct) 등의 정보를 제공하여 Tool을 생성했죠.
* 참고로 api_wrapper는 Default Tools 부분을 참고해주세요.
20번 째 줄에서 tool.name을 통해 이름을 확인해보니 'wiki-tool'이라는 결과가 나왔나요?
여기까지 따라왔다면 여러분은 사용 목적에 따라 Tool을 만들어 낼 준비가 된거에요.
이제 Agents에 대해 알아볼게요!
# Agents
Agents는 언어 모델을 사용하여 수행할 작업을 결정해줘요.
Agents는 Tool에 의해 정의되기도 해요.
Agents를 실행할 때에는 Executor(실행기)가 필요한다.
Executor는 실제로 Angents를 호출하고, 선택한 Tool을 실행하고, 작업 결과를 Agents에게 반환하는 역할을 반복해요.
즉, 작업 결과를 전달받은 Agents는 또 다시 구문을 분석하고 다음 단계를 어떻게 수행할지 선택하게 되죠.
Agents의 핵심 아이디어는 언어 모델을 사용하여 어떤 작업을 수행할 것인지 선택하는 거에요.
아래에서 학습할 '체인'과 관련이 있는데요.
먼저 체인은 모델 간 연결을 도와주는 Component라고만 알면 되요.
* Chains에 대한 자세한 내용은 이따가 알아볼게요.
즉, Agents는 언어 모델이 액션 수행을 어떤 순서로 진행할 것인지 결정하는 추론 엔진으로 사용되요.
Agents 프레임워크를 가장 잘 이해하기 위해서 두 가지 도구를 갖춘 Agent를 만들어볼건데요.
하나는 온라인 항목을 조회하는 Tavily라는 도구이고,
다른 하나는 인덱스에 로드한 특정 데이터를 조회하는 Retriever 도구에요.
* Retriever에 대해 자세히 알고싶다면 '여기'를 클릭해주세요.
Setup : LangSmith
Agents란 입력값에 따라 스스로 결정한 여러 단계를 거친 후, 최종적으로 사용자에게 결과를
반환하는 시스템을 말해요.
이러한 특성 때문에 에이전트 시스템을 디버깅하는 것이 특히 어려운데요.
디버깅을 하기 위해 각 단계를 추적하고 관찰하는 기능이 매우 중요해요.
이 때 사용할 수 있는 라이브러리가 바로 LangSmith!
LangSmith를 사용하면 에이전트가 어떤 과정을 거쳐 결과를 도출했는지
쉽게 확인할 수 있고, 문제를 찾아 해결하는데 큰 도움이 된답니다!
export LANGCHAIN_TRACING_V2="true"
export LANGCHAIN_API_KEY="YOUR-LangSmith-API-KEY"
LangSmith를 설정하려면 위의 코드와 같이 환경 변수만 설정하면 됩니다.
Define Tools
Agents를 사용하기 전에 먼저 Agents에 등록할 Tool을 만들어야 해요.
Tavily(온라인 검색용)와 로컬 인덱스를 통한 검색기(Retriever), 두 가지 도구를 사용해볼게요.
1. Tavily
LangChain은 Tavily 검색 엔진을 Tool로 쉽게 사용할 수 있도록 내장하고 있어요.
Tavily를 사용하기 위해서는 API 키가 필요한데요.
무료 버전도 있지만 API 키가 없거나 굳이 만들지 않겠다면 Tavily에 대한 설명은 넘어가도 된답니다!
export TAVILY_API_KEY="..."
먼저 Tavily API Key를 환경 변수로 등록해주세요.
1 from langchain_community.tools.tavily_search import TavilySearchResults
2
3 search = TavilySearchResults()
4 search.invoke("What is the weather in SF?")
# 결과
[{'url': 'https://www.weatherapi.com/',
'content': "{'location': {'name': 'San Francisco', 'region': 'California', 'country': 'United States of America', 'lat': 37.78, 'lon': -122.42, 'tz_id': 'America/Los_Angeles', 'localtime_epoch': 1712847697, 'localtime': '2024-04-11 8:01'}, 'current': {'last_updated_epoch': 1712847600, 'last_updated': '2024-04-11 08:00', 'temp_c': 11.1, 'temp_f': 52.0, 'is_day': 1, 'condition': {'text': 'Partly cloudy', 'icon': '//cdn.weatherapi.com/weather/64x64/day/116.png', 'code': 1003}, 'wind_mph': 2.2, 'wind_kph': 3.6, 'wind_degree': 10, 'wind_dir': 'N', 'pressure_mb': 1015.0, 'pressure_in': 29.98, 'precip_mm': 0.0, 'precip_in': 0.0, 'humidity': 97, 'cloud': 25, 'feelslike_c': 11.5, 'feelslike_f': 52.6, 'vis_km': 14.0, 'vis_miles': 8.0, 'uv': 4.0, 'gust_mph': 2.8, 'gust_kph': 4.4}}"},
{'url': 'https://www.yahoo.com/news/april-11-2024-san-francisco-122026435.html',
'content': "2024 NBA Mock Draft 6.0: Projections for every pick following March Madness With the NCAA tournament behind us, here's an updated look at Yahoo Sports' first- and second-round projections for the ..."},
{'url': 'https://world-weather.info/forecast/usa/san_francisco/april-2024/',
'content': 'Extended weather forecast in San Francisco. Hourly Week 10 days 14 days 30 days Year. Detailed ⚡ San Francisco Weather Forecast for April 2024 - day/night 🌡️ temperatures, precipitations - World-Weather.info.'},
{'url': 'https://www.wunderground.com/hourly/us/ca/san-francisco/94144/date/date/2024-4-11',
'content': 'Personal Weather Station. Inner Richmond (KCASANFR1685) Location: San Francisco, CA. Elevation: 207ft. Nearby Weather Stations. Hourly Forecast for Today, Thursday 04/11Hourly for Today, Thu 04/11 ...'},
{'url': 'https://weatherspark.com/h/y/557/2024/Historical-Weather-during-2024-in-San-Francisco-California-United-States',
'content': 'San Francisco Temperature History 2024\nHourly Temperature in 2024 in San Francisco\nCompare San Francisco to another city:\nCloud Cover in 2024 in San Francisco\nDaily Precipitation in 2024 in San Francisco\nObserved Weather in 2024 in San Francisco\nHours of Daylight and Twilight in 2024 in San Francisco\nSunrise & Sunset with Twilight and Daylight Saving Time in 2024 in San Francisco\nSolar Elevation and Azimuth in 2024 in San Francisco\nMoon Rise, Set & Phases in 2024 in San Francisco\nHumidity Comfort Levels in 2024 in San Francisco\nWind Speed in 2024 in San Francisco\nHourly Wind Speed in 2024 in San Francisco\nHourly Wind Direction in 2024 in San Francisco\nAtmospheric Pressure in 2024 in San Francisco\nData Sources\n See all nearby weather stations\nLatest Report — 3:56 PM\nWed, Jan 24, 2024\xa0\xa0\xa0\xa013 min ago\xa0\xa0\xa0\xa0UTC 23:56\nCall Sign KSFO\nTemp.\n60.1°F\nPrecipitation\nNo Report\nWind\n6.9 mph\nCloud Cover\nMostly Cloudy\n1,800 ft\nRaw: KSFO 242356Z 18006G19KT 10SM FEW015 BKN018 BKN039 16/12 A3004 RMK AO2 SLP171 T01560122 10156 20122 55001\n While having the tremendous advantages of temporal and spatial completeness, these reconstructions: (1) are based on computer models that may have model-based errors, (2) are coarsely sampled on a 50 km grid and are therefore unable to reconstruct the local variations of many microclimates, and (3) have particular difficulty with the weather in some coastal areas, especially small islands.\n We further caution that our travel scores are only as good as the data that underpin them, that weather conditions at any given location and time are unpredictable and variable, and that the definition of the scores reflects a particular set of preferences that may not agree with those of any particular reader.\n 2024 Weather History in San Francisco California, United States\nThe data for this report comes from the San Francisco International Airport.'}]
그리고 TavilySearchResult()를 통해 질문(입력)을 하면 Tavily가 검색 결과를 알려줄거에요.
여기까지 했다면 Tavily 끝~
2. Retriever
Tavily를 사용하지 않아도 내장된 검색 도구가 있으니 괜찮아요.
이번에는 내장된 검색 도구를 Tool로 만들어볼게요.
1 from langchain_community.document_loaders import WebBaseLoader
2 from langchain_community.vectorstores import FAISS
3 from langchain_openai import OpenAIEmbeddings
4 from langchain_text_splitters import RecursiveCharacterTextSplitter
5
6 loader = WebBaseLoader("https://docs.smith.langchain.com/overview")
7 docs = loader.load()
8 documents = RecursiveCharacterTextSplitter(
9 chunk_size=1000, chunk_overlap=200
10 ).split_documents(docs)
11 vector = FAISS.from_documents(documents, OpenAIEmbeddings())
12 retriever = vector.as_retriever()
13
14 retriever.invoke("How to upload a dataset?")[0]
# 결과
Document(page_content='import Clientfrom langsmith.evaluation import evaluateclient = Client()# Define dataset: these are your test casesdataset_name = "Sample Dataset"dataset = client.create_dataset(dataset_name, description="A sample dataset in LangSmith.")client.create_examples( inputs=[ {"postfix": "to LangSmith"}, {"postfix": "to Evaluations in LangSmith"}, ], outputs=[ {"output": "Welcome to LangSmith"}, {"output": "Welcome to Evaluations in LangSmith"}, ], dataset_id=dataset.id,)# Define your evaluatordef exact_match(run, example): return {"score": run.outputs["output"] == example.outputs["output"]}experiment_results = evaluate( lambda input: "Welcome " + input[\'postfix\'], # Your AI system goes here data=dataset_name, # The data to predict and grade over evaluators=[exact_match], # The evaluators to score the results experiment_prefix="sample-experiment", # The name of the experiment metadata={ "version": "1.0.0", "revision_id":', metadata={'source': 'https://docs.smith.langchain.com/overview', 'title': 'Getting started with LangSmith | 🦜️🛠️ LangSmith', 'description': 'Introduction', 'language': 'en'})
이제 검색을 수행할 인덱스를 채웠으니 아래 소스코드와 같이 Tool로 쉽게 전환할 수 있어요.
15 retriever_tool = create_retriever_tool(
16 retriever,
17 "langsmith_search",
18 "Search for information about LangSmith. For any questions about LangSmith, you must use this tool!",
19 )
여기까지 했다면 Retriever도 끝~
마지막으로!
생성한 Tool을 다운스트림에서 사용할 수 있도록 tools에 등록해놓을게요.
아래 코드를 따라서 작성해주세요.
20 tools = [search, retriever_tool]
Agents 만들기
필요한 Tool도 정의했으니 이제 Agent를 만들어볼게요.
Agent는 OpenAI Functions 에이전트를 사용하여 만들거에요!
1 from langchain_openai import ChatOpenAI
2
3 llm = ChatOpenAI(model="gpt-3.5-turbo-0125", temperature=0)
먼저 OpenAI에서 제공하는 "gpt-3.5-turbo-0125" 모델을 사용하도록 llm을 만들었어요.
다른 언어 모델을 사용하고 싶으시면 바꾸셔도 되요!
model과 temperature에 대해 자세히 알고싶다면 "여기"를 클릭해주세요.
4 from langchain import hub
5
6 # Get the prompt to use - you can modify this!
7 prompt = hub.pull("hwchase17/openai-functions-agent")
8 prompt.messages
# 결과
[SystemMessagePromptTemplate(prompt=PromptTemplate(input_variables=[], template='You are a helpful assistant')),
MessagesPlaceholder(variable_name='chat_history', optional=True),
HumanMessagePromptTemplate(prompt=PromptTemplate(input_variables=['input'], template='{input}')),
MessagesPlaceholder(variable_name='agent_scratchpad')]
그리고 Agent를 안내하는 데 사용할 프롬프트를 선택해요.
9 from langchain.agents import create_tool_calling_agent
10
11 agent = create_tool_calling_agent(llm, tools, prompt)
Agents에서 사용할 Tool, 프롬프트, LLM을 모두 만들었으니 이제 Agent를 만들어야겠죠?
create_tool_calling_agent() 함수에 Tool과 프롬프트, 그리고 LLM을 전달하여 초기화된 Agent를 만들었어요.
이제 Agent는 어떤 액션을 먼저 수행할지 결정할 수 있을까요?
답은 'No!'
Agent가 초기화되었을 뿐, 아직 액션 수행 순서를 추론할 수 없어요.
그럼 어떻게 해야 Agent가 추론할 수 있을까요?
12 from langchain.agents import AgentExecutor
13
14 agent_executor = AgentExecutor(agent=agent, tools=tools, verbose=True)
마지막으로 AgentExecutor를 통해 Agent의 두뇌를 만들어줘야 해요.
15 from langchain.agents import AgentExecutor
16
17 agent_executor = AgentExecutor(agent=agent, tools=tools, verbose=True)
여기까지 이해했나요?
드디어 Agent의 두뇌까지 만들었어요.
즉, Agent가 추론을 통해 어떤 순서로 액션을 수행할 것인지 정할 수 있죠.
여기까지 준비가 되었다면 Agent를 실행해봅시다!
Agents 실행하기
Agent가 추론할 수 있도록 만들었으니 이제 실행해볼까요?
참고로 지금까지 만든 Agent는 메모리가 없어서 여러분과 대화했던 내용을 기억하지 못한답니다.
1 agent_executor.invoke({"input": "hi!"})
# 로그
[1m> Entering new AgentExecutor chain...←[0m
[32;1m←[1;3mHello! How can I assist you today?←[0m
[1m> Finished chain.←[0m
# 결과
{'input': 'hi!', 'output': 'Hello! How can I assist you today?'}
간단한 인사말로 대화를 시작했네요!
2 agent_executor.invoke({"input": "how can langsmith help with testing?"})
# 로그
[1m> Entering new AgentExecutor chain...←[0m
[32;1m←[1;3m
Invoking: `langsmith_search` with `{'query': 'how can LangSmith help with testing'}`
[0m←[33;1m←[1;3mGetting started with LangSmith | 🦜️🛠️ LangSmith
Skip to main contentLangSmith API DocsSearchGo to AppQuick StartUser GuideTracingEvaluationProduction Monitoring & AutomationsPrompt HubProxyPricingSelf-HostingCookbookQuick StartOn this pageGetting started with LangSmithIntroductionLangSmith is a platform for building production-grade LLM applications. It allows you to closely monitor and evaluate your application, so you can ship quickly and with confidence. Use of LangChain is not necessary - LangSmith works on its own!Install LangSmith←We offer Python and Typescript SDKs for all your LangSmith needs.PythonTypeScriptpip install -U langsmithyarn add langchain langsmithCreate an API key←To create an API key head to the setting pages. Then click Create API Key.Setup your environmentShellexport LANGCHAIN_TRACING_V2=trueexport LANGCHAIN_API_KEY=<your-api-key># The below examples use the OpenAI API, though it's not necessary in generalexport OPENAI_API_KEY=<your-openai-api-key>Log your first trace←We provide multiple ways to log traces
Learn about the workflows LangSmith supports at each stage of the LLM application lifecycle.Pricing: Learn about the pricing model for LangSmith.Self-Hosting: Learn about self-hosting options for LangSmith.Proxy: Learn about the proxy capabilities of LangSmith.Tracing: Learn about the tracing capabilities of LangSmith.Evaluation: Learn about the evaluation capabilities of LangSmith.Prompt Hub Learn about the Prompt Hub, a prompt management tool built into LangSmith.Additional Resources←LangSmith Cookbook: A collection of tutorials and end-to-end walkthroughs using LangSmith.LangChain Python: Docs for the Python LangChain library.LangChain Python API Reference: documentation to review the core APIs of LangChain.LangChain JS: Docs for the TypeScript LangChain libraryDiscord: Join us on our Discord to discuss all things LangChain!FAQ←How do I migrate projects between organizations?←Currently we do not support project migration betwen organizations. While you can manually imitate this by
team deals with sensitive data that cannot be logged. How can I ensure that only my team can access it?←If you are interested in a private deployment of LangSmith or if you need to self-host, please reach out to us at sales@langchain.dev. Self-hosting LangSmith requires an annual enterprise license that also comes with support and formalized access to the LangChain team.Was this page helpful?NextUser GuideIntroductionInstall LangSmithCreate an API keySetup your environmentLog your first traceCreate your first evaluationNext StepsAdditional ResourcesFAQHow do I migrate projects between organizations?Why aren't my runs aren't showing up in my project?My team deals with sensitive data that cannot be logged. How can I ensure that only my team can access it?CommunityDiscordTwitterGitHubDocs CodeLangSmith SDKPythonJS/TSMoreHomepageBlogLangChain Python DocsLangChain JS/TS DocsCopyright © 2024 LangChain, Inc.←[0m←[32;1m←[1;3mLangSmith is a platform for building production-grade LLM applications that can help with testing in the following ways:
1. **Tracing**: LangSmith provides tracing capabilities that allow you to closely monitor and evaluate your application during testing. You can log traces to track the behavior of your application and identify any issues.
2. **Evaluation**: LangSmith offers evaluation capabilities that enable you to assess the performance of your application during testing. This helps you ensure that your application functions as expected and meets the required standards.
3. **Production Monitoring & Automations**: LangSmith allows you to monitor your application in production and automate certain processes, which can be beneficial for testing different scenarios and ensuring the stability of your application.
4. **Prompt Hub**: LangSmith includes a Prompt Hub, a prompt management tool that can streamline the testing process by providing a centralized location for managing prompts and inputs for your application.
Overall, LangSmith can assist with testing by providing tools for monitoring, evaluating, and automating processes to ensure the reliability and performance of your application during testing phases.←[0m
[1m> Finished chain.←[0m
# 결과
{'input': 'how can langsmith help with testing?',
'output': 'LangSmith is a platform for building production-grade LLM applications that can help with testing in the following ways:\n\n1. **Tracing**: LangSmith provides tracing capabilities that allow you to closely monitor and evaluate your application during testing. You can log traces to track the behavior of your application and identify any issues.\n\n2. **Evaluation**: LangSmith offers evaluation capabilities that enable you to assess the performance of your application during testing. This helps you ensure that your application functions as expected and meets the required standards.\n\n3. **Production Monitoring & Automations**: LangSmith allows you to monitor your application in production and automate certain processes, which can be beneficial for testing different scenarios and ensuring the stability of your application.\n\n4. **Prompt Hub**: LangSmith includes a Prompt Hub, a prompt management tool that can streamline the testing process by providing a centralized location for managing prompts and inputs for your application.\n\nOverall, LangSmith can assist with testing by providing tools for monitoring, evaluating, and automating processes to ensure the reliability and performance of your application during testing phases.'}
어떤가요?
앞서 인사말을 했던 대화 내용은 찾아볼 수 없죠?
대신 두 번째 질문에 대한 결과(답변)가 나왔네요!
3 agent_executor.invoke({"input": "whats the weather in sf?"})
# 로그
[1m> Entering new AgentExecutor chain...[0m
[32;1m←[1;3m
Invoking: `tavily_search_results_json` with `{'query': 'weather in San Francisco'}`
[0m←[36;1m←[1;3m[{'url': 'https://www.weatherapi.com/', 'content': "{'location': {'name': 'San Francisco', 'region': 'California', 'country': 'United States of America', 'lat': 37.78, 'lon': -122.42, 'tz_id': 'America/Los_Angeles', 'localtime_epoch': 1712847697, 'localtime': '2024-04-11 8:01'}, 'current': {'last_updated_epoch': 1712847600, 'last_updated': '2024-04-11 08:00', 'temp_c': 11.1, 'temp_f': 52.0, 'is_day': 1, 'condition': {'text': 'Partly cloudy', 'icon': '//cdn.weatherapi.com/weather/64x64/day/116.png', 'code': 1003}, 'wind_mph': 2.2, 'wind_kph': 3.6, 'wind_degree': 10, 'wind_dir': 'N', 'pressure_mb': 1015.0, 'pressure_in': 29.98, 'precip_mm': 0.0, 'precip_in': 0.0, 'humidity': 97, 'cloud': 25, 'feelslike_c': 11.5, 'feelslike_f': 52.6, 'vis_km': 14.0, 'vis_miles': 8.0, 'uv': 4.0, 'gust_mph': 2.8, 'gust_kph': 4.4}}"}, {'url': 'https://www.yahoo.com/news/april-11-2024-san-francisco-122026435.html', 'content': "2024 NBA Mock Draft 6.0: Projections for every pick following March Madness With the NCAA tournament behind us, here's an updated look at Yahoo Sports' first- and second-round projections for the ..."}, {'url': 'https://www.weathertab.com/en/c/e/04/united-states/california/san-francisco/', 'content': 'Explore comprehensive April 2024 weather forecasts for San Francisco, including daily high and low temperatures, precipitation risks, and monthly temperature trends. Featuring detailed day-by-day forecasts, dynamic graphs of daily rain probabilities, and temperature trends to help you plan ahead. ... 11 65°F 49°F 18°C 9°C 29% 12 64°F 49°F ...'}, {'url': 'https://weatherspark.com/h/y/557/2024/Historical-Weather-during-2024-in-San-Francisco-California-United-States', 'content': 'San Francisco Temperature History 2024\nHourly Temperature in 2024 in San Francisco\nCompare San Francisco to another city:\nCloud Cover in 2024 in San Francisco\nDaily Precipitation in 2024 in San Francisco\nObserved Weather in 2024 in San Francisco\nHours of Daylight and Twilight in 2024 in San Francisco\nSunrise & Sunset with Twilight and Daylight Saving Time in 2024 in San Francisco\nSolar Elevation and Azimuth in 2024 in San Francisco\nMoon Rise, Set & Phases in 2024 in San Francisco\nHumidity Comfort Levels in 2024 in San Francisco\nWind Speed in 2024 in San Francisco\nHourly Wind Speed in 2024 in San Francisco\nHourly Wind Direction in 2024 in San Francisco\nAtmospheric Pressure in 2024 in San Francisco\nData Sources\n See all nearby weather stations\nLatest Report — 3:56 PM\nWed, Jan 24, 2024\xa0\xa0\xa0\xa013 min ago\xa0\xa0\xa0\xa0UTC 23:56\nCall Sign KSFO\nTemp.\n60.1°F\nPrecipitation\nNo Report\nWind\n6.9 mph\nCloud Cover\nMostly Cloudy\n1,800 ft\nRaw: KSFO 242356Z 18006G19KT 10SM FEW015 BKN018 BKN039 16/12 A3004 RMK AO2 SLP171 T01560122 10156 20122 55001\n While having the tremendous advantages of temporal and spatial completeness, these reconstructions: (1) are based on computer models that may have model-based errors, (2) are coarsely sampled on a 50 km grid and are therefore unable to reconstruct the local variations of many microclimates, and (3) have particular difficulty with the weather in some coastal areas, especially small islands.\n We further caution that our travel scores are only as good as the data that underpin them, that weather conditions at any given location and time are unpredictable and variable, and that the definition of the scores reflects a particular set of preferences that may not agree with those of any particular reader.\n 2024 Weather History in San Francisco California, United States\nThe data for this report comes from the San Francisco International Airport.'}, {'url': 'https://www.msn.com/en-us/weather/topstories/april-11-2024-san-francisco-bay-area-weather-forecast/vi-BB1lrXDb', 'content': 'April 11, 2024 San Francisco Bay Area weather forecast. Posted: April 11, 2024 | Last updated: April 11, 2024 ...'}][0m[32;1m[1;3mThe current weather in San Francisco is partly cloudy with a temperature of 52.0°F (11.1°C). The wind speed is 3.6 kph coming from the north, and the humidity is at 97%.←[0m
[1m> Finished chain.←[0m
# 결과
{'input': 'whats the weather in sf?',
'output': 'The current weather in San Francisco is partly cloudy with a temperature of 52.0°F (11.1°C). The wind speed is 3.6 kph coming from the north, and the humidity is at 97%.'}
세 번째 결과도 마찬가지에요.
앞서 대화했던 내용은 사라지고 조금 전에 입력한 질문에 대해서 답변을 할 뿐이에요.
Memory 추가하기
조금전까지 Agent는 여러분과 대화했던 내용을 기억하지 못한다고 했죠.
하지만 '대화'라는 것은 앞서 얘기했던 내용을 바탕으로 이어서 말하기 마련이죠!
Agnet에게 이 능력을 주려면 뭐가 필요할까요?
바로 메모리에요.
메모리를 제공하려면 previous를 전달해야 합니다.
chat_history...
1 # Here we pass in an empty list of messages for chat_history because it is the first message in the chat
2 agent_executor.invoke({"input": "hi! my name is bob", "chat_history": []})
# 로그
[1m> Entering new AgentExecutor chain...←[0m
[32;1m←[1;3mHello Bob! How can I assist you today?←[0m
[1m> Finished chain.←[0m
# 결과
{'input': 'hi! my name is bob',
'chat_history': [],
'output': 'Hello Bob! How can I assist you today?'}
자! 다시 간단한 인사말로 대화를 시작했죠?
3 from langchain_core.messages import AIMessage, HumanMessage
4
5 agent_executor.invoke(
6 {
7 "chat_history": [
8 HumanMessage(content="hi! my name is bob"),
9 AIMessage(content="Hello Bob! How can I assist you today?"),
10 ],
11 "input": "what's my name?",
12 }
13 )
# 로그
[1m> Entering new AgentExecutor chain...←[0m
[32;1m←[1;3mYour name is Bob. How can I assist you, Bob?←[0m
[1m> Finished chain.←[0m
# 결과
{'chat_history': [HumanMessage(content='hi! my name is bob'),
AIMessage(content='Hello Bob! How can I assist you today?')],
'input': "what's my name?",
'output': 'Your name is Bob. How can I assist you, Bob?'}
두 번째 질문을 하기 전에!
"chat_history" 영역에 앞서 대화했던 내용을 입력했네요.
HumanMessage는 당연히 여러분들이 작성한 질문이고,
AIMessage는 여러분의 질문에 대한 LLM의 답변이에요.
대화 내용을 전달하면서 "내 이름이 뭐야"라는 질문을 했더니
LLM이 "Bob"이라고 알려주네요.
분명 앞서 대화했던 내용을 참고하고 있는거에요.
LLM에게 기억할 수 있는 능력(메모리)이 생긴거죠!
만약에 메시지를 자동으로 추적하고 싶다면
RunnableWithMessageHistory 라이브러리를 사용하면 되요.
아래 작성된 소스코드를 참고하면서 사용해봐요.^^
14 from langchain_community.chat_message_histories import ChatMessageHistory
15 from langchain_core.runnables.history import RunnableWithMessageHistory
16
17 message_history = ChatMessageHistory()
18
19 agent_with_chat_history = RunnableWithMessageHistory(
20 agent_executor,
21 # This is needed because in most real world scenarios, a session id is needed
22 # It isn't really used here because we are using a simple in memory ChatMessageHistory
23 lambda session_id: message_history,
24 input_messages_key="input",
25 history_messages_key="chat_history",
26 )
27
28 agent_with_chat_history.invoke(
29 {"input": "hi! I'm bob"},
30 # This is needed because in most real world scenarios, a session id is needed
31 # It isn't really used here because we are using a simple in memory ChatMessageHistory
32 config={"configurable": {"session_id": "<foo>"}},
33 )
# 로그
[1m> Entering new AgentExecutor chain...←[0m
[32;1m←[1;3mHello Bob! How can I assist you today?←[0m
[1m> Finished chain.←[0m
# 결과
{'input': "hi! I'm bob",
'chat_history': [],
'output': 'Hello Bob! How can I assist you today?'}
34 agent_with_chat_history.invoke(
35 {"input": "what's my name?"},
36 # This is needed because in most real world scenarios, a session id is needed
37 # It isn't really used here because we are using a simple in memory ChatMessageHistory
38 config={"configurable": {"session_id": "<foo>"}},
39 )
# 로그
[1m> Entering new AgentExecutor chain...←[0m
[32;1m←[1;3mYour name is Bob! How can I help you, Bob?←[0m
[1m> Finished chain.←[0m
# 결과
{'input': "what's my name?",
'chat_history': [HumanMessage(content="hi! I'm bob"),
AIMessage(content='Hello Bob! How can I assist you today?')],
'output': 'Your name is Bob! How can I help you, Bob?'}
RunnableWithMessageHistory를 사용했더니 "chat_history"를 직접 입력하지 않아도 되네요.
Agents를 만들 때 편리한 라이브러리인 것 같아요!
지금까지 Agents에 대해 알아봤어요.
어떤가요?
Agents가 무엇이고 어떻게 구현하면 되는지 감이 잡히나요?
더 정보가 필요하다면 공식 문서를 참고해보세요~
드디어!
이번 포스팅의 마지막 Component인 Chains에 대해 알아볼게요!
# Chains
Chains는 Model I/O, Retrieval과 같이 랭체인을 구성하는 빌딩 블록 컴포넌트에요.
이번 포스팅에서는 Chains의 개념을 간단히 알아볼게요.
Chains는 LLM, Tool 또는 데이터 전처리 단계에서 호출이 이어지는 순서를 알려주는 Component에요.
예를 들어 GPT-3에서 생성한 결과를 GPT-4에게 전달하고,
GPT-4는 작업을 수행해서 얻은 결과를 또 다른 모델에 전달하며 작업을 수행할 수 있는데요.
이런 기능을 담당하는 Component가 바로 Chains에요.
Chains를 처리하는 주요 방법은 LCEL을 사용하는거에요.
LCEL은 체인을 구성하는 데 매우 유용할뿐만 아니라
이미 만들어진 체인(off-the-shelf chains)을 사용할 수 있도록 지원해줘요.
LangChain에서는 두 가지 유형의 미리 만들어진 체인(off-the-shelf chains)을 지원해요.
- LCEL로 구축된 Chains의 경우, LangChain은 고수준의 Constructor 메서드를 제공해요.
하지만 Chains가 내부적으로 처리해야 하는 작업(로직)은 LCEL을 사용해 만들어야 해요. - [Legacy] Chains는 기존 Chain 클래스에서 하위 클래스로 구성된 체인이에요.
이 Chains는 내부적으로 LCEL을 사용하지 않는, 독립적인 클래스들이에요.
대부분의 Chains는 LCEL을 활용하여 만들어요.
그 이유는
- LCEL 버전으로 구성된 Chains에는 장점이 있어요.
Chains의 내부를 수정하고 싶을 때 LCEL만 수정하면 되거든요. - 이렇게 구성된 Chains는 기본적으로 스트리밍, 비동기, 일괄 처리 기능을 지원해요.
- 그리고 이 Chains는 각 단계에서 자동으로 관찰 가능성을 제공해요.
공식 문서에서는 LCEL로 구축된 Chains와 Legacy Chais의 Constructor에 대해
자세히 설명하고 있으니 참고해보시면 좋을 것 같아요!
Chains에 대해 조금 더 자세히 설명하고 싶지만...
공식 문서의 내용을 참고해서 개념만 정리해봤어요.
앞으로 LangChain을 직접 구현해보면서 Chains에 대해
자세히 알아갈 예정이니 기다려주세요^^
# 마무리
이번 포스팅을 통해 Tool과 Agents, 그리고 Chains에 대해 이해하셨나요?
공식 문서를 보고 필요한 내용만 작성한건데... 학습해야 할 양이 많네요!
저는 포스팅을 작성하며 Tool과 Agents, 그리고 Chains가 어떤 역할을 하는 것인지,
어떻게 구현할 수 있는지에 대한 개념을 학습할 수 있었는데요.
이번에 학습한 내용이 추후 LangChain을 구현하는데 많은 도움이 될 것이라고 생각되요!
물론... 아직 알아야 할 정보가 산더미처럼 많이 있지만요^^
특히 Chains에 대해서는 개념 설명만 짧게 되어 있어서 아쉽지만
실제 구현을 하면서 꼭 알아두면 좋은 정보들을 포스팅할게요.
글을 읽으면서 잘못된 점이 있으면 언제든지 지적해주세요.
더욱 더 공부를 하고 수정을 해나갈게요.
그리고 개념과 예제 소스코드는 랭체인 공식 문서에서 가져왔으니,
공식 문서도 참고하면서 봐주세요.
# 참고
- LangChain Docs > Components : https://python.langchain.com/v0.1/docs/modules/
How-to guides | 🦜️🔗 LangChain
Here you’ll find answers to “How do I….?” types of questions.
python.langchain.com
- LangChain Docs > composition : https://python.langchain.com/v0.1/docs/modules/composition/
Composition | 🦜️🔗 LangChain
This section contains higher-level components that combine other arbitrary systems (e.g. external APIs and services) and/or LangChain primitives together.
python.langchain.com
- LangChain Docs > composition > Agents > Quickstart : https://python.langchain.com/v0.1/docs/modules/agents/quick_start/
Quickstart | 🦜️🔗 LangChain
To best understand the agent framework, let's build an agent that has two tools: one to look things up online, and one to look up specific data that we've loaded into a index.
python.langchain.com
'AI' 카테고리의 다른 글
랭체인(LangChain)의 컴포넌트(Components) : Callbacks (0) | 2025.02.24 |
---|---|
랭체인(LangChain)의 컴포넌트(Components) : Memory (0) | 2025.02.19 |
랭체인(LangChain)의 컴포넌트(Components) : Retrieval (0) | 2025.02.06 |
랭체인(LangChain)의 컴포넌트(Components) : Model I/O (0) | 2025.02.05 |
랭체인(LangChain)이란? (0) | 2025.01.21 |