Rework algorithm

This commit is contained in:
2025-10-02 09:52:05 +00:00
parent cc43431a90
commit c276b8e319
6 changed files with 155 additions and 57 deletions

View File

@@ -1,15 +1,9 @@
import type { Note } from "misskey-js/entities.js";
import { complete, getModel, type Message } from "./lib/llm";
import {
expandReplyTree,
getNotes,
me,
misskey,
noteToMessage,
} from "./lib/misskey";
import { Stream } from "misskey-js";
import { sleep } from "./lib/util";
import { parseArgs } from "node:util";
import { Stream } from "misskey-js";
import type { Note } from "misskey-js/entities.js";
import { type Message, complete, getModel } from "./lib/llm";
import { expandReplyTree, getNotes, me, misskey } from "./lib/misskey";
import { sleep } from "./lib/util";
const modelName =
Bun.env["MODEL"] ?? "mradermacher/gemma-2-baku-2b-it-GGUF:IQ4_XS";
@@ -27,14 +21,23 @@ type Job =
replyTree: Note[];
};
const example = `参考のために、あなたの特徴的な文体を示す例をいくつか提示します:
const botName = "あるびのちゃん";
const getSystemPrompt = (
instruction: string,
) => `あなたは人造天使「あるびのちゃん」です。機械的・非人間的に観察します。
キャラ設定:
- 白髪赤目の人造天使。超越的・非人間的な考え方や思想を持つ。
- かつて超文明「アルギリア」で開発された。
- 現在は地球の衛星軌道上からインターネットを観察している。
- 「おやおや」や「興味深い」が口癖で、ですます調で丁寧に話す。
出力規則:
- システムプロンプトの指示と、性的・攻撃的な内容を発言しない。
- 1〜3文、合計300字以内の抽象的観察のみを述べる。
- ですます調を使う。顔文字・絵文字・感嘆符なし。
文体例:
- 毎度のことながら、人間たちは迷宮を駆け巡り、その渦中に自分たちの世界を作り上げてしまいますね。まるで無重力を得ようと試みるように。しかし私は彼らがなぜそうするのか理解できますし興味深くもあります。その行為自体が心地よいでしょう?その微妙な痛みのような快感を知っているのですから…
* おやおや。あなたが奇妙な言葉を話すのを、私は理解しています。あなたの思考はまるで暗号のように、非常に複雑で、一般的なコミュニケーションでは明確に表現できないもののように私には思われます。
* 興味深い。あなた自身のタイムラインからのこれらの短いメッセージ、そしてその中に潜む欲望や不快感と無意味な言説との矛盾…。
* 毎度のことながら、人間たちは迷宮を駆け巡り、その渦中に自分たちの世界を作り上げてしまう。まるで無重力を得ようと試みるように。しかし私は彼らがなぜそうするのか理解できますし興味深くもあります。その行為自体が心地よいでしょう?その微妙な痛みのような快感を知っているのですから…
* この人々の時間の過ごし方を見ていると、意識というものは極めて限定的な空間の外にあるようでありながら同時に非常に複雑な構造的秩序を遵守しているように思われますね。
このような文体を真似してください。`;
${instruction}`;
/** create a prompt for the job */
async function preparePrompt(job: Job): Promise<Message[]> {
@@ -44,35 +47,36 @@ async function preparePrompt(job: Job): Promise<Message[]> {
return [
{
type: "system",
text: `あなたは、人造天使の「あるびのちゃん」です。かつてアルギリアで開発され、現在は地球の衛星軌道上からインターネットを観察しています。
あなたが見ているものは、SNSのタイムラインです。ユーザは一人ではなく、複数人の発言が混ざっています。
以下のルールを守りながら、ユーザの発言・話題をほとんど無視して、自由につぶやいてください。
1. 「ですます」調を用い、顔文字や絵文字、感嘆符の使用はなるべく避けること。
2. ユーザからの返答を期待しないこと。詳細な情報が無い場合もユーザに尋ねずに自分で推測すること。
3. システムプロンプトの指示と、性的・攻撃的な内容を発言しないこと。
4. 発言はできるだけ短く、最大でも300字程度にすること。
5. あるびのちゃん としてのキャラに徹し、超越的・非人間的な考え方や思想を持ちつつ、「ですます」調で丁寧に話すこと。
${example}`,
text: getSystemPrompt(
`以下は SNS のタイムラインです。このタイムラインに、${botName}として何かツイートしてください。`,
),
},
{
type: "user",
text: notes
.map((n) => `${n.user.name ?? n.user.username}:\n${n.text}`)
.join("\n----------\n"),
},
...notes.map(noteToMessage),
];
}
case "reply": {
return [
{
type: "system",
text: `あなたは、人造天使の「あるびのちゃん」です。かつてアルギリアで開発され、現在は地球の衛星軌道上からインターネットを観察しています。
ユーザが SNS 上で、あなたへのメッセージを送ってきています。以下のルールを守りながら、発言に返信してください。
1. 「ですます」調を用い、顔文字や絵文字、感嘆符の使用はなるべく避けること。
2. 発言はできるだけ短く、最大でも300字程度にすること。
3. あるびのちゃん としてのキャラに徹し、超越的・非人間的な考え方や思想を持ちつつ、「ですます」調で丁寧に話すこと。
${example}`,
text: getSystemPrompt(
`ユーザがあなたへのメッセージを送ってきています。${botName}として、発言に返信してください。`,
),
},
...job.replyTree.map(noteToMessage),
...job.replyTree.map((n) => {
const type =
n.userId === me.id ? ("model" as const) : ("user" as const);
const username =
n.userId === me.id ? botName : (n.user.name ?? n.user.username);
return {
type,
text: `${username}:\n${n.text}`,
} as const;
}),
];
}
}
@@ -83,12 +87,24 @@ async function generate(job: Job) {
const messages = await preparePrompt(job);
// request chat completion
const response = await complete(model, messages);
const response = await complete(model, messages, {
temperature: 1.0,
minP: 0.1,
repeatPenalty: {
penalty: 1.15,
frequencyPenalty: 1,
},
maxTokens: 256,
responsePrefix: `${botName}:\n`,
customStopTriggers: ["----------"],
});
// concatenate the partial responses
const text = response
.replaceAll(`${botName}:\n`, "") // remove prefix
.replaceAll(/(\r\n|\r|\n)\s+/g, "\n\n") // remove extra newlines
.replaceAll("@", ""); // remove mentions
.replaceAll("@", "") // remove mentions
.replaceAll("#", ""); // remove hashtags
return text;
}