update
This commit is contained in:
396
prompts/src/module/sentence-perfect.ts
Normal file
396
prompts/src/module/sentence-perfect.ts
Normal file
@@ -0,0 +1,396 @@
|
||||
import { config } from './config.ts';
|
||||
import { readFileSync, writeFileSync } from 'node:fs';
|
||||
import { Kevisual } from '@kevisual/ai';
|
||||
|
||||
// ============================================
|
||||
// AI优化提示词配置
|
||||
// ============================================
|
||||
|
||||
// 通用哲理句优化提示词
|
||||
export const PERFECT_PROMPT = `你是一个深谙人生哲理的作家。请将以下不完整的哲理句补充完整,使其成为一句发人深省的哲理名言。
|
||||
|
||||
要求:
|
||||
1. 保持原句的核心主题和结构
|
||||
2. 语言要简洁有力,富有哲理深度
|
||||
3. 让人读后有所思考和共鸣
|
||||
4. 符合中文表达习惯
|
||||
5. 字数控制在20-50字之间
|
||||
|
||||
原句:{{sentence}}
|
||||
|
||||
请直接输出优化后的句子,不需要任何解释。`;
|
||||
|
||||
// 不同主题的专项优化提示词
|
||||
export const THEME_PROMPTS: Record<string, string> = {
|
||||
人生: `你是一个智慧的导师。请将以下关于人生的句子优化成一句深刻的人生感悟:
|
||||
|
||||
要求:
|
||||
- 语言平实却蕴含智慧
|
||||
- 让人读后有所触动
|
||||
- 适合作为人生格言
|
||||
|
||||
原句:{{sentence}}
|
||||
|
||||
直接输出优化后的句子。`,
|
||||
|
||||
时间: `你是一个洞察时光的智者。请将以下关于时间的句子优化:
|
||||
|
||||
要求:
|
||||
- 体现时间的珍贵与无情
|
||||
- 让人珍惜当下
|
||||
- 富有诗意但不晦涩
|
||||
|
||||
原句:{{sentence}}
|
||||
|
||||
直接输出优化后的句子。`,
|
||||
|
||||
成长: `你是一个经历过蜕变的智者。请将以下关于成长的句子优化:
|
||||
|
||||
要求:
|
||||
- 体现成长的代价与收获
|
||||
- 让人对成长有新的理解
|
||||
- 有力量感但不鸡汤
|
||||
|
||||
原句:{{sentence}}
|
||||
|
||||
直接输出优化后的句子。`,
|
||||
|
||||
孤独: `你是一个深刻理解孤独的人。请将以下关于孤独的句子优化:
|
||||
|
||||
要求:
|
||||
- 准确描述孤独的本质
|
||||
- 不是消极,而是清醒
|
||||
- 让人学会与孤独和解
|
||||
|
||||
原句:{{sentence}}
|
||||
|
||||
直接输出优化后的句子。`,
|
||||
|
||||
爱: `你是一个懂得爱的人。请将以下关于爱的句子优化:
|
||||
|
||||
要求:
|
||||
- 体现爱的真谛
|
||||
- 不是空洞的情话
|
||||
- 让人对爱有新的认识
|
||||
|
||||
原句:{{sentence}}
|
||||
|
||||
直接输出优化后的句子。`,
|
||||
|
||||
选择: `你是一个善于抉择的人。请将以下关于选择的句子优化:
|
||||
|
||||
要求:
|
||||
- 体现选择的重量
|
||||
- 不是教条,而是智慧
|
||||
- 让人更慎重地面对选择
|
||||
|
||||
原句:{{sentence}}
|
||||
|
||||
直接输出优化后的句子。`,
|
||||
|
||||
自由: `你是一个追求自由的人。请将以下关于自由的句子优化:
|
||||
|
||||
要求:
|
||||
- 准确描述自由的真谛
|
||||
- 让人理解自由的代价
|
||||
- 有深度但不晦涩
|
||||
|
||||
原句:{{sentence}}
|
||||
|
||||
直接输出优化后的句子。`,
|
||||
|
||||
痛苦: `你是一个从痛苦中走过来的人。请将以下关于痛苦的句子优化:
|
||||
|
||||
要求:
|
||||
- 不是宣泄负面情绪
|
||||
- 而是让人从痛苦中获得力量
|
||||
- 转化痛苦为成长
|
||||
|
||||
原句:{{sentence}}
|
||||
|
||||
直接输出优化后的句子。`
|
||||
};
|
||||
|
||||
// ============================================
|
||||
// AI客户端接口
|
||||
// ============================================
|
||||
|
||||
export interface PerfectOptions {
|
||||
/** Kevisual AI 实例 */
|
||||
ai?: Kevisual;
|
||||
/** 使用的提示词模板 */
|
||||
promptTemplate?: string;
|
||||
/** 并发请求数 */
|
||||
concurrency?: number;
|
||||
/** 重试次数 */
|
||||
retryTimes?: number;
|
||||
/** 成功后回调 */
|
||||
onSuccess?: (item: PerfectItem) => void;
|
||||
/** 失败后回调 */
|
||||
onError?: (item: PerfectError) => void;
|
||||
/** 进度回调 */
|
||||
onProgress?: (progress: ProgressInfo) => void;
|
||||
}
|
||||
|
||||
export interface PerfectItem {
|
||||
index: number;
|
||||
text: string;
|
||||
template: string;
|
||||
templateType: string;
|
||||
optimized: string;
|
||||
prompt?: string;
|
||||
theme: string;
|
||||
tags: string[];
|
||||
}
|
||||
|
||||
export interface PerfectError {
|
||||
index: number;
|
||||
original: string;
|
||||
error: string;
|
||||
theme: string;
|
||||
}
|
||||
|
||||
export interface ProgressInfo {
|
||||
current: number;
|
||||
total: number;
|
||||
percentage: number;
|
||||
successCount: number;
|
||||
errorCount: number;
|
||||
}
|
||||
|
||||
// ============================================
|
||||
// 默认AI实例
|
||||
// ============================================
|
||||
|
||||
function createDefaultAI(): Kevisual {
|
||||
return new Kevisual({
|
||||
apiKey: config.KEVISUAL_NEW_API_KEY || '',
|
||||
});
|
||||
}
|
||||
|
||||
// ============================================
|
||||
// 句子优化器类
|
||||
// ============================================
|
||||
|
||||
export class SentencePerfect {
|
||||
private options: Required<PerfectOptions>;
|
||||
private ai: Kevisual;
|
||||
|
||||
constructor(options: PerfectOptions = {}) {
|
||||
this.ai = options.ai || createDefaultAI();
|
||||
|
||||
this.options = {
|
||||
ai: this.ai,
|
||||
promptTemplate: options.promptTemplate || PERFECT_PROMPT,
|
||||
concurrency: options.concurrency ?? 5,
|
||||
retryTimes: options.retryTimes ?? 3,
|
||||
onSuccess: options.onSuccess || (() => { }),
|
||||
onError: options.onError || (() => { }),
|
||||
onProgress: options.onProgress || (() => { })
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取主题对应的提示词
|
||||
*/
|
||||
private getThemePrompt(theme: string, sentence: string): string {
|
||||
const themePrompt = THEME_PROMPTS[theme];
|
||||
if (themePrompt) {
|
||||
return themePrompt.replace('{{sentence}}', sentence);
|
||||
}
|
||||
return this.options.promptTemplate.replace('{{sentence}}', sentence);
|
||||
}
|
||||
|
||||
/**
|
||||
* 优化单条句子(带重试)
|
||||
*/
|
||||
async perfectOne(item: PerfectItem): Promise<PerfectItem> {
|
||||
const prompt = this.getThemePrompt(item.theme, item.text);
|
||||
let lastError: Error | null = null;
|
||||
|
||||
for (let i = 0; i < this.options.retryTimes; i++) {
|
||||
try {
|
||||
await this.ai.chat([{ role: 'user', content: prompt }]);
|
||||
let optimized = this.ai.responseText || '';
|
||||
optimized = optimized.trim().replace(/^["']|["']$/g, '');
|
||||
|
||||
const result: PerfectItem = {
|
||||
...item,
|
||||
prompt: prompt,
|
||||
optimized: optimized || item.text
|
||||
};
|
||||
|
||||
this.options.onSuccess(result);
|
||||
return result;
|
||||
} catch (error) {
|
||||
lastError = error as Error;
|
||||
await new Promise(resolve => setTimeout(resolve, 1000 * (i + 1)));
|
||||
}
|
||||
}
|
||||
|
||||
const error: PerfectError = {
|
||||
index: item.index,
|
||||
original: item.text,
|
||||
error: lastError?.message || '未知错误',
|
||||
theme: item.theme
|
||||
};
|
||||
|
||||
this.options.onError(error);
|
||||
return {
|
||||
...item,
|
||||
optimized: item.text
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* 批量优化句子
|
||||
*/
|
||||
async perfectBatch(
|
||||
items: PerfectItem[]
|
||||
): Promise<PerfectItem[]> {
|
||||
const total = items.length;
|
||||
let successCount = 0;
|
||||
let errorCount = 0;
|
||||
const results: PerfectItem[] = [];
|
||||
|
||||
const batchSize = this.options.concurrency;
|
||||
|
||||
for (let i = 0; i < items.length; i += batchSize) {
|
||||
const batch = items.slice(i, i + batchSize);
|
||||
|
||||
const promises = batch.map(async (item) => {
|
||||
try {
|
||||
const result = await this.perfectOne(item);
|
||||
results.push(result);
|
||||
successCount++;
|
||||
} catch {
|
||||
errorCount++;
|
||||
}
|
||||
|
||||
const current = Math.min(i + batchSize, total);
|
||||
const percentage = Math.round((current / total) * 100);
|
||||
|
||||
this.options.onProgress({
|
||||
current,
|
||||
total,
|
||||
percentage,
|
||||
successCount,
|
||||
errorCount
|
||||
});
|
||||
});
|
||||
|
||||
await Promise.all(promises);
|
||||
|
||||
if (i + batchSize < items.length) {
|
||||
await new Promise(resolve => setTimeout(resolve, 1000));
|
||||
}
|
||||
}
|
||||
|
||||
return results;
|
||||
}
|
||||
|
||||
/**
|
||||
* 从文件加载句子并优化
|
||||
*/
|
||||
async perfectFromFile(
|
||||
inputPath: string,
|
||||
outputPath: string
|
||||
): Promise<{ success: number; failed: number; results: any[] }> {
|
||||
const data = JSON.parse(readFileSync(inputPath, 'utf-8'));
|
||||
const sentences = data.sentences || data;
|
||||
|
||||
const items: PerfectItem[] = sentences.map((s: any, i: number) => ({
|
||||
index: s.index || i + 1,
|
||||
text: s.text || s,
|
||||
template: s.template || '',
|
||||
templateType: s.templateType || '',
|
||||
theme: s.theme || '人生',
|
||||
tags: s.tags || [],
|
||||
optimized: ''
|
||||
}));
|
||||
|
||||
const results = await this.perfectBatch(items);
|
||||
|
||||
// 合并原始数据与优化结果
|
||||
const mergedResults = results.map((r, i) => {
|
||||
return {
|
||||
index: r.index,
|
||||
text: r.text,
|
||||
template: r.template,
|
||||
templateType: r.templateType,
|
||||
theme: r.theme,
|
||||
tags: r.tags,
|
||||
optimized: r.optimized
|
||||
};
|
||||
});
|
||||
|
||||
const successResults = results.filter(r => r.optimized !== r.text);
|
||||
const failedResults = results.filter(r => r.optimized === r.text);
|
||||
|
||||
const output = {
|
||||
meta: {
|
||||
total: results.length,
|
||||
success: successResults.length,
|
||||
failed: failedResults.length,
|
||||
optimizedAt: new Date().toISOString()
|
||||
},
|
||||
sentences: mergedResults
|
||||
};
|
||||
|
||||
writeFileSync(outputPath, JSON.stringify(output, null, 2), 'utf-8');
|
||||
|
||||
return {
|
||||
success: successResults.length,
|
||||
failed: failedResults.length,
|
||||
results: mergedResults
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置AI实例
|
||||
*/
|
||||
setAI(ai: Kevisual): void {
|
||||
this.ai = ai;
|
||||
this.options.ai = ai;
|
||||
}
|
||||
}
|
||||
|
||||
// ============================================
|
||||
// 便捷函数
|
||||
// ============================================
|
||||
|
||||
/**
|
||||
* 快速优化单条句子
|
||||
*/
|
||||
export async function quickPerfect(
|
||||
sentence: string,
|
||||
theme: string = '人生'
|
||||
): Promise<string> {
|
||||
const perfect = new SentencePerfect();
|
||||
const item: PerfectItem = {
|
||||
index: 0,
|
||||
text: sentence,
|
||||
template: '',
|
||||
templateType: '',
|
||||
theme,
|
||||
tags: [],
|
||||
optimized: ''
|
||||
};
|
||||
const result = await perfect.perfectOne(item);
|
||||
return result.optimized;
|
||||
}
|
||||
|
||||
/**
|
||||
* 从JSON文件优化句子
|
||||
*/
|
||||
export async function perfectFromJSON(
|
||||
inputPath: string,
|
||||
outputPath: string,
|
||||
options: Partial<PerfectOptions> = {}
|
||||
): Promise<{ success: number; failed: number }> {
|
||||
const perfect = new SentencePerfect(options);
|
||||
const result = await perfect.perfectFromFile(inputPath, outputPath);
|
||||
return { success: result.success, failed: result.failed };
|
||||
}
|
||||
|
||||
export default SentencePerfect;
|
||||
Reference in New Issue
Block a user