
如何快速實現REST API集成以優化業務流程
當然我們今天的主角是他的開放平臺[2]:
注冊之后登錄進入控制臺就可以看到模型、文檔、賬單等模塊:
查看?API Key?可以看到默認的 API Key,直接拷貝使用,或者創建新的 API Key:
從控制臺的首頁點擊 API 文檔,進入 API 的使用指南[3]:
快速安裝:pip install zhipuai
然后寫一個例子測試下:
import zhipuai
zhipuai.api_key = "xxx" # 你的 api key
def invoke_prompt(prompt):
response = zhipuai.model_api.invoke(
model="chatglm_turbo",
prompt=[
{"role": "user", "content": prompt},
],
top_p=0.7,
temperature=0.9,
)
if response['code'] == 200:
return response['data']['choices'][0]['content']
return 'LLM not worked'
if __name__ == '__main__':
response = invoke_prompt('簡單介紹下人工智能是什么')
print(response)
回答如下:
人工智能(Artificial Intelligence,簡稱AI)是一門研究、開發模擬、延伸和擴展人類智能的理論、方法、技術及應用系統的新興技術科學。人工智能領域的研究涵蓋了多個方面,如機器人、語言識別、圖像識別、自然語言處理和專家系統等。其目標是使計算機能夠模擬和實現人類智能的功能, 從而在某些領域達到甚至超過人類的智能水平。\n\n人工智能專業是一門多學科交叉的新興學科,旨在培養掌握人工智能基礎理論、 基本方法和應用技術的人才。專業課程包括人工智能概論、認知科學、機器學習、模式識別、深度學習、知識工程、數據挖掘、 物聯網等系列課程。\n\n人工智能的發展包括多個階段,如啟蒙、繁榮、低谷等。從20世紀50年代開始,人工智能逐漸成為一門獨立的學科。隨著計算機技術、網絡技術和大數據技術的快速發展,人工智能進入了一個新的黃金時期。在我國,人工智能專業的發展也得到了政府和企業的大力支持,被視為未來科技創新的重要驅動力。”
上面代碼我們注意到,prompt
參數是一個數組,其設計是天然針對對話、以及少樣本提示的。
比如:
prompt = [
{"role": "user", "content": '提問1'},
{"role": "assistant", "content": '回答1'},
{"role": "user", "content": '提問2'},
{"role": "assistant", "content": '回答2'},
{"role": "user", "content": prompt},
]
AI 會跟去前面的對話歷史,對最后的 prompt
進行回答。
少樣本提示少樣本提示 雖然是提示工程中最簡單的一個技術,但這種方法其實有很大的威力, 在一個優秀的 LLM 之上進行少樣本提示甚至可以在很多場景下代替模型微調, 達到意想不到的效果。
好了,現在基本調用是可以了。我們再來實現一個 AI 的常用場景,知識庫檢索。
我們這次實現知識庫,已然使用?LlamaIndex[4], LlamaIndex 是一個簡單靈活且強大的數據框架,用于將自定義數據源連接到大型語言模型。感興趣的朋友可以去查看 LlmaIndex 文檔[5]?或者去我 LlamaIndex 的合集去了解更多信息。
先用 Pip 簡單安裝一下 Llama Index:
pip?install?llama-index
然后我們導入下測試是否安裝成功:
import llama_index
print(llama_index.__version__)
# 0.9.10
接下來讓 Llama Index 使用 智譜AI 作為大模型。
我們到 LlamaIndex 的文檔「Available LLM integrations[6]」看下它現在支持哪些大模型。
我們看到,雖然他支持了很多的商業模型和開源項目,但是并沒有 「智譜 AI」 以及國內的一眾 AI 產品。
國產AI 崛起之路還真是任重而道遠啊。
前面我們提到,Llama Index 是一個簡單靈活的數據框架,既然官方還沒有集成,我們就自己集成一下好了。
LlamaIndex 提供了一個叫做?CustomLLM
?的抽象類來讓我們方便的集成自己的大模型產品:
class CustomLLM(LLM):
"""Simple abstract base class for custom LLMs.
Subclasses must implement the __init__
, complete
,
stream_complete
, and metadata
methods.
"""
從注釋就能看到,實現一個自己的 LLM 其實很簡單,只需要實現 __init__
, complete
, stream_complete
以及 metadata
這幾個方法即可。
什么是元數據元數據稍微正式的解釋是描述數據的數據。比較繞口,需要仔細體會。簡單說就是記錄的屬性、表的結構、界面的布局、數據的特征、程序的參數。
上面四個方法中我們比較陌生的應該是 metadata
了,metadata 翻譯一下就是元數據, 而 LLM 的元數據是什么, 比較通用的有如下一些:
model_name: str = "chatglm_turbo"
top_p = 0.7
temperature = 0.9
num_output: int = 256
context_window: int = 3900
像「模型名稱」、「溫度」、「top p」這些參數\屬性大家想必已經很了解了, 我們簡單實現一下:
class ZhipuLLM(CustomLLM):
model_name: str = "chatglm_turbo"
top_p = 0.7
temperature = 0.9
@property
def metadata(self) -> LLMMetadata:
"""Get LLM metadata."""
return LLMMetadata(
context_window=self.context_window,
num_output=self.num_output,
model_name=self.model_name,
)
因為 智譜AI 的API 也沒有太多的參數,我們把?top_p
?和?temperature
?取一個比較合理的值, 直接放到調用程序里面,其實可以不需要設計 Metadata,實現一個空方法即可:
class ZhipuLLM(CustomLLM):
@property
def metadata(self) -> LLMMetadata:
return LLMMetadata()
接下來就是實現?complete
?方法,前面我們有一個?invoke_prompt
?方法來實現 智譜AI 的調用,這里直接拿來用, 也不去實例化或者過多設置參數,越簡單越好:
@llm_completion_callback()
def complete(self, prompt: str, **kwargs: Any) -> CompletionResponse:
response = invoke_prompt(prompt)
return CompletionResponse(text=response)
stream_complete流式返回官方也有例子,我這里就不實現了。
智譜 AI 也提供了文本嵌入接口,那我們當然也是直接拿來用了,這樣子就徹底擺脫了了 OpenAI 和自己搭建模型了。
LlamaIndex 的嵌入式基于?BaseEmbedding
?實現的,我們也寫一個 智譜AI 的實現,來不及做過多解釋了,直接看代碼:
class ZhipuEmbedding(BaseEmbedding):
_model: str = PrivateAttr()
_instruction: str = PrivateAttr()
def __init__(
self,
instructor_model_name: str = "text_embedding",
instruction: str = "Represent a document for semantic search:",
**kwargs: Any,
) -> None:
self._model = 'text_embedding'
self._instruction = instruction
super().__init__(**kwargs)
@classmethod
def class_name(cls) -> str:
return "zhipu_embeddings"
async def _aget_query_embedding(self, query: str) -> List[float]:
return self._get_query_embedding(query)
async def _aget_text_embedding(self, text: str) -> List[float]:
return self._get_text_embedding(text)
def _get_query_embedding(self, query: str) -> List[float]:
embeddings = invoke_embedding(query)
return embeddings
def _get_text_embedding(self, text: str) -> List[float]:
embeddings = invoke_embedding(text)
return embeddings
def _get_text_embeddings(self, texts: List[str]) -> List[List[float]]:
return [self._get_text_embedding(text) for text in texts]
現在讓我們把前面的成果合在一起,寫一個簡單的程序看看,能不能行得通:
首先我們再目錄下放置一個文本文件,當前 PDF、Excel、Docx 都行,我這里還是用之前亞運會獎牌設計的文案:
然后直接運行程序:
# define our LLM
llm = ZhipuLLM()
embed_model = ZhipuEmbedding()
service_context = ServiceContext.from_defaults(
llm=llm, embed_model=embed_model
)
# Load the your data
documents = SimpleDirectoryReader(doc_path).load_data()
index = VectorStoreIndex.from_documents(documents, service_context=service_context)
# Query and print response
query_engine = index.as_query_engine()
response = query_engine.query("杭州亞運會獎牌的工藝和設計理念?,請用中文回答。")
print(response)
來看下回答:
杭州亞運會獎牌的工藝和設計理念如下:
1. 工藝:獎牌采用了一系列復雜的工藝,包括壓印成型、
數銑外形及槽坑、修整刷拋、鍍金鍍銀、表面防護等。
綬帶采用織錦提花工藝、環保印花技術,雙面手工縫合。
此外,獎牌正面采用了江南傳統工藝——打鏨雕,
將四種書法(真、草、隸、篆)的杭州與亞奧理事會
的英文縮寫有機結合。
2. 設計理念:獎牌設計融合了杭州三大世界文化遺產
——西湖、大運河、良渚古城遺址,
展現了杭州山水景觀和江南文化。
獎牌正面勾勒出“三面云山一面城”的杭城畫卷,
背面形似方形印章,寓意運動員在杭州亞運會上
留下美好印記。整體設計別具一格,
具有高度辨識度,體現了美美與共、和而不同的含義。
此外,獎牌設計還展現了杭州生態文明之都的氣質,
湖光山色,綠水青山,鑄就了金山銀山,
也體現了勇攀高峰的體育精神。
獎牌直徑70毫米,厚度6毫米,
正面圓形漸變色,背面采用杭州江南絲繡技藝呈現的篆刻圖案。
整體獎牌設計充滿東方意蘊之美,
將深厚底蘊的南宋文化與杭州地域特色相結合,
表達獨特的美學理念。
回答均來源于文案,但是進行了重新組織,我只想說中文表達如此流暢!遠勝我自己。
Llama Index 里使用大模型的地方主要是上面兩處。這兩個點對接之后,余下的各種玩法也均和使用 OpenAI 無異。更多的場景以及可落地的 AI 玩法,后面再和大家分享。
[1]
?智譜 AI:?https://www.zhipuai.cn/[2]
?開放平臺:?https://open.bigmodel.cn/[3]
?API 的使用指南:?https://open.bigmodel.cn/dev/api[4]
?LlamaIndex:?https://www.llamaindex.ai/[5]
?LlmaIndex 文檔:?https://docs.llamaindex.ai/en/stable/[6]
?Available LLM integrations:?https://docs.llamaindex.ai/en/stable/module_guides/models/llms/modules.html
文章轉自微信公眾號@數翼