
如何快速實(shí)現(xiàn)REST API集成以優(yōu)化業(yè)務(wù)流程
可以看到,guardrails 定義了一套類似 XML 的語(yǔ)言用于結(jié)構(gòu)化輸出,又結(jié)合了自然語(yǔ)言的 Prompt。雖然比起常見(jiàn)的模板語(yǔ)言要更加“繁瑣”,但可以包含的內(nèi)容也可以更加完善。比如可以提供字段的描述信息,檢查規(guī)范,一定程度上也能幫助 LLM 更好地理解需求,生成預(yù)期的結(jié)果。
I was given the following JSON response, which had problems due to incorrect values.
{
"patient_info": {
"symptoms": [
{
"affected area": {
"incorrect_value": "face & hair",
"error_message": "Value face & hair is not in choices ['head', 'neck', 'chest']."
}
},
{
"affected area": {
"incorrect_value": "beard, eyebrows & nares",
"error_message": "Value beard, eyebrows & nares is not in choices ['head', 'neck', 'chest']."
}
}
]
}
}
Help me correct the incorrect values based on the given error messages.
后續(xù) LLM 的返回可以僅針對(duì)這部分問(wèn)題的修正,而不需要再重復(fù)生成整個(gè) JSON。生成的新結(jié)果會(huì)由 guardrails 再自動(dòng)填寫回原來(lái)的位置,非常絲滑。除了 JSON 格式的檢查外,RAIL spec 中還提供了通過(guò)腳本檢查的擴(kuò)展支持,可以用來(lái)檢查更加復(fù)雜的內(nèi)容,例如 Python 代碼是否合法,結(jié)果中是否有敏感信息,甚至通過(guò) LLM 再來(lái)檢查生成的內(nèi)容是否有害,做結(jié)果過(guò)濾等。
來(lái)自 Nvidia 的一個(gè)同名項(xiàng)目,其目標(biāo)相比 guardrails 更有野心,想要確保 LLM 應(yīng)用整體的可信度,無(wú)害性以及數(shù)據(jù)安全性等,而不僅僅只是輸出的結(jié)構(gòu)化檢查和修復(fù)。因此其實(shí)現(xiàn)思路上也復(fù)雜不少,設(shè)計(jì)了一種專門的 Colang 語(yǔ)言,來(lái)支持更加通用多樣的業(yè)務(wù)流,而不僅僅是生成 -> 檢查 -> 修復(fù)。不過(guò)它的設(shè)計(jì)都是基于對(duì)話做的。實(shí)際開(kāi)發(fā)應(yīng)用可能不太合適。
define user ask capabilities
"What can you do?"
"What can you help me with?"
"tell me what you can do"
"tell me about you"
"How can I use your help?"
define flow
user ask capabilities
bot inform capabilities
define bot inform capabilities
"I am an AI assistant which helps answer questions based on a given knowledge base. For this interaction, I can answer question based on the job report published by US Bureau of Labor Statistics."
從代碼可以看出其結(jié)合了 Python 和自然語(yǔ)言,方便相似度檢索。
其整體的運(yùn)作流程如下:
之前在 guardrails 中的做法是在 Prompt 中給出說(shuō)明和示范,希望 LLM 能夠遵循指令來(lái)輸出。但現(xiàn)實(shí)中往往會(huì)出現(xiàn)各種問(wèn)題,例如額外帶了一些其它的文字說(shuō)明,或者生成的 JSON 格式不正確等,所以需要后續(xù)的 ReAsk 來(lái)進(jìn)行修正。LangChain 里也提供了各種 output parser 來(lái)幫忙提取回復(fù)中的結(jié)構(gòu)化信息部分,但也經(jīng)常容易運(yùn)行失敗。
在 guidance 中,也是通過(guò)“模板語(yǔ)言”來(lái)定義 LLM 的輸出結(jié)構(gòu),以確保輸出格式的正確性。
# load a model locally (we use LLaMA here)
guidance.llm = guidance.llms.Transformers("your_local_path/llama-7b", device=0)
# we can pre-define valid option sets
valid_weapons = ["sword", "axe", "mace", "spear", "bow", "crossbow"]
# define the prompt
program = guidance("""The following is a character profile for an RPG game in JSON format.
json
{
"description": "{{description}}",
"name": "{{gen 'name'}}",
"age": {{gen 'age' pattern='[0-9]+' stop=','}},
"armor": "{{#select 'armor'}}leather{{or}}chainmail{{or}}plate{{/select}}",
"weapon": "{{select 'weapon' options=valid_weapons}}",
"class": "{{gen 'class'}}",
"mantra": "{{gen 'mantra'}}",
"strength": {{gen 'strength' pattern='[0-9]+' stop=','}},
"items": [{{#geneach 'items' num_iterations=3}}
"{{gen 'this'}}",{{/geneach}}
]
}""")
# execute the prompt
program(description="A quick and nimble fighter.", valid_weapons=valid_weapons)
在之前傳統(tǒng)的做法中,這一整個(gè) JSON 都需要由 LLM 來(lái)生成。但是 JSON 的結(jié)構(gòu)是我們預(yù)先定義的,例如有哪些字段,開(kāi)閉的花括號(hào)等,其實(shí)都不需要 LLM 來(lái)生成。優(yōu)點(diǎn):
除了 Prompt 模板,它還提供了:
從項(xiàng)目代碼來(lái)看,還是有比較濃的“research 味道”的,可讀性并不好。實(shí)際測(cè)試結(jié)果也比較翻車。
在 guidance 的基礎(chǔ)上,lmql 這個(gè)項(xiàng)目進(jìn)一步把“Prompt 模板”這個(gè)概念推進(jìn)到了一種新的編程語(yǔ)言。從官網(wǎng)能看到給出的一系列示例。語(yǔ)法結(jié)構(gòu)看起來(lái)有點(diǎn)像 SQL,但函數(shù)與縮進(jìn)都是 Python 的風(fēng)格。
從支持的功能來(lái)看,相比 guidance 毫不遜色。例如各種限制條件,代碼調(diào)用,各種 caching 加速,工具集成等基本都具備。這個(gè)框架的格式化輸出是其次,其各種可控的輸出及語(yǔ)言本身或許更值得關(guān)注。
TypeChat 將 Prompt 工程替換為 schema 工程:無(wú)需編寫非結(jié)構(gòu)化的自然語(yǔ)言 Prompt 來(lái)描述所需輸出的格式,而是編寫 TS 類型定義。TypeChat 可以幫助 LLM 以 JSON 的形式響應(yīng),并且響應(yīng)結(jié)果非常合理:例如用戶要求將這句話「我可以要一份藍(lán)莓松餅和一杯特級(jí)拿鐵咖啡嗎?」轉(zhuǎn)化成 JSON 格式,TypeChat 響應(yīng)結(jié)果如下:
其本質(zhì)原理是把 interface 之類的 ts 代碼作為 Prompt 模板。因此它不僅可以對(duì)輸出結(jié)果進(jìn)行 ts校驗(yàn),甚至能夠輸入注釋描述,不可謂非常方便 js 開(kāi)發(fā)者。不過(guò),近日 typechat 爆火,很多開(kāi)發(fā)者企圖嘗試將 typechat 移植到 Python,筆者認(rèn)為這是緣木求魚,因?yàn)槠湫r?yàn)本身依賴的是 ts。筆者在開(kāi)發(fā)過(guò)程中,將 typechat 融合到自己的庫(kù)中,效果不錯(cuò)。但是它本身自帶的 Prompt 和筆者輸入的 Prompt 還是存在沖突,還是需要扣扣源碼。
如果你關(guān)注了過(guò)去幾個(gè)月中人工智能的爆炸式發(fā)展,那你大概率聽(tīng)說(shuō)過(guò) LangChain。簡(jiǎn)單來(lái)說(shuō),LangChain 是一個(gè) Python 和 JavaScript 庫(kù),由 Harrison Chase 開(kāi)發(fā),用于連接 OpenAI 的 GPT API(后續(xù)已擴(kuò)展到更多模型)以生成人工智能文本。
LangChain 具有特別多的結(jié)構(gòu)化輸出工具。例如使用 yaml 定義 Schema,輸出結(jié)構(gòu)化 JSON。使用 zodSchema 定義 Schema,輸出結(jié)構(gòu)化 JSON。使用 FunctionParameters 定義 Schema,輸出結(jié)構(gòu)化 JSON。
但是筆者這里不打算介紹 LangChain。究其原因,是筆者被 LangChain 折磨不堪。明明可以幾行代碼寫清楚的東西,LangChain 可以各種封裝,花了好幾十行才寫出來(lái)。更何況,筆者是用 ts 開(kāi)發(fā),開(kāi)發(fā)時(shí)甚至偷不了任何懶,甚至其文檔絲毫不友好。這幾天,《機(jī)器之心》發(fā)布文章表示放棄 LangChain。要想讓 LangChain 做筆者想讓它做的事,就必須花大力氣破解它,這將造成大量的技術(shù)負(fù)擔(dān)。因?yàn)槭褂萌斯ぶ悄鼙旧砭托枰ㄙM(fèi)足夠的腦力。LangChain 是為數(shù)不多的在大多數(shù)常用情況下都會(huì)增加開(kāi)銷的軟件之一。所以筆者建議非必要,不使用 LangChain。
LLM 的可控性、穩(wěn)定性、事實(shí)性、安全性等問(wèn)題是推進(jìn)企業(yè)級(jí)應(yīng)用中非常關(guān)鍵的問(wèn)題,上面分享的這些項(xiàng)目都是在這方面做了很多探索,也有很多值得借鑒的地方??傮w思路上來(lái)說(shuō),主要是:
即使我們不直接使用上述的項(xiàng)目做開(kāi)發(fā),也可以從中學(xué)習(xí)到很多有用的思路。當(dāng)然也非常期待這個(gè)領(lǐng)域出現(xiàn)更多有意思的想法與研究,以及 Prompt 與編程語(yǔ)言結(jié)合能否碰撞出更多的火花。
同時(shí)筆者認(rèn)為自動(dòng)處理機(jī)制、自己設(shè)計(jì)的編程語(yǔ)言等等內(nèi)容,隨著時(shí)間發(fā)展,一定會(huì)層出不窮,不斷迭代更新。筆者拋去這些時(shí)效性較弱的內(nèi)容,從描述信息和位置信息兩方面思考 Prompt 模板該如何設(shè)計(jì),當(dāng)然只是淺淺的拋磚引玉一下。
到底哪種方式更容易于LLM去理解?我們不談框架的設(shè)計(jì),只考慮 Prompt 的設(shè)計(jì)。上述框架關(guān)于這方面有一些參考,例如有些直接拿 JSON 作為 Prompt模板,有些拿 xml 作為 Prompt 模板,有些拿自己設(shè)計(jì)的語(yǔ)言作為 Prompt,有些拿自然語(yǔ)言作為 Prompt 模板。時(shí)至今日,選用哪種最適合LLM去理解格式化的信息,輸出格式化的內(nèi)容完全沒(méi)有蓋棺定論。甚至?xí)r至今日,格式化輸出問(wèn)題還是沒(méi)有得到可靠穩(wěn)定的解決,要不然筆者肯定不會(huì)介紹這么多框架實(shí)踐了。
筆者認(rèn)為不管哪種方式,都可以從兩個(gè)方面考量:更簡(jiǎn)單,更結(jié)構(gòu)。如果想要在開(kāi)發(fā)的時(shí)候更簡(jiǎn)單,或者在使用時(shí)更簡(jiǎn)單,選擇 md、yaml 方式描述結(jié)構(gòu)化信息更合適。如果想要更結(jié)構(gòu)化的方式,選擇 JSON、XML、TS,輸出都能更有結(jié)構(gòu),甚至之后做結(jié)構(gòu)校驗(yàn)都更方便。
想要 LLM 結(jié)構(gòu)化輸出更加穩(wěn)定和理想,筆者認(rèn)為選擇 Prompt 模板時(shí)必須考慮每個(gè)字段是否有足夠的輔助信息。例如 XML 描述時(shí),每個(gè)標(biāo)簽都有一個(gè)描述屬性描述這個(gè)標(biāo)簽時(shí)什么意思。
額外引申
筆者之前在開(kāi)發(fā) LLM 應(yīng)用時(shí),也曾思考類似的問(wèn)題。筆者需要將多模態(tài)的數(shù)據(jù)進(jìn)行結(jié)構(gòu)化的標(biāo)注,方便 LLM 去理解。但是標(biāo)注成什么樣卻是一個(gè)很大的難題。筆者選擇的是 JSON。但是,關(guān)于里面許多內(nèi)容的標(biāo)注。筆者在眾多方案中徘徊。在細(xì)節(jié)處深挖,如何設(shè)計(jì)一種既簡(jiǎn)單,又能表示各種結(jié)構(gòu)復(fù)雜關(guān)系,還能夠節(jié)約 token 的方案及其的難。
是否有人注意到 LLM 對(duì)于關(guān)鍵信息在 Prompt 中的位置會(huì)對(duì)結(jié)果產(chǎn)生影響呢?在設(shè)計(jì) Prompt 方面,人們通常建議為語(yǔ)言模型提供詳盡的任務(wù)描述和背景信息。近期的一些語(yǔ)言模型有能力輸入較長(zhǎng)的上下文,但它究竟能多好地利用更長(zhǎng)的上下文?這一點(diǎn)卻相對(duì)少有人知。近日,有學(xué)者研究發(fā)現(xiàn)如果上下文太長(zhǎng),語(yǔ)言模型會(huì)更關(guān)注其中的前后部分,中間部分卻幾乎被略過(guò)不看,導(dǎo)致模型難以找到放在輸入上下文中部的相關(guān)信息。下文部分是該論文一些核心內(nèi)容:
這是由其本身訓(xùn)練和結(jié)構(gòu)設(shè)計(jì)有關(guān)的,但卻對(duì)于我們開(kāi)發(fā)有著莫大的幫助和指導(dǎo)意義。
相比之下,在多文檔問(wèn)答任務(wù)上,查詢感知型上下文化的影響很小。特別指出,當(dāng)相關(guān)信息位于輸入上下文的最開(kāi)始時(shí),它可以提高性能,但在其他設(shè)置中會(huì)稍微降低性能。借此,我們可以認(rèn)為,將重要的信息放在開(kāi)頭,結(jié)尾放置結(jié)構(gòu)化模板,或許是一種優(yōu)質(zhì)選擇。
那么如果真的為其提供這么多 token,那會(huì)真的有用嗎?這個(gè)問(wèn)題的答案是:由下游任務(wù)決定。因?yàn)檫@取決于所添加上下文的邊際價(jià)值以及模型有效使用長(zhǎng)輸入上下文的能力。所以如果能有效地對(duì)檢索文檔排序(讓相關(guān)信息與輸入上下文的起始處更近)或?qū)σ雅判虻牧斜磉M(jìn)行截?cái)嗵幚恚ū匾獣r(shí)返回更少的文檔),那么也許可以提升基于語(yǔ)言模型的閱讀器使用檢索上下文的能力。
參考資料:
https://mp.weixin.qq.com/s?__biz=MzA3MzI4MjgzMw==&mid=2650885029&idx=4&sn=ac01576a8957b41529dd3c877d262d5e&chksm=84e48fdbb39306cd8979a4fa7f7da14a9428dc28ccc47880d668ef6293b1a8b7b0964569ec36&mpshare=1&scene=23&srcid=0725w9FPsVnOOzkPGPB7lH8h&sharer_sharetime=1690303766527&sharer_shareid=d2396b329b12f49d34967e2b183540dd#rd
https://mp.weixin.qq.com/s/BngY2WgCcpTOlvdyBNJxqA
https://microsoft.github.io/TypeChat/
https://mp.weixin.qq.com/s?__biz=MzA3MzI4MjgzMw==&mid=2650885029&idx=4&sn=ac01576a8957b41529dd3c877d262d5e&chksm=84e48fdbb39306cd8979a4fa7f7da14a9428dc28ccc47880d668ef6293b1a8b7b0964569ec36&mpshare=1&scene=23&srcid=0725w9FPsVnOOzkPGPB7lH8h&sharer_sharetime=1690303766527&sharer_shareid=d2396b329b12f49d34967e2b183540dd#rd
本文章轉(zhuǎn)載微信公眾號(hào)@HelloTech技術(shù)派
對(duì)比大模型API的內(nèi)容創(chuàng)意新穎性、情感共鳴力、商業(yè)轉(zhuǎn)化潛力
一鍵對(duì)比試用API 限時(shí)免費(fèi)