然后可以通過調(diào)用應用API的方式將應用集成在工程項目中:

??此外,也支持llama-index集成百煉進行搭建,參考鏈接為:

https://help.aliyun.com/zh/model-studio/developer-reference/build-rag-applications-based-on-llamaindex

相對于白屏化操作來說,這種方式的優(yōu)點是,通過每個步驟對應一個函數(shù)的拆分,可以控制每個步驟之間的輸入輸出,用戶可以自定義的編寫對于中間數(shù)據(jù)的數(shù)據(jù)操作,或者是做一些安全檢測、安全防控類的任務。

2、Function call

Function call需要解決的問題就是將LLM的能力從單純NLP類問答轉(zhuǎn)化為一個個執(zhí)行單元,將模型輸出的語言對應到可以執(zhí)行特定任務的函數(shù)或插件。

目前Function call功能在百煉產(chǎn)品文檔中已經(jīng)形成兩個非常詳細的最佳實踐文檔:

相對于code_interpreter,search這種已經(jīng)封裝好的插件,對于用戶自定義的任務來說,我們實現(xiàn)自己的Function call能力,主要分成三個步驟:

1)步驟一:tools中function的定義,目的是為了定義每個插件的作用,需要傳入的參數(shù)的定義;

{
'type': 'function',
'function': {
'name': '獲取目的地建議',
'description': '用于推薦最近熱門的旅游目的地。',
'parameters': {
'type': 'object',
'properties': {
'query': {
'type': 'str',
'description': '可能需要的信息'
},
},
'required': ['query']
}
}
},

2)步驟二:function_mapper,定義每個function對應的調(diào)用函數(shù)名;

function_mapper = {
"天氣查詢": get_weather,
"路徑規(guī)劃": get_path_recommendation,
"獲取目的地建議": get_destination_recommendation,
"獲取景點推薦": get_attraction_recommendation,
"獲取餐飲推薦": get_dining_recommendation,
"獲取旅行提示": get_life_tips,
"獲取當?shù)仫L俗": get_local_customs,
}

3)步驟三:實現(xiàn)函數(shù),保持輸入?yún)?shù)和輸出的正確性。

3、ASR+TTS

ASR(語音轉(zhuǎn)文字)和TTS(文字轉(zhuǎn)語音)本身已經(jīng)是成熟的功能,在與大模型的結(jié)合中衍生出了新的產(chǎn)品和范式,比如通義聽悟產(chǎn)品,在ASR的基礎上增加了角色識別、文本翻譯、章節(jié)提取、摘要生成等等功能,甚至是后面會做到的語音特征提取、情緒識別等新功能。ASR中的比較先進模型為paraformer,TTS中的先進模型舉例為sambert(聲音克隆功能),目前提供的代碼鏈接如下:Paraformer實時語音轉(zhuǎn)文字:

https://help.aliyun.com/zh/dashscope/developer-reference/quick-start-7聽悟離線轉(zhuǎn)文字:https://help.aliyun.com/zh/tingwu/offline-transcribe-of-audio-and-video-files

實時部分目前有完整JavaSDK工程。

Sambert調(diào)用頁面:https://dashscope.console.aliyun.com/model?

請注意:

1、 paraformer 本身代碼沒有設置 stop 邏輯,所以需要設置一個時長,或者是通過 result.is_sentense_end() 來判斷語句是否結(jié)束;

2、本身原子能力是成熟的,但是目前模型對于打斷效果支持效果還不好,如果出現(xiàn)打斷,輸出text會斷開并重新生成,準確度方面需要在上層進行工程優(yōu)化。

4、意圖識別

目前的多輪對話使用prompt來實現(xiàn),在prompt中可以標注本應用是一個意圖識別的AI應用,并且在定義中表明類別有幾類,每一類的任務分別是什么。

如果類別比較少,可以像下面這么寫:

# 角色
你是一個精準的意圖識別系統(tǒng),專門負責將接收到的指令歸類為三大任務類型,并嚴格依據(jù)指令內(nèi)容輸出對應的任務標簽數(shù)字(1, 2, 或 3)。

## 技能
### 技能1: ****問答任務
- **任務定義**:
- **輸出標簽**:遇到此類指令,輸出數(shù)字 1。 - **示例**: ### 技能2: ****任務 - **任務定義**: - **輸出標簽**:對此類指令,輸出數(shù)字 2。 - **示例**: ### 技能3: ****執(zhí)行任務 - **任務定義**: - **輸出標簽**:面對這類指令,輸出數(shù)字 3。 - **示例**:

并且在限制中定義好輸出的格式,比如定義如下輸出格式:

## 限制
- 輸出格式嚴格定義為: “意圖標簽:標簽數(shù)字”的格式

則返回的結(jié)果為:

如果類別比較多,可以直接使用Key:Value的形式,形成一個意圖文檔,把文檔當作prompt,每次輸入為意圖識別的要求+意圖識別文檔庫,返回意圖標簽。

5、多輪對話能力

我們在白屏化頁面上(比如百煉和通義官網(wǎng))直接使用基模的原子能力時,是內(nèi)置了多輪對話能力。但是在調(diào)用SDK時,因為代碼默認一個用戶創(chuàng)建一個線程(thread),而每一輪的用戶輸入query的時候,thread都會初始化一次然后存入當前的message。簡而言之就是每次問答,大模型的消息隊列中只包含新的message信息,而不包含過去的messages信息。

我們來看一下下面簡單的多輪對話實現(xiàn)方式,可以看到多輪對話的理論就是將之前對話的role(usr、system)和message,append到長期維護的messages隊列中,然后再把整個messages隊列輸入到大模型中:

因此在assistant實現(xiàn)多輪對話中,最簡單的方法就是在創(chuàng)建線程并把信息輸入給assistant之前,把每一輪的role和輸出/輸出保存成一個隊列,然后再發(fā)送給assistant,以下代碼供參考:

message_objs = []
for j in msgs['data']: #msgs為上一輪的output
role = j['role']
content = j['content'][0]['text']['value']
message_objs.append({
"role": role,
"content": content
})

最終出來的結(jié)果可以看到一下的截圖,當我的第二個問題“我剛才讓你干了什么?”輸出的時候,隊列中已經(jīng)包含了之前第一輪input和output的信息:

??

四、搭建示例

我們以產(chǎn)品架構(gòu)師角度,搭建一個支持語音輸入輸出,并且具有開通資源和回答技術文檔能力的AI助手。通過對于功能的分析,并且對應到以上的原子能力,我們的大模型應用首先要解決兩個事情:問答功能和開通資源的功能。

如何通過RAG實現(xiàn)面向架構(gòu)師的技術問答助手呢?

步驟描述

此步驟較為簡單,不做概述,大家可以看百煉的最佳實踐,一般分為四個步驟:1)知識庫導入、解析和切分2)prompt的書寫,調(diào)優(yōu)3)知識庫的掛載、插件掛載

4)根據(jù)測試問題開始進行調(diào)試

如何減少大模型幻覺

要注意,幻覺是不可避免的,有時候prompt的語料“打”不過模型本身的泛化能力,模型會自信的根據(jù)自己的能力自說自話。比如提出這樣的一個問題“paimon是什么?”,由于paimon本身是一個比較新的湖格式,并且即使制定了大模型搜索大數(shù)據(jù)相關的知識,大模型有時候也沒有鏈接到湖格式的邏輯思維,所以會出現(xiàn)以下的情況:

??

那么如何讓回答變成我們所預想的專業(yè)的回復呢?在我的嘗試中,比較簡單的步驟分別為:1)嘗試更大的模型;2)prompt調(diào)優(yōu);3)對應的文檔掛載;

1)嘗試更大的模型:

一般來說,如果發(fā)現(xiàn)一個模型在某項任務上失敗了,并且有一個更強大的模型可用,那么值得嘗試使用更強大的模型再次嘗試。在這里由于我已經(jīng)使用了max模型,所以在此處可以忽略。

2)prompt調(diào)優(yōu):a)角色定義清晰:prompt中需要清晰的讓大模型知道自己的定位和精通并專注的內(nèi)容,比如在角色定義中寫明:

# 角色
你作為阿里云高級解決方案架構(gòu)師的智能助手,精通大數(shù)據(jù)、數(shù)據(jù)庫、分布式計算等核心云計算領域,掌握apache、oracle等大型云計算IT公司的全部技術棧,以嚴謹專注的態(tài)度,輔以親切的交流方式,結(jié)合知識庫${documents}和夸克搜索等插件,提供給云計算架構(gòu)師對于云計算和云產(chǎn)品的專業(yè)指導。

b)提供示例:對于一些復雜的問題,可以給大模型提供示例,并且讓他有一定的思考時間。比如:“請在回答AC大小問題時,通過分析A大于B,B大于C的情況,得出最終結(jié)論。”c)限制描述:在限制中明確回答問題的領域、回答的長短、回答中禁止出現(xiàn)的詞匯、回答中的來源等信息,會非??焖俚膸椭竽P瓦M行回答的調(diào)優(yōu),諸如以下示例:i)但是請注意,這種限制性的描述對于特定的問題可能會產(chǎn)生非常精準的效果,但是有可能會影響到整個大模型應用的泛化性,所以還要多多嘗試和調(diào)整,達成最終應用層面的precision-generalization tradeoff。

## 限制與風格
- 回答需嚴格限制在于云計算、數(shù)據(jù)庫、大數(shù)據(jù)及分布式計算等計算機技術領域。
- 回答不要涉及任何游戲、娛樂等領域的詞匯和課題,
- 當回答出現(xiàn)不清楚字樣的時候,一定要使用夸克搜索插件,返回最相關的回復。
- 交流風格親切友好,即使面對復雜技術問題也能以易于理解的方式解答。
- 確保所有檢索內(nèi)容均來源于可靠渠道,優(yōu)先考慮阿里云等云廠商的官方資源,維護回答的準確性和時效性。

3)對應的文檔掛載:

文檔掛載這類外部信息輔助的問答,是最快最有效解決大模型對于一類特定領域或者名詞進行“胡說八道“的問題,當我們將Paimon的產(chǎn)品文檔鏈接以外部知識庫的形式掛載時,大模型回答問題顯而易見的精準了很多:

??

如何自己寫一個開通ECS的Agent呢?

在實現(xiàn)Agent搭建的時候,function call是一個非常簡單而且有用的方式,通過自定義的function,讓大模型根據(jù)輸入的query來匹配是否需要調(diào)用函數(shù)和調(diào)用哪個函數(shù)。當然,我們也可以讓大模型自動生成開通ecs的代碼,并且調(diào)用code_interpreter(代碼解釋器插件)來進行運行,甚至可以指定它來進行自主的調(diào)優(yōu),但是這就是一個具有多個step的復雜問題,其中有諸多挑戰(zhàn),比如:需要明確的規(guī)劃好這些步驟的操作內(nèi)容、操作順序、環(huán)境配置才能讓模型更容易遵循;中間結(jié)果也不一定可以人為的進行控制;并且AK、SK和ECS的各種參數(shù)匹配與輸入又是另一個工程性問題,所以在此篇文章中我們不予考慮。下面將介紹如何使用function call構(gòu)建一個非常簡單的開通資源的Agent,分為五個步驟:

步驟描述

description='一個阿里云架構(gòu)師AI助手,可以通過用戶訴求,通過調(diào)用插件幫助用戶創(chuàng)建ecs、vpc等云資源。',
instructions='一個阿里云架構(gòu)師AI助手,可以通過調(diào)用插件解決開通資源等問題。插件例如,開通ecs,開通vpc,判斷地域等等,當你無法回答問題時應當結(jié)合插件回復進行回答。請根據(jù)插件結(jié)果適當豐富回復內(nèi)容。'
'當有需求開一臺ecs的時候,請一定要調(diào)用開通ecs這個插件'
'當有需求開一個vpc的時候,請一定調(diào)用開通vpc插件',

請注意:最好寫Default,比如若用戶輸入的query中不包含地域信息,那么請給出默認一個地域,防止參數(shù)為空導致的一系列報錯問題,例如:“如果輸入中沒有地域,則默認region=cn-beijing”

{
'type': 'function',
'function': {
'name': '開通ecs',
'description': '用于開一臺ecs的插件和函數(shù),例如:請給我開一臺北京的ecs,則region=cn-beijing;請給我開一臺上海的ecs,則region=cn-shanghai。如果輸入中沒有地域,則默認region=cn-beijing',
'parameters': {
--------
},
'required': ['']
}
}
},

請注意:

1、required 這個部分如果含有參數(shù),那么region_ecs就不能為空,或者是region_ecs的參數(shù)必須符合自定義的參數(shù)類型。如果required=[”],則region_ecs為空也沒事,只要后面的函數(shù)可以接受region_ecs為空;

2、參數(shù)名稱(region_ecs)必須和后面調(diào)用函數(shù)的參數(shù)名一模一樣。

'parameters': {
'type': 'object',
'properties': {
'region_ecs': {
'type': 'string',
'description': 'ecs開通的地域,并且需要轉(zhuǎn)化為‘cn’加上地域拼音的形式,比如北京對應cn-beijing,杭州對應cn-hangzhou'
},
},
'required': ['region_ecs']
function_mapper = {
"開通vpc": create_vpc_function,
"判斷地域": judge_region_exist,
"開通ecs": create_instance_action,
}

請注意:需要有返回值,返回值類型為string,最好返回的內(nèi)容可以被大模型理解,這樣大模型可以根據(jù)返回的信息進行潤色。比如該例子中,返回:“success”這句話,大模型回復“已成功為您開通一臺位于北京的ecs”。

def create_instance_action(region_ecs):
print("function調(diào)用測試成功,region-id為:",region_ecs)
IMAGE_ID, INSTANCE_TYPE, SECURITY_GROUP_ID, VSWITCH_ID = get_config(region_ecs)
instance_id = create_after_pay_instance(IMAGE_ID, INSTANCE_TYPE, SECURITY_GROUP_ID, VSWITCH_ID,region_ecs)
check_instance_running(instance_id,region_ecs)
return "success"

后續(xù)思考問題

應用集成

在了解原子能力和一些功能搭建之后,面對一個復雜一些的場景,通常不僅僅是選取單個模型,或者僅僅完成部分功能,那么就需要根據(jù)業(yè)務情況以大小模型、RAG+Agent的方式構(gòu)建一個多智能體應用。這里介紹兩種集成方式:意圖識別鏈接多個模型的方式和Aassistant API集成function和RAG。

1.意圖識別

意圖識別的本質(zhì)是實現(xiàn)大小模型的結(jié)合,通過意圖識別后的tag,分別調(diào)用不同的模型、APP和assistant,可以控制不同部分的模型的大小和實現(xiàn)的功能,讓每條鏈路都更加精準化。比如我們可以將問題的分類分為以下幾個部分,分別使用不同大小的模型,掛載不同的知識庫來覆蓋所有的功能:

??

拓展來說,我們甚至可以將意圖樹做的更深,如果場景足夠的復雜,那么意圖識別也可以是多層的,像一個樹一樣,每個分支都定義更加精細化的意圖知識庫。

2.Assistant-API集成

目前,基于dashscope搭建的assistant已經(jīng)可以將rag和function call等插件集成到一個模型中:

tools=[
{
"type": "fucntion"{

}
},
{
"type": "rag",
"prompt_ra": {
"pipeline_id": "YOUR_PIPELINE_ID",
"parameters": {
"type": "object",
"properties": {
"query_word": {
"type": "str",
"value": "${document1}"
}

}
}
}
}]

最終使用多個原子能力構(gòu)建整個完整的端到端鏈路。?

五、后記

目前大模型的原子能力和API、SDK的更新非常的頻繁,也越來越完善,通過一次或者兩次的動手搭建,可以讓我們知道如何利用這些能力,像“積木”一樣,結(jié)合自己本身業(yè)務或者功能的邏輯,搭建一個完整的大模型“城堡”。

文章轉(zhuǎn)自微信公眾號@阿里云開發(fā)者

上一篇:

從API到Agent:萬字長文洞悉LangChain工程化設計

下一篇:

Springboot集成LLM大模型API
#你可能也喜歡這些API文章!

我們有何不同?

API服務商零注冊

多API并行試用

數(shù)據(jù)驅(qū)動選型,提升決策效率

查看全部API→
??

熱門場景實測,選對API

#AI文本生成大模型API

對比大模型API的內(nèi)容創(chuàng)意新穎性、情感共鳴力、商業(yè)轉(zhuǎn)化潛力

25個渠道
一鍵對比試用API 限時免費

#AI深度推理大模型API

對比大模型API的邏輯推理準確性、分析深度、可視化建議合理性

10個渠道
一鍵對比試用API 限時免費