
先前我利用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' });
    }
}

