From 70cf96de20efb7953e0836216d04bcb4fe3540aa Mon Sep 17 00:00:00 2001 From: DIYgod Date: Thu, 23 Mar 2023 16:44:34 +0000 Subject: [PATCH] refactor: use a better way of summarizing --- showcase.json | 2 +- src/lib/redis.server.ts | 2 +- src/pages/api/summary.ts | 76 ++++++++++++++++++---------------------- 3 files changed, 37 insertions(+), 43 deletions(-) diff --git a/showcase.json b/showcase.json index 0102efb4..b0552455 100644 --- a/showcase.json +++ b/showcase.json @@ -8,5 +8,5 @@ 33483, 19, 50877, 33420, 50094, 49213, 33276, 50351, 42993, 50216, 50132, 45763, 50143, 43754, 32168, 500, 47399, 33538, 48951, 33471, 33396, 37223, 33458, 39133, 20004, 43625, 42787, 43258, 33462, 47109, 46939, 45701, 33233, - 37346, 40671, 33870, 33421, 51552, 51585, 51477 + 37346, 40671, 33870, 33421, 51552, 51585, 51477, 48937, 51562, 51379, 51460 ] diff --git a/src/lib/redis.server.ts b/src/lib/redis.server.ts index bb0e48c3..974efad6 100644 --- a/src/lib/redis.server.ts +++ b/src/lib/redis.server.ts @@ -42,7 +42,7 @@ export async function cacheGet(options: { redisKey = options.key } const cacheValue = await redis.get(redisKey) - if (cacheValue) { + if (cacheValue && cacheValue !== "undefined" && cacheValue !== "null") { if (!options.noUpdate) { setTimeout(() => { options.getValueFun().then((value) => { diff --git a/src/pages/api/summary.ts b/src/pages/api/summary.ts index a63478d0..3ace2317 100644 --- a/src/pages/api/summary.ts +++ b/src/pages/api/summary.ts @@ -1,59 +1,53 @@ import { NextApiRequest, NextApiResponse } from "next" -import { RecursiveCharacterTextSplitter } from "langchain/text_splitter" + +import { OpenAI } from "langchain" +import { loadSummarizationChain } from "langchain/chains" +import { PromptTemplate } from "langchain/prompts" +import { AnalyzeDocumentChain } from "langchain/chains" import { cacheGet } from "~/lib/redis.server" import { toGateway } from "~/lib/ipfs-parser" -const returnLimit = 400 -const chunkSize = 4000 - -const splitter = new RecursiveCharacterTextSplitter({ - chunkSize, - chunkOverlap: 1, +const model = new OpenAI({ + openAIApiKey: process.env.OPENAI_API_KEY, + modelName: "gpt-3.5-turbo", + temperature: 0.3, + maxTokens: 400, }) +const chains = new Map() + async function segmentedSummary( content: string, lang: string, ): Promise { - const segments = await splitter.createDocuments([content]) + let chain = chains.get(lang) + if (!chain) { + const prompt = new PromptTemplate({ + template: `Summarize this in ${lang} language: + "{text}" + CONCISE SUMMARY:`, + inputVariables: ["text"], + }) - const results: string[] = await Promise.all( - segments.map(async (segment) => { - const prompt = `Summarize this in ${lang} language in less than ${returnLimit} characters: ${segment.pageContent}` + const combineDocsChain = loadSummarizationChain(model, { + prompt, + combineMapPrompt: prompt, + combinePrompt: prompt, + }) - const response = await ( - await fetch("https://api.openai.com/v1/chat/completions", { - method: "POST", - headers: { - "Content-Type": "application/json", - Authorization: `Bearer ${process.env.OPENAI_API_KEY}`, - }, - body: JSON.stringify({ - model: "gpt-3.5-turbo-0301", - temperature: 0, - top_p: 1, - frequency_penalty: 1, - presence_penalty: 1, - messages: [ - { - role: "user", - content: prompt, - }, - ], - }), - }) - ).json() + chain = new AnalyzeDocumentChain({ + combineDocumentsChain: combineDocsChain, + }) - return response.choices?.[0]?.message?.content?.trim() - }), - ) - - if (results.length > 1) { - return segmentedSummary(results.join("\n"), lang) - } else { - return results[0] + chains.set(lang, chain) } + + const res = await chain.call({ + input_document: content, + }) + + return res?.text } export async function getSummary(cid: string, lang: string = "en") {