
GraphRAG:基于PolarDB+通義千問api+LangChain的知識圖譜定制實踐
AI Agent,即人工智能代理,是一種能夠感知環境、做出決策并執行操作的智能實體。與傳統的人工智能不同,AI Agent 具備自行思考并使用工具逐步實現目標的能力。舉例來說,如果你告訴 AI Agent 代理的退款系統進行退款辦理,它可以通過意圖確認(退款哪個商品、退款原因、退款是否和比例判斷)和用戶進行交互,并自動調用退款系統進行退款,無需人工指定每個步驟。
其中關鍵模塊:
prompt:提示詞;
Chain: 將多個任務或操作按照一定的順序組合起來,以實現特定目標的方法;
LLM:大模型基座;
Tools: Tool的參數定義、描述定義和邏輯實現;Actions: Agent Planning下一步做的事情;
首先從業務場景來看,本人以客服機器人這個典型應用場景為例:
業務背景:電商;
知識結構:知識庫(QA形式維護,且有相似問);
用戶群體:售前咨詢/下單顧客;Agent功能:作為人工客服回答用戶問題;
幻覺問題在LLM(大型語言模型)應用開發中是一個常見的問題。幻覺指的是模型在生成文本時產生的錯誤信息、無根據的斷言或不真實的內容。這些內容雖然可能看起來表面上合乎邏輯和流暢,但它們并不基于事實或現實的數據。其原因包括:
1.數據訓練不足或質量不高:模型可能基于有限或不準確的數據進行訓練,導致其生成的內容缺乏真實依據;
2.模型復雜性:復雜的模型可能更容易產生不合理的聯想和推斷;3.語言和語義的復雜性:自然語言本身具有模糊性和多義性,這可能導致模型產生誤解。?
說明:不同業務場景對于RAG的要求有區別,像內外小蜜等小蜜系列,關于RAG非常深的研究,包括檢索、生成等,小蜜場景更多是一問一答,對于RAG的知識質量要求非常高;而在Agent的場景中,Agent重點是planning能力和Tool精準調用的,但是RAG仍然是Agent重要的模塊,是Agent穩定性的保障。較好的RAG實踐可以參考:《?RAG優化方案與實踐?》
對于業務場景,很多時候用戶本身的信息,決定了回答的準確度。比如一個簡單的case:
user: 我的XX卡折扣是多少?
aiAssistant: ?
知識庫中的信息假設是:
Query: 我的XX卡能打幾折?
(相似問:XX卡的折扣是多少?XX卡怎么打折的……)
Answer: 對于初級會員打5折,對于高級會員打6折,對于XX會員打XX折;
那么當沒有用戶身份的時候,進入大模型的回答,基于RAG成功召回的case,大概率會是對于Answer的改寫。
user: 我的XX卡折扣是多少?
aiAssistant: 您好,我們的會員卡對于不同會員折扣不同,初級會員是5折,.....
少數情況會直接吐出一個折扣或者反問;直接吐出的情況就有概率錯誤;反問的話,其實邏輯上沒問題,但是對于可以直接獲取的信息,其實增加了Agent對話的復雜度,不夠智能。
優化:
1.將memory信息代入用戶的prompt,構建對于業務有判斷作用的信息,包括用戶信息、訂單信息(咨詢主體)、店鋪信息,用于幫助RAG發揮更大的效果,比如用戶是高級會員的信息代入memory并進入prompt,最后的效果就是如下:
user: 我的XX卡折扣是多少?
aiAssistant: 您好,您是尊貴的高級會員,XX卡可以享受6折的折扣優惠;
2.其中某些對象可能會隨著用戶的咨詢而更新,比如用戶的咨詢主體,要保證memory有每輪次ReAct前更新的操作。
1.query重寫輔助RAG更好的召回
進行query重寫,補全語句缺失實體,或者錯誤語義改寫一下,提升RAG召回的成功率;技術方案也是走LLM的;比如:
user: 我買了個糕點吃不完了
aiAssistant: 您好,您是買的哪一款糕點,有什么問題呢?
user: 保質期多久呢
改寫之后:
user: 我買了個糕點吃不完了
aiAssistant: 您好,您是買的哪一款糕點,有什么問題呢?
user: 糕點的保質期有多久呢?
2.知識的臟數據和及時性問題
這是比較棘手的問題,知識庫中有一些過時的數據,但是其關鍵字又很像,結果被embedding召回回來產生了干擾,RAG的質量,還是較強的依賴源頭本身知識的質量;需要業務配合進行正確維護和管理。
核心:盡可能獲得高質量的線上業務數據,用于微調。
在電商領域為例,現階段的核心數據是語料,但是其中包含大量的卡片,大模型對于卡片的理解能力偏弱。
因為LLM的語料以自然語言為主,但是在客服、小蜜等大量的語料場景中,卡片非常多。比如類似這種:
那么在語料中,可能就是(隨意以JSON舉個例子,實際要復雜):
user: 我買的蘋果保質期多久
aiAssistant:"{\n"
+ " \"type\": orderSelector,\n"
+ " \"width\": 5,\n"
+ " \"height\": 3,\n"
+ " \"orderId\": 12345,\n"
+ " \"showXXX\": false,\n"
+ " \"title\": \"請問是。。。。。\",\n"
+ " \"itemName\": \"\",\n"
+ " ....\n"
+ "}"
user: "{\n"
+ " \"type\": \"XX\",\n"
+ " \"isSelect\": true,\n"
+ " \"content\": \"orderId: XXXX\",\n"
+ " \"content\": \"orderName: XXXX\",\n"
+ " ....\n"
+ "}"
那么這樣的語料灌進LLM推測或者訓練,對于大模型就很吃力了。
那么”化個妝”呢,我們再看一下這樣的:
user: 我買的蘋果保質期多久
aiAssistant:請問您是要確認XX時間買的XX元的XX商品訂單嗎?(目前這個訂單狀態是XX)
user: 是的,我就是確認這個XX商品訂單的問題
好了,這時候大模型不用去管無聊的JSON結構和Id這種字段了。并且可以通過拼接直接實現,可以對整個電商的所有卡片,基于type格式,在Agent運轉層/語料層進行重寫;大大提升電商卡片場景的理解程度??偨Y一下優點:
由于agent并不是永遠穩定,其輸出的內容和格式存在一定的隨機性,對于ReAct模式,可能會有陷入循環的問題,導致Agent智能體不響應;其次Agent可能會遇到較多的異常case,其表現可能是未知的,所以需要對于Agent框架進行異常的處理和兜底;一個簡單的Agent運轉抽象如下:
首先,Agent的rethink模式,決定了一些異常case下大模型是可能陷入循環問題(比如成功調用Tool輸出,但是沒有相關數據,Agent可能會一直調用)。
對象包括組裝prompt、LLM調用、輸出解析、Tool調用,這邊Agent建議按照特點決定是否重試某些模塊。定義重試異常類型:
定義非重試異常類型:
重試的主體有哪些?
那么有些異常不重試的情況怎么辦呢?
重要場景下的AI應用一定是要有人工托管的,從copilot模式像AI托管模式邁進,這是漸進的必要灰度保障和最后兜底;就像武漢的蘿卜快跑背后是有人工監管的,在重要的情況完成接管。在電商客服Agent場景也是,在無法解決的場景和異常時,Agent通過返回接管信號,讓背后的小二進入接管AI,恢復人工對話模式。Agent主動要求人工介入的時機:
總之,人工托管的兜底,給了Agent應用可以先灰度上線積攢寶貴經驗的可能,再通過擴大Agent基座能力和業務場景,逐步完善Agent能力。
和孔乙己回字的N種寫法一樣,在實際很多Agent中,期望大模型的回復是一個JSON的String格式,實際的格式還是會在單模型中有隨機性,并且在不同模型的回復中有明顯的差異性;適配變得很重要。
比如一個兩級JSON實際返回的結果有四種情況:
"Tools": {
"api_name": "XXTool",
"parameters": [
{
"name": "xxId",
"value": "12345"
}
]
}
"Tools": [{
"api_name": "XXTool",
"parameters": [
{
"name": "xxId",
"value": "12345"
}
]
}]
"Tools": [{
"api_name": "XXTool",
"parameters":
{
"name": "xxId",
"value": "12345"
}
}]
"Tools": {
"api_name": "XXTool",
"parameters":
{
"name": "xxId",
"value": "12345"
}
}
1.構建清晰和典型的few-shot,在prompt中給出示例;
2.實現一個異常處理鏈路,比如先做剔除前后空字符的直接JSON解析,再進行中文冒號的異常case替換嘗試解析,再進行花括號缺失情況的異常case匹配(補充花括號);那么所有鏈式節點嘗試都失敗了,那就報錯;(鏈太長時也可以考慮并發一下)
3.如果還是不穩定。嘗試降低 temprature 參數的值讓結果更穩定。最近業界進展:
OpenAI近日在其API引入了結構化輸出,這應該會緩解JSON解析的問題,待更新和跟進驗證其效果。
首先從監控的視角,一個系統,無非是很多點連成的線,對于每個點的監控以及端到端的監控,是常見的思路;目前這里先focus在重要節點的監控,其維度如下:
這里有的Tool耗時慢,因為背后是大模型的服務。
核心的目標,就是監控大模型的調用情況,Tool的調用情況,目前先用Sunfire做一版簡單的版本。
文章轉自微信公眾號@阿里云開發者