haixunMaster/lib/ai/optimize-post.ts

75 lines
2.5 KiB
TypeScript
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import { z } from "zod";
import type { ProviderApiKeys } from "./keys";
import { generateStructuredObject } from "./generate-structured";
import { getModel } from "./provider";
import { HASHTAG_WRITING_RULES } from "./hashtag-rules";
import { buildSystemPrompt } from "./prompts";
import { THREADS_MAX_CHARS } from "@/lib/utils";
export type OptimizeMode = "polish" | "hook" | "shorter" | "engaging" | "custom";
const MODE_INSTRUCTIONS: Record<Exclude<OptimizeMode, "custom">, string> = {
polish: "整體潤飾:改善語氣流暢度、可讀性與說服力,保留核心觀點。",
hook: "強化開頭 hook讓前 12 句更有吸引力,讓人想停下來看。",
shorter: "精簡篇幅:刪除贅字,保留重點,盡量壓到更短但不失完整。",
engaging: "提升互動感:加入引發留言的問句、觀點或行動呼籲,但不過度推銷。",
};
const optimizeSchema = z.object({
text: z.string().max(THREADS_MAX_CHARS),
summary: z.string(),
});
export interface OptimizeInput {
text: string;
mode?: OptimizeMode;
instruction?: string | null;
persona?: string | null;
angle?: string | null;
aiProvider: string;
aiModel: string;
apiKeys?: ProviderApiKeys;
}
export async function optimizePost(input: OptimizeInput) {
const mode = input.mode ?? "polish";
const modeInstruction =
mode === "custom"
? input.instruction?.trim() || "依照使用者指示優化貼文。"
: MODE_INSTRUCTIONS[mode];
const model = getModel(input.aiProvider, input.aiModel, input.apiKeys ?? {});
const object = await generateStructuredObject({
model,
provider: input.aiProvider,
modelId: input.aiModel,
schema: optimizeSchema,
system: `${buildSystemPrompt(input.persona)}
你現在的任務是「優化既有 Threads 貼文草稿」,不是從零重寫。
- 保留原文核心觀點與事實,不要捏造
- 優化後必須更符合上方人設,尤其語氣與代表句範例的語感
- 保留或補上結尾的 13 個 #話題標籤,不要優化掉
${HASHTAG_WRITING_RULES}
- 輸出繁體中文台灣用語
- 字數必須 ≤ ${THREADS_MAX_CHARS}
- summary 用 12 句話說明你做了什麼調整`,
prompt: `請優化以下 Threads 貼文草稿。
優化方向:${modeInstruction}
${input.angle ? `切入角度:${input.angle}` : ""}
原文:
"""
${input.text}
"""
請輸出優化後的貼文text與調整說明summary`,
});
return {
text: object.text.slice(0, THREADS_MAX_CHARS),
summary: object.summary,
};
}