知人と共同創業し、自分は開発を主に担当。
求職者向けには、LLMを用いて職務経歴書の添削、求職者の経験や志向性に基づいたレコメンドを行うサービスを提供した。
企業の人事や面接官向けには、AIにより応募者の職務経歴書をレビューする機能を提供。さらに、選考ステップをワークフロー化し、面接の日程調整やメール送信を限りなく自動化することを目指した。
また人事によるスカウト業務を効率化するため、ダイレクトスカウトサービスに登録された求職者をAIが事前にレビューし、採用要件に合致した求職者を提案する機能を Google 拡張機能として開発した。
プライベート環境で OpenAI API を使用するため、初めて Azure を利用。
上述したように LLM が基盤技術となるため、当初はバックエンドに Python (Django) を採用し、 LangChain や LlamaIndex 等の LLM 関連ライブラリをバックエンドで直接使用する形で実装した。
しかし、この領域は黎明期ということもあってライブラリの破壊的変更が多く、スタートアップとして求められる開発スピードを達成できない不安があったため、途中でライブラリを使用せず直接 OpenAI API を利用する方針に切り替えた。
Python という制約が無くなったので、新規プロダクトに関しては開発スピードを優先に、バックエンドを Node.js にし、 TypeScript による monorepo 構成とした(フロントエンドは共通して Next.js)。
インフラはこれまでの経験から最も使い慣れた AWS を選択。バックエンドは RDS, ECS, ALB 等の定番構成。フロントエンドは Amplify を主に使用しつつ、タイムアウトの制約問題などにより一部の Next.js プロジェクトは App Runner で運用。その他、求人検索や RAG のベクトルデータベースとして ElasticSearch も使用。
ジュニアレベルのメンバーが中心の開発チームで、技術的なサポート役を担った。
開発に関しては主に設計の壁打ちや、リファクタリングをメインに担当した。
とにかく「あたりまえの開発体制」を早急に作るべきだと判断した。
Django, DRF, OpenAPI, TypeScript, Node.js, WebSocket, Next.js, MySQL, Terraform, AWS Amplify, ECS, RDS, CircleCI, GitHub Actions
Shopifyを利用してECサイトを構築した。Shopifyの機能に乗ることで決済やフロントエンドの開発はほぼ無かったが、ロジスティクス部分(日別の在庫管理、セット商品の内訳管理、発注、ピッキング用の帳票出力、配送管理など)は自前で開発する必要があり、RailsとShopifyのAPIを連携させたWebアプリを一人で構築した。
リリース後は、データ分析やユーザーインタビューといったカイゼン系、カスタマーサポート、及び競合調査や事業PL策定など、ビジネス側の業務を担当した。
物流センターでのピッキングや配送業務にも携わったことで、ITだけではどうにもならない多くの課題と向き合えたことは良かった。あるべき理想像との折り合いについて悩むことも多かったが、新規事業に求められるスピード感を維持しながらも、ある程度堅牢なシステムを組めたのではないかと思う。
一方、どれだけスマートなシステムを作ることができても、事業として持続可能なビジネスモデルなくしてはエンジニアとして価値を発揮できないのだと強く認識した。
会社のメインプロダクトである、飲食店向けに水産品などの生鮮品を販売するECサイトを3、4人のチームで開発した。主な開発内容は顧客向け画面やCS用の管理画面、ピッキングや配送などのロジスティクスの管理機能など。
数ある食品の中でも特殊な「魚」というモノを扱う複雑なオペレーションをどう抽象化し、システムとして設計するか悩むことが多かった。小さいチームであったので、開発だけでなく現場での調整や仕様検討から携わることができたのは良い経験になったと思う。
またRailsやRubyのアップデート、CIの整備など、自分の興味と課題意識が強い分野を率先して担当し、ある程度モダンな開発環境に近づけることができたことで自信につながった。
一方でパフォーマンスやスケーラビリティといったWebアプリとしての技術的課題はあまり多くなかったので、今後はそのような要件に対しても強みを持ちたいと考えるきっかけになったと思う。
これまで手書きされていた配送情報を記載したラベルシールを、Android端末、ハンディスキャナ、ポータブルプリンターを用いて自動印刷するシステムを1人で企画、設計、開発した。
RubyとJavaScript以外はほとんど業務で触ることが無く、初めてのAndroidアプリ開発ではあったが、Kotlinのシンプルな言語仕様とIDEの力に助けられ、思ったよりもかなりスムーズに開発を進めることができた。JavaScriptによるフロントエンド開発と親和性を感じられたからか、MVVM的な実装もうまくやれたと思う。
Bluetoothの不安定な接続には悩まされたりもしたが、通常のWeb開発ではあまり経験できないようなバックグランド処理やスレッドの扱いなどを経験することができたのは良かった。
社内向けの小規模なアプリケーション開発をいくつか担当した。
特に難しい技術的課題は無かったが、企画段階からすべてを1人で担当したので、この会社としては初めて本番環境でDockerを使用したり、ライブラリのバージョンアップを自動化する仕組みを導入したり、デプロイを含む完全なCI/CIパイプラインを構築したりと、インフラ周りを自由に構築することができたのは良かった。
かなり雑然としているので箇条書きで記す。
機械学習を用いて、自社で運営しているECサイトの未来の受注件数を予測する仕組みを1人で構築した。
大型連休などのイレギュラーを除くと、90%以上の精度で明日以降の受注件数を予測することができるようになり、仕入れ量や現場でのシフト配置を効率化することに役立っている。
使用する特徴量やハイパーパラメータの調整をひたすら試行錯誤した結果、思った以上に良い精度が得られたので一旦追加の開発は止まってしまったが、本当はもっと機械学習に関わる全般的な知識を磨いて、さらなる課題に挑んでみたかった。
自社サービスである医師限定SNS (既存プロジェクト) の機能追加、運用保守を1人で担当している。
SNSの機能はFacebookをかなり意識した作りになっており、テキストや写真、動画、ドキュメントファイルの投稿が出来る他、コミュニティページを開設し、コミュニティメンバー内でディスカッションやイベントの告知が可能。
テキスト投稿欄にURL形式の文字列を貼り付けると、バックエンド側でリンク先ページのタイトルや概要文、サムネイルを取得しそれをプレビュー表示するという、FacebookやSlack等でよく見かけるような機能のバックエンドとフロントエンドの設計、開発を担当した。
元々、サイト全体のフロントエンドは全てBackbone.jsで作られており、かなりコードが複雑化していたため、当機能部分との接続が極力少なくなるようコンポーネント的な設計を心掛けた。フレームワークはBackbone.jsをそのまま利用した。
Rails、CoffeeScript、Backbone.js、全てが初めての経験ということで多くを学べた。
Railsで作られたプロジェクトの英語化作業を行った。YAMLの辞書ファイルを用意し、ビューテンプレートを手作業で書き換えた。レンダリングされるテキストがビューだけでなく、モデルやコントローラーで与えられている箇所も多く、また既に使用されていないコードも大量に見つかったため、そのリファクタリング作業に苦労した。
Backbone.jsで作られたフロントエンドがかなり混沌としており、jQueryの野良コードも混在していて安易に改修出来ない状態であるため、切り分けられそうな部分からRiot.jsによるコンポーネント化を施していきたい。
また、これまでエンジニアが本番サーバー上で行っていたrakeタスクによるバッチ処理を、非エンジニアの運用メンバーでも扱えるよう、社内用の管理画面 (Active Adminを使用) を使いやすく改修できればと思う。
医師が利用する症例検索システムにログインし、特定の症例の検索結果画面をスクレイピングした後、適切にデータを加工してCSVファイルを生成し、ユーザーがそれをダウンロードできるChrome拡張機能 (既存プロジェクト) の運用、改善などを1人で担当している。
スクレイピング対象の症例検索システムは自社管理ではないため、検索システムのアップデートに追随していく必要があることが辛い部分。今は定期的に動作確認をしてその都度アップデートをしているが、ビジネス的には検索システムを運営している組織に対して、API連携を持ちかけるというのも1つの方策だろうか。
バックエンドはLaravel(PHP)、フロントエンドは主にBackbone.jsを利用。システムの設計は社内の別のエンジニアが担当した。
学んだこと
小規模な学会や医師の研究会向けに、手軽に導入できる症例データベースサービスを開発中。特定の手術の記録を各病院施設で登録し全国のデータを集計することで、医師が行う論文の執筆や、メーカーの医療機器開発に役立てることを目的としている。
実際に学会を主導する立場にあるキーパーソンの医師とミーティングを重ね、要件定義から詳細設計、開発までほぼ一人で行っている。2016年11月頃から開発に着手し、2017年1月にα版リリース、4月に正式リリースを予定している。
次に引き継ぐ人のことを考慮して、メタプログラミング的な実装(そういうことが自在に出来るわけでは無い)や独自のカスタマイズは極力少なくし、出来る限りシンプルな実装になるよう心掛けている。これにより、メンテしなくてはならないコードの量や仕様書を減らすことにも繋がっている。
SPAを想定していたが、自分のスキル不足と、モダンなフロントエンドを運用できるメンバーがいないことを踏まえ、Railsによるサーバーサイドレンダリングを採用した。その代わりサイト全体でTurboLinksを活用し、SPAと同じようなUXに近づくよう気をつけている。
動的にテーブル項目を増やしたいという要件を踏まえ症例データ用のDBはMongoDBを採用したが、ユーザー情報やチーム情報等はMySQLで管理しており、MongoDBとMySQLが共存する形となっている。これが妥当な設計なのか検討を重ねたが未だに確証は無い。αテストの段階で見極めていきたい。
会員は月額料金を支払い、サイトに登録されている手術動画や講演動画を閲覧できるというシンプルなサービス (既存プロジェクト) の保守運用、新機能開発を1人で担当している。
全く別のRailsプロジェクトとDBを共有している部分が存在する。それをAPIによる連携に移行し、マイクロサービス的なアーキテクチャに作り変えていきたい。
会費の決済を行うモジュールが前任者の独自実装となっており、仕様書も無いためリファクタリングしづらい状況にある。最近はAPIとクライアントライブラリをセットで提供している決済サービスも多いため、そういったサービスを利用し、お金に関わる部分の責務を外部に移管したい。
ユーザーログに関して、Google Analyticsによる最低限のトレースしか出来ていないため、例えば動画の再生時間やスキップ位置など、動画プレイヤーをJS実装に移行したからこそ取れるデータをログとして収集し、サービス改善に繋げていくようなフローを導入したい。
「いいね」機能のようなSNS的な要素を実装し、熱心なユーザーを掻き立てることでサービス全体が活性化していくような流れを生み出したい。