自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

面向AI應(yīng)用開發(fā)實戰(zhàn)分享-基礎(chǔ)篇

人工智能
基于Langchain的AI流程編排系統(tǒng),主語言Nodejs,為Langchain的每個模型類和組件類提供了可視化的低代碼組件,通過在畫布上的拖拽組件,即可完成AI的整套交付流程,組件包括Chain(進(jìn)程)、Prompt、Agent Tool、Chat Module等。

引言

如果你是一名前端開發(fā),同時又對AI開發(fā)很感興趣,那么恭喜你,機(jī)會來了。

如果不是也沒關(guān)系,同樣能幫大家了解AI應(yīng)用的開發(fā)思路。

本文將帶大家從面向AI開發(fā)的基礎(chǔ)知識開始,再到RAG,Agent,流程編排,深入了解如何在企業(yè)內(nèi)部落地AI項目。

基礎(chǔ)篇

一、如何面向AI交互

通常,我們使用一段文字輸入,AI模型都會基于大模型自身來進(jìn)行回答,這個相信大家已經(jīng)都非常了解。但是,如果想讓AI能夠基于我們所期待的內(nèi)容回答,或者說是基于我們的私域信息來進(jìn)行回答,我們有哪些辦法?

  • 模型訓(xùn)練
  • 微調(diào)Fine-tuning
  • Prompt提示詞工程
  • RAG檢索增強(qiáng)生成

模型訓(xùn)練:

通過從huggingface下載開源模型,在本地完成部署,比如最新推出的Llama 3 8B版,小模型對GPU的要求會相對低些,后通過大量的文檔資料完成模型訓(xùn)練。

雖說小型模型降低了GPU的算力資源但成本也不是普通企業(yè)能承擔(dān)的,除了自身的硬件成本、模型優(yōu)化的人力成本,也存在模型的汰換風(fēng)險,一旦外部大廠出個大招,那我們訓(xùn)練的模型就會面臨淘汰,但企業(yè)也應(yīng)采取防御型戰(zhàn)略,先擁抱,畢竟AI已是大勢所趨,模型在應(yīng)用層接口方面在開源社區(qū)里已經(jīng)標(biāo)準(zhǔn)化,開發(fā)設(shè)計時模型與功能解耦,隨時替換。

微調(diào)Fine-tuning:

很多商業(yè)AI的服務(wù)模型都提供了這一能力,允許用戶針對特定的應(yīng)用場景調(diào)整預(yù)訓(xùn)練好的模型,以獲得更符合預(yù)期的輸出結(jié)果。

比如,你的公司有一個內(nèi)部項目代號為"Project”,您希望使用LLM模型來自動生成關(guān)于"Project"的文檔或回答員工關(guān)于"Project"的查詢。但預(yù)訓(xùn)練模型沒有接觸過"Project"這個術(shù)語,因此無法生成相關(guān)的準(zhǔn)確信息。這時候就可以通過一些術(shù)語或上下文來調(diào)整模型對于這一塊的理解。

最后,微調(diào)是一種付費服務(wù),如果未來換其他模型,你需要重新進(jìn)行微調(diào)以適應(yīng)新模型的特性和改進(jìn)。這將再次產(chǎn)生計算和時間成本。

Prompt提示詞工程:

這個應(yīng)該是剛接觸AI開發(fā)的同學(xué),最先使用的,讓AI能夠按照我們的期望完成指令交付的方式。比如,讓模型盡量用中文回答。你需要準(zhǔn)備一份包含角色、背景、技巧、輸出風(fēng)格、輸出范圍等的Prompt提示詞,然后在每次通訊時攜帶在上下文里。

如果你使用chat_model(Langchain術(shù)語)方式,則會在message數(shù)組的0鍵位一直保持system prompt,如果是LLM(Langchain術(shù)語)方式,則是在每次通訊時的message字符串里包裝prompt+question,這里我們更應(yīng)該基于chat_model方案來開發(fā)。

但是當(dāng)你想要正式的投入到自己的項目中時,你可能會發(fā)覺Prompt非常難優(yōu)化,AI并不能完全按照你的要求去執(zhí)行??偨Y(jié),Prompt會有以下幾個痛點:

1. 設(shè)計難度大,如果模型的輸出依賴于我們的提示詞反饋,這可能會形成一個循環(huán),我們需要不斷地調(diào)整提示詞以獲得更好的輸出。2. 長度限制,每次通訊的message通常會包含:Prompt + n輪上下文history + 本次的question,這些內(nèi)容的總文字?jǐn)?shù)也是計算我們單次會話的token總成本,過長的prompt很容易使AI產(chǎn)生幻覺,影響回復(fù)結(jié)果。3. Prompt依然無法解決讓模型面向私域,我們公司內(nèi)部的知識庫進(jìn)行回答。

RAG檢索增強(qiáng)生成:

RAG對剛接觸的同學(xué)可能會比較抽象,借用Langchain的圖來介紹一下:

1. 首先是embedding向量存儲

我們把內(nèi)部文檔在提取內(nèi)容后進(jìn)行切片,將內(nèi)容轉(zhuǎn)為段落數(shù)組(chunk),然后傳入大模型的embed接口,模型會返回浮點數(shù)字,這個過程就是embedding,最后我們會把浮點數(shù)存入向量庫,常見的向量庫有es、faiss。

圖片圖片

2. 接著是內(nèi)容召回

輸入一個問題,先通過模型embedding把問題轉(zhuǎn)為向量數(shù)據(jù),然后在我們的文檔庫里進(jìn)行相似度搜索,召回相似度接近的數(shù)據(jù)后再交由大模型進(jìn)行總結(jié),最后返回給用戶。

圖片

以上就是RAG的整個過程,RAG是個非??简灱夹g(shù)的工作,以上的流程是無法描述出RAG復(fù)雜性的,包括我們的產(chǎn)品在上線后,至今還在不斷嘗試如何更好的提升RAG的質(zhì)量,做到能用很簡單,但要做好非常難。

后面講到內(nèi)部知識庫時再來討論目前我們的方案,和線上實際效果。

引用在其他文章里看到的一句話,感同身受。

RAG涉及的內(nèi)容其實廣泛,包括Embedding、分詞分塊、檢索召回(相似度匹配)、chat系統(tǒng)、ReAct和Prompt優(yōu)化等,最后還有與LLM的交互,整個過程技術(shù)復(fù)雜度很高。如果你用的LLM非常好,反而大模型這一塊是你最不需要關(guān)心的。而這些環(huán)節(jié)里面我們每個都沒達(dá)到1(比如0.9、0.7...),那么最終的結(jié)果可能是這些小數(shù)點的乘積。

https://mp.weixin.qq.com/s/WjiOrJHt8nSW5OGe2x4BAg

二、Agent

前面主要是AI在文字內(nèi)容上的交付,那如何讓AI完成工作的交付呢?

當(dāng)在工作匯報時,如果能用下面這張圖來演示你的AI Agent功能,會不會很有吸引力?

(取自QCon上的一張分享圖)

目前想實現(xiàn)Agent,主要有以下2種方式:

ReAct自我推理

Few-shot Prompt + Thought + Action + Observation 。

通過構(gòu)造一個內(nèi)含工具、推理和規(guī)劃的prompt結(jié)構(gòu),模型在內(nèi)部通過與提示的互動進(jìn)行自我迭代和調(diào)整,以選擇適當(dāng)?shù)墓ぞ呋蛏筛玫妮敵觥?/p>

例如:

{
    "messages": [
        {
            "role": "system",
            "content": "Assistant is a large language model trained by OpenAI.\n\nAssistant is designed to be able to assist with a wide range of tasks, from answering simple questions to providing in-depth explanations and discussions on a wide range of topics. As a language model, Assistant is able to generate human-like text based on the input it receives, allowing it to engage in natural-sounding conversations and provide responses that are coherent and relevant to the topic at hand.\n\nAssistant is constantly learning and improving, and its capabilities are constantly evolving. It is able to process and understand large amounts of text, and can use this knowledge to provide accurate and informative responses to a wide range of questions. Additionally, Assistant is able to generate its own text based on the input it receives, allowing it to engage in discussions and provide explanations and descriptions on a wide range of topics.\n\nOverall, Assistant is a powerful system that can help with a wide range of tasks and provide valuable insights and information on a wide range of topics. Whether you need help with a specific question or just want to have a conversation about a particular topic, Assistant is here to assist. However, above all else, all responses must adhere to the format of RESPONSE FORMAT INSTRUCTIONS."
        },
        {
            "role": "user",
            "content": "TOOLS\n------\nAssistant can ask the user to use tools to look up information that may be helpful in answering the users original question. The tools the human can use are:\n\ninfo-tool: Useful for situations where you need to retrieve content through one or more URLs from https://info.bilibili.co/. Input should be a comma-separated list in the format of \"one or more valid URLs with the domain https://info.bilibili.co/pages/viewpage.action, where the URL should include the pageId parameter\", followed by \"the information you need to summarize, or to obtain a summary\".\n\nRESPONSE FORMAT INSTRUCTIONS\n----------------------------\n\nOutput a JSON markdown code snippet containing a valid JSON object in one of two formats:\n\n**Option 1:**\nUse this if you want the human to use a tool.\nMarkdown code snippet formatted in the following schema:\n\n```json\n{\n    \"action\": string, // The action to take. Must be one of [info-tool]\n    \"action_input\": string // The input to the action. May be a stringified object.\n}\n```\n\n**Option #2:**\nUse this if you want to respond directly and conversationally to the human. Markdown code snippet formatted in the following schema:\n\n```json\n{\n    \"action\": \"Final Answer\",\n    \"action_input\": string // You should put what you want to return to use here and make sure to use valid json newline characters.\n}\n```\n\nFor both options, remember to always include the surrounding markdown code snippet delimiters (begin with \"```json\" and end with \"```\")!\n\n\nUSER'S INPUT\n--------------------\nHere is the user's input (remember to respond with a markdown code snippet of a json blob with a single action, and NOTHING else):\n\nhttps://info.bilibili.co/pages/viewpage.action?pageId=849684529\n這篇文章講了什么"
        }
    ]
}

我們通過Prompt告訴模型,它善于使用工具來解決問題,告訴它每一個工具的介紹,和需要填入什么參數(shù),最后要求模型每次回復(fù)時必須遵循使用markdown code格式返回,然后我們會在Agent進(jìn)程里消費返回的json-schema,是調(diào)用工具還是Final Answer。

Tool-call 代理交互

很明顯ReAct會導(dǎo)致我們的上下文過長,很容易造成模型在經(jīng)過幾輪迭代之后不已markdown code的格式來返回內(nèi)容,最終導(dǎo)致Agent走不下去。

tool-call的出現(xiàn)解決了這一問題,我們會把Prompt里這些非結(jié)構(gòu)化的工具描述轉(zhuǎn)化為結(jié)構(gòu)化的api字段,這樣既節(jié)省了Prompt的上下文長度,也變的容易控制。

例如:

// POST /chat/completions
{
  ...
  "tools": [
      {
        "type": "function",
        "function": {
          "name": "info-tool",
          "description": "打開一個或多個帶有pageId的xxxx網(wǎng)站,完成用戶需求",
          "parameters": {
            "type": "object",
            "properties": {
              "pageId": {
                "type": "number",
                "description": "請?zhí)顚懢W(wǎng)址里的pageId,多個用逗號隔開"
              },
              "task": {
                "type": "string",
                "description": "描述需求"
              }
            },
            "required": [
              "pageId",
              "task"
            ],
            "additionalProperties": false,
            "$schema": "http://json-schema.org/draft-07/schema#"
          }
        }
      },
      ...更多其他工具
  ],
  ...
}

此時,模型也會以結(jié)構(gòu)化的方式告訴你他使用的工具:

// API Response
{
    ...
    "tool_calls": [
        {
            "index": 0,
            "id": "info-tool:0",
            "type": "function",
            "function": {
            "name": "info-tool",
            "arguments": "{\n    \"task\": \"獲取頁面內(nèi)容\",\n    \"pageId\": 845030990\n}"
            }
        }
    ]
    ...
}

三、開發(fā)框架

再來介紹下我們選擇的技術(shù)框架,之后也會介紹其優(yōu)點和不足之處。

Langchain

在許多討論AI的文章里都會提到Langchain,或者很多的開源框架都在和Langchain作比較。Langchain是一個集成了商業(yè)和開源模型,并提供了一整套工具和功能,簡化了開發(fā)、集成和部署基于語言模型的應(yīng)用。

- 組件化:為使用語言模型提供抽象層,以及每個抽象層的一組實現(xiàn)。組件是模塊化且易于使用的,無論是否使用LangChain框架的其余部分。- 現(xiàn)成的鏈:結(jié)構(gòu)化的組件集合,用于完成特定的高級任務(wù)。

通俗的講,它為不同的模型,不同的組件提供了統(tǒng)一的輸入和輸出規(guī)范。

在Chain里可以傳入[Prompt、Model、Tool、Memory(歷史會話)、OutputParser],也能將多個model進(jìn)行嵌套,讓上一個model的輸出作為下一個PromptTemplate的輸入。

目前官方提供了2種語言的版本,一個是Python,另一個是Nodejs。

Flowise

基于Langchain的AI流程編排系統(tǒng),主語言Nodejs,為Langchain的每個模型類和組件類提供了可視化的低代碼組件,通過在畫布上的拖拽組件,即可完成AI的整套交付流程,組件包括Chain(進(jìn)程)、Prompt、Agent Tool、Chat Module等。

同類的還有Dify,它提供了多模型對接、RAG、任務(wù)編排、等整套的產(chǎn)品化方案。

Flowise更像是一個毛坯房,提供了解決方案,但所有的產(chǎn)品化還是需要自己開發(fā),讀懂它,能讓你在開發(fā)Langchain時事半功倍。Dify更像豪華大別墅,大多數(shù)的功能都已經(jīng)做好了產(chǎn)品化,內(nèi)部獨立維護(hù)了與模型的api封裝,主語言Python。

Flowise中的packages介紹:

- Server:express,CRUD、完成組件庫內(nèi)的實例運行- Component:JavaScript,實現(xiàn)Langchain類的可視化和低代碼- UI:React,AI流程編排的畫布,和一些維護(hù)頁面。

以下是一個通過Agent由AI判斷選擇使用哪些工具的編排展示,我們重新開發(fā)了Agent組件,已更適應(yīng)我們的tool-call功能,在Bili Agent主進(jìn)程中,組件會負(fù)責(zé)消費這些關(guān)聯(lián)了的工具。

圖片圖片

部分代碼示例:

import { AgentExecutor } from 'langchain/agents'
 
// 將工具的配置信息轉(zhuǎn)為model接口里tools的結(jié)構(gòu)化字段
// 由于對齊了接口規(guī)范,所以可以直接使用formatToOpenAITool函數(shù)
const modelWithTools = model.bind({
    tools: [...tools.map((tool: any) => formatToOpenAITool(tool))]
})
 
// 按順序組合
const runnableAgent = RunnableSequence.from([
    // 包含了用戶的指令,和將模型消息里的tool_calls format后得到的ToolMessage,和上下文聊天記錄
    // 以上這些都會輸入給prompt
    {
        [inputKey]: (i: { input: string; steps: AgentStep[] }) => i.input,
        agent_scratchpad: (i: { input: string; steps: ToolsAgentStep[] }) => formatToolAgentSteps(i.steps),
        [memoryKey]: async (_: { input: string; steps: AgentStep[] }) => {
            const messages = (await memory.getChatMessages(flowObj?.sessionId, true, chatHistory)) as BaseMessage[]
            return messages ?? []
        }
    },
    prompt,
    modelWithTools,
    new OpenAIToolsAgentOutputParser()
])
 
const executor = AgentExecutor.fromAgentAndTools({
    agent: runnableAgent,
    tools,
    returnIntermediateSteps: true,
    maxIterations: 5
})
 
executor.invoke({input: '明天是幾月幾號?'})
 
// tool_calls示例
{
    "tool_calls": [
      {
        "index": 0,
        "id": "GetDate:0",
        "type": "function",
        "function": {
          "name": "GetDate",
          "arguments": "{\n    \"task\": \"獲取明天的日期\"\n}"
        }
      }
    ]
}

最后通過Agent的配置,就可以讓模型在通用域和私域或是工具插件里自由的選擇進(jìn)行聊天。

圖片圖片

以上就是基礎(chǔ)篇的全部內(nèi)容,至此可以發(fā)現(xiàn),為什么本篇開頭會提到恭喜前端。是的,以上技術(shù)棧全部來自前端領(lǐng)域。

責(zé)任編輯:武曉燕 來源: 嗶哩嗶哩技術(shù)
相關(guān)推薦

2021-01-15 11:36:16

鴻蒙HarmonyOSAI應(yīng)用

2021-01-15 09:50:06

鴻蒙HarmonyOSAI應(yīng)用

2021-01-14 12:06:22

鴻蒙HarmonyOSAI應(yīng)用

2021-01-25 09:58:01

鴻蒙HarmonyOS應(yīng)用開發(fā)

2023-04-07 09:20:55

2017-09-30 11:57:45

曙光服務(wù)器DeskHPC

2011-07-07 10:49:41

JavaScript

2022-09-06 08:54:00

SpringBootController

2012-12-27 10:05:15

2010-06-02 15:24:15

PHP+MySQL

2011-03-29 11:32:29

2024-02-19 15:59:52

鴻蒙應(yīng)用開發(fā)操作系統(tǒng)

2010-12-10 13:57:45

PHP Extensi

2020-08-24 11:48:49

人工智能

2011-06-13 09:42:44

JAVA

2021-01-28 08:34:30

Java對象定義

2019-10-31 08:00:00

機(jī)器學(xué)習(xí)人工智能AI

2020-12-24 08:36:14

JavaJava基礎(chǔ)

2024-11-26 07:53:07

點贊
收藏

51CTO技術(shù)棧公眾號