大模型實(shí)操Agent-如何從0開始搭建function calling

構(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)抖僵。

讓Kimi幫買張火車票

2、Agent構(gòu)建思路

首先理清思路瀑构,確定好Agent的目標(biāo)裆针、需要的function,其次理解用戶問題寺晌、選擇工具世吨,最后將返回的結(jié)果,整理好給用戶呻征。

設(shè)計(jì)思路

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框架的原理浦马。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末时呀,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子晶默,更是在濱河造成了極大的恐慌谨娜,老刑警劉巖,帶你破解...
    沈念sama閱讀 217,542評論 6 504
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件磺陡,死亡現(xiàn)場離奇詭異趴梢,居然都是意外死亡漠畜,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,822評論 3 394
  • 文/潘曉璐 我一進(jìn)店門坞靶,熙熙樓的掌柜王于貴愁眉苦臉地迎上來憔狞,“玉大人,你說我怎么就攤上這事彰阴●遥” “怎么了?”我有些...
    開封第一講書人閱讀 163,912評論 0 354
  • 文/不壞的土叔 我叫張陵尿这,是天一觀的道長簇抵。 經(jīng)常有香客問我,道長射众,這世上最難降的妖魔是什么碟摆? 我笑而不...
    開封第一講書人閱讀 58,449評論 1 293
  • 正文 為了忘掉前任,我火速辦了婚禮叨橱,結(jié)果婚禮上典蜕,老公的妹妹穿的比我還像新娘。我一直安慰自己罗洗,他們只是感情好愉舔,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,500評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著伙菜,像睡著了一般屑宠。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上仇让,一...
    開封第一講書人閱讀 51,370評論 1 302
  • 那天典奉,我揣著相機(jī)與錄音,去河邊找鬼丧叽。 笑死卫玖,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的踊淳。 我是一名探鬼主播假瞬,決...
    沈念sama閱讀 40,193評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼迂尝!你這毒婦竟也來了脱茉?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,074評論 0 276
  • 序言:老撾萬榮一對情侶失蹤垄开,失蹤者是張志新(化名)和其女友劉穎琴许,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體溉躲,經(jīng)...
    沈念sama閱讀 45,505評論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡榜田,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,722評論 3 335
  • 正文 我和宋清朗相戀三年益兄,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片箭券。...
    茶點(diǎn)故事閱讀 39,841評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡净捅,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出辩块,到底是詐尸還是另有隱情蛔六,我是刑警寧澤,帶...
    沈念sama閱讀 35,569評論 5 345
  • 正文 年R本政府宣布废亭,位于F島的核電站古今,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏滔以。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,168評論 3 328
  • 文/蒙蒙 一氓拼、第九天 我趴在偏房一處隱蔽的房頂上張望你画。 院中可真熱鬧,春花似錦桃漾、人聲如沸坏匪。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,783評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽适滓。三九已至,卻和暖如春恋追,著一層夾襖步出監(jiān)牢的瞬間凭迹,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,918評論 1 269
  • 我被黑心中介騙來泰國打工苦囱, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留嗅绸,地道東北人。 一個月前我還...
    沈念sama閱讀 47,962評論 2 370
  • 正文 我出身青樓撕彤,卻偏偏與公主長得像鱼鸠,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子羹铅,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,781評論 2 354

推薦閱讀更多精彩內(nèi)容