-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathfunction_calling.qmd
208 lines (163 loc) Β· 8.22 KB
/
function_calling.qmd
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
# ν¨μ νΈμΆ
**ν¨μ νΈμΆ(function calling)**μ λκ·λͺ¨ μΈμ΄ λͺ¨λΈ(LLM)μ λ₯λ ₯μ νμ₯νκ³ νΉμ μμ
μ μννλ κ°λ ₯ν λ©μ»€λμ¦μ΄λ€. LLMμ μ¬μ©μμ μ
λ ₯μ λΆμνκ³ , μ μ ν ν¨μλ₯Ό μ ννμ¬ νμν 맀κ°λ³μμ ν¨κ» νΈμΆνλ€. μ΄ κ³Όμ μ ν΅ν΄ LLMμ μ€μκ° λ°μ΄ν° κ²μ, κ³μ° μν, μΈλΆ μμ€ν
κ³Όμ μνΈμμ© λ± λ€μν μμ
μ μνν μ μλ€. ν¨μ νΈμΆμ LLMμ μμ°μ΄ μ²λ¦¬ λ₯λ ₯κ³Ό ꡬ쑰νλ μμ
μν λ₯λ ₯μ κ²°ν©νμ¬, λ μ ννκ³ λ§₯λ½μ λ§λ μλ΅μ μμ±νλ€.
ν¨μ νΈμΆμ μ£Όμ μ₯μ μ μ μ°μ±κ³Ό νμ₯μ±μ μλ€. κ°λ°μλ νΉμ λλ©μΈμ΄λ μ¬μ© μ¬λ‘μ λ§λ μ¬μ©μ μ μ ν¨μλ₯Ό μ μν μ μμΌλ©°, μ΄λ₯Ό ν΅ν΄ LLMμ κΈ°λ₯μ ν¬κ² νμ₯ν μ μλ€. μλ₯Ό λ€μ΄, λ μ¨ μ 보 κ²μ, λ°μ΄ν°λ² μ΄μ€ 쿼리, μμ½ μμ€ν
μ κ·Ό λ± λ€μν κΈ°λ₯μ LLMμ ν΅ν©ν μ μλ€.
```{mermaid}
%%| label: function-calling
%%| fig-align: center
graph TB
A[μ¬μ©μ μ
λ ₯] -->|μμ°μ΄| B[LLMμ΄ μ
λ ₯ μ²λ¦¬]
subgraph LLM_μ²λ¦¬["LLM μ²λ¦¬ κ³Όμ "]
B --> C{ν¨μ νμ?}
C -->|μ| D[μ μ ν ν¨μ μ ν]
C -->|μλμ€| E[μ§μ μλ΅ μμ±]
D --> F[ν¨μ 맀κ°λ³μ μ€λΉ]
end
subgraph ν¨μ_νΈμΆ["ν¨μ νΈμΆ κ³Όμ "]
F --> G[ν¨μ νΈμΆ]
G --> H[ν¨μ μΆλ ₯ μμ ]
end
subgraph μλ΅_μμ±["μλ΅ μμ± κ³Όμ "]
H --> I[μΆλ ₯μ μλ΅μ ν΅ν©]
E --> J[μ΅μ’
μλ΅ μμ±]
I --> J
end
J --> K[μ¬μ©μμκ² μλ΅ λ°ν]
```
## JSON μΆλ ₯
ν¨μ νΈμΆμ JSON νμμΌλ‘ ꡬ쑰ννλ κ²μ λ°μ΄ν°μ μΌκ΄μ±κ³Ό ν΄μμ μ©μ΄μ±μ ν¬κ² ν₯μμν¨λ€. JSONμ μΈκ°κ³Ό κΈ°κ³ λͺ¨λκ° μ½κ² μ½κ³ μ΄ν΄ν μ μλ νμμΌλ‘, 볡μ‘ν λ°μ΄ν° ꡬ쑰λ₯Ό λͺ
ννκ² ννν μ μμ΄, νΉν λ€μν μ νμ μ 보λ₯Ό ν¬ν¨νλ ν¨μ νΈμΆμμ λ§€μ° μ μ©νλ©°, νλΌλ―Έν°μ μ΄λ¦κ³Ό κ°μ λͺ
νν μ°κ²°νμ¬ μ€λ₯μ κ°λ₯μ±μ μ€μΈλ€.
λν, JSONμ μ¬μ©ν ν¨μ νΈμΆμ μμ€ν
κ°μ μνΈ μ΄μ©μ±μ ν¬κ² ν₯μμν¨λ€. λ§μ νλ‘κ·Έλλ° μΈμ΄μ νλ«νΌμ΄ JSONμ κΈ°λ³Έμ μΌλ‘ μ§μνκΈ° λλ¬Έμ, λ€μν νκ²½μμ μ½κ² ν΅ν©λ μ μλ€. μΉ κΈ°λ° μ ν리μΌμ΄μ
μ΄λ λ§μ΄ν¬λ‘μλΉμ€ μν€ν
μ²μμ μ€μνλ©°, API ν΅μ μ νμ€μΌλ‘ μ리 μ‘μλ€. κ²°κ³Όμ μΌλ‘, JSONμ ν΅ν ν¨μ νΈμΆμ κ°λ° κ³Όμ μ κ°μννκ³ , μμ€ν
μ μ μ§λ³΄μμ±κ³Ό νμ₯μ±μ ν₯μμν€λ λ° ν¬κ² κΈ°μ¬νλ€.
## ν¬λ‘μλ
ν¨μ νΈμΆ ν¬λ‘μλ νλ‘κ·Έλ¨μ OpenAIμ GPT λͺ¨λΈμ μ¬μ©νμ¬ κ°λ¨ν μΈμ¬ κΈ°λ₯μ ꡬννλ€. νλ‘κ·Έλ¨μ λ¨Όμ `hello_world`λΌλ ν¨μλ₯Ό μ μνκ³ , μ΄ ν¨μμ μ€λͺ
μ OpenAI APIμ μ 곡ν λ€μ, μ¬μ©μμ μ
λ ₯μ APIμ μ μ‘νλ©΄, GPT λͺ¨λΈμ΄ μ΄λ₯Ό ν΄μνμ¬ μ μ ν ν¨μ νΈμΆμ κ²°μ νλ€. APIκ° `hello_world` ν¨μ νΈμΆμ μμ²νλ©΄, νλ‘κ·Έλ¨μ μ΄ ν¨μλ₯Ό μ€ννμ¬ κ°μΈνλ μΈμ¬λ§μ μμ±νκ³ μΆλ ₯ν©λλ€.
```{python}
from openai import OpenAI
import os
from dotenv import load_dotenv
import json
load_dotenv()
client = OpenAI(api_key=os.getenv("OPENAI_API_KEY"))
# κ°λ¨ν ν¨μ μ μ
def hello_world(name):
return f"μλ
νμΈμ, {name}λ!"
# OpenAIμ μ 곡ν ν¨μ μ€λͺ
functions = [
{
"name": "hello_world",
"description": "μ΄λ¦μ λ°μ μΈμ¬λ§μ λ°ννλ ν¨μ",
"parameters": {
"type": "object",
"properties": {"name": {"type": "string", "description": "μ¬μ©μμ μ΄λ¦"}},
"required": ["name"],
},
}
]
# OpenAI API νΈμΆ
response = client.chat.completions.create(
model="gpt-3.5-turbo",
messages=[{"role": "user", "content": "λ΄ μ΄λ¦μ νκΈΈλμ΄μΌ. μΈμ¬ν΄μ€."}],
functions=functions,
function_call="auto",
)
# μλ΅ μ²λ¦¬ λ° ν¨μ μ€ν
message = response.choices[0].message
if message.function_call:
function_args = json.loads(message.function_call.arguments)
result = hello_world(function_args["name"])
print(result)
```
## λ μ¨ API
λ μ¨ API νΈμΆ μ½λλ OpenAIμ GPT λͺ¨λΈκ³Ό OpenWeatherMap APIλ₯Ό κ²°ν©νμ¬ μ¬μ©μμ λ μ¨ κ΄λ ¨ μ§λ¬Έμ λ΅νλ€. λ¨Όμ OpenWeatherMap APIλ₯Ό μ¬μ©νμ¬ νΉμ λμμ λ μ¨ μ 보λ₯Ό κ°μ Έμ€λ `get_weather` ν¨μλ₯Ό μ μνλ€. κ·Έ λ€μ μ΄ ν¨μμ μ€λͺ
μ OpenAI APIμ μ 곡νκ³ , μ¬μ©μμ μμ°μ΄ μ
λ ₯μ μ²λ¦¬νλλ‘ GPT λͺ¨λΈμ μμ²νλ€. GPT λͺ¨λΈμ μ¬μ©μμ μ§λ¬Έμ ν΄μνμ¬ μ μ ν λμ μ΄λ¦μ μΆμΆνκ³ `get_weather` ν¨μλ₯Ό νΈμΆνλ€. λ§μ§λ§μΌλ‘ ν¨μμ λ°νκ°μ μΆλ ₯νμ¬ μ¬μ©μμκ² νμ¬ λ μ¨ μ 보λ₯Ό μ 곡νλ€. μ΄ κ³Όμ μ ν΅ν΄ μμ°μ΄ μ²λ¦¬μ μ€μκ° λ°μ΄ν° μ‘°νλ₯Ό κ²°ν©ν μ€μ©μ μΈ AI μ ν리μΌμ΄μ
μ κΈ°λ³Έ ꡬ쑰λ₯Ό ꡬννλ€.
```{python}
from openai import OpenAI
import requests
import os
from dotenv import load_dotenv
# νκ²½ λ³μ λ‘λ
load_dotenv()
# OpenAI λ° OpenWeatherMap API ν€ μ€μ
openai_api_key = os.getenv("OPENAI_API_KEY")
weather_api_key = os.getenv("OPENWEATHER_API_KEY")
# OpenAI ν΄λΌμ΄μΈνΈ μ΄κΈ°ν
client = OpenAI(api_key=openai_api_key)
def get_weather(city):
"""OpenWeatherMap APIλ₯Ό μ¬μ©νμ¬ λ μ¨ μ 보λ₯Ό κ°μ Έμ€λ ν¨μ"""
base_url = "http://api.openweathermap.org/data/2.5/weather"
params = {"q": city, "appid": weather_api_key, "units": "metric"} # μμ¨ μ¨λ μ¬μ©
response = requests.get(base_url, params=params)
if response.status_code == 200:
data = response.json()
weather_desc = data["weather"][0]["description"]
temp = data["main"]["temp"]
return f"{city}μ νμ¬ λ μ¨λ {weather_desc}μ΄λ©°, κΈ°μ¨μ {temp}Β°C μ
λλ€."
else:
return "λ μ¨ μ 보λ₯Ό κ°μ Έμ€λλ° μ€ν¨νμ΅λλ€."
# OpenAIμ μ 곡ν ν¨μ μ€λͺ
functions = [
{
"name": "get_weather",
"description": "νΉμ λμμ νμ¬ λ μ¨ μ 보λ₯Ό κ°μ Έμ€λ ν¨μ",
"parameters": {
"type": "object",
"properties": {
"city": {"type": "string", "description": "λ μ¨λ₯Ό μκ³ μΆμ λμ μ΄λ¦"}
},
"required": ["city"],
},
}
]
# μ¬μ©μ μ
λ ₯ μ²λ¦¬ λ° ν¨μ νΈμΆ
user_input = "μμ΄μ μ€λ λ μ¨ μ΄λ?"
response = client.chat.completions.create(
model="gpt-3.5-turbo",
messages=[{"role": "user", "content": user_input}],
functions=functions,
function_call="auto",
)
# μλ΅ μ²λ¦¬ λ° ν¨μ μ€ν
message = response.choices[0].message
if message.function_call:
function_args = eval(message.function_call.arguments)
result = get_weather(function_args["city"])
print(result)
else:
print(message.content)
```
## λμ²΄μΈ λꡬ
ν¨μ νΈμΆμ νΉμ GPT λͺ¨νμ νΉνλ λ°λ©΄ λμ²΄μΈ λꡬλ νΉμ GPT λͺ¨νμ μ’
μλμ§ μλλ€.
```{python}
from langchain.agents import Tool
from langchain.agents import AgentType
from langchain.memory import ConversationBufferMemory
from langchain.chat_models import ChatOpenAI
from langchain.agents import initialize_agent
from langchain.tools import DuckDuckGoSearchRun
import os
from dotenv import load_dotenv
load_dotenv()
# OpenAI API ν€ μ€μ
os.environ["OPENAI_API_KEY"] = os.getenv("OPENAI_API_KEY")
# ChatOpenAI λͺ¨λΈ μ΄κΈ°ν
llm = ChatOpenAI(temperature=0)
# DuckDuckGo κ²μ λꡬ μ΄κΈ°ν
search = DuckDuckGoSearchRun()
# λꡬ μ μ
tools = [
Tool(
name="DuckDuckGo Search",
func=search.run,
description="useful for when you need to answer questions about current events or the current state of the world",
)
]
# λ©λͺ¨λ¦¬ μ΄κΈ°ν
memory = ConversationBufferMemory(memory_key="chat_history", return_messages=True)
# μμ΄μ νΈ μ΄κΈ°ν
agent = initialize_agent(
tools,
llm,
agent=AgentType.CHAT_CONVERSATIONAL_REACT_DESCRIPTION,
verbose=True,
memory=memory,
)
# μμ΄μ νΈ μ€ν
response = agent.run("What's the latest news about SpaceX?")
print(response)
```