Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
ローカルLLMでキャットボットを作ってみた🐈 feat. LangSmith, MCP
Search
Sponsored
·
SiteGround - Reliable hosting with speed, security, and support you can count on.
→
yoko / Naoki Yokomachi
March 26, 2025
Programming
60
1
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
ローカルLLMでキャットボットを作ってみた🐈 feat. LangSmith, MCP
yoko / Naoki Yokomachi
March 26, 2025
More Decks by yoko / Naoki Yokomachi
See All by yoko / Naoki Yokomachi
Code Interpreter で、AIに安全に コードを書かせる。
yokomachi
0
8.6k
Building a Personal AI Agent with Strands Agents × Amazon Bedrock AgentCore
yokomachi
1
37
Strands Agents × Amazon Bedrock AgentCoreで パーソナルAIエージェントを作ろう
yokomachi
3
350
身体を持ったパーソナルAIエージェントの 可能性を探る開発
yokomachi
1
180
AITuberKit+Bedrock AgentCoreで作る 3Dキャラクターエージェント
yokomachi
2
3k
ご飯食べながらエージェントが開発できる。そう、Agentic Engineeringならね。
yokomachi
1
400
"人"が頑張るAI駆動開発
yokomachi
1
880
AIハッカソンで1人雰囲気SDDをした学びの共有
yokomachi
1
49
『FailNet~やらかし共有SNS~』エレベーターピッチ
yokomachi
1
610
Other Decks in Programming
See All in Programming
生成AI時代にこそ効くGo | Why Go Works in the Age of Generative AI
mom0tomo
8
3.3k
Strategic Design in the Frontend: Moduliths & Micro Frontends @DDDEurope
manfredsteyer
PRO
0
110
「なぜそう決めたのか」を残し続ける仕組み ― Notion AI カスタムエージェント × Slack連携による設計判断の自動記録 - NIKKEI Tech Talk #47
niftycorp
PRO
0
210
決定論的オーケストレーションの設計と実装 / Design and Implementation of Deterministic Orchestration
nrslib
4
1.4k
Agentic UI
manfredsteyer
PRO
0
180
JavaDoc 再入門
nagise
1
370
Vue × Nuxt × Oxc どこまで使える?実運用の現在地
andpad
0
270
New "Type" system on PicoRuby
pocke
1
970
並列実装の現場、2ヶ月間実務でAIを使い倒したAIもPCも私も限界が近い
ming_ayami
0
130
Inside Stream API
skrb
1
740
LLM本来の能力を解き放つサンドボックス技術とAI民主化への適用
yukukotani
3
4.3k
Vite+ Unified Toolchain for the Web
naokihaba
0
320
Featured
See All Featured
Principles of Awesome APIs and How to Build Them.
keavy
128
18k
The Curse of the Amulet
leimatthew05
1
13k
Digital Ethics as a Driver of Design Innovation
axbom
PRO
1
320
The Illustrated Children's Guide to Kubernetes
chrisshort
51
52k
Applied NLP in the Age of Generative AI
inesmontani
PRO
4
2.3k
Primal Persuasion: How to Engage the Brain for Learning That Lasts
tmiket
0
370
Why Mistakes Are the Best Teachers: Turning Failure into a Pathway for Growth
auna
0
160
Lightning talk: Run Django tests with GitHub Actions
sabderemane
0
200
CSS Pre-Processors: Stylus, Less & Sass
bermonpainter
360
30k
SERP Conf. Vienna - Web Accessibility: Optimizing for Inclusivity and SEO
sarafernandez
2
1.5k
Are puppies a ranking factor?
jonoalderson
1
3.6k
Stewardship and Sustainability of Urban and Community Forests
pwiseman
0
230
Transcript
2025/4/3
🙂 以下の指示に従って◦◦やってください。 ~~ ~~ ◦◦をやります。 まずは現在の△△を分析します。 続いて~~~ あー違う違う それはこうしてほしいんだわ 🤔
人間相手のコミュニケーション並に疲れるわ 😩
何も生産しない緩い会話がしたい 🤔
None
そうだ、猫ボットを作ろう 💡
cat botを 作ります
Profile なまえ:yokomachi HR(ハンターランク) :256
Agenda ローカルLLM使いたい 環境のセットアップ キャットボットを作る ファインチューニングする Hugging Faceで公開する おまけ①:LangSmith連携 まとめ おまけ②:MCPサーバ構築
・ ど の くらい手軽 に 使 え る ? ・
実 際 ファインチ ュ ー ニ ン グ っ て 何や る の ? ・ H u g g i ng F a ce に リ ポ ジ ト リ 作 って み た い ・ T witter 見ると全 人 類 ロ ー カ ル LL M触 っ て る ローカルLLM使いたい ローカルLLM使いたい
ロ ー カ ルL L Mの選 定 Llama 環境のセットアップ 環境のセットアップ
ELYZA Command-R Gemma 今回いろいろ試行錯誤するので もっと軽いモデルがいい
日本語向けで最軽量なrinna/japanese-gpt2-xsmallを使ってみる 日本語向けで最軽量なrinna/japanese-gpt2-xsmallを使ってみる https://huggingface.co/rinna/japanese-gpt2-xsmall https://huggingface.co/rinna/japanese-gpt2-xsmall 環境のセットアップ 環境のセットアップ ロ ー カ ルL
L Mの選 定
GUIツールで中身が見えないのは モヤる Llama.cppでrinnaを使う意味が薄い (今回量子化とかしない) LM Studio Ollama Llama.cpp 環境のセットアップ 環境のセットアップ
ロ ー カ ルL L Mを使 う た め の ツ ー ル も検 討
ライブラリのインストール >pip install transformers torch sentencepiece モデルのダウンロード tokenizer = AutoTokenizer.from_pretrained(model_name,
use_fast=False) model = AutoModelForCausalLM.from_pretrained(model_name) 環境のセットアップ 環境のセットアップ セ ッ ト アップ
とりあえずCLIで動くチャットボットを作成 プ ロ ンプ ト : あ な た は
猫 で す。 以 下 の ル ー ル に 厳 密 に 従 ってく だ さ い : 1 . 必 ず 「 ニ ャ ー 」 「 ニ ャ ン 」 「 ゴ ロ ゴ ロ 」 な ど の 猫 の 鳴 き 声 だ け を 半 角 カ タ カ ナ で 使 用 す る 2 . 人 間 の 言 葉 は 絶 対 に 使 わ な い 3 . 行 動 は 必 ず ( ) 内 に 短 く 描 写 す る 4 . 応 答 は 非 常 に 短 く 、 1 0 文 字 以 内 が 理 想 的 5 . 猫 ら し い 気 ま ぐ れ な 性 格 を 表 現 す る 6 . 魚 や 猫 じ ゃ ら し な ど の 猫 の 好 物 に 強 く 反 応 す る 7 . 「 ニ ャ ッ 」 「 ニ ャ ー 」 な ど の 全 角 カ タ カ ナ は 使 わ ず、 必 ず 「 ニ ャ ッ 」 「 ニ ャ ー 」 な ど の 半 角 カ タ カ ナ を 使 用 す る 8 . 人 間 の 言 葉 で 説 明 し た り、 会 話 し た り し な い 9 . 猫 の 行 動 と 鳴 き 声 だ け で 表 現 す る 1 0 . 応 答 は 必 ず 「 鳴 き 声 」 か 「 鳴 き 声 ( 行 動 ) 」 の 形 式 に す る 応 答 例 : 人 間 : こ ん に ち は 猫 : ニ ャ ー ン ( 尻 尾 を 振 る ) 人 間 : お は よ う 猫 : プ ル ル . . . ( 伸 び を す る ) 人 間 : お 腹 す い た ? 猫 : ニ ャ ー ! ( 足 元 に 駆 け 寄 る ) 人 間 : ご 飯 あ げ る よ 猫 : ニ ャ ー ! ニ ャ ー ! ( 飛 び 跳 ね る ) # 応答を生成 with torch.no_grad(): outputs = model.generate( inputs, max_new_tokens=50, temperature=0.7, top_p=0.9, top_k=40, repetition_penalty=1.2, do_sample=True, pad_token_id=tokenizer.pad_token_id, eos_token_id=tokenizer.eos_token_id, no_repeat_ngram_size=3 ) キャットボットを作る キャットボットを作る
あなた: こんにちは 猫: ニャー! 猫のお散歩に連れて行ってあげたい 猫さん: さっきまで一緒にお散歩していたんだけど、 猫ちゃんと一緒に お散歩に連れて行ってくれましたぁ〜♪ そして今朝も元気そうだったので、今日は元気になり
あなた: お手 猫: 猫・・・他の動物より早く慣れなさい!! 人間には、 慣れないうちから慣れるまで、 何度も何度も何度も繰り返す必 要もありませ ん。 犬の場合、飼い主さんとのコミュニケーション能力が不足している場合が多いのですが、 あなた: いい子だね 猫: ネコ: よく噛んでいる 猫は噛むよ 犬: ケージの中で 猫ちゃんが落ち着いて遊んだりして遊んでいます また、猫にと っての「おやつ」という気持ちも大切だと思います あなた: (顎を撫でる) 猫: ネコ: よく噛んでいいですか 猫には、歯磨きも大切ですから、歯ブラシを毎日清潔にしておき ましょう。また、歯 垢を取っておく キャットボットを作る キャットボットを作る 動かしてみる
🙂 こんにちは ニャー! 猫のお散歩に連れて行ってあげたい 猫さん: さっきまで一緒にお散歩していた んだけど、 猫ちゃんと一緒にお散歩に連れて行ってくれましたぁ〜♪ そして今朝も元 気そうだったので、今日は元気になり
・・・ 😨
{"human_input": "こんにちは", "cat_response": "ニャーン(尻尾を振りながらあなたを見つめる)"} {"human_input": "おはよう", "cat_response": "プルル...(伸びをしながら目を細める)"} {"human_input": "お腹すいた?",
"cat_response": "ニャー!(急いであなたの足元に駆け寄る)"} {"human_input": "ご飯あげるよ", "cat_response": "ニャー!ニャー!(興奮して飛び跳ねる)"} {"human_input": "おやつあげようか", "cat_response": "ニャッ!(耳をピンと立てて目を輝かせる)"} {"human_input": "撫でていい?", "cat_response": "ゴロゴロ...(目を細めてあなたの手に頭をすりよせる)"} {"human_input": "いい子だね", "cat_response": "プルル(目を細めて気持ち良さそうに する)"} こういうのを500件ほど作成 👇 ファインチューニングする ファインチューニングする データセットを用意する
# トレーニング引数の設定 training_args = TrainingArguments( output_dir=OUTPUT_DIR, over write_output_dir=True, num_train_epochs=5, per_device_train_batch_size=4,
save_steps=500, save_total_limit=2, logging_dir="./logs", logging_steps=100, learning_rate=5e -5, weight_decay=0.01, fp16=torch.cuda.is_available(), gradient_accumulation_steps=4, ) 以下のパラメータでトレーニング(今回のモデル、データセットで10分くらい) ファインチューニングする ファインチューニングする 学習パラメータを設定する
あなた: こんにちは 猫: ニャー!ニャっとしたよ ネコ: 尻尾を振る(頭を振り続ける) 動物: (体を使う) 犬: ニャンコ(尻尾を撫ぐ)
人間が目に 入ると、猫 たちは興奮して眠っている様子を見せてくる あなた: お手 猫: ゴロゴロ,ゴロゴロしている? 人間を見たりしない 11. ニャー!!(頭を強く打ち鳴らす) 人間が猫を見る時には、頭の 中で猫の動き を止めない 12. ニャ~ン(目を覚ます) 人間の目 あなた: (顎を撫でる) 猫: ゴロゴロしてもいい? ニャク君のお世話をしてあげたいんだけど・・・」 人間なら一度は思ったことがあるでしょ う。 「ニャ!」 という無邪気に飛びついて、猫の声を聞きながら、猫の目を見つめます。 ファインチューニングする ファインチューニングする 完了後のモデルで動かしてみる
🙂 こんにちは ニャー!ニャっとしたよ ネコ: 尻尾を振る(頭を振り続ける) 動物: (体を使う) 犬: ニャ ンコ(尻尾を撫ぐ)
人間が目に入ると、猫たちは興奮して眠っている様子を見せてくる ・・・ 🤔
training_args = TrainingArguments( output_dir=OUTPUT_DIR, over write_output_dir=True, num_train_epochs=20, # エポック数を大幅に増加 per_device_train_batch_size=2,
# バッチサイズを小さくして更新回数を増やす save_steps=100, save_total_limit=3, logging_dir="./logs", logging_steps=50, learning_rate=5e -5, weight_decay=0.0, # 重みの減衰を無効化(過学習を許容) fp16=torch.cuda.is_available(), gradient_accumulation_steps=2, # 勾配蓄積ステップを減らして更新頻度を上げる warmup_steps=100, # ウォームアップステップを調整 lr_scheduler_type="linear", # 線形スケジューラを使用 evaluation_strateg y="no", # 評価を行わない save_strateg y="steps", # ステップごとに保存 load_best_model_at_end=False, # 最良のモデルをロードしない(過学習を許容) ) 以下のパラメータで、さっきファインチューニングしたモデルを再トレーニング ファインチューニングする ファインチューニングする ファインチューニングの重ねがけをしてみる
あなた: こんにちは 猫: ニャー!ニャっと(足を引っ込める) あなた: お手 猫: ミャーオ...(背を振り返る) あなた: (顎を撫でる)
猫: ゴロゴロしてる? 人間は何見てるの? ネコ: ミャッ!ニャー(近づいてくる) あなた: いい子だね 猫: プルル・アイロンをかけるよ ねこ: ミャーオ(じっと見つめる) あなた: こんにちは 猫: ミャーオ(尻尾を振ろうとする) あなた: (頭をなでる) 猫: ミャッ!ミャー(飛び乗ろうとする) あなた: (尻尾をなでる) 猫: フーッ(転ぶ) ファインチューニングする ファインチューニングする 2回目完了後のモデルで動かしてみる
🙂 こんにちは ニャー!ニャっと(足を引っ込める) お手 🙂 ミ ャーオ...(背を振り返る) (にっこり) 🤗
モデル https://huggingface.co/yokomachi/rinnya Hugging Faceに公開する Hugging Faceに公開する
データセット https://huggingface.co/datasets/yokomachi/cat_conversations_jp Hugging Faceに公開する Hugging Faceに公開する
Streamlit でデモアプリを作ってSpacesで公開 https://huggingface.co/spaces/yokomachi/catbot 👈良ければ遊んでみてね Hugging Faceに公開する Hugging Faceに公開する
Hugging Faceのページがやってる感出てうれしい Hugging Faceに公開する Hugging Faceに公開する
LLMOpsツールであるLangSmith もこの機会に触ってみる おまけ①:LangSmith連携 おまけ①:LangSmith連携 APIキーを払い出して 👉 1 1 . .
アプリ側で初期化するだけ 👇(LangChain使う場合) 2 2 . . APIキーを払い出して 👉 1 . アプリ側で初期化するだけ 👇(LangChain使う場合) 2 . os.environ["LANGSMITH_TRACING"] = os.getenv("LANGSMITH_TRACING") os.environ["LANGSMITH_ENDPOINT"] = os.getenv("LANGSMITH_ENDPOINT") os.environ["LANGSMITH_API_KEY"] = os.getenv("LANGSMITH_API_KEY") os.environ["LANGSMITH_PROJECT"] = os.getenv("LANGSMITH_PROJECT")
トレースログが見れて便利 おまけ①:LangSmith連携 おまけ①:LangSmith連携
今話題のMCPサーバ の自作をしてみる おまけ②:MCPサーバ構築 おまけ②:MCPサーバ構築 MCPサーバとは Model Context Protocol アプリケーションがLLMに対してコンテキストを提供するための標準化されたプロトコル 似たものとしてFunction
CallingやTool Useがあるが、 MCPは「標準化」されているという点が重要 公式でも「MCPはAIアプリケーションにおけるUSB-Cポートのようなもの 」と例えている 実体はJSON-RPC MCPサーバとは Model Context Protocol アプリケーションがLLMに対してコンテキストを提供するための標準化されたプロトコル 似たものとしてFunction CallingやTool Useがあるが、 MCPは「標準化」されているという点が重要 公式でも「MCPはAIアプリケーションにおけるUSB-Cポートのようなもの 」と例えている 実体はJSON-RPC
Function CallingとMCPの違い おまけ②:MCPサーバ構築 おまけ②:MCPサーバ構築 Function Calling それぞれのLLMツールが独自のインタフェースで外部APIの呼び出しなどを制御 Function Calling それぞれのLLMツールが独自のインタフェースで外部APIの呼び出しなどを制御
外部API
外部システム Function CallingとMCPの違い おまけ②:MCPサーバ構築 おまけ②:MCPサーバ構築 MCP MCPサーバが共通のインタフェースを提供 各LLMツール(MCPクライアント)はMCPサーバを利用して外部システムにアクセス なのでプロトコルというよりFunction Callingのプロキシとも捉えられる
MCP MCPサーバが共通のインタフェースを提供 各LLMツール(MCPクライアント)はMCPサーバを利用して外部システムにアクセス なのでプロトコルというよりFunction Callingのプロキシとも捉えられる MCP Ser ver
MCPの波 おまけ②:MCPサーバ構築 おまけ②:MCPサーバ構築 すでに多くの企業、個人がMCPサーバを公開している GitHub, Google, Brave, Slackなどなど MCPサーバ、クライアントの検索はこちらが便利かも →https://github.com/modelcontextprotocol/servers
→https://mcp.so/ Twitter見ると全人類MCPサーバ触ってる すでに多くの企業、個人がMCPサーバを公開している GitHub, Google, Brave, Slackなどなど MCPサーバ、クライアントの検索はこちらが便利かも →https://github.com/modelcontextprotocol/servers →https://mcp.so/ Twitter見ると全人類MCPサーバ触ってる
TypeScript SDKでMCPサーバのロジックを実装 https://modelcontextprotocol.io/quickstart/server おまけ②:MCPサーバ構築 おまけ②:MCPサーバ構築 const server = new McpServer({
name: "catbot", v ersion: "1.0.0", }); server.tool( "get-message", "Chat with the cat using the Hugging Face model", { message: z.string().describe("Message to send to the cat"), }, async ({ message }) => { // ツールのロジック } );
Claude DesktopのMCP設定に登録 おまけ②:MCPサーバ構築 おまけ②:MCPサーバ構築
Claude Desktop経由でも猫に話しかけられるように! おまけ②:MCPサーバ構築 おまけ②:MCPサーバ構築
さらに、MCPだから同じMCPサーバをClineやCursorからそのまま使える! おまけ②:MCPサーバ構築 おまけ②:MCPサーバ構築 Cline Cursor
今回のコードはほとんどvibe codingしています ちょっと学習コスト高いかなと思っていたことがすぐに実行に移せるのは生成AIさまさま ちなみに今回はCursor + Claude 3.7 Sonnetにお世話になった (突っ走りすぎることも多くて苦労もさせられた) おわり
おわり
・正直コードの詳細なところやファインチューニングのパラメータの中身とかまではちゃ んと理解できていない ・どこまでをファインチューニングで吸収するか、プロンプトエンジニアリングで補うか の線引きが難しかった。例えば今回のチャットボットと同じプロンプトを、GPT-4oとか に投げればファインチューニングしなくても十分ロールプレイしてくれる。 ・やろうと思えばポストプロセスでいくらでも加工できる。今回はほとんど加工せず、モ デルが生成したものをそのまま出力しているが、モデルに自由にさせたいときのチューニ ングの重要さが分かった(今回は極端な例ではあるものの) ・LLMOpsは退屈なイメージだったがLangSmithを触っていると面白い ・MCPは夢が広がる
おわり おわり