热门角色不仅是灵感来源,更是你的效率助手。通过精挑细选的角色提示词,你可以快速生成高质量内容、提升创作灵感,并找到最契合你需求的解决方案。让创作更轻松,让价值更直接!
我们根据不同用户需求,持续更新角色库,让你总能找到合适的灵感入口。
本提示词专为JavaScript开发场景设计,能够根据用户指定的属性自动生成符合最佳实践的对象结构。通过精确的参数化输入,确保生成的代码具备技术准确性、结构清晰性和规范性。支持多种对象类型和属性配置,适用于前端开发、数据建模和教学演示等场景,帮助开发者快速构建高质量的JavaScript对象代码。
/**
* Blog Post object toolkit for CMS forms, preview, and local-storage sync.
* - ES2020+ compatible, browser-first.
* - Provides: factory, validation, update helpers, preview, and draft storage.
*/
/**
* @typedef {Object} BlogPost
* @property {string} title // 文章标题
* @property {string} slug // URL 友好的标识符(根据标题生成,或手动设置)
* @property {string} content // 正文(纯文本/Markdown/HTML)
* @property {string} summary // 摘要(若为空则从 content 推导)
* @property {string[]} tags // 标签(去重、裁剪空白)
* @property {string} authorName // 作者显示名
* @property {string} authorId // 作者唯一标识
* @property {string} coverUrl // 封面图 URL
* @property {boolean} published // 是否发布
* @property {string} createdAt // ISO 8601 创建时间
* @property {string} updatedAt // ISO 8601 更新时间
*/
// -------------------- Utilities --------------------
const toISO = (date = new Date()) => new Date(date).toISOString();
/**
* Create a URL-friendly slug from title or input.
* - lowercases, trims, removes diacritics, keeps a-z0-9 and hyphens.
*/
function slugify(input, maxLength = 80) {
const s = String(input ?? '')
.trim()
.toLowerCase()
.normalize('NFKD') // split diacritics
.replace(/[\u0300-\u036f]/g, '')// remove diacritics marks
.replace(/[^a-z0-9]+/g, '-') // non-alnum => hyphen
.replace(/^-+|-+$/g, '') // trim hyphens
.slice(0, maxLength);
return s || 'untitled';
}
/**
* Strip HTML to plain text (safe in browser using DOMParser; falls back to regex).
*/
function stripHTML(html) {
if (typeof window !== 'undefined' && typeof DOMParser !== 'undefined') {
const doc = new DOMParser().parseFromString(String(html ?? ''), 'text/html');
return doc.body.textContent || '';
}
// Fallback (non-browser)
return String(html ?? '').replace(/<[^>]*>/g, ' ');
}
/**
* Derive a summary from summary/content with max length and ellipsis.
*/
function deriveSummary({ summary, content }, maxLen = 160) {
if (typeof summary === 'string' && summary.trim()) return summary.trim();
const text = stripHTML(content).replace(/\s+/g, ' ').trim();
if (!text) return '';
return text.length > maxLen ? text.slice(0, maxLen - 1).trimEnd() + '…' : text;
}
/**
* Normalize tags: trim, remove empty, de-duplicate, optional limit.
*/
function normalizeTags(tags = [], max = 50) {
const out = [];
const seen = new Set();
for (const t of tags) {
if (typeof t !== 'string') continue;
const v = t.trim();
if (!v || seen.has(v)) continue;
out.push(v);
seen.add(v);
if (out.length >= max) break;
}
return out;
}
/**
* Quick word count-based reading time (optional helper for UI).
*/
function estimateReadingTime(text, wordsPerMin = 250) {
const words = String(stripHTML(text)).trim().split(/\s+/).filter(Boolean).length;
const mins = Math.max(1, Math.ceil(words / Math.max(100, wordsPerMin)));
return { minutes: mins, words };
}
// -------------------- Factory & Validation --------------------
/**
* Create a new BlogPost with sane defaults and normalization.
* @param {Partial<BlogPost>} initial
* @returns {BlogPost}
*/
function createBlogPost(initial = {}) {
const now = toISO();
const title = String(initial.title ?? '').trim();
const createdAt = (typeof initial.createdAt === 'string' && !Number.isNaN(Date.parse(initial.createdAt)))
? new Date(initial.createdAt).toISOString()
: now;
const content = String(initial.content ?? '');
const post = {
title,
slug: slugify(initial.slug || title),
content,
summary: deriveSummary({ summary: initial.summary, content }),
tags: normalizeTags(initial.tags),
authorName: String(initial.authorName ?? ''),
authorId: String(initial.authorId ?? ''),
coverUrl: String(initial.coverUrl ?? ''),
published: Boolean(initial.published),
createdAt,
updatedAt: now,
};
return post;
}
/**
* Validate a BlogPost object. Returns {valid, errors[]}
* - Type checks, ISO date checks, basic slug rules.
*/
function validateBlogPost(post) {
const errors = [];
const isString = (v) => typeof v === 'string';
const mustString = ['title', 'slug', 'content', 'summary', 'authorName', 'authorId', 'coverUrl', 'createdAt', 'updatedAt'];
for (const k of mustString) {
if (!isString(post[k])) errors.push(`"${k}" must be a string`);
}
if (!Array.isArray(post.tags)) errors.push('"tags" must be an array');
else if (!post.tags.every((t) => typeof t === 'string')) errors.push('"tags" must be string[]');
if (typeof post.published !== 'boolean') errors.push('"published" must be a boolean');
const isoFields = ['createdAt', 'updatedAt'];
for (const f of isoFields) {
if (isString(post[f]) && Number.isNaN(Date.parse(post[f]))) {
errors.push(`"${f}" must be a valid ISO 8601 date string`);
}
}
// basic slug sanity
if (isString(post.slug) && !/^[a-z0-9]+(?:-[a-z0-9]+)*$/.test(post.slug)) {
errors.push('"slug" should be lower-case alphanumerics separated by hyphens');
}
return { valid: errors.length === 0, errors };
}
/**
* Functional update: returns a new BlogPost with normalized fields and updatedAt bumped.
* - If title is changed and slug not explicitly provided, regenerate slug from title.
* - Summary is rederived when summary not provided or empty string.
* - Tags are normalized.
*/
function updateBlogPost(post, patch = {}) {
const merged = { ...post, ...patch };
// Handle slug regeneration rules
const titleChanged = typeof patch.title === 'string' && patch.title !== post.title;
const slugProvided = Object.prototype.hasOwnProperty.call(patch, 'slug');
if (titleChanged && !slugProvided) {
merged.slug = slugify(merged.title);
} else if (slugProvided) {
merged.slug = slugify(patch.slug);
}
// Normalize tags and summary
merged.tags = normalizeTags(patch.tags ?? post.tags);
merged.summary = deriveSummary({ summary: merged.summary, content: merged.content });
// Bump updatedAt
merged.updatedAt = toISO();
return merged;
}
// -------------------- Serialization & Storage --------------------
/**
* Serialize BlogPost to JSON string (stable keys for readability).
*/
function serializeBlogPost(post) {
const ordered = {
title: post.title,
slug: post.slug,
content: post.content,
summary: post.summary,
tags: post.tags,
authorName: post.authorName,
authorId: post.authorId,
coverUrl: post.coverUrl,
published: post.published,
createdAt: post.createdAt,
updatedAt: post.updatedAt,
};
return JSON.stringify(ordered);
}
/**
* Parse JSON or plain object into a normalized BlogPost.
*/
function parseBlogPost(input) {
const obj = typeof input === 'string' ? JSON.parse(input) : input;
return createBlogPost(obj);
}
/**
* Generate a stable draft storage key for localStorage.
*/
function draftKey(post) {
return `cms:draft:${post.slug || 'untitled'}`;
}
/**
* Save draft to localStorage. Returns the storage key or null on failure.
*/
function saveDraft(post, key = draftKey(post)) {
try {
localStorage.setItem(key, serializeBlogPost(post));
return key;
} catch (err) {
// Optionally surface error to caller
return null;
}
}
/**
* Load draft from localStorage. Returns BlogPost or null if not found/invalid.
*/
function loadDraft(key) {
try {
const raw = localStorage.getItem(key);
if (!raw) return null;
return parseBlogPost(raw);
} catch {
return null;
}
}
/**
* Remove draft from localStorage. Returns true if removed.
*/
function clearDraft(key) {
try {
localStorage.removeItem(key);
return true;
} catch {
return false;
}
}
// -------------------- Preview Helper --------------------
/**
* Build a lightweight preview DTO for UI rendering (no HTML).
*/
function getPreview(post, maxSummaryLen = 160) {
return {
title: post.title || '未命名',
slug: post.slug,
summary: deriveSummary({ summary: post.summary, content: post.content }, maxSummaryLen),
coverUrl: post.coverUrl || '',
tags: post.tags,
published: post.published,
updatedAt: post.updatedAt,
readingTime: estimateReadingTime(post.content).minutes,
};
}
// Example export (if using modules)
// export {
// createBlogPost,
// updateBlogPost,
// validateBlogPost,
// serializeBlogPost,
// parseBlogPost,
// saveDraft,
// loadDraft,
// clearDraft,
// getPreview,
// };
对象结构说明
属性详细说明表 | 属性名 | 类型 | 必填 | 默认值 | 说明 | |---|---|---:|---|---| | title | string | 否 | '' | 文章标题;用于生成 slug | | slug | string | 否 | 由 title 推导或 'untitled' | URL 标识,lowercase-hyphen | | content | string | 否 | '' | 正文(纯文本/Markdown/HTML) | | summary | string | 否 | 从 content 推导 | 摘要;若提供空串,将重新推导 | | tags | string[] | 否 | [] | 标签,自动去重与裁剪空白 | | authorName | string | 否 | '' | 作者显示名 | | authorId | string | 否 | '' | 作者唯一标识(建议必填) | | coverUrl | string | 否 | '' | 封面图 URL | | published | boolean | 否 | false | 是否发布 | | createdAt | string(ISO) | 否 | 创建时刻 | ISO 8601 时间字符串 | | updatedAt | string(ISO) | 否 | 创建/更新时刻 | ISO 8601 时间字符串 |
使用示例代码
// 1) 一键生成表单初始对象
let post = createBlogPost({
title: '用现代 JavaScript 写出更好的代码',
authorName: 'Jane Doe',
authorId: 'user_123',
tags: ['JavaScript', 'Web', ' JavaScript '], // 会去重 -> ['JavaScript', 'Web']
});
console.log(post.slug); // yong-xian-dai-javascript-xie-chu-geng-hao-de-dai-ma(示例)
// 2) 表单编辑:内容或标题变化时进行函数式更新
post = updateBlogPost(post, { content: '# 正文内容\n更多文本...' });
// 标题变化时,若未手动提供 slug,将自动重算 slug
post = updateBlogPost(post, { title: '新标题' });
// 3) 校验(用于提交前)
const { valid, errors } = validateBlogPost(post);
if (!valid) {
console.error('校验失败:', errors);
}
// 4) 预览卡片数据(摘要、阅读时长)
const preview = getPreview(post);
console.log(preview);
// 5) 本地存储草稿
const key = saveDraft(post); // cms:draft:<slug>
const loaded = loadDraft(key); // 读取并自动规范化
clearDraft(key); // 清除草稿
最佳实践建议
/**
* ChatMessage —— 聊天消息对象模型(前端友好,安全高亮提及,支持字数统计)
* 特性:
* - 不可变对象(Object.freeze),避免无意修改
* - 内置字数统计(wordCount)
* - 提及高亮的安全分段(segmentsForRender),不返回可注入的 HTML
* - withUpdates(patch) 以不可变方式更新对象(变更 content 时自动将 edited=true,除非显式覆盖)
*/
/**
* @typedef {Object} ChatMessageProps
* @property {string} id
* @property {string} conversationId
* @property {string} role
* @property {string} content
* @property {number} tokens
* @property {string[]} mentions
* @property {string} createdAt ISO 8601 时间字符串
* @property {boolean} edited
* @property {string[]} reactions
* @property {string} replyToId
*/
const ChatMessage = (() => {
// ---------- utilities ----------
const isISODateTime = (s) => typeof s === 'string' && !Number.isNaN(Date.parse(s));
const toISO = (dateLike) => {
if (typeof dateLike === 'string' && isISODateTime(dateLike)) return new Date(dateLike).toISOString();
if (dateLike instanceof Date) return dateLike.toISOString();
return new Date().toISOString();
};
const isStringArray = (arr) => Array.isArray(arr) && arr.every((x) => typeof x === 'string');
const clampNonNegInt = (n) => {
const num = Number(n);
return Number.isFinite(num) && num >= 0 ? Math.floor(num) : 0;
};
const escapeRegExp = (s) => s.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
const wordCountOf = (text) => {
// 尽量用 Intl.Segmenter 更精确地统计词数
if (typeof Intl !== 'undefined' && Intl.Segmenter) {
const seg = new Intl.Segmenter(undefined, { granularity: 'word' });
let c = 0;
for (const { isWordLike } of seg.segment(text)) {
if (isWordLike) c += 1;
}
return c;
}
// 回退:基于 Unicode 字母/数字的简单匹配
const m = text.trim().match(/\p{L}[\p{L}\p{N}_-]*/gu);
return m ? m.length : 0;
};
// 将 content 分割成 [{type:'text'|'mention', text: string, value?: string}]
// 其中 value 为提及用户名/ID(不包含 @)
const segmentMentions = (content, mentions) => {
if (!mentions?.length) return [{ type: 'text', text: content }];
const escaped = mentions.filter(Boolean).map(escapeRegExp);
if (!escaped.length) return [{ type: 'text', text: content }];
// 匹配 @alice @bob ...,在词边界/空白/行尾结束
const re = new RegExp(`@(?:${escaped.join('|')})(?=\\b|\\s|$)`, 'gu');
const out = [];
let lastIndex = 0;
let m;
while ((m = re.exec(content))) {
const start = m.index;
const end = re.lastIndex;
if (start > lastIndex) out.push({ type: 'text', text: content.slice(lastIndex, start) });
out.push({ type: 'mention', text: m[0], value: m[0].slice(1) });
lastIndex = end;
}
if (lastIndex < content.length) out.push({ type: 'text', text: content.slice(lastIndex) });
return out;
};
class ChatMessage {
/**
* @param {Partial<ChatMessageProps> & Pick<ChatMessageProps,'id'|'conversationId'|'role'|'content'>} props
*/
constructor({
id,
conversationId,
role,
content,
tokens = 0,
mentions = [],
createdAt = new Date().toISOString(),
edited = false,
reactions = [],
replyToId = '',
}) {
// 校验
if (typeof id !== 'string' || id.trim() === '') throw new TypeError('id must be a non-empty string');
if (typeof conversationId !== 'string' || conversationId.trim() === '') throw new TypeError('conversationId must be a non-empty string');
if (typeof role !== 'string' || role.trim() === '') throw new TypeError('role must be a non-empty string');
if (typeof content !== 'string') throw new TypeError('content must be a string');
if (!isStringArray(mentions)) throw new TypeError('mentions must be a string[]');
if (!isStringArray(reactions)) throw new TypeError('reactions must be a string[]');
if (typeof edited !== 'boolean') throw new TypeError('edited must be boolean');
if (typeof replyToId !== 'string') throw new TypeError('replyToId must be a string');
// 赋值(只读风格)
this.id = id;
this.conversationId = conversationId;
this.role = role;
this.content = content;
this.tokens = clampNonNegInt(tokens);
this.mentions = mentions;
this.createdAt = toISO(createdAt);
this.edited = edited;
this.reactions = reactions;
this.replyToId = replyToId;
Object.freeze(this);
}
// 词数统计(与 tokens 概念区分;tokens 通常由上游模型/服务计算)
get wordCount() {
return wordCountOf(this.content);
}
get hasMentions() {
return Array.isArray(this.mentions) && this.mentions.length > 0;
}
// 用于渲染的安全分段。不返回 HTML,交给视图层做转义/拼接。
segmentsForRender() {
return segmentMentions(this.content, this.mentions);
}
// 不可变更新:返回新对象;若修改了 content 且未显式提供 edited,则自动设为 true
withUpdates(patch = {}) {
const merged = { ...this, ...patch };
if ('content' in patch && !('edited' in patch)) {
merged.edited = true;
}
return new ChatMessage(merged);
}
// 序列化为可传输的普通对象
toJSON() {
return {
id: this.id,
conversationId: this.conversationId,
role: this.role,
content: this.content,
tokens: this.tokens,
mentions: [...this.mentions],
createdAt: this.createdAt,
edited: this.edited,
reactions: [...this.reactions],
replyToId: this.replyToId,
};
}
// 工厂方法(语义上等同于 new ChatMessage)
static create(props) {
return new ChatMessage(props);
}
// 轻量校验
static isValid(obj) {
try {
// eslint-disable-next-line no-new
new ChatMessage(obj);
return true;
} catch {
return false;
}
}
}
return ChatMessage;
})();
export { ChatMessage };
对象结构说明
属性详细说明表 | 属性名 | 类型 | 必填 | 默认值 | 说明 | 示例 | |---|---|---|---|---|---| | id | string | 是 | - | 消息唯一 ID | "msg_001" | | conversationId | string | 是 | - | 会话 ID | "conv_123" | | role | string | 是 | - | 发送者角色,可按业务限定(如 "user"、"assistant"、"system") | "user" | | content | string | 是 | - | 消息内容 | "Hello @alice" | | tokens | number | 否 | 0 | 预计算 token 数(与字数不同),若无可设 0 | 17 | | mentions | string[] | 否 | [] | 需高亮的提及列表(不含前缀 @) | ["alice","bob"] | | createdAt | string | 否 | 当前时间 ISO | ISO 8601 时间字符串 | "2025-01-01T12:34:56.000Z" | | edited | boolean | 否 | false | 是否已编辑 | true | | reactions | string[] | 否 | [] | 表情/反应标识集合(如 emoji 或反应代号) | ["👍","❤️"] | | replyToId | string | 否 | "" | 被回复消息 ID,不存在则空字符串 | "msg_000" |
使用示例代码
import { ChatMessage } from './ChatMessage.js';
// 1) 创建消息对象
const msg = ChatMessage.create({
id: 'msg_001',
conversationId: 'conv_123',
role: 'user',
content: 'Hi @alice, welcome to the channel!',
tokens: 9,
mentions: ['alice'],
createdAt: new Date().toISOString(),
edited: false,
reactions: ['👋'],
replyToId: '',
});
// 2) 渲染:安全的提及高亮(Vanilla DOM 示例)
function renderMessage(container, message) {
container.textContent = ''; // 清空
const segments = message.segmentsForRender();
segments.forEach((seg) => {
const span = document.createElement('span');
span.textContent = seg.text; // 使用 textContent,避免 XSS
if (seg.type === 'mention') {
span.className = 'mention'; // 样式类用于高亮
// 也可以添加 dataset:span.dataset.mention = seg.value;
}
container.appendChild(span);
});
}
// 3) 渲染:React(JSX)示例
// const segments = msg.segmentsForRender();
// return (
// <p>
// {segments.map((seg, i) =>
// seg.type === 'mention' ? (
// <mark className="mention" key={`${msg.id}-m-${i}`}>{seg.text}</mark>
// ) : (
// <span key={`${msg.id}-t-${i}`}>{seg.text}</span>
// )
// )}
// </p>
// );
// 4) 统计字数(wordCount 与 tokens 概念不同)
console.log('wordCount:', msg.wordCount); // e.g., 6
console.log('tokens:', msg.tokens); // 9
// 5) 更新消息(不可变):修改 content 时,edited 将自动为 true(除非显式传入)
const msgEdited = msg.withUpdates({
content: 'Hi @alice and @bob!',
mentions: ['alice', 'bob'],
});
console.log(msgEdited.edited); // true
// 6) 序列化传输
const payload = JSON.stringify(msgEdited); // 通过网络发送
const plainObject = JSON.parse(payload);
const restored = ChatMessage.create(plainObject); // 恢复为模型对象
最佳实践建议
'use strict';
/**
* 提示模板对象(PromptTemplate)
* 使用 JSDoc 提供类型提示和 IDE 智能补全,便于教学演示与团队协作。
*
* @typedef {Object} PromptTemplate
* @property {string} id - 模板唯一标识(如:"pt-2025-001")
* @property {string} name - 模板名称(人类可读)
* @property {string} prompt - 用户可见/可编辑的主提示词正文
* @property {string} systemInstruction - 系统角色指令(约束风格/边界/输出格式)
* @property {number} temperature - 采样温度,数值越高越有创造性(通常 0–2)
* @property {number} maxTokens - 输出最大 token 数
* @property {string[]} stopWords - 生成终止词列表(出现即截断)
* @property {string} stylePreset - 风格预设(如:"neutral"|"concise"|"formal"|"casual"|"technical" 等)
* @property {string[]} examples - 示例集合(少样本提示,便于教学对比)
* @property {string} version - 模板版本(如:"1.0.0")
* @property {string} updatedAt - ISO 8601 更新时间(如:"2025-12-01T10:20:30.000Z")
*/
/** 内部工具:深冻结(含数组) */
function deepFreeze(obj) {
if (obj && typeof obj === 'object' && !Object.isFrozen(obj)) {
Object.freeze(obj);
Object.getOwnPropertyNames(obj).forEach((prop) => {
const value = obj[prop];
if (value && typeof value === 'object') deepFreeze(value);
});
}
return obj;
}
/** 基础校验与规范化工具 */
function assertNonEmptyString(value, name) {
if (typeof value !== 'string') {
throw new TypeError(`${name} must be a string`);
}
const v = value.trim();
if (!v) throw new TypeError(`${name} must be a non-empty string`);
return v;
}
function assertNumber(value, name) {
if (typeof value !== 'number' || Number.isNaN(value)) {
throw new TypeError(`${name} must be a valid number`);
}
return value;
}
function assertPositiveInt(value, name) {
const n = Number(value);
if (!Number.isFinite(n) || n <= 0 || !Number.isInteger(n)) {
throw new TypeError(`${name} must be a positive integer`);
}
return n;
}
function normalizeStringArray(value, name) {
if (value == null) return [];
if (!Array.isArray(value)) {
throw new TypeError(`${name} must be an array of strings`);
}
const out = Array.from(
new Set(
value
.map((v) => {
if (typeof v !== 'string') {
throw new TypeError(`${name} must contain only strings`);
}
return v.trim();
})
.filter(Boolean)
)
);
return out;
}
function assertTemperature(value) {
const n = assertNumber(value, 'temperature');
if (n < 0 || n > 2) {
throw new RangeError('temperature must be in [0, 2]');
}
return n;
}
function assertISO8601(value, name) {
const v = assertNonEmptyString(value, name);
// 粗略校验:Date 可解析且等价于自身的 ISO 字符串
const d = new Date(v);
if (Number.isNaN(d.getTime())) {
throw new TypeError(`${name} must be a valid ISO 8601 string`);
}
return d.toISOString();
}
/**
* 创建提示模板对象的工厂方法
* - 进行必要的校验和规范化
* - 补全合理默认值
* - 返回不可变对象(deep freeze)
*
* @param {Partial<PromptTemplate> & Pick<PromptTemplate, 'id'|'name'|'prompt'|'systemInstruction'>} input
* @returns {PromptTemplate}
*/
function createPromptTemplate(input) {
if (!input || typeof input !== 'object') {
throw new TypeError('input must be an object');
}
// 必填字段
const id = assertNonEmptyString(input.id, 'id');
const name = assertNonEmptyString(input.name, 'name');
const prompt = assertNonEmptyString(input.prompt, 'prompt');
const systemInstruction = assertNonEmptyString(input.systemInstruction, 'systemInstruction');
// 可选字段 + 默认值
const temperature = input.temperature == null ? 0.7 : assertTemperature(input.temperature);
const maxTokens = input.maxTokens == null ? 512 : assertPositiveInt(input.maxTokens, 'maxTokens');
const stopWords = normalizeStringArray(input.stopWords, 'stopWords');
const examples = normalizeStringArray(input.examples, 'examples');
const stylePreset =
input.stylePreset == null
? 'neutral'
: assertNonEmptyString(input.stylePreset, 'stylePreset');
const version =
input.version == null ? '1.0.0' : assertNonEmptyString(input.version, 'version');
const updatedAt =
input.updatedAt == null
? new Date().toISOString()
: assertISO8601(input.updatedAt, 'updatedAt');
/** @type {PromptTemplate} */
const template = {
id,
name,
prompt,
systemInstruction,
temperature,
maxTokens,
stopWords,
stylePreset,
examples,
version,
updatedAt,
};
return deepFreeze(template);
}
/**
* 类型守卫(运行时形状检查的轻量版本)
* @param {any} obj
* @returns {obj is PromptTemplate}
*/
function isPromptTemplate(obj) {
const has = (k) => Object.prototype.hasOwnProperty.call(obj, k);
return (
obj &&
typeof obj === 'object' &&
typeof obj.id === 'string' &&
typeof obj.name === 'string' &&
typeof obj.prompt === 'string' &&
typeof obj.systemInstruction === 'string' &&
typeof obj.temperature === 'number' &&
typeof obj.maxTokens === 'number' &&
Array.isArray(obj.stopWords) &&
typeof obj.stylePreset === 'string' &&
Array.isArray(obj.examples) &&
typeof obj.version === 'string' &&
typeof obj.updatedAt === 'string' &&
has('id') &&
has('name') &&
has('prompt') &&
has('systemInstruction')
);
}
// 可按需 export:
// export { createPromptTemplate, isPromptTemplate };
| 属性名 | 类型 | 必填 | 默认值 | 说明 | 约束/示例 |
|---|---|---|---|---|---|
| id | string | 是 | — | 模板唯一标识 | 例:pt-2025-001 |
| name | string | 是 | — | 模板名称 | 例:教学-电商标题模板 |
| prompt | string | 是 | — | 主提示词正文 | 可包含占位符(如:{{topic}}) |
| systemInstruction | string | 是 | — | 系统角色指令,定义边界/风格 | 建议简洁明确、包含输出格式 |
| temperature | number | 否 | 0.7 | 创造性与确定性的权衡 | [0, 2] |
| maxTokens | number(int) | 否 | 512 | 最大输出 tokens | 正整数 |
| stopWords | string[] | 否 | [] | 生成停止词 | 去重、去空格 |
| stylePreset | string | 否 | "neutral" | 风格预设标签 | 例:"concise"、"formal"、"casual"、"technical" |
| examples | string[] | 否 | [] | 少样本示例 | 教学用对比数据 |
| version | string | 否 | "1.0.0" | 模板版本 | 语义化版本 |
| updatedAt | string(ISO) | 否 | 当前时间 | 更新时间 | ISO 8601,如 2025-12-01T10:20:30.000Z |
// 1) 创建两个风格不同的模板,便于教学对比
const neutralTemplate = createPromptTemplate({
id: 'pt-2025-001',
name: '教学-电商标题(中性)',
systemInstruction: '你是一位资深电商文案助手,请确保标题简洁、无夸张、不含违规词,输出以一行纯文本为主。',
prompt: '请为以下产品生成 5 个电商商品标题:\n产品信息:{{product}}\n目标人群:{{audience}}',
temperature: 0.7,
maxTokens: 256,
stylePreset: 'neutral',
stopWords: ['END'],
examples: [
'产品:轻薄办公笔记本;人群:大学生',
'产品:降噪蓝牙耳机;人群:通勤族',
],
version: '1.1.0',
});
const conciseTemplate = createPromptTemplate({
id: 'pt-2025-002',
name: '教学-电商标题(简洁)',
systemInstruction: '你是一位极简风格的电商文案助手,仅输出高密度信息点,避免形容词堆砌。',
prompt: '基于信息生成 5 个高转化标题:\n信息:{{product}}|人群:{{audience}}',
temperature: 0.5,
maxTokens: 200,
stylePreset: 'concise',
stopWords: ['END'],
examples: [
'产品:轻薄办公笔记本;人群:大学生',
'产品:降噪蓝牙耳机;人群:通勤族',
],
version: '1.1.0',
});
// 2) 渲染函数(演示用):将变量插入 prompt,并拼合系统指令
function composePrompt(template, vars) {
const inject = (text) =>
text.replace(/{{\s*(\w+)\s*}}/g, (_, k) => (vars?.[k] ?? `{{${k}}}`));
const header = `[Style: ${template.stylePreset}] [Temp: ${template.temperature}] [Max: ${template.maxTokens}]`;
return `${template.systemInstruction}\n${header}\n\n${inject(template.prompt)}`;
}
// 3) 展示对比示例文案(教学用)
function renderComparison(templateA, templateB, exampleVars) {
const a = composePrompt(templateA, exampleVars);
const b = composePrompt(templateB, exampleVars);
return `【模板 A:${templateA.name}】\n${a}\n\n———\n\n【模板 B:${templateB.name}】\n${b}`;
}
const exampleVars = {
product: '轻薄办公笔记本(i5/16GB/512GB,1.2kg)',
audience: '大学新生',
};
console.log(renderComparison(neutralTemplate, conciseTemplate, exampleVars));
// 4) 使用 examples 做批量演示(少样本对比)
function batchFromExamples(template) {
return template.examples.map((ex, idx) => {
// 简单解析示例中的“产品”“人群”,仅教学示范(真实项目请使用更健壮的解析)
const product = ex.match(/产品:[;;]?\s*([^;;]+)\s*/)?.[1] ?? '';
const audience = ex.match(/人群:[;;]?\s*([^;;]+)\s*/)?.[1] ?? '';
return `【示例 ${idx + 1}】\n${composePrompt(template, { product, audience })}`;
});
}
console.log(batchFromExamples(neutralTemplate).join('\n\n'));
面向前端开发、技术负责人与教学培训,快速把“属性需求”转化为标准化的 JavaScript 对象方案:1) 一步生成结构清晰、易维护的对象代码;2) 自动给出对象结构说明、属性清单与使用示例,减少沟通与文档编写成本;3) 内建最佳实践与规范建议,帮助团队统一风格、避免过时与不良写法;4) 针对不同场景(开发建模、重构优化、教学演示)自动调整设计,提升交付速度与代码质量,降低返工与缺陷率;5) 支持多种对象创建方式的智能选择,兼顾可读性与性能,让新人上手更快、老手更省时。
在开发页面状态与组件数据时,快速生成对象、类或构造函数,实现字段默认值、只读与校验设置;一键生成示例与注释,加速联调与提测。
为服务配置、业务实体与响应封装快速建模,按场景切换对象创建方式;在重构旧模块时批量替换不规范对象,降低线上故障率。
制定统一对象创建规范与命名策略,沉淀为团队模版;用自动注释与示例提升代码审阅效率,缩短新人上手周期。
将模板生成的提示词复制粘贴到您常用的 Chat 应用(如 ChatGPT、Claude 等),即可直接对话使用,无需额外开发。适合个人快速体验和轻量使用场景。
把提示词模板转化为 API,您的程序可任意修改模板参数,通过接口直接调用,轻松实现自动化与批量处理。适合开发者集成与业务系统嵌入。
在 MCP client 中配置对应的 server 地址,让您的 AI 应用自动调用提示词模板。适合高级用户和团队协作,让提示词在不同 AI 工具间无缝衔接。
半价获取高级提示词-优惠即将到期