feat:生文

This commit is contained in:
R524809
2026-01-30 16:04:10 +08:00
parent d4fc8f44ee
commit e7b4a948ac
63 changed files with 981954 additions and 1124 deletions
@@ -0,0 +1,253 @@
const fs = require("fs");
const path = require("path");
const https = require("https");
const crypto = require("crypto");
// 腾讯云混元大模型配置
// 请设置环境变量 TENCENT_SECRET_ID 和 TENCENT_SECRET_KEY
const SECRET_ID = process.env.TENCENT_SECRET_ID;
const SECRET_KEY = process.env.TENCENT_SECRET_KEY;
// API配置
const HOST = "hunyuan.tencentcloudapi.com";
const SERVICE = "hunyuan";
const REGION = "ap-guangzhou";
const ACTION = "ChatCompletions";
const VERSION = "2023-09-01";
const MODEL = "hunyuan-lite"; // 使用混元lite模型,可根据需要更换
// 签名相关函数
function sha256(message, secret = "", encoding = "hex") {
const hmac = secret
? crypto.createHmac("sha256", secret)
: crypto.createHash("sha256");
return hmac.update(message).digest(encoding);
}
function getDate(timestamp) {
const date = new Date(timestamp * 1000);
const year = date.getUTCFullYear();
const month = ("0" + (date.getUTCMonth() + 1)).slice(-2);
const day = ("0" + date.getUTCDate()).slice(-2);
return `${year}-${month}-${day}`;
}
function generateSignature(secretId, secretKey, host, payload, timestamp) {
const date = getDate(timestamp);
// 步骤1:拼接规范请求串
const httpRequestMethod = "POST";
const canonicalUri = "/";
const canonicalQueryString = "";
const contentType = "application/json";
const canonicalHeaders = `content-type:${contentType}\nhost:${host}\nx-tc-action:${ACTION.toLowerCase()}\n`;
const signedHeaders = "content-type;host;x-tc-action";
const hashedRequestPayload = sha256(payload);
const canonicalRequest = `${httpRequestMethod}\n${canonicalUri}\n${canonicalQueryString}\n${canonicalHeaders}\n${signedHeaders}\n${hashedRequestPayload}`;
// 步骤2:拼接待签名字符串
const algorithm = "TC3-HMAC-SHA256";
const credentialScope = `${date}/${SERVICE}/tc3_request`;
const hashedCanonicalRequest = sha256(canonicalRequest);
const stringToSign = `${algorithm}\n${timestamp}\n${credentialScope}\n${hashedCanonicalRequest}`;
// 步骤3:计算签名
const secretDate = sha256(date, "TC3" + secretKey, "buffer");
const secretService = sha256(SERVICE, secretDate, "buffer");
const secretSigning = sha256("tc3_request", secretService, "buffer");
const signature = sha256(stringToSign, secretSigning);
// 步骤4:拼接Authorization
const authorization = `${algorithm} Credential=${secretId}/${credentialScope}, SignedHeaders=${signedHeaders}, Signature=${signature}`;
return authorization;
}
// 调用混元API
async function callHunyuan(prompt) {
return new Promise((resolve, reject) => {
const timestamp = Math.floor(Date.now() / 1000);
const payload = JSON.stringify({
Model: MODEL,
Messages: [
{
Role: "user",
Content: prompt,
},
],
Stream: false,
});
const authorization = generateSignature(
SECRET_ID,
SECRET_KEY,
HOST,
payload,
timestamp
);
const options = {
hostname: HOST,
port: 443,
path: "/",
method: "POST",
headers: {
"Content-Type": "application/json",
Host: HOST,
"X-TC-Action": ACTION,
"X-TC-Version": VERSION,
"X-TC-Timestamp": timestamp.toString(),
"X-TC-Region": REGION,
Authorization: authorization,
},
};
const req = https.request(options, (res) => {
let data = "";
res.on("data", (chunk) => (data += chunk));
res.on("end", () => {
try {
const result = JSON.parse(data);
if (result.Response && result.Response.Choices) {
resolve(result.Response.Choices[0].Message.Content.trim());
} else if (result.Response && result.Response.Error) {
reject(new Error(result.Response.Error.Message));
} else {
reject(new Error("Unknown API response: " + data));
}
} catch (e) {
reject(e);
}
});
});
req.on("error", reject);
req.write(payload);
req.end();
});
}
// 为单个汉字生成介绍
async function generateIntroduce(char) {
const prompt = `请为汉字"${char}"生成一个简短的词组介绍,格式为"${char}XXX的${char}",其中XXX是一个包含该汉字的常见词语。
例如:
- 汉字"天"的介绍是"天,天空的天"
- 汉字"地"的介绍是"地,大地的地"
- 汉字"人"的介绍是"人,人民的人"
请只输出介绍内容,不要包含其他解释。比如对于"天",只输出"天,天空的天"。`;
try {
const response = await callHunyuan(prompt);
// 清理响应,只保留核心内容
let introduce = response.replace(/["""]/g, "").trim();
// 如果响应包含多余内容,尝试提取核心部分
const match = introduce.match(/..+的./);
if (match) {
introduce = match[0];
}
// 确保格式正确:如果没有逗号,添加逗号
if (!introduce.startsWith(char + "")) {
// 尝试提取词组部分
const wordMatch = introduce.match(/(.+的.)/);
if (wordMatch) {
introduce = `${char}${wordMatch[1]}`;
} else {
introduce = `${char}${char}字的${char}`;
}
}
return introduce;
} catch (error) {
console.error(`生成 "${char}" 介绍失败:`, error.message);
return `${char}${char}字的${char}`;
}
}
// 延时函数
function delay(ms) {
return new Promise((resolve) => setTimeout(resolve, ms));
}
// 主函数
async function main() {
// 检查环境变量
if (!SECRET_ID || !SECRET_KEY) {
console.error("请设置环境变量 TENCENT_SECRET_ID 和 TENCENT_SECRET_KEY");
console.error("例如:");
console.error(
" export TENCENT_SECRET_ID=your_secret_id"
);
console.error(
" export TENCENT_SECRET_KEY=your_secret_key"
);
process.exit(1);
}
// 读取汉字数据
const charStringPath = path.join(
__dirname,
"../data/char/char_string.json"
);
const charString = JSON.parse(fs.readFileSync(charStringPath, "utf-8"));
// 获取所有汉字
const chars = charString["3500"].split("");
console.log(`共有 ${chars.length} 个汉字需要处理`);
// 检查是否有已存在的进度文件
const outputPath = path.join(
__dirname,
"../data/char/char_introduce.json"
);
let results = [];
let startIndex = 0;
if (fs.existsSync(outputPath)) {
try {
results = JSON.parse(fs.readFileSync(outputPath, "utf-8"));
startIndex = results.length;
console.log(`发现已有进度,从第 ${startIndex + 1} 个汉字继续`);
} catch (e) {
console.log("已有文件解析失败,从头开始");
}
}
// 批量处理
const BATCH_SIZE = 10; // 每批处理10个
const DELAY_BETWEEN_BATCHES = 1000; // 批次间延迟1秒
for (let i = startIndex; i < chars.length; i += BATCH_SIZE) {
const batch = chars.slice(i, Math.min(i + BATCH_SIZE, chars.length));
console.log(
`处理第 ${i + 1} - ${Math.min(i + BATCH_SIZE, chars.length)} 个汉字...`
);
// 并行处理当前批次
const batchResults = await Promise.all(
batch.map(async (char, idx) => {
// 每个请求之间稍微错开
await delay(idx * 100);
const introduce = await generateIntroduce(char);
console.log(` ${char}: ${introduce}`);
return { char, introduce };
})
);
results.push(...batchResults);
// 每批处理完后保存进度
fs.writeFileSync(outputPath, JSON.stringify(results, null, 2), "utf-8");
console.log(`已保存进度:${results.length}/${chars.length}`);
// 批次间延迟,避免API限流
if (i + BATCH_SIZE < chars.length) {
await delay(DELAY_BETWEEN_BATCHES);
}
}
console.log(`\n完成!共生成 ${results.length} 个汉字介绍`);
console.log(`结果已保存到: ${outputPath}`);
}
main().catch(console.error);