通用基础项目
9. 使用AI自动生成内容
会员专享 · 非会员仅可阅读 30% 的正文。
- 发布时间
- May 17, 2025
- 阅读时间
- 8 min read
- 作者
- Felix
- 访问
- 会员专享
这是预览内容
非会员仅可阅读 30% 的正文。
上一节讲了登录,这一节就讲AI自动生成文章内容,需要生成文章内容的核心原因:页面太少在Google没流量,需要长期的内容更新才有流量。
创建表结构完成后端接口
这一段表结构添加到lib/db/schema.ts,用于描述发布的文章。
export const posts = sqliteTable('posts', {
id: text('id')
.primaryKey()
.$defaultFn(() => crypto.randomUUID()),
slug: text('slug').notNull().unique(),
title: text('title').notNull(),
excerpt: text('excerpt').notNull(),
content: text('content').notNull(),
locale: text('locale').notNull().default('en'),
publishedAt: integer('published_at', { mode: 'timestamp_ms' }),
createdAt: integer('created_at', { mode: 'timestamp_ms' })
.default(sql`CURRENT_TIMESTAMP`)
.notNull(),
updatedAt: integer('updated_at', { mode: 'timestamp_ms' })
.default(sql`CURRENT_TIMESTAMP`)
.notNull()
})
```
上面定义的表结构包含以下字段:
- id: 文章的唯一标识符,使用UUID自动生成
- slug: 文章的URL,用于在网址中显示,必须唯一
- title: 文章标题,用于MetaTitle
- excerpt: 文章摘要,用于MetaDescription
- content: 文章的完整内容,存储为Markdown
- locale: 文章的语言,默认为英文('en'),、
- publishedAt: 文章发布时间,可为null表示未发布的草稿
- createdAt: 文章创建时间,自动设置为当前时间戳
- updatedAt: 文章最后更新时间,自动设置为当前时间戳
> 值得关注的点是关于语言的设置,显然文章是需要做I18n的,但不用每篇文章都AI硬翻译成不同的意义,最佳实践:是针对不同的国家的关键词去完成文章生成。
紧接着执行`pnpm db:migrate-local`把本地的表先生成了,接下来完成后端的Api编写。
## 完成Api的编写
在`actions`里面添加`ai-content.ts`文件,这里就包含所有与AI内容生成相关的服务器端函数,值得注意的开发小习惯是:`尽量拆细一点,按照功能拆分`。
首先是`generateArticle`,这个函数是我们AI文章生成的核心,大部分都是常规逻辑,但是有一些地方需要我们关注一下:
1. 关于Prompt的写法,有一套最常用的模版,以Markdown的结构和层级来表示要求和重点,在开头完成角色定位,在结尾完成输出约束。
2. 在大多数场景都可以不要求强制以JSON输出,这会影响AI的自由度和输出,并且会遇到难以 `JSON.Parse` 的情况,采用以正则提取的方式是更好的选择。
3. 注意看这段价值万金的提示词:`Please use "keywords" as the keyword to search the first 20 search results on Google, and record their article structure and titles. Then, based on these contents, output an article that conforms to Google SEO logic and user experience. `
这一句并不会真正的去联网搜索,但是我们想象一下AI的数据本身就是从各大搜索引擎爬取的,这样写提示词的方式会引导查找向量在它的大数据中的近似坐标附近进行输出和查找答案。(有点绕,Prompt本身就是不停帮助模型在它的大宇宙中修正坐标的,简单的理解这么写一句输出会好很多)
4. `typeof analysisResult === 'object'`这个写法是帮助TS类型推导。
5. I18n在有些语言需要在提示词中特别声明。
6. 这个提示词有很大的优化空间,好点的模型可以把具体的SEO的最佳文章实践和要求都写进去,这种低参数模型只能泛提示词了(不遵守细规则)。
```typescript
'use server'
import { desc, eq } from 'drizzle-orm'
import { locales } from '@/i18n/routing'
import { createAI } from '@/lib/ai'
import { createDb } from '@/lib/db'
import { posts } from '@/lib/db/schema'
interface ArticleGenerationParams {
keyword: string
locale?: string
}
interface BatchArticleGenerationParams {
keywords: string[]
locale?: string
}
function getLanguageNameFromLocale(localeCode: string): string {
const locale = locales.find((l) => l.code === localeCode)
if (locale) {
return locale.name
}
return 'English'
}
export async function generateArticle({ keyword, locale = 'en' }: ArticleGenerationParams) {
const languageName = getLanguageNameFromLocale(locale)
const systemPrompt = `
You are an SEO content writer. Your job is write blog post optimized for keyword, title and outline. Please use "keywords" as the keyword to search the first 20 search results on Google, and record their article structure and titles. Then, based on these contents, output an article that conforms to Google SEO logic and user experience.
Format requirements:
- Start with a single H1 title (# Title) that is EXACTLY 50 characters or less
- The title must include the main keyword and be compelling for readers
- Use markdown formatting with proper heading structure (# for H1, ## for H2, etc.)
- Include well-formatted paragraphs, lists, and other elements as appropriate
- Maintain a professional, informative tone
SEO requirements:
- Make the first paragraph suitable for a meta description
- Answer common user questions related to the topic in a conversational tone
- Write in a natural, flowing style that mimics human writing patterns with varied sentence structures
- Avoid obvious AI patterns like excessive lists and formulaic paragraph structures
- Incorporate personal anecdotes, analogies, and relatable examples where appropriate
- Include the most up-to-date information and recent developments on the topic
- Ensure comprehensive coverage with sufficient depth (minimum 1500 words)
Language requirement:
- Write the entire article in ${languageName} language
- Ensure the content is culturally appropriate for ${languageName}-speaking audiences
- Use proper grammar, idioms, and expressions specific to ${languageName}
${locale === 'ar' ? '- Follow right-to-left (RTL) text conventions' : ''}
IMPORTANT: At the very end of your response, include two separate sections:
1. "META_DESCRIPTION:" followed by a concise, SEO-friendly excerpt (130-140 characters max) that includes the main keyword naturally.
2. "URL_SLUG:" followed by an SEO-friendly URL slug会员专享
订阅后解锁完整文章
支持创作、解锁全文,未来更新也会第一时间送达。
评论
加入讨论
登录后评论
还没有评论,来占个沙发吧。