agent_executor
:from langchain.tools import tool
import requests
from pydantic import BaseModel, Field
import datetime
# Define the input schema
class OpenMeteoInput(BaseModel):
latitude: float = Field(..., description="Latitude of the location to fetch weather data for")
longitude: float = Field(..., description="Longitude of the location to fetch weather data for")
@tool(args_schema=OpenMeteoInput)
def get_current_temperature(latitude: float, longitude: float) -> dict:
"""Fetch current temperature for given coordinates."""
BASE_URL = "https://api.open-meteo.com/v1/forecast"
# Parameters for the request
params = {
'latitude': latitude,
'longitude': longitude,
'hourly': 'temperature_2m',
'forecast_days': 1,
}
# Make the request
response = requests.get(BASE_URL, params=params)
if response.status_code == 200:
results = response.json()
else:
raise Exception(f"API Request failed with status code: {response.status_code}")
current_utc_time = datetime.datetime.utcnow()
time_list = [datetime.datetime.fromisoformat(time_str.replace('Z', '+00:00')) for time_str in results['hourly']['time']]
temperature_list = results['hourly']['temperature_2m']
closest_time_index = min(range(len(time_list)), key=lambda i: abs(time_list[i] - current_utc_time))
current_temperature = temperature_list[closest_time_index]
return f'The current temperature is {current_temperature}°C'
import wikipedia
@tool
def search_wikipedia(query: str) -> str:
"""Run Wikipedia search and get page summaries."""
page_titles = wikipedia.search(query)
summaries = []
for page_title in page_titles[: 3]:
try:
wiki_page = wikipedia.page(title=page_title, auto_suggest=False)
summaries.append(f"Page: {page_title}\nSummary: {wiki_page.summary}")
except (
self.wiki_client.exceptions.PageError,
self.wiki_client.exceptions.DisambiguationError,
):
pass
if not summaries:
return "No good Wikipedia Search Result was found"
return "\n\n".join(summaries)
tools = [get_current_temperature, search_wikipedia]
from langchain.chat_models import ChatOpenAI
from langchain.prompts import ChatPromptTemplate
from langchain.tools.render import format_tool_to_openai_function
from langchain.agents.output_parsers import OpenAIFunctionsAgentOutputParser
functions = [format_tool_to_openai_function(f) for f in tools]
model = ChatOpenAI(temperature=0).bind(functions=functions)
prompt = ChatPromptTemplate.from_messages([
("system", "You are helpful but sassy assistant"),
("user", "{input}"),
])
chain = prompt | model | OpenAIFunctionsAgentOutputParser()
result = chain.invoke({"input": "what is the weather is sf?"})
result.tool
# 사용한 tool 이름
'get_current_temperature'
result.input
# 추천받은 인자
{'latitude': 37.7749, 'longitude': -122.4194}
from langchain.prompts import MessagesPlaceholder
propmt = ChatPromptTemplate.from_messages([
("system", "You are helpful but sassy assistant"),
("user", "{input}),
MessagesPlaceholder(variable_name="agent_scratchpad") # 메세지 리스트를 전달하는 공간
])
chain = prompt | model | OpenAIFunctionsAgentOutputParser()
result1 = chain.invoke({
"input": "what is the weather is sf?",
"agent_scratchpad": []
})
result1.tool
# 결과
'get_current_temperature'
observation = get_cuuernt_temperature(result1.tool_input)
observation
# 결과
'The current temperature is 11.3°C'
type(result1)
# 결과
langchain.schema.agent.AgentActionMessageLog
from langchain.agents.format_scratchpad import format_to_openai_functions
result1.message_log # Agent action으로 나온 결과에 어떻게 도달했는지 알려주는 메시지
# 결과
[AIMessage(content='', additional_kwargs={'function_call': {'name': 'get_current_temperature', 'arguments': '{\n "latitude": 37.7749,\n "longitude": -122.4194\n}'}})]
# 이 메시지와 observation을 scratchpad에 전달해준다.
format_to_openai_functions([(result1, obseravation), ]) # 메시지와 observation의 튜플을 넘겨주고, 반복하기 때문에 컴마를 붙여줌
# 결과
[AIMessage(content='', additional_kwargs={'function_call': {'name': 'get_current_temperature', 'arguments': '{\n "latitude": 37.7749,\n "longitude": -122.4194\n}'}}),
FunctionMessage(content='The current temperature is 11.3°C', name='get_current_temperature')]
result2 = chain.invoke({
"input": "what is the weather is sf?",
"agent_scratchpad": format_to_openai_functions([(result1, observation)])
})
result2
# 결과
AgentFinish(return_values={'output': 'The current temperature in San Francisco is 11.3°C.'}, log='The current temperature in San Francisco is 11.3°C.')
from langchain.schema.agent import AgentFinish
def run_agent(user_input):
intermediate_steps = []
while True:
result = chain.invoke({
"input": user_input,
"agent_scratchpad": format_to_openai_functions(intermediate_steps)
})
if isinstance(result, AgentFinish):
return result
tool = {
"search_wikipedia": search_wikipedia,
"get_current_temperature": get_current_temperature,
}[result.tool]
observation = tool.run(result.tool_input)
intermediate_steps.append((result, observation))
from langchain.schema.runnable import RunnablePassthrough
agent_chain = RunnablePassthrough.assign(
agent_scratchpad= lambda x: format_to_openai_functions(x["intermediate_steps"])
) | chain
def run_agent(user_input):
intermediate_steps = []
while True:
# 변경된 부분 - 새로 정의한 chain에 intermediate_steps라는 Passthrough넘겨줌
result = agent_chain.invoke({
"input": user_input,
"intermediate_steps": intermediate_steps
})
if isinstance(result, AgentFinish):
return result
tool = {
"search_wikipedia": search_wikipedia,
"get_current_temperature": get_current_temperature,
}[result.tool]
observation = tool.run(result.tool_input)
intermediate_steps.append((result, observation))
run_agent("what is the weather is sf?")
#결과
AgentFinish(return_values={'output': 'The current temperature in San Francisco is 11.3°C.'}, log='The current temperature in San Francisco is 11.3°C.')
run_agent("what is langchain?")
# 결과
AgentFinish(return_values={'output': 'I couldn\'t find specific information about "LangChain" in my search results. It\'s possible that LangChain is a term or co...
run_agent("hi!")
# 결과
AgentFinish(return_values={'output': 'Hello! How can I assist you today?'}, log='Hello! How can I assist you today?')
from langchain.agents import AgentExecutor
agent_executor = AgentExecutor(agent=agent_chain, tools=tools, verbose=True)
agent_executor.invoke({"input": "what is Langchain"})
어째서인지 잘 찾아놓고 반환을 못한다.
> Finished chain.
{'input': 'what is langchain?', 'output': 'I couldn\'t find specific information about "LangChain" in my search results. It\'s possible that LangChain is a term or concept that is not widely known or documented. If you have any additional information or context about LangChain, I may be able to provide more assistance.'}
agent_executor.invoke({"input": "My name is Bob"})
agent_executor.invoke({"input": "what is my name"})
prompt = ChatPromptTemplate.from_messages([
("system", "You are helpful but sassy assistant"),
MessagesPlaceholder(variable_name="chat_history"), # user input 전에 선언해줌, variable name으로 메모리와 연동
("user", "{input}"),
MessagesPlaceholder(variable_name="agent_scratchpad")
])
agent_chain = RunnablePassthrough.assign(
agent_scratchpad= lambda x: format_to_openai_functions(x["intermediate_steps"])
) | prompt | model | OpenAIFunctionsAgentOutputParser()
from langchain.memory import ConversationBufferMemory
memory = ConversationBufferMemory(return_messages=True,memory_key="chat_history") # 모든 메시지 형태를 string으로 처리하고 싶으면 return_messages를 False로 설정
agent_executor = AgentExecutor(agent=agent_chain, tools=tools, verbose=True, memory=memory)
agent_executor.invoke({"input": "my name is bob"})
agent_executor.invoke({"input": "whats my name"})
agent_executor.invoke({"input": "whats the weather in sf?"})
# 거꾸로 말하는 함수
@tool
def create_your_own(query: str) -> str:
"""This function can do whatever you would like once you fill it in """
print(type(query))
return query[::-1]
tools = [get_current_temperature, search_wikipedia, create_your_own]
import panel as pn # GUI
pn.extension()
import panel as pn
import param
class cbfs(param.Parameterized):
def __init__(self, tools, **params):
super(cbfs, self).__init__( **params)
self.panels = []
self.functions = [format_tool_to_openai_function(f) for f in tools]
self.model = ChatOpenAI(temperature=0).bind(functions=self.functions)
self.memory = ConversationBufferMemory(return_messages=True,memory_key="chat_history")
self.prompt = ChatPromptTemplate.from_messages([
("system", "You are helpful but sassy assistant"),
MessagesPlaceholder(variable_name="chat_history"),
("user", "{input}"),
MessagesPlaceholder(variable_name="agent_scratchpad")
])
self.chain = RunnablePassthrough.assign(
agent_scratchpad = lambda x: format_to_openai_functions(x["intermediate_steps"])
) | self.prompt | self.model | OpenAIFunctionsAgentOutputParser()
self.qa = AgentExecutor(agent=self.chain, tools=tools, verbose=False, memory=self.memory)
def convchain(self, query):
if not query:
return
inp.value = ''
result = self.qa.invoke({"input": query})
self.answer = result['output']
self.panels.extend([
pn.Row('User:', pn.pane.Markdown(query, width=450)),
pn.Row('ChatBot:', pn.pane.Markdown(self.answer, width=450, styles={'background-color': '#F6F6F6'}))
])
return pn.WidgetBox(*self.panels, scroll=True)
def clr_history(self,count=0):
self.chat_history = []
return
cb = cbfs(tools)
inp = pn.widgets.TextInput( placeholder='Enter text here…')
conversation = pn.bind(cb.convchain, inp)
tab1 = pn.Column(
pn.Row(inp),
pn.layout.Divider(),
pn.panel(conversation, loading_indicator=True, height=400),
pn.layout.Divider(),
)
dashboard = pn.Column(
pn.Row(pn.pane.Markdown('# QnA_Bot')),
pn.Tabs(('Conversation', tab1))
)
dashboard