链(chains) : 链不仅仅是单个 LLM 调用,还包括一系列调用(无论是调用 LLM 还是不同的实用工具),可以与其他工具集成并提供了用于常见应用程序的端到端的链调用。在一个任务当中很少能够单个LLM调用能够完成任务,还需要其他一系列调用,很多复杂场景会分解多个操作,第一个链的结果要带入第二个链的输入。例如我们需要写一篇文章,我们将写文章拆解为两部,首先输出提纲,再根据提纲完善内容,那这里会有两次LLM,每次的LLM给到的prompt是不一样的,所以每次LLM前通过PromptTemplate进行格式化后再传递给LLM.
目前ts版本也有比较多多链,如LLMChain、QA链、顺序链、API链、数据库链.
各链的实现:https://github.com/langchain-ai/langchainjs/tree/main/langchain/src/chains
BaseChain是LLMChain、QA、API的链实现的基类
继承BaseChain的类只要重写_call、chainType、inputKeys、outputKeys方法就可以得到自己场景的Chain类.所以我们只有少量的改动即可能是一个新的链.
BaseChain中的invoke主要是做调用链的过程处理
export abstract class BaseChain<RunInput extends ChainValues = ChainValues,RunOutput extends ChainValues = ChainValues> extends BaseLangChain<RunInput, RunOutput> implements ChainInputs {
get lc_namespace(): string[] {
return ["langchain", "chains", this._chainType()];
}
/**
* 处理存储
*/
_selectMemoryInputs(values: ChainValues): ChainValues {
const valuesForMemory = { ...values };
return valuesForMemory;
}
/**
* 调用执行该链
*/
async invoke(input: RunInput, options?: RunnableConfig): Promise<RunOutput> {
const fullValues = await this._formatValues(input);
let outputValues: RunOutput = this._call(fullValues as RunInput, runManager, config));
this._selectMemoryInputs(input)
return outputValues;
}
/**
* 验证输出
*/
private _validateOutputs(outputs: Record<string, unknown>): void {}
/**
* 输出的预处理
*/
async prepOutputs( inputs: Record<string, unknown>, outputs: Record<string, unknown>, returnOnlyOutputs = false) {
this._validateOutputs(outputs);
return { ...inputs, ...outputs };
}
/**
* 链的核心执行逻辑,集成基类后一般都是需要重写该方法
*/
abstract _call(values: RunInput, runManager?: CallbackManagerForChainRun, config?: RunnableConfig): Promise<RunOutput>;
/**
* 链的唯一标识,实现的链都需要自己定义链的唯一标识
*/
abstract _chainType(): string;
/**
* 格式化
*/
protected async _formatValues(values: ChainValues & { signal?: AbortSignal; timeout?: number }) {
const fullValues = { ...values } as typeof values;
this._selectMemoryInputs(values)
return fullValues;
}
/**
* 序列化
*/
serialize(): SerializedBaseChain {
throw new Error("Method not implemented.");
}
/**
* 反序列化,加载链
*/
static async deserialize(data: SerializedBaseChain, values: LoadValues = {}): Promise<BaseChain> {}
}
LLMChain它是由一个能够支持prompt定义和LLM组成.
使用示例:
import { xxxLLMAI } from "langchain/llms/xxxLLMAI";
import { PromptTemplate } from "langchain/prompts";
import { LLMChain } from "langchain/chains";
const model = new xxxLLMAI({ temperature: 0 });
const prompt = PromptTemplate.fromTemplate(
"帮我生成一个关于 {subject} 为主题大纲?"
);
const chainA = new LLMChain({ llm: model, prompt });
const resA = await chainA.call({ subject: "动物世界的快乐" });
APIChain是使用LLM与API交互,通过所提供的API文档构造API的结果
使用示例:
import { xxxLLMAI } from "langchain/llms/xxxLLMAI";
import { APIChain } from "langchain/chains";
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 xxxLLMAI({ temperature: 0 });
const chain = APIChain.fromLLMAndAPIDocs(model, OPEN_METEO_DOCS);
const res = await chain.call({
question:
"What is the weather like right now in Munich, Germany in degrees Farenheit?",
});
console.log({ res });
}
RetrievalQAChain检索链,它可用于RAG中,结合向量数据库进行召回的问答
使用示例:
import { xxxLLMAI } from "langchain/llms/xxxLLMAI";
import { RetrievalQAChain } from "langchain/chains";
import { HNSWLib } from "langchain/vectorstores/hnswlib";
import { xxxLLMAIEmbeddings } from "langchain/embeddings/xxxLLMAI";
import { RecursiveCharacterTextSplitter } from "langchain/text_splitter";
import * as fs from "fs";
export const run = async () => {
const model = new xxxLLMAI({});
const text = fs.readFileSync("xxx.txt", "utf8");
const textSplitter = new RecursiveCharacterTextSplitter({ chunkSize: 1000 });
const docs = await textSplitter.createDocuments([text]);
const vectorStore = await HNSWLib.fromDocuments(docs, new OpenAIEmbeddings());
const chain = RetrievalQAChain.fromLLM(model, vectorStore.asRetriever());
const res = await chain.call({
query: "我的私有库中有关于langchian的知识吗?",
});
console.log({ res });
};
比如我们的帮助文档中心就可以采用RGA检索法.
const files = fs.readdirSync(docFilePath);
const pdfFiles = files.filter(file => path.extname(file).toLowerCase() === '.pdf');
let docs: any = [];
for (let i = 0; i < pdfFiles.length; i++) {
const loader = new PDFLoader(docFilePath + "/" + pdfFiles[i]);
const docsNew = await loader.load();
docs = [...docs, ...docsNew];
}
if (this.embeddings != null && this.model != null && docs.length > 0) {
const vectorStoreVec = await LangchainVectorStore.fromDocuments(
docs,
this.embeddings,
{
url: process.env.VECTOR_URL || "",
username: "xxx",
key: process.env.VECTOR_KEY,
timeout: 10,
databaseName: "string28996",
collectionName: "string28996"
}
);
const chain = new RetrievalQAChain({
combineDocumentsChain: loadQAStuffChain(this.model, { prompt }),
retriever: vectorStoreVec.asRetriever(),
});
chain.returnSourceDocuments = true;
const res = await chain.call({
query: query,
});
res.request = this.model.requestMessage;
return res;
}
如果langchain中的链无法满足业务场景,可以通过自定义链来实现自己的链
import { LLMChain, ChainInputs, BaseChain } from "langchain/chains"
export class xxxxChains extends BaseChain {
//链的调用
_call(values: ChainValues, runManager?: CallbackManagerForChainRun | undefined): Promise<ChainValues> {
throw new Error("Method not implemented.");
}
//定义链的唯一标识
_chainType(): string {
throw new Error("Method not implemented.");
}
get inputKeys(): string[] {
throw new Error("Method not implemented.");
}
get outputKeys(): string[] {
throw new Error("Method not implemented.");
}
}
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。