Streaming Message Drafts (stream)
Plugin ini memungkinkan Anda untuk mengirim pesan teks panjang ke Telegram. Setiap iterator potongan teks dapat langsung dialirkan ke obrolan pribadi mana pun.
Misalnya, Anda dapat membuat output LLM muncul secara bertahap saat menghasilkan respons.
Panduan Cepat
Plugin ini menginstal ctx pada objek konteks context object.
Streaming pesan melakukan banyak panggilan API dengan sangat cepat. Disarankan untuk menggunakan plugin auto
-retry bersama dengan plugin stream.
import { Bot, type Context } from "grammy";
import { autoRetry } from "@grammyjs/auto-retry";
import { stream, type StreamFlavor } from "@grammyjs/stream";
type MyContext = StreamFlavor<Context>;
const bot = new Bot<MyContext>("");
bot.api.config.use(autoRetry()); // sangat direkomendasikan!
bot.use(stream());
async function* slowText() {
// membuat teks secara lambat
yield "Ini adalah te";
await new Promise((r) => setTimeout(r, 2000));
yield "ks yang dihasil";
await new Promise((r) => setTimeout(r, 2000));
yield "kan secara lambat";
}
// Telegram hanya mendukung streaming di obrolan pribadi.
bot.chatType("private")
.command("stream", async (ctx) => {
// Stream pesannya!
await ctx.replyWithStream(slowText());
});
bot.start();2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
const { Bot } = require("grammy");
const { autoRetry } = require("@grammyjs/auto-retry");
const { stream } = require("@grammyjs/stream");
const bot = new Bot("");
bot.api.config.use(autoRetry()); // sangat direkomendasikan!
bot.use(stream());
async function* slowText() {
// membuat teks secara lambat
yield "Ini adalah te";
await new Promise((r) => setTimeout(r, 2000));
yield "ks yang dihasil";
await new Promise((r) => setTimeout(r, 2000));
yield "kan secara lambat";
}
// Telegram hanya mendukung streaming di obrolan pribadi.
bot.chatType("private")
.command("stream", async (ctx) => {
// Stream pesannya!
await ctx.replyWithStream(slowText());
});
bot.start();2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
import { Bot, type Context } from "https://deno.land/x/grammy@v1.42.0/mod.ts";
import { autoRetry } from "https://deno.land/x/grammy_auto_retry@v2.0.2/mod.ts";
import {
stream,
type StreamFlavor,
} from "https://deno.land/x/grammy_stream@v1.0.1/mod.ts";
type MyContext = StreamFlavor<Context>;
const bot = new Bot<MyContext>("");
bot.api.config.use(autoRetry()); // sangat direkomendasikan!
bot.use(stream());
async function* slowText() {
// membuat teks secara lambat
yield "Ini adalah te";
await new Promise((r) => setTimeout(r, 2000));
yield "ks yang dihasil";
await new Promise((r) => setTimeout(r, 2000));
yield "kan secara lambat";
}
// Telegram hanya mendukung streaming di obrolan pribadi.
bot.chatType("private")
.command("stream", async (ctx) => {
// Stream pesannya!
await ctx.replyWithStream(slowText());
});
bot.start();2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
Itulah dia!
Integrasi LLM
Sebagian besar integrasi LLM memungkinkan Anda untuk menampilkan output secara langsung saat sedang diproses. Anda dapat menggunakan plugin ini untuk menampilkan output LLM secara bertahap di obrolan pribadi mana pun.
Misalnya, jika Anda menggunakan AI SDK, konfigurasi Anda dapat terlihat seperti ini:
import { streamText } from "ai";
import { google } from "@ai-sdk/google";
bot.chatType("private")
.command("credits", async (ctx) => {
// Kirim perintah ke LLM:
const { textStream } = streamText({
model: google("gemini-2.5-flash"),
prompt: "Sebarapa keren bot grammY?",
});
// Otomatis mengalirkan respons dengan grammY:
await ctx.replyWithStream(textStream);
});2
3
4
5
6
7
8
9
10
11
12
13
14
import { streamText } from "npm:ai";
import { google } from "npm:@ai-sdk/google";
bot.chatType("private")
.command("credits", async (ctx) => {
// Kirim perintah ke LLM:
const { textStream } = streamText({
model: google("gemini-2.5-flash"),
prompt: "Sebarapa keren bot grammY?",
});
// Otomatis mengalirkan respons dengan grammY:
await ctx.replyWithStream(textStream);
});2
3
4
5
6
7
8
9
10
11
12
13
14
Pastikan untuk mengganti gemini dengan model apapun yang tersedia.
Streaming Formatted Messages
Ini jauh lebih sulit daripada yang kamu bayangkan.
- LLMs menghasilkan Markdown probabilistik. Seringkali benar, tetapi kadang-kadang tidak. Tidak mengikuti standar tertentu. Khususnya, mereka tidak selalu menghasilkan Markdown yang kompatibel dengan Telegram. Ini berarti mencoba mengirim ke Telegram akan gagal.
- LLMs menghasilkan entitas Markdown yang parsial. Meskipun outputnya sepenuhnya sesuai dengan spesifikasi MarkdownV2 Telegram, potongan outputnya mungkin rusak. Jika Anda membuka bagian teks miring tetapi hanya menutupnya di potongan berikutnya, streaming akan crash dan pesan tidak akan terkirim.
- LLMs terkadang menghasilkan format yang tidak didukung oleh Telegram (meskipun Anda telah menginstruksikan mereka untuk tidak melakukannya). Misalnya, sebagian besar LLMs sangat menyukai tabel, poin-poin, dan daftar bernomor. Klien Telegram tidak dapat menampilkannya.
Telegram juga mendukung format HTML. Ini memiliki masalah yang sama persis dengan Markdown. Selain itu, output HTML mengonsumsi jauh lebih banyak token, yang tidak diperlukan dan mahal.
Jadi… apa sekarang?
Sayangnya, tidak ada solusi yang baik. Namun, berikut beberapa ide:
- Minta LLM Anda untuk menghasilkan teks tanpa format.
- Semoga LLM Anda tidak membuat kesalahan saat menghasilkan Markdown, dan jika gagal, coba ulang dengan teks biasa.
- Gunakan format HTML dan semoga ini dapat memperbaiki situasi sedikit.
- Tulis fungsi transformer kustom yang secara otomatis mencoba ulang permintaan yang gagal.
- Gunakan parser Markdown streaming dan buat array
MessageAnda sendiri untuk memformat setiapEntity MessageDraft Piece - Stream Markdown dalam teks biasa, lalu gunakan parser Markdown biasa untuk menerapkan pemformatan hanya setelah stream selesai dan semua pesan dikirim.
- Temukan solusi brilian yang belum pernah dipikirkan orang lain sebelumnya, dan ceritakan kepada kami di group chat