阿里妹導讀
一、概況
二、大模型發展現狀
目前大模型發展籠統的可以分為兩個部分,自然語言處理大模型(Qwen語言系列等)和多模態大模型,同時多模態大模型又分為多模態理解(Qwen-VL、Qwen-Audio等)和多模態生成(萬相、EMO等)。
自然語言處理
在自然語言處理領域,短短的2個月內,大家已經看到了價格的急劇下降,這是得益諸如OpenAI的ChatGPT系列、Llama、通義、GLM等標志性大模型的發布和應用,也代表著這個技術在算法和模型層面上的進入了成熟的新階段。這些自然語言處理大模型憑借其龐大的參數量和在海量數據上的訓練,展現出了令人驚嘆的語言理解和生成能力,除了原始的文本生成、機器翻譯、情感分析和自動問答等基礎功能,還衍生出了以檢索增強生成和Agent搭建為背景的特定領域功能,比如客服質檢、風控輔助、智能投研等。它們不僅大幅提高了交互的自然度和效率,還促進了諸如智能客服、內容創作、教育輔助工具等多種產品的創新與升級,實現了技術和業務需求的融合。
多模態
相比之下,多模態技術,尤其涉及視覺、聽覺與文本等多種感官信息融合的多模態大模型,在Sora推出之后收到了廣泛的關注,并且已經應用在一些客服、座艙、營銷等領域。在GPT-4o發出后,端到端的多模態理解與生成模型也成為了每個公司所希望打造的模型之一。目前大多數對于多模態的應用還集中于原子能力的使用,比如圖像描述生成、視頻內容理解和生成等,與業務緊密結合的最佳實踐還沒有形成完整的體系,如何落地端到端的自然語言處理和多模態應用仍然在嘗試和共創的過程中。
本文主要介紹自然語言處理模型如何在業務場景中進行落地,將模型價值轉化為生產力價值。?
三、原子能力概括
目前基于百煉平臺、靈積平臺和dashscope sdk等功能,非算法工程師和技術人員也可以學習并構建自己的大模型應用。總結多個產品和功能后,排除百煉本身單個功能(比如模型測試、模型微調等)外,目前的原子能力可以分為以下幾個部分:
1、RAG
目前RAG的實現方式有兩種:
第一種通過百煉白屏化的方式,通過一下步驟快速搭建一個RAG應用:1、數據管理-導入數據;2、數據應用-知識索引-創建知識庫;3、模型應用-新建應用-開通知識檢索增強。
?
然后可以通過調用應用API的方式將應用集成在工程項目中:
?
https://help.aliyun.com/zh/model-studio/developer-reference/build-rag-applications-based-on-llamaindex
相對于白屏化操作來說,這種方式的優點是,通過每個步驟對應一個函數的拆分,可以控制每個步驟之間的輸入輸出,用戶可以自定義的編寫對于中間數據的數據操作,或者是做一些安全檢測、安全防控類的任務。
https://blog.csdn.net/qq_23953717/article/details/136553084
注意項:
2、Function call
Function call需要解決的問題就是將LLM的能力從單純NLP類問答轉化為一個個執行單元,將模型輸出的語言對應到可以執行特定任務的函數或插件。
目前Function call功能在百煉產品文檔中已經形成兩個非常詳細的最佳實踐文檔:
https://help.aliyun.com/zh/model-studio/user-guide/assistant-api-based-travel-assistant
https://help.aliyun.com/zh/model-studio/user-guide/use-local-functions
相對于code_interpreter,search這種已經封裝好的插件,對于用戶自定義的任務來說,我們實現自己的Function call能力,主要分成三個步驟:
1)步驟一:tools中function的定義,目的是為了定義每個插件的作用,需要傳入的參數的定義;
{
'type': 'function',
'function': {
'name': '獲取目的地建議',
'description': '用于推薦最近熱門的旅游目的地。',
'parameters': {
'type': 'object',
'properties': {
'query': {
'type': 'str',
'description': '可能需要的信息'
},
},
'required': ['query']
}
}
},
2)步驟二:function_mapper,定義每個function對應的調用函數名;
function_mapper = {
'天氣查詢': get_weather,
'路徑規劃': get_path_recommendation,
'獲取目的地建議': get_destination_recommendation,
'獲取景點推薦': get_attraction_recommendation,
'獲取餐飲推薦': get_dining_recommendation,
'獲取旅行提示': get_life_tips,
'獲取當地風俗': get_local_customs,
}
3)步驟三:實現函數,保持輸入參數和輸出的正確性。
3、ASR+TTS
ASR(語音轉文字)和TTS(文字轉語音)本身已經是成熟的功能,在與大模型的結合中衍生出了新的產品和范式,比如通義聽悟產品,在ASR的基礎上增加了角色識別、文本翻譯、章節提取、摘要生成等等功能,甚至是后面會做到的語音特征提取、情緒識別等新功能。ASR中的比較先進模型為paraformer,TTS中的先進模型舉例為sambert(聲音克隆功能),目前提供的代碼鏈接如下:
https://help.aliyun.com/zh/dashscope/developer-reference/quick-start-7
實時部分目前有完整JavaSDK工程。
Sambert調用頁面:https://dashscope.console.aliyun.com/model?
請注意:
1、 paraformer 本身代碼沒有設置 stop 邏輯,所以需要設置一個時長,或者是通過 result.is_sentense_end() 來判斷語句是否結束;
2、本身原子能力是成熟的,但是目前模型對于打斷效果支持效果還不好,如果出現打斷,輸出text會斷開并重新生成,準確度方面需要在上層進行工程優化。
4、意圖識別
目前的多輪對話使用prompt來實現,在prompt中可以標注本應用是一個意圖識別的AI應用,并且在定義中表明類別有幾類,每一類的任務分別是什么。
如果類別比較少,可以像下面這么寫:
# 角色
你是一個精準的意圖識別系統,專門負責將接收到的指令歸類為三大任務類型,并嚴格依據指令內容輸出對應的任務標簽數字(1, 2, 或 3)。
## 技能
### 技能1: ****問答任務
- **任務定義**:
- **輸出標簽**:遇到此類指令,輸出數字 `1`。
- **示例**:
### 技能2: ****任務
- **任務定義**:
- **輸出標簽**:對此類指令,輸出數字 `2`。
- **示例**:
### 技能3: ****執行任務
- **任務定義**:
- **輸出標簽**:面對這類指令,輸出數字 `3`。
- **示例**:
并且在限制中定義好輸出的格式,比如定義如下輸出格式:
## 限制
- 輸出格式嚴格定義為: “意圖標簽:標簽數字”的格式
則返回的結果為:
?
如果類別比較多,可以直接使用Key:Value的形式,形成一個意圖文檔,把文檔當作prompt,每次輸入為意圖識別的要求+意圖識別文檔庫,返回意圖標簽。
5、多輪對話能力
我們在白屏化頁面上(比如百煉和通義官網)直接使用基模的原子能力時,是內置了多輪對話能力。但是在調用SDK時,因為代碼默認一個用戶創建一個線程(thread),而每一輪的用戶輸入query的時候,thread都會初始化一次然后存入當前的message。簡而言之就是每次問答,大模型的消息隊列中只包含新的message信息,而不包含過去的messages信息。
我們來看一下下面簡單的多輪對話實現方式,可以看到多輪對話的理論就是將之前對話的role(usr、system)和message,append到長期維護的messages隊列中,然后再把整個messages隊列輸入到大模型中:
?
因此在assistant實現多輪對話中,最簡單的方法就是在創建線程并把信息輸入給assistant之前,把每一輪的role和輸出/輸出保存成一個隊列,然后再發送給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
})
最終出來的結果可以看到一下的截圖,當我的第二個問題“我剛才讓你干了什么?”輸出的時候,隊列中已經包含了之前第一輪input和output的信息:
?
四、搭建示例
我們以產品架構師角度,搭建一個支持語音輸入輸出,并且具有開通資源和回答技術文檔能力的AI助手。通過對于功能的分析,并且對應到以上的原子能力,我們的大模型應用首先要解決兩個事情:問答功能和開通資源的功能。
如何通過RAG實現面向架構師的技術問答助手呢?
此步驟較為簡單,不做概述,大家可以看百煉的最佳實踐,一般分為四個步驟:
4)根據測試問題開始進行調試
要注意,幻覺是不可避免的,有時候prompt的語料“打”不過模型本身的泛化能力,模型會自信的根據自己的能力自說自話。比如提出這樣的一個問題“paimon是什么?”,由于paimon本身是一個比較新的湖格式,并且即使制定了大模型搜索大數據相關的知識,大模型有時候也沒有鏈接到湖格式的邏輯思維,所以會出現以下的情況:
?
那么如何讓回答變成我們所預想的專業的回復呢?在我的嘗試中,比較簡單的步驟分別為:1)嘗試更大的模型;2)prompt調優;3)對應的文檔掛載;
1)嘗試更大的模型:
一般來說,如果發現一個模型在某項任務上失敗了,并且有一個更強大的模型可用,那么值得嘗試使用更強大的模型再次嘗試。在這里由于我已經使用了max模型,所以在此處可以忽略。
2)prompt調優:
# 角色
你作為阿里云高級解決方案架構師的智能助手,精通大數據、數據庫、分布式計算等核心云計算領域,掌握apache、oracle等大型云計算IT公司的全部技術棧,以嚴謹專注的態度,輔以親切的交流方式,結合知識庫${documents}和夸克搜索等插件,提供給云計算架構師對于云計算和云產品的專業指導。
## 限制與風格
- 回答需嚴格限制在于云計算、數據庫、大數據及分布式計算等計算機技術領域。
- 回答不要涉及任何游戲、娛樂等領域的詞匯和課題,
- 當回答出現不清楚字樣的時候,一定要使用夸克搜索插件,返回最相關的回復。
- 交流風格親切友好,即使面對復雜技術問題也能以易于理解的方式解答。
- 確保所有檢索內容均來源于可靠渠道,優先考慮阿里云等云廠商的官方資源,維護回答的準確性和時效性。
3)對應的文檔掛載:
文檔掛載這類外部信息輔助的問答,是最快最有效解決大模型對于一類特定領域或者名詞進行“胡說八道“的問題,當我們將Paimon的產品文檔鏈接以外部知識庫的形式掛載時,大模型回答問題顯而易見的精準了很多:
?
如何自己寫一個開通ECS的Agent呢?
在實現Agent搭建的時候,function call是一個非常簡單而且有用的方式,通過自定義的function,讓大模型根據輸入的query來匹配是否需要調用函數和調用哪個函數。當然,我們也可以讓大模型自動生成開通ecs的代碼,并且調用code_interpreter(代碼解釋器插件)來進行運行,甚至可以指定它來進行自主的調優,但是這就是一個具有多個step的復雜問題,其中有諸多挑戰,比如:需要明確的規劃好這些步驟的操作內容、操作順序、環境配置才能讓模型更容易遵循;中間結果也不一定可以人為的進行控制;并且AK、SK和ECS的各種參數匹配與輸入又是另一個工程性問題,所以在此篇文章中我們不予考慮。下面將介紹如何使用function call構建一個非常簡單的開通資源的Agent,分為五個步驟:
step1: 寫好應用的description和instruction,目的是讓大模型知道自己的定位和功能。并且由于要調用插件調用插件,需要制定當實現某些功能時,調用何種插件,比如:“請給我開通一臺北京的ecs”這句話,屬于“開通ecs”這個函數:
description='一個阿里云架構師AI助手,可以通過用戶訴求,通過調用插件幫助用戶創建ecs、vpc等云資源。',
instructions='一個阿里云架構師AI助手,可以通過調用插件解決開通資源等問題。插件例如,開通ecs,開通vpc,判斷地域等等,當你無法回答問題時應當結合插件回復進行回答。請根據插件結果適當豐富回復內容。'
'當有需求開一臺ecs的時候,請一定要調用開通ecs這個插件'
'當有需求開一個vpc的時候,請一定調用開通vpc插件',
step2: 定義tools中的function,我們以定義開通ecs的function來舉例,此function作用是用來開通ecs,所以在description中必須寫明該插件是用戶開通ecs的插件:
請注意:最好寫Default,比如若用戶輸入的query中不包含地域信息,那么請給出默認一個地域,防止參數為空導致的一系列報錯問題,例如:“如果輸入中沒有地域,則默認region=cn-beijing”
{
'type': 'function',
'function': {
'name': '開通ecs',
'description': '用于開一臺ecs的插件和函數,例如:請給我開一臺北京的ecs,則region=cn-beijing;請給我開一臺上海的ecs,則region=cn-shanghai。如果輸入中沒有地域,則默認region=cn-beijing',
'parameters': {
--------
},
'required': ['']
}
}
},
Step3:定義function的參數,比如開通ecs之前,需要得知用戶想要開通ecs的地域信息,并且把地域信息轉換成代碼能夠識別的參數,例如:首先從“給我開一臺北京的ecs”中解析出 “北京” 這個地域信息,然后根據description中的描述,大模型將“北京”轉換為cn-beijing,最后的region_ecs為'cn-beijing’。
請注意:
1、required 這個部分如果含有參數,那么region_ecs就不能為空,或者是region_ecs的參數必須符合自定義的參數類型。如果required=[''],則region_ecs為空也沒事,只要后面的函數可以接受region_ecs為空;
2、參數名稱(region_ecs)必須和后面調用函數的參數名一模一樣。
'parameters': {
'type': 'object',
'properties': {
'region_ecs': {
'type': 'string',
'description': 'ecs開通的地域,并且需要轉化為'cn’加上地域拼音的形式,比如北京對應cn-beijing,杭州對應cn-hangzhou'
},
},
'required': ['region_ecs']
Step4: 將定義的function與大模型實際調用的函數匹配,function_mapper很好理解:
function_mapper = {
'開通vpc': create_vpc_function,
'判斷地域': judge_region_exist,
'開通ecs': create_instance_action,
}
Step5: 調用create_instance_action函數,把region_ecs傳進去,并且調通整條鏈路,示例如下,本部分可以參考ecs文檔的開發sdk內容進行改寫:
請注意:需要有返回值,返回值類型為string,最好返回的內容可以被大模型理解,這樣大模型可以根據返回的信息進行潤色。比如該例子中,返回:“success”這句話,大模型回復“已成功為您開通一臺位于北京的ecs”。
def create_instance_action(region_ecs):
print('function調用測試成功,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'
如何操作一些更為復雜的函數,比如在已知查詢價格接口的基礎上,如何實現實時查詢一Cascade CPU架構的n核nG ECS包年包月/按量付費的價格??
應用集成
在了解原子能力和一些功能搭建之后,面對一個復雜一些的場景,通常不僅僅是選取單個模型,或者僅僅完成部分功能,那么就需要根據業務情況以大小模型、RAG+Agent的方式構建一個多智能體應用。這里介紹兩種集成方式:意圖識別鏈接多個模型的方式和Aassistant API集成function和RAG。
1.意圖識別
意圖識別的本質是實現大小模型的結合,通過意圖識別后的tag,分別調用不同的模型、APP和assistant,可以控制不同部分的模型的大小和實現的功能,讓每條鏈路都更加精準化。比如我們可以將問題的分類分為以下幾個部分,分別使用不同大小的模型,掛載不同的知識庫來覆蓋所有的功能:
?
拓展來說,我們甚至可以將意圖樹做的更深,如果場景足夠的復雜,那么意圖識別也可以是多層的,像一個樹一樣,每個分支都定義更加精細化的意圖知識庫。
2.Assistant-API集成
目前,基于dashscope搭建的assistant已經可以將rag和function call等插件集成到一個模型中:
首先,最重要的步驟是在toos中定義一個名字叫做“rag”的“type”,并且將百煉平臺的知識庫id寫入到YOUR_PIPELINE_ID中。
其次,類似我們實現function call的功能,我們需要在description中指明,回答何種問題需要使用名叫“rag”的插件。這樣在匹配到類似的問題的時候,assistant可以調用“rag”插件,在文檔${document1}中做搜索倒排之后,返回TopN信息,然后輸入大模型進行整合:
tools=[
{
'type': 'fucntion'{
}
},
{
'type': 'rag',
'prompt_ra': {
'pipeline_id': 'YOUR_PIPELINE_ID',
'parameters': {
'type': 'object',
'properties': {
'query_word': {
'type': 'str',
'value': '${document1}'
}
}
}
}
}]
最終使用多個原子能力構建整個完整的端到端鏈路。?
五、后記
目前大模型的原子能力和API、SDK的更新非常的頻繁,也越來越完善,通過一次或者兩次的動手搭建,可以讓我們知道如何利用這些能力,像“積木”一樣,結合自己本身業務或者功能的邏輯,搭建一個完整的大模型“城堡”。
RDS MySQL 遷移至 PolarDB MySQL
通過本方案,RDS MySQL的數據可在線實時同步到PolarDB MySQL版,并且升級切換后的PolarDB集群包含源RDS實例的賬號信息、數據庫、IP白名單和必要的參數。這樣可實現不修改應用代碼的情況下,將RDS MySQL數據庫遷移升級至PolarDB MySQL版。