
先前我利用Langchain 來優化德國某電子商務網站的 SEO,當時使用的是 Azure AI,不過,由於月底總是預算耗盡,我開始尋找替代方案,最終找到Facebook 開源的AI 模型 llama 替代 。
其實我有用了 Python 和 Langchain 寫了一個 AI bot 的算命機器人,但考慮到團隊成員主要精通 JavaScript,而不是 Python,為了統一的技術棧,大家比較能相互備援,我決定嘗試使用 Next 的API 開發這個 AI 相關功能,最後做成 AI Agent BOT API。
Langchain 是一個可以整合多種大型 AI 模型的框架,透過它可以輕鬆調用各類大型語言模型。這個框架提供了模版、解析器、動態路由,並且可以與 Python 、node 、C# 後端語言整合。
我們都了解AI對文字非常擅長,而且非常有效率,應用程式和AI 互動,可以做到,很多的應用延伸,像是:
如果使用情境很單純,只需要與大型語言模型單純一問一答,那麼,我覺得可以不需要使用到langchain ,但如果你希望依據使用者輸入的語意讓 AI 決定要做什麼事,或是需要在一次使用請求中和大型模型語言交互多次,像是從自己的向量資料庫查不到相關資料,再與外部api 交換,那麼 langchain 這個使用情境,就非常適合。
npm install langchain @langchain/azure-openai @langchain/ollama @langchain/openai --save
import { AzureChatOpenAI } from '@langchain/openai';
import { NextApiRequest, NextApiResponse } from 'next';
export default async function handler(req: NextApiRequest, res: NextApiResponse) {
const model = new AzureChatOpenAI({
azureOpenAIApiKey: process.env.AZURE_OPENAI_API_KEY,
azureOpenAIApiDeploymentName: 'gpt-4',
azureOpenAIApiInstanceName: 'your-instance-name',
azureOpenAIApiVersion: '2023-03-15-preview',
temperature: 0, // 用來調控AI 的隨機性
maxTokens: 500,
});
try {
const result = await model.invoke('為一個鞋店起一個好的名字。');
res.status(200).json({ result });
} catch (error) {
res.status(500).json({ error: 'Failed to generate name' });
}
}
現在透過 ChatOllama 來生成鞋店的店名 Langchain 是不是很方便,它把界面設計的很好,直接把 AzureChatOpenAI 換成 ChatOllama,後程式也都不用改,就把模型換掉
import { ChatOllama } from '@langchain/ollama';
import { NextApiRequest, NextApiResponse } from 'next';
export default async function handler(req: NextApiRequest, res: NextApiResponse) {
const model = new ChatOllama({
model: 'llama3.2',
temperature: 0,
maxRetries: 2,
baseUrl: 'http://localhost:11434',
});
try {
const result = await model.invoke('為一個鞋店起一個好的名字。');
const content = JSON.stringify(result.content);
res.status(200).json(content);
} catch (error) {
res.status(500).json({ error: 'Failed to generate name' });
}
}
import { ChatOllama } from '@langchain/ollama';
import { NextApiRequest, NextApiResponse } from 'next';
export default async function handler(req: NextApiRequest, res: NextApiResponse) {
const { brandName, modelVersion = 'llama3.2', temperature = 0 } = req.body;
const model = new ChatOllama({
model: modelVersion,
temperature,
maxRetries: 2,
baseUrl: 'http://localhost:11434',
});
try {
const result = await model.invoke(`為一個鞋店起一個好的名字:${brandName}`);
const content = JSON.stringify(result.content);
res.status(200).json(content);
} catch (error) {
res.status(500).json({ error: 'Failed to generate name' });
}
}
import { StringOutputParser } from '@langchain/core/output_parsers';
import { ChatPromptTemplate } from '@langchain/core/prompts';
import { ChatOllama } from '@langchain/ollama';
import { NextApiRequest, NextApiResponse } from 'next/types';
// 定義 API route
export default async function handler(req: NextApiRequest, res: NextApiResponse) {
const { modelVersion = 'llama3.2', temperature = 0 } = req.body;
try {
const question = 'What is the weather in Taipei?';
// 1. 初始化模型
const model = new ChatOllama({
model: modelVersion,
temperature,
maxRetries: 2,
baseUrl: 'http://localhost:11434',
});
// 2. 定義一個處理步驟的 prompt
const prompt = ChatPromptTemplate.fromMessages([['human', 'Ask the weather for {question}']]);
// 2. 定義 output parser
const outputParser = new StringOutputParser();
// 3. 使用 pipe 來串聯步驟:prompt -> model -> parser
const pipeChain = prompt.pipe(model).pipe(outputParser);
// 4. 執行 chain 並取得結果
const weatherResponse = await pipeChain.invoke({ question });
// 5. 回應 API 結果
res.status(200).json({ weather: weatherResponse });
} catch (error) {
res.status(500).json({ message: 'Internal Server Error' });
}
}
import { ChatOllama } from '@langchain/ollama';
import { APIChain } from 'langchain/chains';
import { NextApiRequest, NextApiResponse } from 'next/types';
const OPEN_METEO_DOCS = `api document ...`;
// Next.js API route
export default async function handler(req: NextApiRequest, res: NextApiResponse) {
const { question, modelVersion = 'llama3.2', temperature = 0 } = req.body;
try {
const model = new ChatOllama({
model: modelVersion,
temperature,
maxRetries: 2,
baseUrl: 'http://localhost:11434',
});
const chain = APIChain.fromLLMAndAPIDocs(model, OPEN_METEO_DOCS, {
headers: {
// API-specific headers if required
},
});
const weatherResponse = await chain.invoke({ question });
res.status(200).json({ weather: weatherResponse });
} catch (error) {
console.error('Error fetching weather:', error);
res.status(500).json({ message: 'Internal Server Error' });
}
}

