RareJob Tech Blog

レアジョブテクノロジーズのエンジニア・デザイナーによる技術ブログです

Cursor Meetup Philippines に参加してきました! Ryo Lu 氏の30分間のトークに大興奮!

レアジョブ英会話開発グループの高縄智徳です。
2021年6月に入社し、2023年9月からはフィリピンに拠点を移して、東京と行き来しながら働いています。
気付いたら入社5年目、27歳になっていました。そしてここにブログ記事を書くのは実は今回が初めてです。

さて、 気づいたらAIまみれ2025、AWS Summit もあるよ - RareJob Tech Blog にもある通り、私たちは日々の業務で AI コードエディタを利用していて、私は Cursor を利用しています。

数週間前に Cursor Meetup Tokyo が開催されましたが、フィリピンでは先日 Cursor Meetup Philippines が開催され、およそ30人が参加しました。

Cursor Meetup Philippines 2025
Cursor Meetup Philippines 2025

今回はその Cursor Meetup Philippines の様子を書いていきたいと思います。現地直送便です。

まず当日のタイムラインは以下の通りです。

  • 12:45 PM | Doors open, early birds welcome
  • 1:00–1:30 PM | Registration & Hangout (grab your kit)
  • 1:30–1:45 PM | Opening Keynote
  • 1:45–2:25 PM | Building MVPs with Cursor
  • 2:25–3:00 PM | Product Deep Dive — AMA & Demo with Ryo, Head of Design at Cursor
  • 3:00–3:20 PM | Pizza + Networking Break
  • 3:20–4:00 PM | Lightning Demos and Product Showcase
  • 4:00–5:00 PM | Maker Space (hackathon) + group photo

1:05 PM

会場に到着しました。
フィリピンではエアコンが効きすぎているということがよくありますが、今回はちょうどよかったです。持参した厚めのパーカーの出番はありませんでした。

会場の様子
会場の様子

1:45 PM

会が始まりました。写真はないです。
主催していたのは大学生で、この数年は同じように Notion 関連のイベントを開催して普及活動をされていたようです。
後から休憩中に聞きましたが、大学2年生ということでしたので、 Notion の普及活動は高校生の時にしていたのかと思うと、ただただ感心するばかりでした。

2:00 PM

1人目の LT です。写真はあるのですが、写真が多くても読みづらいので、文字だけで失礼します。
LT の内容としては、フロントエンドに詳しくないが Cursor のおかげで開発の幅が広がったことや、 Cursor Rules を活用してコンテキストを与えることの大切さについての LT でした。

LT の後は10分間の休憩がありました。

2:30 PM

Ryo Lu 氏との AMA (Ask Me Anything) セッションの始まりです。
サンフランシスコは夜の11時30分で、事前に公開されていたタイムライン通りではありますが、夜遅くに30分という長い時間オンラインでたくさんの質問に答えてくれたり、画面共有して色々な話をしてくれて、とても貴重な時間でした。感謝です。

肝心の AMA の内容は、特に前半は音声/通信トラブルもあり聞き取れない部分も多かったものの、概要としてはこのような感じでした。

  1. Notion から Cursor に移ったモチベーション
  2. ソフトウェア開発の思想的/方法的転換: Painting to Sculpting, and Prototyping
  3. センスをどう磨いていくか
  4. Cursor のデータプライバシーとセキュリティへの配慮
  5. Cursor の今後の展望
  6. 意外と知られていない Cursor のパワフルな機能
  7. 好きなフォント、疲れた日に食べるもの、 NewJeans、 Liquid Glass について
  8. 最後に開発者とデザイナーへのメッセージ

概要として書いた内容だけ見てもとても興味深いセッションだったことが分かるかと思いますが、本記事では7番の "好きなフォント"、"疲れた日に食べるもの"、そして8番の "開発者とデザイナーへのメッセージ" だけ抜粋して、会の雰囲気を少しでもお伝えできたらと思います。
前述の主催者が彼の大ファンということもあり、一問一答的なやり取りに終始せず、全て書き起こしたいくらい胸アツなセッションでした。

Host: Favorite font?
Ryo: SF Pro.
Host: I thought you were a big fan of Inter.

Host: What’s your go-to comfort food after a long day of vibe coding?
Ryo: I love McDonald's ice cream, and then you put the fries in the ice cream.

Host: What would be your last word or message to builders and designers in this room who want to also shape the future of software tool making with AI?
Ryo: (5秒以上考えた後) ... Just build. I think now is the time where it’s so easy to build. Whatever idea — it doesn’t matter what it is. It can be dumb, it can be smart, it doesn’t matter. Just do it. (中略) You might make more friends who also build and you share your things that you build and then you find more friends, so that'll be fun.

写真はないですが、最後の "then you find more friends" のあたりで猫ちゃんが擦り寄ってて可愛かったです。

3:00 PM

Pizza + Networking Break です。
写真だと独りでいるように見えますが、独りで食べた後にちゃんと人と話して Networking してきました。

Pizza
Pizza

3:30 PM

3名の方が LT をしました。
1名は AI コードエディタをより効果的に使っていくために取り組んでいることの発表で、私の手元に残っていたメモを貼ります。

1. Use Cursor Rules. Keep updating these rules.
2. Install CLI Tools because some tools including Cursor can use the terminal.
3. Generate lots of logs. Logs make it easy to give it context. (NOTE: only pre-prod)
4. Use tasks.md (for Cursor to put logs and understand what it's been doing)
5. Deploy background agents like using Slack or Cursor's Bugbot.
6. Use MCPs.
7. Create your own Prompt Library. Find prompts online. Tweak it to work for you.

もう1名は自身のプロダクトを開発する際にどのように AI コードエディタを活用したか、そして自身のプロダクトに AI を使っているかなどが中心の発表でした。

もう1名はほぼタガログ語でしたので、まだ私には理解が難しかったです。タガログ語がんばります。

4:20 PM

ハッカソンをしました。

その場で5-6人のグループを作って、40分という短い時間の中で

  • 生成 AI を使ったプロダクトのアイデアを出し合って、
  • 実際にアプリケーションを作って、
  • 会場でプレゼンテーションをする。

というハッカソンをしました。

最終的に生成 AI (Gemini) を使ったちゃんと動く React ウェブアプリができて、プレゼンテーションも笑いが取れていたので大成功でした。

作るプロダクトは実用的なものでなくて構わないということでしたので、我々は振り切って、こんなウェブアプリを作りました。

Trapo App
Trapo App

Trapo は「伝統的政治家(traditional politician)」を略したタガログ語で、皮肉的に使われる言葉です。チーム仲間が教えてくれました。
これは、それっぽい trapo スピーチを作ってくれるというもので、何かの役に立つというものではないですが、こういう場でしか作らないなというのであえて作ってみました。

私のハッカソン経験は マナビアップデートソン2023 しかなく、マナビアップデートソンは準備期間は3週間ほどありました。
しかし今回は初めましての人たちと40分間で1つアプリケーションを作るという内容でしたので、40分のカウントダウンが開始されて、まずは GitHub リポジトリの URL や API キーを送り合う術がないからと連絡先を交換し、いざプロンプト一発で作ったアプリケーションを動かしてみたらエラーが出るぞと騒いで、発表時は Zoom に入室して画面シェアしますからと言われ Zoom を立ち上げたらアップデートが走り発表に間に合わないぞと焦ったり、とにかく終始わちゃわちゃでした。

でも振り返ってみると、自分もそのわちゃわちゃの中心にいたので、その分達成感も味わえましたし、英語や環境を理由に気後れしてその場をやり過ごすのではなくちゃんと行動できるんだという自信も得られましたので、その点でもとても良い経験になりました。

ちなみにハッカソンが終わった後はみんなでどのチームのプレゼンが良かったかを投票し、さらに各チームの総評を LT にも登壇していた方がしてくれました。(我々が何位だったかは伏せます。)

その後は全体で写真を撮り、いろんな人と会話をしたり連絡先を交換し、帰りは同じ方向の人たちと途中まで一緒にタクシーで帰りました。
車内でもずっとそれぞれの会社のことや Cursor のことで会話が盛り上がって、またどこかのイベントで一緒になったらいいなと思っています。

以上、 Cursor Meetup Philippines の現地レポートでした!

改めて、 Cursor Meetup Philippines を開催してくれた運営チーム、 LT の登壇メンバー、 30分間の AMA セッションに出てくれた Ryo Lu 氏に感謝です!

そして実は今回、我々が PH チームとも呼んでいる RareJob Philippines の開発チームの仲間と一緒に参加したいと思って探してきたテックイベントだったのですが、結局のところ PH のメンバーと参加することは叶いませんでした。
フィリピンには電車の路線は3本しかありませんし交通渋滞も非常に多いので、東京であれば通勤圏内と言えるような距離であっても、我々の場合は休日に都心部で集まるというのは簡単なことではないのかもしれないと、改めて感じる機会にもなりました。

ただこれからも、日本とフィリピン両開発組織のためにフィリピンにいるからこそ出来ることを見つけ実践し、世の中のマナビをアップデートするプロダクトを届けていきたいです。

では最後に Ryo Lu 氏の言葉を、もう一度。

"Just build."

Amazon Bedrock をフル活用したAI講師による新しい英会話レッスン

aws.amazon.com

お疲れ様です、@jumboOrNotです。 この記事をあなたが読んでいるということは・・・もう AWS Summit 2025 は終わったということでしょう・・・

こちらの記事でも書かせていただいた AWS Summit 2025 が終わりましたー! 今年も多くの方にブースにも訪問いただき、プロダクトのご紹介やテクノロジーに関する議論を多くさせていただく機会に恵まれました。

構成図や仕組みについてブースで展示されていた資料に多くのご質問や資料が欲しいと言っていただけたので「あとでテックブログ書くんで見てくださいー!」と言ってしまった手前、この記事の中で資料の中で言及していたことをご紹介していこうと思います。 少しでも訪問いただいた方にも届くようにタイトルを出展名にしている都合、めっちゃ堅い。堅いタイトル。

今回の展示内容「AI講師による英会話体験」

レアジョブではAIを活用した様々なサービスを提供しており、「レアジョブ英会話」というプロダクトの中でもいくつかのプロトタイプを提供しています。AI英会話はそのうちの機能の一つで、下記のような機能です。

AI講師とのチャット形式で英会話を行います。Daily News Article教材を活用し、日常的なトピックで英語力を高めます。レッスン中にはAIがリアルタイムでフィードバックを提供し、語彙や表現の向上を手助けします。

www.rarejob.com

実際の利用の様子

現在ではレアジョブ英会話の会員様向けに弊社でも人気の英語記事 Daily News Article を利用したレッスンに対応し限定的に公開しています。

構成するリソースと仕組み

AI英会話の構成図は以下のようになっています。

またそれぞれを簡単に紹介すると

  • Amazon Transcribe: 生徒が発話した音声をテキストに書き起こします。
  • Amazon Bedrock: AIメッセージ生成の核となるサービスで、基盤モデルとして図にはClaude 3.5 Sonnetと記載していますが現在はClaude 3.5 Haikuを利用しています。
  • Amazon Polly: 講師の発話するテキストを音声データに変換します。
  • Amazon ECS (Elastic Container Service): Web Socket接続を処理し、各サービス間の連携をオーケストレーションするコンテナ実行環境です。
  • AWS IoT: 生徒と講師とのリアルタイム双方向通信の基盤を提供します。Publish/Subscribeモデルでメッセージをやり取りします。
  • Amazon RDS: 会話のテキストデータなど、構造化されたデータを格納します。
  • Amazon S3: 音声データなど、非構造化データを格納します。

構成としてはシンプルですが、実際のレッスンをシミュレーションできるようにWebSocketを扱うために AWS IoT を使っていたり、発話もAmazon Pollyで音声にしているなどシームレスなレッスン体験になるようにフロント・バックエンドともに工夫をしています。

主に構成図などに質問いただいたこととしては

Q, AWS Iot を使っているのはなぜ?

A, シームレスなレッスンになるようにWeb Socketを導入している。構成としてシンプルにしたい理由もあり、自前で管理することなくIoT CoreのWebSocketを利用している。

Q, Amazon Transcribeの精度は問題になる?

A, 現在は英会話レベルも少し高い人向けの教材を利用しているため、そもそも発話のレベルが一定高い人が使っており課題になっていない。発話環境(ノイズなど)にも依存はするが今のユースケースでは問題ない。

Q, コストはどうか

A, フルマネージドな構成を主としており、利用量に基本は応じるがサービス提供で課題にはならないレベル。発話量などにも依存するため、今後は課題が出るようなレッスン形式も出てきそうに思っている。

Q, Bedrockのspeech to speech は使わないのか

A, 将来的に音声やテキストの情報を集計してメトリクスやレポートを提供する予定でテキストも必要なのでテキストで扱いたいためこうしている

Q, モデルは適切なのか

A, コスト・品質の面から考えても今のところは課題はない。レッスンの構成自体がシンプルなので回答や生徒の発話する内容もブレにくいためだと思っている

さいごに

お足元も悪い中弊社のブースにお越しいただいた皆様ありがとうございました。また来れてない方でも本記事を見てくださりありがとうございました! サービスやプロダクトについて不明点などあれば遠慮なくXや問い合わせからご連絡ください。

来年のAWS Summitもよろしくお願いしますー!

気づいたらAIまみれ2025、AWS Summit もあるよ

レアジョブテクノロジーズでCTOをしている @jumboOrNot です。

もうAIって言葉を目にしない・耳にしない・口にしない日はないくらい日々様々なサービスやテクノロジーがアップデートされ続けています。 弊社においてはプロダクトでの活用はもちろん、業務においてもAIに関する様々な取り組みをしているのですが外部向けにあまり書いてなかったので書こうと思います。 弊社の採用選考の中でも聞かれることも増えてきていて、そういった方やこれから弊社を知っていただく方向けに書ければと思います。(あくまでこの時点の話で、すぐ状況も変わるのであくまで現時点の状況と方針をば・・・)

業務におけるAI活用(コーディングエージェント編)

よく使われてるツール

コーディングにおいては、以下のツールを会社として導入し、積極的に業務で利用しています。

  • Cursor Business
  • GitHub Copilot Pro
  • Windsurf

これらのツールは、コード生成、デバッグ支援、リファクタリングなど、多岐にわたる開発タスクにおいて、私たちの生産性に貢献してくれています。

昨年は一部の希望メンバーにのみアカウントを用意していましたが、今ではその効果を実感し、ほぼ全員のPdM、デザイナー、Web、アプリ、インフラといった多岐にわたる業務領域のメンバーにアカウントを付与し、日々の業務で役立ててもらっています。チーム全体の生産性が向上しないと意味がないという考えから、契約形態にかかわらず積極的にアカウントを付与しAIの恩恵を受けています。

弊社で利用しているAIコーディングエージェントの中で、最も利用が多いのはCursor Businessです。VSCodeベースなことだったり、直感的なインターフェースと強力なコード生成能力は、開発のスピードアップに大きく貢献しています。XcodeやJetBrains製品をエディタとして使っているメンバーはプラグイン的に使うことが多く、Copilot の利用者が多いです。

もちろん、メインは上記のようなツールではありますが特定のツールに固執することなく、常に新しいサービスの検討と調査を続けています。いずれのサービスも日々進化しており、限定することでノウハウやナレッジをチーム内で共有しやすくなるというメリットもありますが、メンバーそれぞれが異なるエディターや扱う言語を用いることもあるため、最適な選択肢を模索し続けています。

こういったツールは単にアカウントを付与するだけでなく、導入後のフォローやサポートのためにAIツールの利用状況を個別にモニタリングしています。これらの内容を元に勉強会や各チームの動きを全体に共有しています。 Cursorでは管理画面から詳細な利用状況を把握できるほか、GitHub Copilotについては copilot-metrics-viewer を活用し、利用実態のヒアリングなども行っています。私も自分の管掌部門でないチームがどんな用途で使っているかは想像にも限界があり、数値を元に気になりポイントをヒアリングするようにしています。 直近でも特定部門での Premium Request の利用料が多く、考えてなかったユースケースもあり学びがありました。 Cursorについては、Premium Request のチーム全体での金額上限設定については、利用者からは見えにくい部分でもあります。そのため、利用状況全体を見ながら、常に最適なバランスを全体で相談しています。利用者側もどれくらい使うかをイメージできないと思うので、必要に応じて利用料を確認できる権限を必要な人に付与して必要な時に利用できる状態を全体で議論できるといいと思います。

業務におけるAI活用(その他編)

弊社は Google Workspace を導入しているので身近なところでは Gemini と NotebookLM がよく使われているように思います。 最近は録画や議事録の自動作成も全部やってくれるので、MTGに集中できる人が増えましたね。去年くらいはまだ日本語の文字起こしすら対応してなかった気がするので、時間の進み方が本当に早いですね。 Deep Research で調査・作成したレポートを社内展開するみたいなケースではコードまで Gemini で作成して Google Site に貼り付けて共有したり。調べる工程と結果をまとめる工程が一気に進められるのでとても助かっています。

業務におけるAI活用(今後)

AIを最大限に活用したプロダクト開発やプロジェクト推進が当たり前になり始めているので、AIを実際に活用したり経験できる環境自体が職場環境における優先度が上がってきているように思います。 ツールの導入やトライアルは、セキュリティ・ガバナンス・費用・効果など考えることが多く、ケースによっては全体で予算調整したり、セキュリティ受容したりガイドラインを設けたりと、なかなかボトムアップでやるのが難しいので、CXOが現場と話しつつバランス感を持って推進していくのが重要だし効果的だと考えています。とはいいつつ、ツール試していると本当に時間が溶けるので、メンバーからも希望やフィードバックをもらいながら何を選ぶかを日々悩みながら進めています。 休む間もなくツールが増えていくので、時間の許す限り片っ端から試しはしつつもリソースに限りはあるので判断が難しいことは多いですが、その分楽しんでいけたらと思います。

検証・検討していること

まだまだ定常的な運用まで辿り着いてないですが、下記のようなことも検証・検討しています。

  • GitLabやFigma(ちょうど公式が出たところ)などのMCPにおけるAI機能の検証と活用、FigmaがMCP出したことでAIによりプロダクトデザインとエンジニアリングの境界が曖昧になっているところが徐々に出てきており、デザインチーム・フロントエンドチーム主導で試しています
  • 弊社のグループ企業である RareJob Philippines にも講師向けシステムを作ってくれているエンジニアチームがあり、安全・効果的に導入活用してもらえるようにフォローの仕方を検討しています
  • コードの生産量が増えることで、PRも増えてレビューコストも増える見込みもあり、PR-Agent 段階的に導入し効率化と品質維持をできないか検証しています
  • グループ企業に対してのヒアリングを通して、Difyなどのソリューションベースでの運用改善を始めました

などなど、いろいろやっているところです。 エンジニアの生産性だけでなく、全体の生産性を大きく変える可能性のある手段が多く提供されている時代なのでトライアンドエラーを様々な分野で進めていこうと考えています。

AI英会話機能:ベータ版公開中!

prtimes.jp

このようなAIコーディングエージェントを積極的に活用しながら開発しているAI英会話機能が、現在ベータ版として公開されています!

AIがあなたの英会話学習を強力にサポートし、より実践的なコミュニケーション能力の向上に貢献します。 レアジョブ英会話をご利用のユーザー様であれば、ウェイトリストにご登録いただくことでご利用いただけます。 ぜひ、この新しいAI英会話機能を活用していただき、忌憚のないフィードバックをいただけますと幸いです。皆様からのご意見が、サービスのさらなる進化に繋がります。

www.rarejob.com

AWS Summit 2025 出展決定!

aws.amazon.com

そして、このAI英会話機能の技術的な詳細やデモンストレーションを、今年のAWS Summit 2025でも展示予定です。開発に興味のあるエンジニアの皆様、ぜひブースにお立ち寄りください!レアジョブテクノロジーズは、AIの力を最大限に活用し、より良い英会話体験と、より効率的な開発環境の実現に向けて、これからも挑戦を続けていきます。

レアテクでは社内LT会が月1であり、この前第5回を迎えましたと言う話

はじめに

はじめまして。プラットフォームチームの奥山阿論です。

今回の話はタイトルの通り、「レアジョブテクノロジーズでは社内LT会が存在し、先日第5回を終了した」です。

筆者が言う社内LT会とは?

LTはLightning Talkの略称です。基本は5分以内にスライドを用いて何かしら発表することを指します。(と思ってます。)

エンジニアをやっててコミュニティに参加している方達だと、 カンファレンスや地域に根差した言語コミュニティなどで見かけることが多いかもしれません。

1時間の枠をとって時間の許す限りLTやろう!と言うのを社内でやってます。

発案者が私なので運用は私がやってます。

なぜ社内なのか?

社内に転がっている技術的に面白い話には、外に出せないものもあります。(まずい負債が放置されていると言う感じではなく、レアジョブの各種プロダクトに関する前提知識を結構持ってないと楽しめない等々)

それもLTネタとして出していただくことを考慮した結果、社内に閉じた会にすることにしました。

現状

毎回の参加人数は13~18人くらいです。(ここは私のゆるふわ記憶です)

発表内容の内訳ですが、私の独断と偏見でざっくりとカテゴリ分けするとこんな感じです。

カテゴリ内訳

発表タイトルは下記参照ください。(事情から一部タイトルを私の方で変更したものもあります)

発表タイトル一覧

運用

コンセプトとしては「長く続けられるようなるべくシンプルにする」となります。

と言っても運営が開催までにやることは下記のとおりです。

  • 次回の開催日程を決めて、Slackの専用チャンネルと全体チャンネルで周知する(メンションはつけない)

  • 参加したい方がエントリできるようエントリ宣言先を用意する(弊社ではConfluenceにテンプレートを用意している)

  • 開催までに適度なサイクルで周知して参加者と登壇者を募る

あとは当日、Confluenceを眺めながら発表管理をすればOKです。

LT初回開催のために準備したもの

運用は上記の通りなので

  • 専用のSlackチャンネル開設

  • エントリ宣言先のテンプレート化

だけしました。

LT初回開催のための社内コミュニケーション

長いのでまとめると

  • 会の存在を社内パブリックな場で周知する

  • 会自体に参加しやすいとアピールする

  • 参加者が安心して参加できるよう自分がちゃんと保護すると周知する

を実行しました。

LT初回開催のための社内コミュニケーション(具体例)

人が集まるために自分が必要だと思うことをしました。

  • 社内で承認を得た存在であること

  • LT会を認知してもらうこと

このような存在であると薄く認知してもらえればまあ10人くらいは来てくださるだろうと思いました。

弊社にはこれを達成するピッタリな場があります。

プロダクトよもやま会」です。週2回設定されてますが、何もない場合はskipされます。

このmtgでは

  • レアジョブテクノロジーズで見ているプロダクトに関するアーキテクチャやリリース前のレビュー

  • 障害発生時のポストモーテムをシェアする

  • 社内制度・システムの変更内容の周知

など「割と社内全体が知るべき/知っておいても良さそう」な内容が発表されます。

このmtgで話す内容は割と社内全体向けの傾向が高くなっています。

CTOに「この内容で話しても良いでしょうか?」と念の為の承認を得た上で、まずはこの場を利用してLT会に関するプレゼンを行いました。

会のその場で「OK」と言う話になったため、即日Slackチャンネルを作成し、その中でConfluenceのテンプレートを用意して周知しました。

次に、参加障壁を下げるために

  • 資料形式はConfluence, スライド, 画面共有 などなんでも良い。そしてカテゴリは問わない。

  • もし誹謗中傷があった場合に私がどんな対処をするか?

を何回かに分けてプロダクトよもやま会で周知しました。

と言っても協力的な姿勢の方が多かった・・・

弊社には実況チャンネルが存在してます。

そこを使って実況すると言う発想がなかったので、始めてくださった重谷さん(弊社アプリエンジニア)、そしてそこで積極的にワイワイしてくださっている皆さんには感謝しかありません。

チャット上でのワイワイは個人的にLT会実施の際の醍醐味だと考えてます。

他にもテンプレートの改善案、資料の置き場所変えたらどうだろうと言った提案などなど・・・。

色々な方から改善案を頂戴できました。

(もし私が見落としている提案があったら本当にすいません。もっと気付けるようにします。)

参加者の皆さんのおかげで小さな改善がたくさんあって5回目でかなり良い形になっていると思います。

この場を借りてお礼申し上げます。ありがとうございます。

LT会をより社内にとって良い存在にするために

  • 発表内容にテックカテゴリが多いですが、デザインカテゴリが増えるようにしたいと考えてます。

  • 参加意思をお持ちでかつ開催する時間帯が合わない方が散見されているので、時間帯の改善を実施したいです。

  • LT会への参加・不参加を問わず、不満や意見を集積する場所を作りたいです。

何よりも、「参加意思のある方たちの気持ちを第一に考えた運用をしていきたい」と考えてます。

もう1つ感謝を・・・

LTを社内導入するにあたり、Kyoto.goにおけるコミュニティ運営の経験が生きました。

私が運営に携わり始めたのは、(私から見ると)運営の型がかなり出来上がった状態だったため、そのシステムに乗って学ばせていただいたと思ってます。

後から考えると、「LT会立ち上げとその運用をレアジョブテクノロジーズではどうやるか?」を考える際、運営する中で染みついたものがかなり役立ったと思いました。

私を運営に誘ってくださったKyoto.goメンバーの皆様、そしてKyoto.goの参加者の皆様にとても感謝してます。

ありがとうございます。

最後に

We're hiring!
弊社では、一緒に働いてくださるエンジニアを募集しています。

ぜひ一緒にLT会でワイワイできたら嬉しいです。
rarejob-tech.co.jp

Vでレアジョブ英会話を受けてみた

まえがき

こんにちは、EdTech LabのYumaです!Apple Vision Proが登場した昨年、私は確信しました—これからはMR(Mixed Reality)の時代がやってきます。この新時代の英会話レッスン、皆さんはどんな風になると思いますか?

きっとアバターを使った授業が主流になり、その中にはAI教師も登場するでしょう。特に、技術とリソースが既に成熟した今、Vtuber的なアバターが人気になると思います。そこで今回、実験として、Vtuberアバターを使ってレアジョブ英会話を受けてみることにしました!

なんと、Mac一台でこれを実現する方法が見つかったんです!この方法を皆さんにシェアしたいと思います。

ちなみに、この方法はGoogle MeetやZoomでも応用可能なので、ぜひ試してみてくださいね!

レアジョブ英会話では、アバターの利用を公式にサポートしておらず、また推奨もしておりませんので、ご了承ください。

基本の流れ

Vtuber姿でレアジョブ英会話を受ける方法は、一般的なVtubing配信とほぼ同じです。違いは、映像の出力先が変わるだけです。以下の3つのステップで実現できます:

  1. アバターの準備
  2. アバターの操作
  3. 映像の出力

この基本をマスターすれば、オンラインミーティングだけでなく、配信も楽しめます!配信に興味のある方もぜひ参考にしてみましょう。

アバターの準備

Vtubingに使うアバターは、主に以下の2種類に分類されます:

  1. Vroid (3D)
  2. Live2D (2D)

今回は、初心者でも取り組みやすいVroidを使用します。
Vroidアバターは、自分で作るか、既存のアバターを利用します。一番手軽なのは、VRoid Hubから既存アバターをダウンロードすることです。ダウンロードするときは、アバターの利用規約をしっかり確認してくださいね。

アバターの操作

次に、アバターを動かしてみましょう!Vroidアバターを操作する方法はいくつもありますが、今回はMac一台で簡単にできる方法をご紹介します。使うのは「VCam」というアプリです。

VCamは、Mac上でWebカメラとしてVroidアバターを操作できるオープンソースアプリです。MITライセンスで利用できるのが嬉しいポイント!開発者の皆さんに感謝です。さらに、VCamにはOBSと連携できる専用モジュールもあり、セットアップが簡単です。

VCamの使い方

  1. VCamをダウンロード
  2. アプリに開く
  3. Vroidアバターファイルを読み込む
  4. アバターのサイズや位置を調整 これでVCamを使ってアバターを動かせるようになります。Google MeetやZoomで使うだけならVCamだけで十分ですが、今回はより高い自由度と配信にも応用できるOBSを使った方法をご紹介します。

映像の出力

いよいよ映像の出力です!Vtuber姿でレアジョブ英会話を受けるには、アバターの映像をWebカメラとしてブラウザに認識させる必要があります。そこで登場するのが「OBS」です。

OBSは、リアルタイム映像・音声のキャプチャーとミキシングができる便利なオープンソースソフトウェアです。

設定手順

  1. OBSVCamOBS連携モジュールをダウンロード
  2. OBSを起動
  3. 以下の設定を行う:
    • バックグラウンド画像を追加
    • VCamからのアバター映像を追加
    • アバター映像の背景を透明化
    • アバターのサイズや位置を調整
    • 映像をWebカメラソースとして出力
    • レッスンルームのカメラインプットでOBSの出力を選択

これでアバター姿で授業ができるようになります!やってみると意外と簡単ですよ。

レッスン体験

実際にVtuberの姿でレッスンを受けてみました。先生の対応は予想以上に塩対応で、もう少しビックリするのを期待していました。ただ、もともとDaily News Articleのレッスンだったため、雑談する時間はほとんどありませんでした。「これ、ちゃんと動いてるかな?」といった確認程度の会話しかなく、少し物足りない印象でした。雑談の時間が多いFree Talkのレッスンを選んだ方がよかったかもしれません。

今回はパーフェクトシンクを使用していませんでしたので、アバターの口や手の動きが少し見られる程度で、画面オフでレッスンを受けている感覚に近いものでした。次回はパーフェクトシンクを活用して、より自然なアバター体験に挑戦してみようと思います。

まとめ

いかがでしたか?今回はVtuber姿でレアジョブ英会話を受ける方法をご紹介しました!この方法を使えば、Google MeetやZoomなどのオンラインミーティングでも同じように活用できます。ぜひ一度試してみましょう!

ただし、英会話の授業では、先生が生徒の表情や仕草を観察し、それに応じたサポートを行うことが大切です。そのため、Vtuber姿で授業を行うのはおすすめしません。遊び感覚でたまにやる程度が良いでしょう。

高度な表情同期をしたい場合は、パーフェクトシンクと言う方法もありますが、アバターには限界があることも忘れずに。できるだけ顔出しで授業を行うのがおすすめです!

それでは、みなさんもぜひ挑戦してみてくださいね!

RoadRunner + Slim Framework で高性能な PHP 実行環境の構築

はじめに

こんにちは、DevOps グループの中島です。
最近急に寒くなり、年の瀬を感じる時節になってきましたね。そういえば去年の年末は Herman Miller でセールをしていたので、駆け込みでイスを買ったのを思い出しました。

今回は性能が高いと評判の PHP アプリケーションサーバー RoadRunner を Slim Framework (Slim 4) で使うための設定手順と、簡単な性能の検証結果を共有したいと思います。

RoadRunner とは

RoadRunner は Go で書かれたオープンソースの高性能な PHP アプリケーションサーバ & プロセスマネージャで、プラグイン機構をサポートしています。

RoadRunner is an open-source (MIT licensed) high-performance PHP application server, process manager written in Go and powered with plugins ❤️. It supports running as a service with the ability to extend its functionality on a per-project basis with plugins.

nginx + php-fpm ではその構成上 HTTP サーバとアプリケーションサーバが分離されているため、リクエストを受け付けるたびに PHP 側でフレームワークの初期化を行う必要がありましたが、 RoadRunner では付属の HTTP サーバでリクエストを受け付けたあと、すでに初期化が走ったあとでデーモン的に動作している PHP のワーカーがリクエストを処理する構成となっているため、パフォーマンスの向上に繋がっています。

細かい特徴は ドキュメントZenn の記事 に譲ります。

セットアップ

まずは必要なツール類をインストールします。 OS は Ubuntu 24.04 LTS を利用しました。

PHP インストール

$ sudo apt update
$ sudo apt install php php-xml php-mbstring unzip

Composer インストール

$ curl -s https://getcomposer.org/installer | php
$ sudo mv composer.phar /usr/local/bin/composer

RoadRunner インストール

$ wget https://github.com/roadrunner-server/roadrunner/releases/download/v2024.3.0/roadrunner-2024.3.0-linux-amd64.deb
$ sudo dpkg -i roadrunner-2024.3.0-linux-amd64.deb
$ rm roadrunner-2024.3.0-linux-amd64.deb

アプリケーション作成

次に、Slim のサンプルプロジェクトを作成します。

サンプルプロジェクト作成

$ composer create-project slim/slim-skeleton sample-app

ここまでで、サーバを起動してアクセスするとサンプルが動作することが確認できます。

$ php -S 0.0.0.0:8080 -t public
$ curl localhost:8080
Hello world!

RoadRunner 用設定

RoadRunner の組み込みに必要な設定をしていきます。

RoadRunner と関連ライブラリを依存関係に追加

$ cd sample-app
$ composer require spiral/roadrunner spiral/roadrunner-worker spiral/roadrunner-http nyholm/psr7

RoadRunner の設定ファイル作成

$ vi .rr.yaml

version: "3"

server:
  command: "php psr-worker.php"

http:
  address: 0.0.0.0:8080

logs:
  level: error

ワーカーの作成

ここから、PHP のワーカーである psr-worker.php を作成していきます。
RoadRunnerのガイド による実装は以下の通りです。

<?php

require __DIR__ . '/vendor/autoload.php';

use Nyholm\Psr7\Response;
use Nyholm\Psr7\Factory\Psr17Factory;

use Spiral\RoadRunner\Worker;
use Spiral\RoadRunner\Http\PSR7Worker;
$worker = Worker::create();

$factory = new Psr17Factory();

$psr7 = new PSR7Worker($worker, $factory, $factory, $factory);

while (true) {
    try {
        $request = $psr7->waitRequest();
        if ($request === null) {
            break;
        }
    } catch (\Throwable $e) {
        $psr7->respond(new Response(400));
        continue;
    }

    try {
        $psr7->respond(new Response(200, [], 'Hello RoadRunner!'));
    } catch (\Throwable $e) {
        $psr7->respond(new Response(500, [], 'Something Went Wrong!'));
        $psr7->getWorker()->error((string)$e);
    }
}

ただ、当然このままでは動作しません。Slim で利用するのですから、Slim のフレームワーク初期化処理やレスポンスの生成処理を加える必要があります。

Slim-Skeletonindex.php では、フレームワークの初期化が走ったあと、以下の部分でレスポンスを生成して出力しています。

<?php
...
// Run App & Emit Response
$response = $app->handle($request);
$responseEmitter = new ResponseEmitter();
$responseEmitter->emit($response);

このため、ワーカーでは上記のレスポンス生成処理を、リクエストを取得して処理するループの中に加えてやれば OK です。

<?php
...
while (true) {
    try {
        $request = $psr7->waitRequest();
        if ($request === null) {
            break;
        }
    } catch (\Throwable $e) {
        $psr7->respond(new Response(400));
        continue;
    }

    try {
        // コメントアウト
        // $psr7->respond(new Response(200, [], 'Hello RoadRunner!'));

        // Slim のレスポンス生成処理を追加
        $response = $app->handle($request);
        $psr7->respond($response);
    } catch (\Throwable $e) {
        $psr7->respond(new Response(500, [], 'Something Went Wrong!'));
        $psr7->getWorker()->error((string)$e);
    }
}

以下に完成したワーカーのコードを置いておきます。

性能検証

Apache Bench で性能を簡単に測定した結果を以下に示します。

条件

項目 内容
サーバのインスタンスタイプ c5.large
クライアントのインスタンスタイプ c5.xlarge
HTTP サーバとアプリケーションサーバ間の通信 Unix ソケット
php-fpm のプロセス数 100 固定
RoadRunner のワーカー数 100 固定
コンテンツ Hello World! を返すだけ
ログ出力 しない

結果

同時接続数 nginx + php-fpm RoadRunner
1 660.75 925.74
2 1059.36 1659.52
3 1241.54 2191.29
4 1283.96 2475.24
5 1308.92 2591.36
10 1363.07 2820.52
100 1373.17 3268.43
150 1353.76 3261.71

RoadRunner は nginx+php-fpm の約 2.5 倍リクエストを捌けていました。すごい。*1

終わりに

Ubuntu と Slim の構成 (とイスの話題) でピンときた方もいると思いますが、これは ISUCON を意識したものです。 社内で声をかけて今回はじめて参加することが出来たので、素振りの時に試した内容を記事にしました。 いろいろ学びがあり、何よりやってて楽しかったので来年以降も参加したいと思っています。

We're hiring!
弊社では、一緒に働いてくださるエンジニアを募集しています。
rarejob-tech.co.jp

*1:本来は業務ロジックが処理の多くを占めるため、ここまでの改善は見込めないと想定される一方で、 PHP のキャッシング機構も利用できるため、既存のプロダクトに適用してどれほど性能が向上できるかはそのプロダクトの性質によります。また、メモリリークが発生しないサードパーティのライブラリを選ぶなどのケアする課題はあるため、本番環境への採用は慎重に行う必要があります。

Flake8, autoflake, Black, isort を Ruff へ置き換える際に行ったこと

はじめに

  • EdTech Lab の中島です。 英語スピーキングテスト PROGOS の機械学習モデル開発・改善などを担当しています。
  • Python プロジェクトで利用していた Linter・Formatter ( Flake8, autoflake, Black, isort ) を Ruff に置き換えることで実行時間を約41%~79%短縮することができました。
  • 以下では使用した環境と Ruff の概要について記載し、その後 Flake8, autoflake, Black, isort を Ruff へ置き換える際に行った内容を説明します。

環境

  • Python 3.9.10
  • Poetry 1.8.3
  • Ruff 0.8.2
  • 使用していた Linter, Formatter
    • Flake8 3.9.2 (静的解析のために使用)
    • autoflake 1.7.8 (未使用の import, 変数を削除するために使用)
    • Black 24.8.0 (Formatter として使用)
    • isort 5.13.2 (import をソートするために使用)

Ruff について

  • GitHub には以下のような特徴が挙げられています。
    • Rust で書かれた高速な Linter 兼 Formatter です。
    • 単一の共通インターフェースの下でより多くの機能を統合しながら、他の代替ツールと比べて桁違いに高速であることを目指しています。
    • URL先のように多数のオープンソースプロジェクトで使用されています。

Flake8, autoflake を Ruff へ置き換える際に行ったこと

  • Flake8, autoflake と Ruff Linter について
    • The Ruff Linter には以下の記載があり、Flake8, autoflake を置き換え可能であることが説明されています。

      The Ruff Linter is an extremely fast Python linter designed as a drop-in replacement for Flake8 (plus dozens of plugins), isort, pydocstyle, pyupgrade, autoflake, and more.

設定ファイル変更内容

  • setup.cfg に記載されていた Flake8 の設定を pyproject.toml へ移行しました。
  • Ruff は pyproject.toml 以外にも、.ruff.toml, ruff.toml に設定を記述することができます。より詳細な説明は URL 先 をご参照ください。

    元の setup.cfg 変更前設定内容

# 元の setup.cfg 変更前設定内容

[flake8]
max-line-length = 119
ignore = E121,E123,E126,E133,E226,E241,E242,E704,W503,W504,W505,E127,E266,E402,W605,W391,E701,E731,E203
exclude = ./path/to/exclude/folder/*

pyproject.toml 変更内容

# pyproject.toml

[tool.ruff]
target-version = "py39"
line-length = 119
extend-exclude = ["./path/to/exclude/folder/*"]


[tool.ruff.lint]
# https://docs.astral.sh/ruff/rules/
select = [
"E", # "E" pycodestyle error
"F", # "F" Pyflakes
"W", # "W" pycodestyle warning
]

ignore = ["E203", "E226", "E241", "E242", "E266", "E402", "W391", "W505", "W605", "E701", "E731"]
extend-safe-fixes = ["F841"]

pyproject.toml の設定内容詳細

  • section 毎に記載します。
  • URL 先は関連する Ruff のドキュメントです。
[tool.ruff]
  • target-version
    • プロジェクトで使用していた Python 3.9 を指定しています。
  • line-length
    • 長い行の違反(例: E501)を検出する際や後述する isort や Formatter が行を折り返す際に用いる長さです。プロジェクトで使用していた 119 を指定しています。
  • extend-exclude
    • exclude に加えてフォーマットやリントから除外するファイルパターンのリストです。プロジェクトで使用していた Flake8 の設定に含まれていたフォルダを指定しています。
[tool.ruff.lint]
  • select
    • Flake8 が wrap している中から Pyflakes, pycodestyle error, pycodestyle warning を指定しました。( McCabe はプロジェクトで使用していなかったため指定していません。)
  • ignore
    • setup.cfg の ignore のうち Ruff で実装されているものを指定しました。
  • extend-safe-fixes
    • Ruff が安全でないとみなしている修正を安全なものとして許可するルールを設定可能です。
    • 使用していた autoflake のオプション --remove-unused-variables と同様の挙動にするため F841 (unused-variable) を追加しました。

Makefile 変更内容

check1: 
-    @poetry run flake8 ./path/to/check1/target
+    @poetry run ruff check ./path/to/check1/target

 check2
-    @poetry run autoflake --remove-all-unused-imports --remove-unused-variables --in-place --recursive .path/to/check2/target 
+    @poetry run ruff check --fix .path/to/check2/target
  • Ruff Linter は ruff check command によって実行することができます。
  • flake8ruff check で置き換えました。
  • autoflake を利用している箇所を ruff check --fix で置き換えました。

Black を Ruff へ置き換える際に行ったこと

  • Black と Ruff Formatter について
    • Black compatibility には The formatter is designed to be a drop-in replacement for Black. との記載があり ruff format を実行することで Black 相当の format を実行することが可能です。( 詳細ドキュメント )
    • Black と Ruff Formatter 間の差異については Known Deviations from Black に記載があります。

設定ファイル変更内容

pyproject.toml 変更内容

# pyproject.toml

[tool.ruff]
target-version = "py39"
line-length = 119
extend-exclude = ["./path/to/exclude/folder/*"]


[tool.ruff.lint]
# https://docs.astral.sh/ruff/rules/
select = [
"E", # "E" pycodestyle error
"F", # "F" Pyflakes
"W", # "W" pycodestyle warning
]

ignore = ["E203", "E226", "E241", "E242", "E266", "E402", "W391", "W505", "W605", "E701", "E731"]

+ [tool.ruff.format]
+ quote-style = "double"

pyproject.toml の設定内容詳細

[tool.ruff.format]
  • quote-style に Black で利用している "double" を指定しました。

Makefile 変更内容

 format-check: 
-    @poetry run black --check --diff --line-length 119 .path/to/format/target
+    @poetry run ruff format --check --diff .path/to/format/target

 format:
-    @poetry run black --line-length 119 .path/to/format/target
+    @poetry run ruff format .path/to/format/target

isort を Ruff へ置き換える際に行ったこと

設定ファイル変更内容

  • 変更前の isort の設定には Ruff のドキュメントに置き換え可能と記載があった profile = "black" を使用していました。

    pyproject.toml 変更内容

# pyproject.toml

[tool.ruff]
target-version = "py39"
line-length = 119
extend-exclude = ["./path/to/exclude/folder/*"]


[tool.ruff.lint]
# https://docs.astral.sh/ruff/rules/
select = [
"E", # "E" pycodestyle error
"F", # "F" Pyflakes
+ "I", # "I" isort
"W", # "W" pycodestyle warning
]

ignore = ["E203", "E226", "E241", "E242", "E266", "E402", "W391", "W505", "W605", "E701", "E731"]
extend-safe-fixes = ["F841"]

[tool.ruff.format]
quote-style = "double"

pyproject.toml の設定内容詳細

[tool.ruff.lint]
  • isort を利用するために select へ "I" を追加しました。

Makefile 変更内容

 format2
-    @poetry  run isort .path/to/isort/target
+    @poetry run ruff check --fix .path/to/isort/target && poetry run ruff format .path/to/isort/target
  • ドキュメントの以下の引用箇所のように isort 利用箇所は2つのコマンドruff check --fixruff format で置き換える必要があります。

    Sorting imports Currently, the Ruff formatter does not sort imports. In order to both sort imports and format, call the Ruff linter and then the formatter:

実行時間比較

  • time コマンドを使用して実行時間を比較しました。
ツール 変更前 (秒) 変更後 (秒) 短縮率
Flake8 → Ruff 3.14 0.69 79%
Black → Ruff 1.79 0.67 62%
autoflake → Ruff 1.53 0.55 64%
isort → Ruff 1.78 1.04 41%

最後に

お知らせ

  • 弊社では URL 先の職種を募集しています。ご応募お待ちしております。

rarejob-tech.co.jp