使用TypeScript和Weaviate构建内容生成:完整实战指南

云信安装大师
90
AI 质量分
11 5 月, 2025
5 分钟阅读
0 阅读

使用TypeScript和Weaviate构建内容生成:完整实战指南

引言

在当今内容驱动的互联网时代,如何高效地管理和生成内容成为开发者面临的挑战。本文将带你使用TypeScript和Weaviate(一个开源的向量搜索引擎)构建一个简单但强大的内容生成系统。通过本教程,你将学会:

  1. 如何设置Weaviate数据库
  2. 如何使用TypeScript与Weaviate交互
  3. 如何利用向量搜索实现智能内容生成

准备工作

环境要求

  • Node.js (v16或更高版本)
  • npm或yarn
  • Docker (用于运行Weaviate)
  • TypeScript基础知识

安装必要工具

代码片段
# 全局安装TypeScript
npm install -g typescript

# 创建一个新项目目录并初始化
mkdir content-generator && cd content-generator
npm init -y
tsc --init

第一步:设置Weaviate数据库

使用Docker启动Weaviate

代码片段
docker run -d \
  --name weaviate \
  -p 8080:8080 \
  -e QUERY_DEFAULTS_LIMIT=25 \
  -e AUTHENTICATION_ANONYMOUS_ACCESS_ENABLED=true \
  -e PERSISTENCE_DATA_PATH=/var/lib/weaviate \
  semitechnologies/weaviate:latest

参数说明:
-p 8080:8080:将容器端口映射到主机端口
AUTHENTICATION_ANONYMOUS_ACCESS_ENABLED=true:允许匿名访问(仅用于开发环境)
PERSISTENCE_DATA_PATH:指定数据存储路径

验证安装

访问 http://localhost:8080/v1/meta,你应该能看到Weaviate的元数据信息。

第二步:创建TypeScript项目结构

安装依赖

代码片段
npm install weaviate-ts-client openai dotenv axios
npm install --save-dev @types/node ts-node typescript

项目结构

代码片段
/content-generator
├── src/
│   ├── config.ts       # Weaviate配置
│   ├── schema.ts       # Weaviate模式定义
│   ├── indexer.ts      # 数据索引逻辑
│   ├── generator.ts    # 内容生成逻辑
│   └── index.ts        # 主入口文件
├── .env                # 环境变量文件
├── package.json
└── tsconfig.json

第三步:配置Weaviate客户端

src/config.ts

代码片段
import weaviate, { WeaviateClient } from 'weaviate-ts-client';
import dotenv from 'dotenv';

dotenv.config();

// Weaviate客户端配置函数
export function getWeaviateClient(): WeaviateClient {
    return weaviate.client({
        scheme: 'http',
        host: process.env.WEAVIATE_HOST || 'localhost:8080',
    });
}

// OpenAI API Key配置(用于向量化)
export const OPENAI_API_KEY = process.env.OPENAI_API_KEY;

.env文件示例

代码片段
WEAVIATE_HOST=localhost:8080
OPENAI_API_KEY=your-openai-api-key-here

注意事项:
1. OpenAI API Key需要从OpenAI官网获取(https://platform.openai.com/)
2. .env文件不应该提交到版本控制,确保添加到.gitignore中

第四步:定义数据模式(Schema)

src/schema.ts

代码片段
import { getWeaviateClient } from './config';

// Content类定义接口
interface ContentClass {
    class: string;
    properties: Array<{
        name: string;
        dataType: string[];
    }>;
}

// Content类模式定义函数
export async function createContentSchema() {
    const client = getWeaviateClient();

    const contentClassDefinition: ContentClass = {
        class: 'Content',
        properties: [
            {
                name: 'title',
                dataType: ['text'],
            },
            {
                name: 'body',
                dataType: ['text'],
            },
            {
                name: 'category',
                dataType: ['text'],
            }
        ],
    };

    try {
        // 检查类是否已存在,避免重复创建
        const schema = await client.schema.getter().do();
        const exists = schema.classes?.some(c => c.class === 'Content');

        if (!exists) {
            await client.schema.classCreator().withClass(contentClassDefinition).do();
            console.log('Content schema created successfully');
        } else {
            console.log('Content schema already exists');
        }
    } catch (err) {
        console.error('Error creating schema:', err);
    }
}

原理说明:
1. Weaviate使用模式(Schema)来定义数据结构,类似于关系型数据库的表结构。
2. Content类有三个属性:title、body和category,都是文本类型。
3. Weaviate会自动为每个对象生成向量表示(embedding),支持语义搜索。

第五步:实现数据索引功能

src/indexer.ts

代码片段
import { getWeaviateClient, OPENAI_API_KEY } from './config';

interface ContentData {
    title: string;
    body: string;
    category?: string;
}

export async function indexContent(data: ContentData) {
    const client = getWeaviateClient();

    try {
        // Weaviate会自动调用OpenAI的text-embedding模型为文本生成向量表示(embedding)
        await client.data.creator()
            .withClassName('Content')
            .withProperties({
                title: data.title,
                body: data.body,
                category: data.category || 'general'
            })
            .withVectorizer('text2vec-openai')
            .do();

        console.log(`Successfully indexed content with title "${data.title}"`);
    } catch (err) {
        console.error('Error indexing content:', err);
    }
}

// Example usage:
// indexContent({
//     title: "Introduction to AI",
//     body: "Artificial Intelligence is transforming industries...",
//     category: "Technology"
// });

实践经验分享:
1. withVectorizer('text2vec-openai')指定使用OpenAI的文本嵌入模型。
2. Weaviate会在后台自动调用OpenAI API为文本生成向量表示。
3. OpenAI API调用会产生费用,注意监控API使用情况。

第六步:实现内容生成功能

src/generator.ts

代码片段
import { getWeaviateClient, OPENAI_API_KEY } from './config';
import axios from 'axios';

interface GeneratedContent {
    title?: string;
    body?: string;
}

export async function generateRelatedContent(queryText: string): Promise<GeneratedContent> {
    const client = getWeaviateClient();

    try {
        // Step1 :从Weaviates搜索相关文档(基于语义相似度)
        const results = await client.graphql.get()
            .withClassName('Content')
            .withFields('title body category _additional { certainty }')
            .withNearText({ concepts: [queryText] })
            .withLimit(3)
            .do();

        if (!results.data.Get.Content.length) {
            return {};
        }

        // Step2 :将搜索结果作为上下文提供给GPT模型进行内容生成

        // Prepare context for GPT prompt 
        let context = '';

        results.data.Get.Content.forEach((content, index) => { 
          context += `\n\nRelated Document ${index +1}:\nTitle:"${content.title}"\nBody:"${content.body}"`;
          if (content.category) context += `\nCategory:"${content.category}"`;
          context += `\nRelevance Score:"${content._additional.certainty.toFixed(2)}"`;
          context += '\n-------------------';
         });

         // Step3 :调用OpenAI API生成新内容 
         const prompt = `
         Based on the following related documents, generate a new piece of content that expands on the topic.

         Query Topic:"${queryText}"

         Related Documents:
         ${context}

         Please generate:
         1.A compelling title for the new content.
         2.A detailed body that builds upon the existing information.
         3.If applicable, suggest a relevant category.

         Respond in JSON format with "title", "body" and "category" fields.
         `;

         const response = await axios.post(
             'https://api.openai.com/v1/chat/completions',
             { 
                 model:"gpt-3.5-turbo",
                 messages:[{ role:"user", content :prompt}],
                 temperature :0.7,
                 max_tokens :1000 
             },
             { headers:{ Authorization:`Bearer ${OPENAI_API_KEY}`} }
         );

         try{
             return JSON.parse(response.data?.choices[0]?.message?.content ||'{}');
         }catch(err){
             console.error("Error parsing GPT response:",err);
             return {};
         }

     }catch(err){
         console.error("Error generating related content:",err);
         return {};
     }
 }

/* Example usage:
generateRelatedContent("Machine Learning applications in healthcare")
.then(content=>console.log(content));
*/

工作原理详解:

  1. 语义搜索阶段

    • Weviate通过nearText查询找到与输入查询语义相似的文档。
    • certainty分数表示结果与查询的相关性程度。
  2. 上下文构建阶段
    -将搜索结果格式化后作为GPT模型的上下文提示。

  3. 内容生成阶段

    • GPT模型基于搜索结果和原始查询生成新的相关内容。
      -我们请求响应采用JSON格式以便于解析。

4.优化提示工程
-明确的结构化提示有助于获得更一致的输出格式。
-温度参数(temperature=0.7)平衡创造性和连贯性。

第七步:整合所有功能并测试

src/index.ts

代码片段
import { createContentSchema}from'./schema';
import{indexContent}from'./indexer';
import{generateRelatedContent}from'./generator';

asyncfunctionmain(){
 //Step1 :确保模式存在 
 await createContentSchema();

 //Step2 :索引一些示例数据(实际应用中可能来自CMS或数据库)
 constsampleContents=[
     { 
       title:"Getting Started with TypeScript",
       body:"TypeScript is a typed superset of JavaScript that compiles to plain JavaScript...",
       category:"Programming"
     },
     { 
       title:"Vector Databases Explained",
       body:"Vector databases are specialized storage systems designed to handle vector embeddings...",
       category:"Database"
     },
     { 
       title:"Building AI Applications with Node.js",
       body:"Node.js provides an excellent platform for building AI-powered applications...",
       category:"Artificial Intelligence"
     }
 ];

 for(constcontentofsampleContents){
     await indexContent(content);
 }

 //Step3 :测试内容生成功能 
 console.log("\nGenerating related content for query:'Modern web development trends'");
 constgenerated=await generateRelatedContent("Modern web development trends");
 console.log("\nGenerated Content:");
 console.log("Title:",generated.title||"N/A");
 console.log("Category:",generated.category||"N/A");
 console.log("Body:",generated.body||"N/A");
}

main().catch(err=>console.error("Application error:",err));

运行应用程序

首先编译TypeScript代码:

代码片段
tsc 

然后运行:

代码片段
node dist/index.js 

预期输出示例:

代码片段
Generating related content for query:'Modern web development trends'

Generated Content:
Title:The Evolution of Full Stack Development in the Modern Web Era  
Category:Ttechnology  
Body:The landscape of web development has evolved significantly in recent years...
[完整的生成内容]

最佳实践和注意事项

1.性能优化
-批量索引大量文档时使用批量操作API(batch endpoint)。
-考虑实现缓存层减少对GPT模型的重复调用。

2.错误处理增强
-添加重试逻辑处理API限流情况。
-实施回退机制当GPT不可用时返回简单的搜索结果。

3.安全考虑
-生产环境中启用Weaviates身份验证。
-限制用户输入长度防止提示注入攻击。

4.成本控制
-监控OpenAI API用量设置预算警报。
-对于大流量应用考虑缓存生成的响应。

5.质量改进方向
-添加人工审核流程验证生成的准确性。
-收集用户反馈持续优化提示工程策略。

总结

本教程展示了如何利用TypeScript和Weaviates构建一个强大的智能内容生成系统:

1.Weaviates提供了高效的向量搜索能力,能够找到语义相关的文档。
2.TypeScript的类型系统确保了代码的健壮性和可维护性。
3.OpenAI的GPT模型赋予系统创造性内容生成能力。

这种架构可以扩展应用于多种场景如:
-知识库增强的内容创作助手
-个性化推荐系统
-自动化的SEO内容优化

下一步可以探索:
1.Weaviates的多模态能力处理图像和视频内容
2.GPT4等更先进的模型提升质量
3.RAG(Retrieval-Augmented Generation)架构优化

希望这篇指南为你提供了坚实的基础!

原创 高质量