ai-startup-skills
AI 제품을 만드는 스타트업을 위한 7단계 에이전트 스킬: 검증 → 비즈플랜 → 정책 → 로드쇼 → 고객 확보 → 가격 책정 → 등록
웹 브라우저만으로 마이크·텍스트·음성 합성으로 3D 캐릭터와 대화하고 캐릭터와 성격을 바꿀 수 있습니다
You can enjoy conversations with 3D characters using only a web browser using a microphone, text input, and speech synthesis. You can also change the character (VRM), set the personality, and adjust t
기타GitHub @zoan37온라인운영자 미확인
써 보셨어요? 한 번만 눌러 주세요. 로그인은 필요 없어요.
저장소 정보는 아직 수집하지 않았습니다.
아직 감지된 업데이트가 없습니다. GitHub 릴리스가 나오면 여기에 보입니다.
Chat with VRM avatar via LLM
저장소 README에서 가져옴
README 전체를 불러오는 중입니다.
README 전문 보기 ↗[This repo was cloned from ChatVRM-jp, which is a fork of @pixiv/ChatVRM.]
ChatVRM is a demo application that allows you to easily talk with a 3D character in your browser.
By importing VRM files, you can adjust the voice to match the character, and generate responses that include emotional expressions.
ChatVRM mainly uses the following technologies.
A demo is available at Vercel.
https://chat-vrm-window.vercel.app/
Clone or download this repository to run locally.
git clone https://github.com/zoan37/ChatVRM.git
Please install the required packages.
npm install
After package installation is complete, start the development web server with the following command.
npm run dev
After execution, access the following URL.
The app can get its LLM responses two ways:
/api/chat serverless function, and is never sent to the browser.To set up the shared key, copy .env.example to .env.local for local dev, and set the same variables in Vercel under Project → Settings → Environment Variables:
cp .env.example .env.local
| Variable | Purpose |
|---|---|
OPENROUTER_API_KEY | Shared key, server-side only. Required for the shared path. |
ALLOWED_ORIGINS | Optional comma-separated origin allowlist for /api/chat. |
SITE_URL | Optional. Sent as HTTP-Referer for OpenRouter's app rankings. |
Never prefix an API key with
NEXT_PUBLIC_. Next.js inlines those values into the JavaScript bundle served to every visitor, so the key becomes public and can be extracted from devtools. This app previously usedNEXT_PUBLIC_OPENROUTER_API_KEYand the key was drained as a result.
Recommended hardening for the shared key:
ALLOWED_ORIGINS to your production domain once you're done testing./api/chat also enforces fixed free models (set in MODELS in src/pages/api/chat.ts, with openrouter/free as the fallback), a 512-token cap, a 24,000-character conversation cap, and a per-IP rate limit (12/min, 200/day). The rate limit is in-memory, so it resets on cold start and isn't shared across regions — treat it as friction against casual abuse, not as the spend ceiling.
OpenRouter model IDs ending in :free cost $0 per token. The free tier allows 20 requests/minute and 50 requests/day, which rises to 1,000/day once you've purchased $10 of credits at any point. The current list is at openrouter.ai/models?max_price=0.
For a talking avatar the binding constraint is time to first token, since nothing can be spoken until it arrives. Measured on a one-sentence reply (August 2026):
| Model | First token | Notes |
|---|---|---|
nvidia/nemotron-3-ultra-550b-a55b:free | 0.8–1.8s | Current primary (measured October 2026). Often busy, so OpenRouter falls back |
nvidia/nemotron-3.5-super-vl:free | 1.1–1.5s | Current second choice (October 2026) |
openrouter/free | 4–17s | Last-resort fallback. Picks any free model, so speed and quality vary |
nvidia/nemotron-3-nano-30b-a3b:free | 0.9s | Former default; removed from OpenRouter by October 2026 |
google/gemma-4-31b-it:free | 5.1s | Better prose, too slow to feel conversational |
openai/gpt-oss-20b:free | 5.6s | Free relative of the paid gpt-oss-120b |
google/gemma-4-26b-a4b-it:free | 7.5s | |
nvidia/nemotron-3.5-lightning:free | 60s | Avoid. Spent the whole 512-token budget reasoning and emitted its scratchpad as the reply |
liquid/lfm-2.5-2.6b:free | — | Avoid. Streamed empty chunks, then hung |
Reasoning models are a poor fit here: their thinking tokens count against max_tokens, delaying speech and risking a truncated reply. reasoning: { effort: "low" } is already sent to limit this.
Note that a static build (npm run export, used by the GitHub Pages workflow) has no serverless functions, so /api/chat won't exist there and visitors must supply their own key.
The default avatar is served from public/AvatarSample_B.vrm on the app's own origin. It used to load from a public IPFS gateway, which gives no availability guarantee and was returning 504s — leaving the page with no avatar and an uncaught error in the console.
The committed model is an optimized build of the original 20 MB VRoid export, produced by scripts/optimize-vrm.mjs:
node scripts/optimize-vrm.mjs original.vrm public/AvatarSample_B.vrm \
--max 1024 --thumb 256 --trim-material HAIR_06 --trim-above 1.545
| Original | Committed | |
|---|---|---|
| File | 20.07 MB | 6.46 MB |
| Textures | 12.12 MB | 4.21 MB |
| Morph targets | 6.14 MB | 0.69 MB |
Two things dominate a VRoid export. Textures: the 2048×2048 thumbnail alone was 2.35 MB despite never being rendered in-scene, and one normal map was stored six times. Morph targets: 90.3% of the blend-shape deltas are exactly zero, because each expression moves only a few vertices of a whole-body mesh — storing them as glTF sparse accessors cuts them by 89%.
The --trim-* flags fix a separate, pre-existing cosmetic bug: four tiny black specks appeared to float in the air above the head. They are the tips of the black ribbon bows (HAIR_06), which taper to a point — above y=1.545 those triangles are narrower than a pixel, so the rasterizer can only draw them as scattered dots detached from the bow. Dropping those 64 triangles (0.18% of the model) removes the specks with no visible change to the bows. Only the index buffer shrinks, so vertices, skin weights and morph targets are untouched. This artifact is present in the untouched 20 MB original — it is not caused by the optimization.
The script deliberately does not use a general-purpose glTF optimizer. VRM keeps its data in the VRMC_vrm / VRM extensions, which reference textures, images and materials by array index; tools that reorder or reindex those arrays silently break expressions, spring bones and material settings. This script only rewrites bufferView payloads and appends new bufferViews, so every existing index still resolves. Run --max 2048 for a losslessly recompressed 9.14 MB build if you'd rather not downscale textures at all.
Requires ImageMagick (magick) on PATH.
ChatVRM supports reading chat messages from a livestream and generating responses, via the Restream API. Currently, X and Twitch sources are supported. It uses a batching system so that the LLM is called for each batch of messages, not for each message.
Steps (this is mostly in the Settings UI):
Troubleshooting: