構(gòu)建Agent的重要的一步是Function calling(函數(shù)調(diào)用)测暗,本文不使用任何langchain等框架或者coze等平臺,從0開始構(gòu)建一個可以調(diào)用function的Agent举反。
Function calling其實(shí)就是提供了一種方式,允許LLM與外部系統(tǒng)進(jìn)行交互扒吁,還有如何進(jìn)行交互火鼻。
1、買火車票
我讓Kimi幫買張火車票,它會直接拒絕魁索,甚至換ChatGPT融撞、文心、通義等其他大模型粗蔚,得到的回答只有:"我無法直接為您購買火車票"尝偎。
不過,LLM是知道買票鹏控,但它不能直接操作致扯,它的本質(zhì)是語言模型,所以需要和外部系統(tǒng)進(jìn)行交互当辐,那么就需要函數(shù)調(diào)用(function call)
抖僵。
2、Agent構(gòu)建思路
首先理清思路瀑构,確定好Agent的目標(biāo)裆针、需要的function,其次理解用戶問題寺晌、選擇工具世吨,最后將返回的結(jié)果,整理好給用戶呻征。
2.1 場景示例-天氣Agent
創(chuàng)建一個獲取最新天氣的Agent耘婚,以及如何使用function call。
Agent的目標(biāo):可以回答關(guān)于天氣的問題陆赋。
function:調(diào)用某地方的天氣情況沐祷,并且反饋
-
流程:
- a.思考: 用戶輸入問題,LLM先對問題進(jìn)行分析
- b.行動: 如果問到了天氣問題攒岛,則分析出需要調(diào)用的function以及function要傳入的參數(shù)
- c.響應(yīng):function返回后赖临,將答案整理好回復(fù)給用戶。
-
函數(shù)自定:
-
a.定義一個獲取天氣的函數(shù)(屬于Tools中的一個灾锯,這里用于演示兢榨,不做真實(shí)調(diào)用):
def get_weather(location): return "天氣晴朗"
-
b.再定義一個大模型的發(fā)送信息的方法:
def send_messages(messages): client = OpenAI( api_key="<你的llm的key>", base_url="https://api.llm.com") response = client.chat.completions.create( model="llm-chat", messages=messages) return response.choices[0].message
-
2.2 實(shí)操Agent-天氣Agent
從“用戶提出問題”到“思考”到“響應(yīng)”調(diào)用了多次LLM模型,所以要求模型按照順序去調(diào)用LLM:
一定需要理清思路顺饮!一定需要理清思路吵聪!
換句話說寫好system prompt!換句話說寫好system prompt兼雄!
以下是思考過程
你在運(yùn)行一個“思考”吟逝,“工具調(diào)用”,“響應(yīng)”循環(huán)赦肋。每次只運(yùn)行一個階段
1.“思考”階段:你要仔細(xì)思考用戶的問題
2.“工具調(diào)用階段”:選擇可以調(diào)用的工具块攒,并且輸出對應(yīng)工具需要的參數(shù)
3.“響應(yīng)”階段:根據(jù)工具調(diào)用返回的影響励稳,回復(fù)用戶問題。
已有的工具如下:
get_weather:
e.g. get_weather:天津
返回天津的天氣情況
Example:
question:天津的天氣怎么樣囱井?
thought:我應(yīng)該調(diào)用工具查詢天津的天氣情況
Action:
{
"function_name":"get_response_time"
"function_params":{
"location":"天津"
}
}
調(diào)用Action的結(jié)果:“天氣晴朗”
Answer:天津的天氣晴朗
提示工程
上邊的邏輯正好可以當(dāng)作system的提示工程:
system="""
你在運(yùn)行一個“思考”麦锯,“工具調(diào)用”,“響應(yīng)”循環(huán)琅绅。每次只運(yùn)行一個階段
1.“思考”階段:你要仔細(xì)思考用戶的問題
2.“工具調(diào)用階段”:選擇可以調(diào)用的工具,并且輸出對應(yīng)工具需要的參數(shù)
3.“響應(yīng)”階段:根據(jù)工具調(diào)用返回的影響鹅巍,回復(fù)用戶問題千扶。
已有的工具如下:
get_weather:
e.g. get_weather:天津
返回天津的天氣情況
Example:
question:天津的天氣怎么樣?
thought:我應(yīng)該調(diào)用工具查詢天津的天氣情況
Action:
{
"function_name":"get_response_time"
"function_params":{
"location":"天津"
}
}
調(diào)用Action的結(jié)果:“天氣晴朗”
Answer:天津的天氣晴朗
"""
用戶Query
第一步骆捧,向模型提問一個問題
question="北京天氣怎么樣"
messages = [{"role": "system", "content": system_prompt},
{"role": "user", "content": question}]
message = send_messages(messages)
print(f"Model-1th>\n {message.content}")
返回值:
Model-1th>
thought:我應(yīng)該調(diào)用工具查詢北京的天氣情況
Action:
{
"function_name":"get_weather",
"function_params":{
"location":"北京"
}
}
可以看出模型已經(jīng)進(jìn)行了思考澎羞,并且返回了可以調(diào)用的工具了
函數(shù)調(diào)用
第二步,如果從“第一步”的返回值中可以提取調(diào)用工具的json
"function_name":"get_weather",
"function_params": "location":"北京"
第三步敛苇,調(diào)用真實(shí)工具,獲取真實(shí)結(jié)果
invoke_function(**function_name,**function_params)
返回結(jié)果
第四步妆绞,將工具調(diào)用的結(jié)果追加到message中,一起給到模型枫攀,讓它總結(jié)回答:
messages.append({"role": "assistant",
"content": f"調(diào)用Action的結(jié)果:{tianqi}"})
message = send_messages(messages)
print(f"result>\n {message.content}")
返回值:
result>
北京今天的天氣晴朗括饶。
3、tools功能的演進(jìn)
上篇文章提過来涨,筆者認(rèn)為function calling和tool using功能相同图焰,只是描述不同,看每個人的語言習(xí)慣蹦掐。
隨著LLM調(diào)用工具的普及技羔,這種調(diào)用方法集成在大模型api接口中就變得越重要。
大部分模型廠商已經(jīng)支持了function call卧抗,下面是deepseek工具調(diào)用的一個例子:
response = client.chat.completions.create(
model="deepseek-chat",
messages=messages,
tools=tools
)
其中 tools是可以供模型選擇的工具藤滥。
寫在最后
從0開發(fā)寫function的邏輯,需要讓模型思考社裆、觀察拙绊、行動。其實(shí)這個流程的循環(huán)其實(shí)就是ReAct框架的原理浦马。