Diseñar un algoritmo basado en LLM para organizar subtítulos en párrafos y capítulos.
De Wikiprompt, la enciclopedia libre de prompts
Diseñar un algoritmo basado en LLM para organizar subtítulos en párrafos y capítulos. Una solicitud detallada pidiendo diseñar un algoritmo usando LLM para organizar segmentos de subtítulos en párrafos y capítulos, con restricciones específicas sobre la ventana de contexto, la paginación, el costo y el formato de salida.
Contenido del PromptGuardar
🌐
// 算法设计:基于大语言模型的字幕分段分章算法
interface SubtitleSegment {
start: number;
end: number;
text: string;
words: { word: string; start: number; end: number }[];
}
interface Subtitle {
segments: SubtitleSegment[];
}
interface Paragraph {
start: number;
end: number;
text: string;
segments: SubtitleSegment[];
}
interface Chapter {
title: string;
paragraphs: Paragraph[];
}
interface Transcription {
chapters: Chapter[];
}
// 分页策略:基于字符数或段数,保留上下文重叠
const PAGE_SIZE = 3000; // 每页字符数
const OVERLAP_SIZE = 500; // 重叠字符数,用于保持上下文连贯
function paginateSegments(segments: SubtitleSegment[]): SubtitleSegment[][] {
const pages: SubtitleSegment[][] = [];
let currentPage: SubtitleSegment[] = [];
let currentLength = 0;
for (const segment of segments) {
const segmentLength = segment.text.length;
// 如果当前页超过大小且已有内容,开始新页
if (currentLength + segmentLength > PAGE_SIZE && currentPage.length > 0) {
// 添加重叠部分:从当前页末尾取一部分段落到新页开头
const overlapSegments = getOverlapSegments(currentPage, OVERLAP_SIZE);
pages.push(currentPage);
currentPage = [...overlapSegments];
currentLength = overlapSegments.reduce((sum, seg) => sum + seg.text.length, 0);
}
currentPage.push(segment);
currentLength += segmentLength;
}
if (currentPage.length > 0) {
pages.push(currentPage);
}
return pages;
}
function getOverlapSegments(segments: SubtitleSegment[], overlapChars: number): SubtitleSegment[] {
const result: SubtitleSegment[] = [];
let totalLength = 0;
// 从末尾向前收集段落到达到重叠字符数
for (let i = segments.length - 1; i >= 0; i--) {
result.unshift(segments[i]);
totalLength += segments[i].text.length;
if (totalLength >= overlapChars) break;
}
return result;
}
// 大语言模型调用函数(模拟)
async function callLLMForChapters(
pageSegments: SubtitleSegment[],
previousContext: { title: string; lastParagraphText: string } | null
): Promise<{ chapters: { title: string; paragraphIndices: number[] }[] }> {
// 构建提示词,包含上下文信息
const prompt = buildPrompt(pageSegments, previousContext);
// 调用LLM,要求返回JSON格式的章节和段落索引映射
// 注意:不要求LLM输出字符位置,只输出段落索引
const response = await llmAPI(prompt);
// 解析响应,处理可能的格式错误
return parseLLMResponse(response);
}
function buildPrompt(
pageSegments: SubtitleSegment[],
previousContext: { title: string; lastParagraphText: string } | null
): string {
let prompt = `请分析以下字幕内容,将其组织成章节(Chapter)和段落(Paragraph)。\n\n`;
if (previousContext) {
prompt += `上一页的上下文信息:\n`;
prompt += `上一章节标题:${previousContext.title}\n`;
prompt += `上一段落结尾:${previousContext.lastParagraphText}\n\n`;
prompt += `请注意,如果当前内容与上一章节主题连续,请继续使用相同章节标题。\n\n`;
}
prompt += `字幕内容(每行格式:索引: 文本):\n`;
pageSegments.forEach((seg, index) => {
prompt += `${index}: ${seg.text}\n`;
});
prompt += `\n请返回JSON格式结果:\n`;
prompt += `{
"chapters": [
{
"title": "章节标题",
"paragraphIndices": [[startIndex, endIndex], [startIndex, endIndex]]
}
]
}\n`;
prompt += `其中paragraphIndices中的每个[startIndex, endIndex]表示一个段落包含的字幕索引范围。\n`;
prompt += `注意:\n`;
prompt += `1. 只返回索引范围,不要返回文本内容\n`;
prompt += `2. 索引范围必须连续\n`;
prompt += `3. 如果内容与上一章节连续,使用相同标题\n`;
return prompt;
}
// 主算法
async function segmentToTranscription(subtitle: Subtitle): Promise<Transcription> {
const pages = paginateSegments(subtitle.segments);
const allChapters: Chapter[] = [];
let previousContext: { title: string; lastParagraphText: string } | null = null;
for (const page of pages) {
// 调用LLM获取该页的章节和段落结构
const llmResult = await callLLMForChapters(page, previousContext);
// 将LLM返回的索引映射到实际的SubtitleSegment
const pageChapters: Chapter[] = [];
for (const llmChapter of llmResult.chapters) {
const paragraphs: Paragraph[] = [];
for (const [startIdx, endIdx] of llmChapter.paragraphIndices) {
// 确保索引在有效范围内
const validStart = Math.max(0, startIdx);
const validEnd = Math.min(page.length - 1, endIdx);
if (validStart > validEnd) continue;
const paragraphSegments = page.slice(validStart, validEnd + 1);
const paragraph: Paragraph = {
start: paragraphSegments[0].start,
end: paragraphSegments[paragraphSegments.length - 1].end,
text: paragraphSegments.map(seg => seg.text).join(' '),
segments: paragraphSegments
};
paragraphs.push(paragraph);
}
if (paragraphs.length > 0) {
const chapter: Chapter = {
title: llmChapter.title,
paragraphs
};
pageChapters.push(chapter);
}
}
// 合并章节:如果与上一页的最后一个章节标题相同,则合并
if (previousContext && pageChapters.length > 0) {
const lastChapter = allChapters[allChapters.length - 1];
const firstPageChapter = pageChapters[0];
if (lastChapter.title === firstPageChapter.title) {
// 合并段落
lastChapter.paragraphs.push(...firstPageChapter.paragraphs);
pageChapters.shift(); // 移除已合并的章节
}
}
allChapters.push(...pageChapters);
// 更新上下文信息
if (allChapters.length > 0) {
const lastChapter = allChapters[allChapters.length - 1];
const lastParagraph = lastChapter.paragraphs[lastChapter.paragraphs.length - 1];
previousContext = {
title: lastChapter.title,
lastParagraphText: lastParagraph ? lastParagraph.text.slice(-200) : ''
};
}
}
return { chapters: allChapters };
}
// 辅助函数:解析LLM响应,处理可能的格式错误
function parseLLMResponse(response: string): { chapters: { title: string; paragraphIndices: number[][] }[] } {
try {
// 尝试直接解析JSON
return JSON.parse(response);
} catch {
// 如果解析失败,尝试提取JSON部分
const jsonMatch = response.match(/\{[\s\S]*\}/);
if (jsonMatch) {
try {
return JSON.parse(jsonMatch[0]);
} catch {
// 如果仍然失败,返回空结果
return { chapters: [] };
}
}
return { chapters: [] };
}
}
// 模拟LLM API调用
async function llmAPI(prompt: string): Promise<string> {
// 实际实现中,这里会调用真实的LLM API
// 返回示例JSON
return JSON.stringify({
chapters: [
{
title: "第一章",
paragraphIndices: [[0, 5], [6, 12]]
},
{
title: "第二章",
paragraphIndices: [[13, 20]]
}
]
});
}
```
## 算法设计说明
### 1. 分页策略
- **基于字符数分页**:每页约3000字符,确保在LLM上下文窗口内
- **重叠机制**:每页末尾500字符与下一页开头重叠,保证章节连续性
- **段落完整性**:分页时不会切断单个字幕段
### 2. 上下文连贯性处理
- **重叠分页**:通过重叠部分,LLM能看到上一页的结尾内容
- **上下文传递**:将上一页的章节标题和最后段落文本传给下一页
- **章节合并**:如果相邻页的章节标题相同,自动合并
### 3. 避免LLM数数问题
- **只返回索引**:要求LLM返回段落索引范围,而非字符位置
- **索引验证**:代码中验证索引范围的有效性
- **容错处理**:解析JSON失败时返回空结果
### 4. 成本优化
- **单次调用**:每页只调用一次LLM,同时返回章节和段落结构
- **减少传输**:只传输字幕文本和索引,不传输重复数据
- **重叠最小化**:重叠部分控制在500字符,平衡上下文和成本
### 5. 数据完整性
- **段落重建**:根据索引从原始数据重建段落,避免LLM删减文字
- **时间戳保留**:段落和章节保留原始时间戳范围
- **文本拼接**:段落文本由原始字幕段拼接,保证准确性
Iniciá sesión para ver el prompt completo
Continuar con:
Al iniciar sesión, aceptás nuestros Términos de uso y Política de privacidad
Uso
Este prompt está diseñado para usarse con coding. Copiá el contenido de arriba y pegalo en tu herramienta de IA preferida.
Para mejores resultados, personalizá los marcadores (indicados con corchetes o mayúsculas) con tus requisitos específicos.
Referencias
- Categoría: Prompts de coding
- Fuente: https://x.com/dotey/status/1869793040484741269
Discusión
0 comentarios