Mark Ku's Blog
首頁 關於我
利用 Azure AI、LangChain 搭配 Next.js 提升 SEO 效益
AI
利用 Azure AI、LangChain 搭配 Next.js 提升 SEO 效益
Mark Ku
Mark Ku
June 02, 2024
1 min

前言

我們都知道AI 擅長文字處理,但礙於我們的德國網站運營規模相當的小,缺乏足夠的人力來維護SEO資料,我們利用AI的文字處理能力來自動生成SEO數據(包括標題、描述和關鍵字)。這種方法不僅節省了大量人力資源,而且通過將頁面預渲染時的數據傳送給AI處理,提升了網站的搜索引擎優化效率。

AI 帶來的變革

Bill Gates 曾說許多軟體「仍然相當愚蠢」,因為它們需要大量的人工輸入才能發揮作用,且他認為人工智慧 (AI) 代理,可以在未來五年內改變這一現狀。

從過去的滑鼠鍵盤輸入及僅接受明確的指令,到提供不同的交互方式,檔案、圖片、聲音、影像及讀懂人類模糊的指令,AI 的出現改變了人與電腦的互動方式,人與電腦的互動方式改變,所有的應用程式都值得用AI 改寫一次。

這篇使用的技術:Next.js、Azure Open AI 與 LangChain

  • Next.js:一個基於React的框架,專門用於構建快速的靜態和動態網頁應用程序,它允許開發者在框架內直接實現API路由,方便進行後端開發。
  • Azure Open AI:大家都知道微軟投資了 OpenAI,當發佈新模型時,身為授權夥伴的微軟,也會同步取得這些模型,封裝成為企業提供客製化的AI 服務。
  • LangChain:這是一個整合多個大型AI模型的框架,輕易就能調用各種大型語言的模型, 提供模版,解析器、動態路由,通常搭配 Fast api 就能和其他異質系統整合。

Azure Open AI 的運作原理

AI 之所以能夠讀懂上下文,其實每次都要將對話回傳回去,透過這個機制,我們能夠在請求AI前封裝AI, 扮演某特定的角色及可以做什麼不可以做什麼。

 You are an SEO expert. Based on the page description provided below, generate an SEO-optimized title, meta description, and keywords. Ensure that the title is engaging and concise, the meta description summarizes the product effectively while enticing users to learn more, and the keywords are relevant to the product's features and market segment. Additionally, translate all content into the language specified by the given language code.
        Company:{companyDescription}
        Ecommerce Page Description: {description}
        Translate Target Language Code: {langCode}
        FormatInstructions: {formatInstructions}

生成 SEO Meta AI Api的設計概念

  1. 頁面請求處理:首先,先在 Next.js 建立一個 API ,並且傳入頁面描述及要翻譯的語言
  2. 語言處理: 接著,利用 LangChain 操作 Azure Chat OpenAI 根據傳入的頁面描述生成 SEO 優化的標題、描述和關鍵詞
  3. 儲存結果:再來,依據頁面 Slug 儲存關鍵詞給下次預渲染使用,同時也節省 Azure AI 的用量。
  4. 結果回傳: 最後將,生成的SEO標籤資料將被回傳並用於網頁的預渲染,進而在搜尋引擎中達到更好的排名。

透過結合 Next.js 的前端技術、Azure AI 的語言生成能力與 LangChain 的結構化輸出,我們能夠創建一個高效且自動化的流程來優化網站的 SEO 表現,這種方法不僅節省了人力資源,也因其精確和針對性的SEO 標籤生成,而提高了網站在搜尋引擎中的能見度和排名。

自動化生成符合 SEO 標籤資料

在 Next.js 中部署的 generateSEOMetadata 函數利用 Azure Chat OpenAI 和 LangChain 處理產品描述,並生成相應的標題、描述和關鍵詞。LangChain 的輸出解析器(Output Parser)確保從 AI 模型接收到的回應符合 SEO 的需求,只提取最關鍵的信息。

Next js 程式碼 

import { BaseOutputParser } from '@langchain/core/output_parsers';
import { ChatPromptTemplate } from '@langchain/core/prompts';
import { AzureChatOpenAI } from '@langchain/openai';
import { LogLevel } from '@utils/log/const-logging';
import { serverSideLog } from '@utils/log/server-side-log';
import { genOnceEncodedURI } from '@utils/product/gear';
import { RedisBase } from '@utils/redis/redis-base';
import { NextApiRequest, NextApiResponse } from 'next';


class CustomOutputParser extends BaseOutputParser<string[]> {
    async parse(output: any) {
        const result = output.replaceAll('```json', '').replaceAll('```', ''); // for gpt4
        const json = await JSON.parse(result);

        return json;
    }

    getFormatInstructions() {
        return 'Only the title, description and keywords of the json structure are returned. example :{"title":"","description":"","keywords":""} Please delete any other unnecessary information. Such as python code, Python Flask API, etc.  Give me json result. Do not send back any other information such as python code, Python Flask API, etc.';
    }
}

async function generateSEOMetadata(description: string, langCode: string) {
    // https://{InstanceName}.openai.azure.com/openai/deployments/my-openai-deployment/
    const model = new AzureChatOpenAI({
        azureOpenAIApiKey: 'YOUR_AZURE_OPENAI_API_KEY',
        azureOpenAIApiDeploymentName: 'YOUR_DEPLOYMENT_NAME', // gpt4
        azureOpenAIApiInstanceName: 'YOUR_INSTANCE_NAME', 
        azureOpenAIApiVersion: '2024-02-01', // '2024-02-01',
        temperature: 0, // 控制模型生成的隨機性或創造性
        maxTokens: 500, // 指定模型生成的回應中最大可用的 token(詞的數量)
    });

    const prompt = ChatPromptTemplate.fromTemplate(
        `
        You are an SEO expert. Based on the page description provided below, generate an SEO-optimized title, meta description, and keywords. Ensure that the title is engaging and concise, the meta description summarizes the product effectively while enticing users to learn more, and the keywords are relevant to the product's features and market segment. Additionally, translate all content into the language specified by the given language code.
        Company:{companyDescription}
        Ecommerce Page Description: {description}
        Translate Target Language Code: {langCode}
        FormatInstructions: {formatInstructions}
        `
    );
    const parser = new CustomOutputParser();

    const companyDescription = `NXPower GmbH markets iBUYPOWER® Computer products in Germany, aiming to offer high-quality products at reasonable prices without compromising service.
We produce custom-made PC systems tailored to individual or business needs, ensuring the best possible system within your budget. Each PC is built with care, reflecting our passion and profession.
Every custom PC includes a 3-year pickup and return warranty, extensive testing, and a 24-hour burn-in test. Our sales team ensures you only pay for components you need, and our top IT technicians provide quick assistance for any issues.
We create dream computers to impress and delight you for years. Partnering with experienced and successful online retailers, we benefit from excellent support.
`;

    const chain = prompt.pipe(model).pipe(parser);

    const response = await chain.invoke({
        companyDescription: companyDescription,
        description: description,
        langCode: langCode,
        formatInstructions: parser.getFormatInstructions(),
    });
    
    return response;
}


export default async function handler(req: NextApiRequest, res: NextApiResponse) {
    try {
        const { description = '', slug = '', forceUpdate = false, langCode = 'en' } = req.query;

        if (!description || !slug) {
            return res.status(400).json({ error: 'Description must be a valid string.' });
        }

        const redis = new RedisBase();
        const seoKey = 'SeoMata:' + langCode + ':' + genOnceEncodedURI(slug as string);

        const seoResult = await redis.get(seoKey);

        if (seoResult && !forceUpdate) {
            return res.status(200).json(JSON.parse(seoResult));
        }

        // Process the description with Langchain and Azure AI
        const metadata = await generateSEOMetadata(description as string, langCode as string);

        await redis.setCacheKey(seoKey, JSON.stringify(metadata), -1);
        // Save the metadata by slug to the database

        // return data for pre-rendering
        res.status(200).json(metadata);
    } catch (err) {
        serverSideLog('SEO Schema Error' + JSON.stringify(err), LogLevel.Error);
        return res.status(500).json({ error: err });
    }
}

在 Next 14 app route , 在頁面中的 generateMetadata 呼叫封裝好的 Azure AI 的 api

export async function generateMetadata({ params }: Props): Promise<Metadata> {
    // 構建URL

    const pathname = new URL(headers().get('x-url')!).pathname;

    const productData: IStoreModel | null = await getStoreModelData(params.locale, params.slug);

    const description = generateTitleAndDescription(productData);

    if (description === '') {
        return generateDefaultMetadata(params.locale, params.slug);
    }

    const imageUrl = (productData && getAbsoluteImageUrl(productData.desc.info.image)) || '';

    try {
        const baseUrl = process.env.NEXT_PUBLIC_BASE_URL;
        const queryParams = new URLSearchParams({
            description: description,
            langCode: params.locale,
            slug: pathname,
            // forceUpdate: 'true',
        });

        const url = `${baseUrl}/api/lang-chain/seo-schema?${queryParams.toString()}`;

        // 獲取數據
        const response = await fetch(url);
        const seoMeta = await response.json();

        const image: ImageProps = {
            url: imageUrl,
            width: 640,
            height: 640,
            alt: seoMeta.title,
        };

        // 返回Metadata
        return {
            title: seoMeta.title,
            keywords: seoMeta.keywords,
            description: seoMeta.description,
            openGraph: {
                title: seoMeta.title,
                description: seoMeta.description,
                ...(imageUrl && {
                    images: image,
                }),
            },
            twitter: {
                title: seoMeta.title,
                description: seoMeta.description,
                card: 'summary_large_image',
            },
        };
    } catch (e) {
        return generateDefaultMetadata(params.locale, pathname);
    }
}

並在 middle ware 取得 slug,並在 header 中傳遞 ``` export default function middleware(request: NextRequest) { const pathname = request.nextUrl.pathname;

request.headers.set('x-url', request.nextUrl.href);
  

return nextIntlMiddleware(request);

} ```

PS. Langchain在JS 版本的,並不是太穩定,文件蠻多都有誤的或功能和python 比有少的,且在不同模型中會跑額外的字元,得自定解析器去處理,生態也不是這麼完整,如果複雜情境使用 python 版本會比較好。

How to use

http://www.xxxx.de/api/lang-chain/seo-schema?description={page description }&langCode={translate to lang code}

Example

http://www.xxxx.de/api/lang-chain/seo-schema?description=Case:%20NZXT%20H5%20Flow%20Gaming%20Geh%C3%A4use%20-%20Schwarz%20Processor:%20AMD%20Ryzen%205%205600X%20Processor%20(6x%203.7GHz/32MB%20L3%20Cache)%20Memory:%2016GB%20DDR4/3200MHz%20Memory(G.Skill%20,Corsair,Kingston)%20Storage:%20Video%20Card:%20NVIDIA%20GeForce%20RTX%203050%20-%208GB%20GDDR6X%20(VR-Ready)%20Motherboard:%20ASRock%20B450%20PRO%204%20ATX%20USB%203.1,%20SATA3,%201x%20M.2&langCode=tw

Result 

{"title":"頂級遊戲體驗:NZXT H5 Flow 黑色遊戲機殼配備 AMD Ryzen 5 與 RTX 3050","meta_description":"探索 NZXT H5 Flow 遊戲機殼,搭載 AMD Ryzen 5 5600X 處理器、16GB DDR4 記憶體、NVIDIA GeForce RTX 3050 顯示卡,為您的遊戲體驗帶來革命性提升。立即了解更多。","keywords":"NZXT H5 Flow, 遊戲機殼, AMD Ryzen 5 5600X, 16GB DDR4, NVIDIA GeForce RTX 3050, VR準備, ASRock B450 PRO 4, 高性能遊戲電腦"}

Tags

Mark Ku

Mark Ku

Software Developer

9年以上豐富網站開發經驗,開發過各種網站,電子商務、平台網站、直播系統、POS系統、SEO 優化、金流串接、AI 串接,Infra 出身,帶過幾次團隊,也加入過大團隊一起開發。

Expertise

前端(React)
後端(C#)
網路管理
DevOps
溝通
領導

Social Media

facebook github website

Related Posts

Docker 安裝AI大型語言模型 Ollama ,並實測比較CPU與GPU硬體加速效能
Docker 安裝AI大型語言模型 Ollama ,並實測比較CPU與GPU硬體加速效能
August 26, 2024
1 min

Quick Links

關於我

Social Media