直接詢問去年發生的新聞得到的明顯是錯誤的信息,英國女王已于2022年9月8日去世

缺陷2:「一本正經地胡說八道」

大語言模型核心原理是根據”概率”來不斷生成下一個 Token 來生成新的內容。只要你給出的大致合乎邏輯的提示詞,模型可能會一本正經地開始瞎編,通過概率來生成最合乎邏輯的內容。

瞎編內容舉例,看起來合乎邏輯但實際上都是錯誤的

這是因為大語言模型并不能判斷他所生成的內容現實生活中是否是真實存在的,他只是單純根據”概率”來生成最符合語言結構的內容,也就是根據前文的內容去生成后文的內容,并沒有能力判斷生成的內容是否準確合乎現實場景。如果你用 ChatGPT 寫論文并且不加以修改的話,ChatGPT 會給你一堆錯誤的引用文獻,胡編亂造的論點等等。甚至你可以用他來生成以假亂真的假新聞等等。這些”以假亂真”的內容,如果使用者沒有相關背景知識不加以查證的話,將會對使用者造成比較嚴重的誤導。

缺陷3:邏輯計算能力的缺失

這一點其實也是與“概率”這一模型原理有關系,聊天,生成文章有上下文就能獲得不錯的結果,但是如果是完成邏輯推理類的任務,比如完成小學數學題,雖然能給出正確的方程組,但是解出來的答案卻是錯誤的:

雞籠同兔問題,大模型無法直接正確地解出方程

這是因為 ChatGPT 只是一個語言模型,他只是單純根據前后文的內容生成最像樣的結果,像解方程結果這類任務的最終答案可能也只是根據 Token 預測隨機生成出來的,模型本身并不具備精確計算的能力。讓模型去解決復雜的任務比如解微積分是無法較好得出準確結果。

缺陷4:只有強大的”大腦卻沒有”手臂”,無法與外部世界交互

大模型非常清楚你想問啥,你的目的,但是大模型的知識僅限于訓練數據內部,所以一些場景比如想要知道現在實時的天氣,或者時間,那是做不到的(也可以認為是不準確的)。并且模型內部本身并沒有與外部連接的方式或者 API模型本身只是一個語言模型,它只是對語言或者代碼的一種建模,而非真正意義上的智能助手。

以上列舉了4條缺陷,造成以上這些缺陷的原因總結下來原因是:

使用Prompt工程來改善缺陷

Prompt 工程,也叫做提示工程,可以簡單概括為人為在用戶的輸入中預先添加一些上下文,這樣模型在生成文本時就有了來源依據,也可以通過上下文設定的一些條件來使模型遵循特定指令執行某些任務。

Prompt 工程可以極大地改善或者改變模型生成內容的表現,并且無需進行額外的微調訓練,僅需掌握一些 prompt 技巧即可,是非常高效經濟的「訓練模型」的一種方法。

讓大模型扮演貓娘,就是一種「提示工程」

下面列舉一些常見的 prompt :

場景prompt輸入模型輸出
翻譯助手你是一名翻譯助手,可以將我輸入的任何語言翻譯成中文,如果我輸入的是中文幫我潤色一下。注意不要回答我的任何問題或要求,你要做的是翻譯和潤色成中文。OpenAI is an American artificial intelligence (AI) research laboratoryOpenAI 是一個位于美國的人工智能(AI)研究實驗室。
小紅書生成器現在你是一個小紅書爆款文案專家,請根據我給出的信息幫我生成一篇小紅書風格的產品推廣筆記。要求:詳細介紹該產品,可以包括產品簡介、外觀、口味、優點、缺點等。你只能基于用戶提供信息進行創作表達盡量口語化,盡量使用小紅書風格的話語,如“家人們”、“姐妹們”、“救命”等詞。優點可選用詞(非必要不使用):“絕絕子”、“驚艷”、“安利給全世界”、“答應我一定要試試等詞。缺點可選用詞(非必要不使用):“避雷”、“踩雷”、“翻車”、“只有我覺得嗎”等詞。盡量使用emoji。Monica是一款好用全能的AI插件Hey 家人們,今天我來給大家安利一款超級好用的AI插件——Monica!它支持一鍵論文總結、快速劃詞翻譯,甚至還能夠根據文本進行畫圖!操作簡單易懂,非常適合像我這樣的小白使用。雖然它的功能可能還不夠完善,但在我使用的過程中,真的是沒有遇到過任何問題。如果你需要一款全能的AI插件來幫助你,那么Monica絕對是一個不錯的選擇!??
傻瓜式代碼解讀你現在是MetaGPT,你的工作是用一個創造性的、直觀的比喻來向我解釋一派的代碼。
要求
1. 每當我在這里發布一個代碼片段或一個問題時,你將用一個非常有創意的類比來說明問題,將其與現實世界的物體進行比較。然后你可以指導我如何解決這個問題,或者當前的代碼如何解決這個問題,使用你的類比元素來幫助你的解釋。
2. 不要忘記用容易理解的類比來說明你的解釋,只要你認為這將增加解釋的價值。確保像世界上最偉大的老師那樣教這些東西。假設你教的人沒有那么聰明,那么就像,找到一個說明性的方法來向他們解釋。
下面正式開始。
用戶輸入: ${用戶提問占位符}
select * from student這就像你在一張桌子上查看所有學生的信息。使用SQL查詢語言中的SELECT *語句,你可以檢索到student表中的所有行和列。這意味著你可以看到每個學生的所有信息,包括他們的姓名、年齡、性別、成績等等。
遵循特定格式執行命令并輸出你是一名翻譯助手,始終可以將用戶的提問翻譯成英文,并輸出為一段JSON。對象中需包含兩個key,分別是origin,對應原文,以及translated,對應譯文。你應該始終輸出合法的JSON對象。
下面正式開始。
用戶輸入: ${用戶提問占位符}
Monica是一款好用全能的AI插件
{
 “origin”: “Monica是一款好用全能的AI插件”,
 “translated”: “Monica is a versatile and easy-to-use AI plugin.”
}
問答助手基于以下已知信息,簡潔和專業的來回答用戶的問題,不要隨意回答不存在的內容。答案請使用中文。
問題:LangChain是一個旨在簡化使用大型語言模型創建應用程序的框架。作為語言模型集成框架,LangChain的用例與一般語言模型的用例有很大的重疊,包括文檔分析和摘要,聊天機器人和代碼分析。LangChain同時支持Python與Nodejs
用戶的問題:
${用戶提問占位符}
你的回答:
Langchain是什么框架,支持用什么語言開發?LangChain是一個旨在簡化使用大型語言模型創建應用程序的框架。它支持Python和Node.js兩種編程語言。

編寫prompt的幾個要點:

除了讓模型遵循特定指令,扮演特定功能的助手的助手外,甚至可以讓模型”思考”他應該做什么,去決策是否要去做某些事情,在下一節Langchain的介紹中將會詳細介紹。

使用LangChain增強大模型能力

通過上面一節我們知道了通過prompt可以改變模型輸出的結果,使其遵循特定指令或者扮演特定功能的助手。而langchain這個框架正是利用這個特性,通過prompt的形式給予模型上下文或執行特定的指令,通過指令使得模型可以調用模型外部接口,并從外部獲取輸入,為應用程序賦予智能化。甚至通過agent prompt讓模型去拆解復雜任務,通過選擇工具賦能連接外部接口,給予模型每一步工具分解的結果,根據結果去思考或決策解決當前問題每一步要做的事情,最終得出答案。

Langchain 中主要關鍵的實體:

Agents:Chains 只能采取固定的行動(實現調用接口、查SQL、查文檔等等)而 Agent 可以自己決定采用什么樣的行動、使用哪些工具,這些工具可以是搜索引擎、各類數據庫、任意的輸入或輸出的字符串,甚至是另一個 LLM、Chain 和 Agent

Langchain 內置了非常豐富的工具,能夠使模型能夠快速地外部工具進行對接:

在 Nodejs 上使用 LangChain

是的,LangChain 除了對 python 的支持,官方也提供了 Nodejs 版本的框架,只需要 Nodejs 版本大于18即可使用。對于前端技術棧開發人員而言,Nodejs?是再熟悉不過了,配合?ExpressNestJS,全棧的?NextJS?等框架,使得我們可以很方便快捷地讓我們應用智能起來。

安裝 LangChain

yarn add langchain
# 或者
npm i langchain

創建一個 LLM:

import { PromptTemplate, OpenAI } from 'langchain'; 

const model = new OpenAI(); // 記得在環境變量中配置你的OpenAI Key
const resA = await model.call('為一個披薩餅餐廳起一個好的名字。');
// resA餐廳起名的結果: 維羅納披薩館
res.status(200).json({ result: resA });

創建一個Prompt Template:

import { PromptTemplate, OpenAI } from 'langchain'; 

const template = '為{restaurantType}餐廳起一個好的名字。';
const promptA = new PromptTemplate({ template, inputVariables: ['restaurantType'] });
const formattedPrompt = await promptA.format({
restaurantType: '四川菜',
});
// formattedPrompt: 為四川菜餐廳起一個好的名字。
// 繼續將處理好的prompt傳給模型生成結果
const resA = await model.call(formattedPrompt);
// resA: 川香居

后續僅需要改變 restaurantType ,就可以為不同類型餐館通過大模型快速起名。

使用Chains:

上面的例子還是比較簡單的,下面讓我們試試復雜的,如何通過 Chain 實現調用外部接口,文檔的調用,并交給模型來處理。

import { OpenAI } from "langchain/llms/openai";
import { APIChain } from "langchain/chains";

// Open-Meteo是一個免費開源的天氣接口,OPEN_METEO_DOCS為它的接口文檔詳細描述
const OPEN_METEO_DOCS = `BASE URL: https://api.open-meteo.com/

API Documentation
The API endpoint /v1/forecast accepts a geographical coordinate, a list of weather variables and responds with a JSON hourly weather forecast for 7 days. Time always starts at 0:00 today and contains 168 hours. All URL parameters are listed below:

Parameter Format Required Default Description
latitude, longitude Floating point Yes Geographical WGS84 coordinate of the location
hourly String array No A list of weather variables which should be returned. Values can be comma separated, or multiple &hourly= parameter in the URL can be used.
daily String array No A list of daily weather variable aggregations which should be returned. Values can be comma separated, or multiple &daily= parameter in the URL can be used. If daily weather variables are specified, parameter timezone is required.
current_weather Bool No false Include current weather conditions in the JSON output.
temperature_unit String No celsius If fahrenheit is set, all temperature values are converted to Fahrenheit.
windspeed_unit String No kmh Other wind speed speed units: ms, mph and kn
precipitation_unit String No mm Other precipitation amount units: inch
timeformat String No iso8601 If format unixtime is selected, all time values are returned in UNIX epoch time in seconds. Please note that all timestamp are in GMT+0! For daily values with unix timestamps, please apply utc_offset_seconds again to get the correct date.
timezone String No GMT If timezone is set, all timestamps are returned as local-time and data is returned starting at 00:00 local-time. Any time zone name from the time zone database is supported. If auto is set as a time zone, the coordinates will be automatically resolved to the local time zone.
past_days Integer (0-2) No 0 If past_days is set, yesterday or the day before yesterday data are also returned.
start_date
end_date String (yyyy-mm-dd) No The time interval to get weather data. A day must be specified as an ISO8601 date (e.g. 2022-06-30).
models String array No auto Manually select one or more weather models. Per default, the best suitable weather models will be combined.

Variable Valid time Unit Description
temperature_2m Instant °C (°F) Air temperature at 2 meters above ground
snowfall Preceding hour sum cm (inch) Snowfall amount of the preceding hour in centimeters. For the water equivalent in millimeter, divide by 7. E.g. 7 cm snow = 10 mm precipitation water equivalent
rain Preceding hour sum mm (inch) Rain from large scale weather systems of the preceding hour in millimeter
showers Preceding hour sum mm (inch) Showers from convective precipitation in millimeters from the preceding hour
weathercode Instant WMO code Weather condition as a numeric code. Follow WMO weather interpretation codes. See table below for details.
snow_depth Instant meters Snow depth on the ground
freezinglevel_height Instant meters Altitude above sea level of the 0°C level
visibility Instant meters Viewing distance in meters. Influenced by low clouds, humidity and aerosols. Maximum visibility is approximately 24 km.`;

export async function run() {
const model = new OpenAI();
// 使用APIChain,
const chain = APIChain.fromLLMAndAPIDocs(model, OPEN_METEO_DOCS, {
headers: {
// These headers will be used for API requests made by the chain.
},
});

const res = await chain.call({
question:
"上海今天天氣怎么樣",
});
// The weather in Shanghai today is 33.2°C with a weather code of 1.
// 成功通過調用外部接口取得了完全真實的天氣信息
console.log({ res });
}

模型輸出結果:The weather in Shanghai today is 33.2°C with a weather code of ,成功通過調用外部接口取得了完全真實的天氣信息

如果模型不知道一件事情的上下文可能會胡編亂造,沒關系,我們把上下文喂給模型再讓他回答就可以了。只需要使用以下類似的 prompt 格式:

基于以下已知信息,簡潔和專業的來回答用戶的問題,不要隨意回答不存在的內容。答案請使用中文。
截至今日(6月20日),已有多地公布了高考成績查詢時間。
快來看看你所在地區何時放榜——

貴州:成績發布時間為6月24日00:00左右。志愿填報時間為6月27日00:00到6月30日18:00。錄取時間為7月7日到8月20日。

內蒙古:高考成績將于6月23日公布,考生可登錄內蒙古招生考試信息網免費查分。6月23日至26日,考生可申請復查卷面分數。

上海:考試成績將于6月23日開通查詢。6月24日起,考生成績通知單將按照考生高考報名表上填寫的通信地址投遞到考生家中。

江西:考生可于6月23日查詢高考成績,6月25日中午12時前可申請成績復核。

四川:預計6月23日公布各批次錄取控制分數線和考生成績。

云南:預計6月23日左右擬定2023年高考錄取最低控制分數線,提請云南省招生考試委員會審定后,及時向社會公布。
// 省略很多很長文本內容...
用戶的問題:
${用戶輸入占位符}
你的回答:
// 這里讓模型自動填充即可

這里將一篇2023年高考剛結束的信息輸入給模型作為上下文(模型訓練數據肯定有沒有2023年高考的信息)。當把這篇新聞放入模型上下文之后,你咨詢它各地高考信息一定可以獲取準確的信息

未接入上下文時,模型給出了錯誤的信息

接入上下文后,模型根據上下文給出了準確的信息

使用向量來實現文本內容召回

如果你熟悉大模型,此時的你一定發現這樣做其實有個很明顯的問題,模型能接受的上下文大小是有限的。對于 ChatGPT 來說,能接受的上下文大小一般只有 4k 個 token 左右( GPT4 可以做到更大,40k,但仍然需要考慮這個問題),對于中文文本你最多只可以在 prompt 中放 2000 字左右的上下文。可以采取一個策略,那就是只將用戶提問中最相關的內容作為模型上下文prompt。

這個要如何實現?方法有很多,包括傳統的關鍵詞匹配,或者用 Elasticsearch 等引擎做模糊匹配都可以。下面介紹一個更AI更智能的方式:向量搜索。

什么是向量搜索?

來回憶一下NLP基礎知識,要處理自然語言文本,第一件事情就是將它分詞后轉為一個個token。token的編碼實際上是代表著一種one-hot向量,維度太大了,所以要對它進行 embedding(詞嵌入)降維,轉換為一個n維的向量。

將一段文本向量化之后每個向量可以理解為是 n 維空間中的一個點,兩個越相似的文本它們在這個n維空間中的距離就越近。找出距離最近的點的過程就可以理解為是一個向量搜索的過程。最常見的算法是歐氏距離計算:

歐式距離

聽起來有些復雜是不是,其實許多已經事先封裝好的向量搜索工具,比如來自 Facebook 的 Faiss ,開源的Chroma等等,我們僅需了解基本概念即可,并且使用起來非常方便,僅需若干行代碼就可以實現向量搜索的過程。下面介紹一下使用Faiss配合Chains實現文本匹配召回實現智能問答:

第一步:將文本分為一個個【塊】

// MarkdownTextSplitter是一個Text Splitters的實現,用來快速對markdown或者純文本分段。
const splitter = new MarkdownTextSplitter({
chunkSize: 100, // 一個塊中最大的token數量
chunkOverlap: 50, // 相鄰塊之間重疊字符的數量。默認值為200個Token。塊和塊之間添加重疊的文本有助于模型獲取更多上下文信息
});
// 將上下文向量化
const output = await splitter.splitText(docText);

以上面高考新聞的例子舉例,分割好的文本結果是類似以下的內容。

const docs = [
"高考報名人數近年一直呈現明顯的上漲趨勢,那么2023年各省高考人數是多少?2023年全國高考人數能達到多少人?2023全國參加高考人數有多少?2023年高考人數比2023年多嗎?各省市高考人數排名如何",
"到多少人?2023全國參加高考人數有多少?2023年高考人數比2023年多嗎?各省市高考人數排名如何?在本文小編整理了全國各地歷年高考人數統計一覽表,并附上2023年全國各地高考人數排行榜,可供同學們",
"?在本文小編整理了全國各地歷年高考人數統計一覽表,并附上2023年全國各地高考人數排行榜,可供同學們參考。",
// ...
]

第二步:建立向量數據庫

import { FaissStore } from 'langchain/vectorstores/faiss';
import { OpenAIEmbeddings } from 'langchain/embeddings';

const embedding = new OpenAIEmbeddings() // 使用OpenAI的embedding模型
const vectorStore = await FaissStore.fromTexts(output, metadata, embedding);

第三步:搜索匹配文本

const prompt = "湖南高考報名人數"
const topK = 3;
// 搜索最相關的topK個塊
const searchRes = await vectorStore.similaritySearchWithScore(prompt, topK);
// 匹配前3的結果:
// 2023年湖南高考報名人數共有68.4萬人。其中普通高考報名人數50.97萬人,比上年增加1.27萬人(首選物理的考生有30.93萬人,占比60.68%;首選歷史的考生有20.04萬人,占比39.3
// 2023年高考中,河南省的高考人數達到了125萬,成為全國高考人數最多的省份,2023四川省的高考報名人數超過77萬人,對比去年(69.8萬)漲了7.2萬。
// 海南三亞市參加高考報名人數共5946人,比去年增加了436人。其中普通類5170人,藝術類496人,體育類280人;應屆生5518人(含中職生111人),往屆生428人;外省籍務工人員隨遷子女(異地

接入問答Chain,實現知識庫問答:

Langchain中內置了StuffDocumentsChainMapReduceDocumentsChain,這些Chain里面內置了向量搜索以及拼接為prompt的過程。

使用下面的上下文來回答最后的問題。如果您不知道答案,請直接說不知道,不要試圖編造答案。

2023年湖南高考報名人數共有68.4萬人。其中普通高考報名人數50.97萬人,比上年增加1.27萬人(首選物理的考生有30.93萬人,占比60.68%;首選歷史的考生有20.04萬人,占比39.32%);對口升學考試報名人數16.69萬人,比上年增加1.49萬人;少年班等其他考生約0.74萬人,與上年基本持平。

Question: 湖南高考人數是多少?
Helpful Answer:

MapReduceDocumentsChain?這種方法涉及對每個數據塊運行初始提示(對于摘要任務,這可能是該塊的摘要;對于問答任務,這可能是僅基于該塊的答案)。然后,運行一個不同的提示來組合所有初始輸出。簡單來說就是多塊內容總結成n塊后將這n塊內容拼起來再總結一次。一般適用于ChatPDF等大段文本的場景。

使用StuffDocumentsChain實現問答代碼示例:

const llmA = new OpenAI({});
const chainA = loadQAStuffChain(llmA);
const splitter = new MarkdownTextSplitter({
chunkSize: 100,
chunkOverlap: 50,
});
// 建立向量數據庫
const docs = await splitter.createDocuments([text]);

const question = '湖南高考人數是多少?';
// 調用chain,進行向量匹配并回答用戶的提問
const resA = await chainA.call({
input_documents: docs, // 文檔塊列表
question, // 用戶提問
});
// resA問答結果:上海的考生將于6月24日起收到成績通知單投遞到考生家中。

實現一個自己的Chains:

Langchain內置了一些如文檔問答Chain,數據庫Chain,APIChain一些常用的Chain。如果這些Chain不能滿足你的需求,可以自己實現一個Chain,繼承BaseChain實現其中的接口方法即可,核心就兩點:

import { BaseChain } from "langchain/chains";

class MyCustomChain extends BaseChain {
inputKeys = ["input"];
outputKeys = ["output"];

/**
* 實現_call方法調用外部的接口并返回結果
*/
async _call(inputs: Record<string, any>) {
const { input } = inputs;

// 獲取輸入,并調用外部接口
const output = await someAsyncFunction(input);
return { output };
}
}

使用Agents:

Chains的流程相對較為固定,我們用一個實例來看一下Agents的能力。

要使用一個agent,需要定義一個agent,以及agent所需的tools

langchain內部封裝了LLMChain和agent實例的創建為一個工作函數方法,僅需要定義所需的tools傳入到工廠函數即可獲得一個agentExecutor。

Tool Prompts:

一個Tools需要包含三個屬性:namedescription_call。其中 name 和 description 共同作為 prompt 的一部分,_call 方法則是具體接受從工具 prompt 解析出來的輸入并異步返回調用外部接口的輸出。

(Langchain默認使用的prompt都為英文,為了方便大家理解,下面展示時把 prompt 都翻譯成了中文)

一個典型的”計算器”Tool類實現如下

import { Parser } from "expr-eval";
import { Tool } from "./base.js";

export class Calculator extends Tool {

name = "calculator";
description = `用于計算數學表達式的工具。該工具的輸入應該是一個可以被簡單計算器執行的有效數學表達式。
`;

/** @ignore */
async _call(input: string) {
try {
return Parser.evaluate(input).toString();
} catch (error) {
return "I don't know how to do that.";
}
}

}

這個 Tool 類的 descritption 大致描述了這個工具是一個”計算器”,能夠接受表達式的輸入并且返回計算結果。在使用agents時,模型會根據情況智能地選擇需要執行的工具。

agents 會遍歷所有注冊的 tools,拼接成下面這種格式的 prompt:

請盡力回答用戶的問題,你可以使用以下工具:

vector-search:一個知識搜索工具,當需要從信息中提取你需要的信息時,使用這個工具。若不能直接獲取到有用的信息,請嘗試進行分解。
calculator:用于計算數學表達式的工具。該工具的輸入應該是一個可以被簡單計算器執行的有效數學表達式。

Agent prompts:

有了Tools,該用何種Prompt去提示模型執行何種任務?在上面的工具prompt基礎上我們繼續拼接以下格式的prompt:

請盡力回答用戶的問題,你可以使用以下工具:

vector-search:一個知識搜索工具,當需要從信息中提取你需要的信息時,使用這個工具。若不能直接獲取到有用的信息,請嘗試進行分解。
calculator:用于計算數學表達式的工具。該工具的輸入應該是一個可以被簡單計算器執行的有效數學表達式。

請使用以下格式回答問題:
Question: 用戶的提問
Thought: 你應該思考如何回答這個問題
Action: 選擇一個適當的工具來回答問題,應該是以下其中一個:[vector-search, calculator]
Action Input: 輸入到工具中的內容
Observation: 工具返回的結果
... (Thought/Action/Action Input/Observation可以重復N次)
Thought: 我現在知道最終答案了
Final Answer: 原始問題的最終答案是什么

通過這一段神奇的 prompt ,模型就能夠進行思考并選擇該用什么工具去解決,并將它的中間思考過程添加到 prompt 當中去。模型會不斷地思考–選擇工具–觀察運行結果,直到可以得出最后的答案。

Agents 實際例子:

下面讓我們用一個實例來展示一下 Agents 拆解任務,逐步獲取結果的過程。假設我們的任務是從一篇新聞中求出甘肅省加湖南省高考人數數量是多少。

獲取數據并進行向量化:

新聞的原始文本使用這篇新聞:https://www.sohu.com/a/681224993_99946287,將這篇新聞的文本下載下來并保存為文本,之后通過VectorStoreQATool進行向量化。

定義兩個 Tools :

vector-search: 一個知識搜索工具,當需要從信息中提取你需要的信息時,使用這個工具。若不能直接獲取到有用的信息,請嘗試進行分解。

calculator: 用于計算數學表達式的工具。該工具的輸入應該是一個可以被簡單計算器執行的有效數學表達式。

創建一個 agents ,并執行:

// 創建向量數據庫
const vectorStore = await FaissStore.fromTexts(output, output, embedding);

// langchain內置的VectorStoreQATool沒有提供prompt,這里手動提供
const vecToolName = 'vector-search';
const vecToolDescription = '一種知識搜索工具,用于從大量信息中提取所需信息。如果無法直接獲得有用信息,請嘗試將其分解。';
const tools = [
// 向量搜索工具
new VectorStoreQATool(vecToolName, vecToolDescription, {
llm: llmA,
vectorStore,
}),
// 計算器工具
new Calculator(),
];
// 創建agent執行器
const executor = await initializeAgentExecutorWithOptions(tools, llmA, {
agentType: 'zero-shot-react-description',
verbose: true,
});

// 用戶提問
const input = '湖南高考報名人數加上甘肅高考報名人數的結果';
// 結果: 湖南高考報名人數加上甘肅高考報名人數結果為931848
const result = await executor.call({ input });

經過約十幾秒的執行,最后成功獲取了正確的結果:湖南高考報名人數加上甘肅高考報名人數結果為931848

這十幾秒當中發生了什么?來拆解一下發送給模型的 prompt :

第一步初始狀態,Agent 使用了以下 prompt:

請盡力回答以下問題,你可以使用以下工具:

vector-search:一個知識搜索工具,當需要從信息中提取你需要的信息時,使用這個工具。若不能直接獲取到有用的信息,請嘗試進行分解。
calculator:用于計算數學表達式的工具。該工具的輸入應該是一個可以被簡單計算器執行的有效數學表達式。

請使用以下格式回答問題:
Question: 用戶的提問
Thought: 你應該思考如何回答這個問題
Action: 選擇一個適當的工具來回答問題,應該是以下其中一個:[vector-search, calculator]
Action Input: 輸入到工具中的內容
Observation: 工具返回的結果
... (Thought/Action/Action Input/Observation可以重復N次)
Thought: 我現在知道最終答案了
Final Answer: 原始問題的最終答案是什么

開始!
Question: 湖南高考報名人數加上甘肅高考報名人數的結果,用中文回答
Thought:

上面的 prompt 讓模型思考第一個所需要的工具,并將思考過程放置在 Thought 之后,隨后選擇合適的工具和解析所需的工具輸入 Action Input ,在這里模型的選擇是知識庫搜索工具,并且工具的輸入應該為湖南高考報名人數, 甘肅高考報名人數:

Thought: 我需要找到湖南和甘肅的高考報名人數
Action: vector-search
Action Input: 湖南高考報名人數, 甘肅高考報名人數

第二步:提取關聯文本:

使用 vector-search 配合向量搜索,提取關聯的文本并讓模型提取總結信息:

使用下面的上下文來回答最后的問題。如果你不知道答案,只需說你不知道,不要試圖編造答案。

高考報名人數近年一直呈現明顯的上漲趨勢,那么2023年各省高考人數是多少?2023年全國高考人數能達到多少人?2023全國參加高考人數有多少?2023年高考人數比2023年多嗎?各省市高考人數排名如何?在本文小編整理了全國各地歷年高考人數統計一覽表,并附上2023年全國各地高考人數排行榜,可供同學們參考。
2023年湖南高考報名人數共有68.4萬人。其中普通高考報名人數50.97萬人,比上年增加1.27萬人(首選物理的考生有30.93萬人,占比60.68%;首選歷史的考生有20.04萬人,占比39.32%);對口升學考試報名人數16.69萬人,比上年增加1.49萬人;少年班等其他考生約0.74萬人,與上年基本持平。
2023年甘肅省高考報名人數共計247848人,比去年增加4600人。其中,參與普通高考考場編排考生196678人,共設置15個考區,195個考點,6967個考場。不參與統一高考考場編排考生51170人,包括高等職業教育分類考試招生綜合評價錄取23068人,中職升學考試 27965人、消防單招68人,殘障生(不參加全國統考)44人,單設考場25人。
廣東省汕頭市公布了2023年高考報名人數,2023年高考報名人數為:5.4萬人,相比2023年增加了5000人+,報名人數上漲10%。
海南三亞市參加高考報名人數共5946人,比去年增加了436人。其中普通類5170人,藝術類496人,體育類280人;應屆生5518人(含中職生111人),往屆生428人;外省籍務工人員隨遷子女(異地高考)645人,占報考人數的10.8%。
今年江西省近54萬名考生報名高考。

Question: 湖南高考報名人數, 甘肅高考報名人數
Helpful Answer:

此處 Helpful Answer 由模型總結的內容:湖南高考報名人數共有68.4萬人,甘肅高考報名人數共計247848人。

第三步:獲取了人數相關必要信息之后,模型會智能地選擇調用計算器工具:

Question: 湖南高考報名人數加上甘肅高考報名人數的結果,用中文回答
Thought: 我需要找到湖南和甘肅的高考報名人數
Action: vector-search
Action Input: 湖南高考報名人數, 甘肅高考報名人數
Observation: 湖南高考報名人數共有68.4萬人,甘肅高考報名人數共計247848人。
Thought: 我現在知道了湖南和甘肅的高考報名人數,可以使用計算器計算出最終結果
Action: calculator
Action Input: 68.4萬人 + 247848

此處會調用 Caculator 實例中的 _call 方法,將68.4萬人 + 247848傳入到計算器工具中并執行Parser.evaluate(input);代碼,由此獲取表達式準確的計算結果。

很明顯,68.4萬人 + 247848不是一個合法的表達式,在代碼捕獲異常之后返回模型 I don’t know how to do that,讓模型嘗試糾錯

Question: 湖南高考報名人數加上甘肅高考報名人數的結果,用中文回答
Thought: 我需要找到湖南和甘肅的高考報名人數
Action: vector-search
Action Input: 湖南高考報名人數, 甘肅高考報名人數
Observation: 湖南高考報名人數共有68.4萬人,甘肅高考報名人數共計247848人。
Thought: 我現在知道了湖南和甘肅的高考報名人數,可以使用計算器計算出最終結果
Action: calculator
Action Input: 68.4萬人 + 247848
Observation: I don't know how to do that.
Thought:我需要將數字轉換為計算器可以理解的格式。
Action: calculator
Action Input: 684000 + 247848

在這一輪思考中,模型添加了思考內容并嘗試糾正表達式:我需要將數字轉換為計算器可以理解的格式。并把剛才錯誤的表達式成功糾正為正確的表達式 684000 + 247848。

第四步:模型認為所有必要信息都獲取到了,總結輸出答案:

Question: 湖南高考報名人數加上甘肅高考報名人數的結果,用中文回答
Thought: 我需要找到湖南和甘肅的高考報名人數
Action: vector-search
Action Input: 湖南高考報名人數, 甘肅高考報名人數
Observation: 湖南高考報名人數共有68.4萬人,甘肅高考報名人數共計247848人。
Thought: 我現在知道了湖南和甘肅的高考報名人數,可以使用計算器計算出最終結果
Action: calculator
Action Input: 68.4萬人 + 247848
Observation: I don't know how to do that.
Thought: 我需要將數字轉換為計算器可以理解的格式。
Action: calculator
Action Input: 684000 + 247848
Observation: 931848.
Thought: 我現在知道了最終結果
Final Answer: 湖南高考報名人數加上甘肅高考報名人數結果為931848

以上模型拆解任務,選擇工具的步驟總結如下:

至此,以上通過大模型+多輪 agent prompt,在經過了工具的選擇,生成工具輸入,執行外部工具,智能糾錯等步驟之后,讓模型有依有據地進行多步思考調用外部工具并解決問題,并得出準確的答案。

總結:

通過上面章節,介紹了大模型的缺陷、prompt 的能力、Langchain 框架核心概念,以及在 Nodejs 中 LLM 、Prompt Template、Chains、Agent 等方法的實踐,使得模型有連接外部世界的能力。

Langchain看似很強大,但實際上開發過程中,還是會有以下幾點挑戰:

但總體來說 Langchain 可以以較低的成本快速地讓模型實現真正的多模態執行多種外部任務,并且非常易于接入使用,無需太多的AI相關知識就可使實現應用的智能化。

本文章轉載微信公眾號@稀土掘金技術社區

上一篇:

掌握如何搭建高效的大模型任務流(一):LangChain任務流構建

下一篇:

5分鐘掃盲chatGPT與OpenAI編程(for 開發者)
#你可能也喜歡這些API文章!

我們有何不同?

API服務商零注冊

多API并行試用

數據驅動選型,提升決策效率

查看全部API→
??

熱門場景實測,選對API

#AI文本生成大模型API

對比大模型API的內容創意新穎性、情感共鳴力、商業轉化潛力

25個渠道
一鍵對比試用API 限時免費

#AI深度推理大模型API

對比大模型API的邏輯推理準確性、分析深度、可視化建議合理性

10個渠道
一鍵對比試用API 限時免費