AWS Step Functionsレシピ集

TECHSCORE
2022-06-02 11:00:00
はじめに AWSで定期的なデータ連携バッチを書く方法の一つにAWS Step Functions(以下Step Functions)があります。Step FunctionsはAWS Lambda(以下Lambda)を始めとするAWSの様々なサービスを組み合わせたワークフローを記述できるサービスです。LambdaおよびStep Functionsはバッチ用のサーバを構築・管理する必要がなく安価にサービスを運用できるため、私のチームでも活用しています。 LambdaおよびStep Functionsにはそれぞれ制約があり工夫が必要となる場合もあります。例えばパイプラインを定義するためにASL(Amazon State Language)というDSLを使いますが、ASLで何ができるかを理解するには時間が掛かります。細かい書き方などはすぐ忘れてしまって、以前書いたのを探すのに苦労したりもします。この記事は主に自分のために、用途別の「レシピ」をまとめようというものです。 西尾 義英(ニシオ ヨシヒデ) 開発から離れていた時期もありましたが最近プロダクトづくりに戻ってきました。 データを活用できる製品・基盤づくりがテーマです。 概要 後の説明のためにStep Functionsで取り扱う概念や用語について説明します。 ワークフロー Step Functionsではいわゆるパイプライン、つまり複数の処理を有向無循環グラフ(DAG)でつなげたワークフローを書けます。開発者ガイドではワークフローのことを状態遷移機械(state machine)、個々の処理を状態(state)またはタスク(task)と呼んでいます。状態遷移図で書いたワークフローの例を示します。 処理の始まりは「Start At: タスク名」で宣言します 最後のstateには「End: true」という属性を付与します あるstateの直後に起動する stateを「Next」で指定します 「Next」は一つだけ指定できますが、分岐やループなどの制御を実現する特別な stateがあります(下図) 分岐やループの中身が一つ以上の stateをもったサブ状態群となる場合があります データの流れ state間の入出力は JSON形式のテキストで、Lambdaとの連携が自然に行なえます。デベロッパーズガイドでは payloadと呼ばれることがあります。デフォルトではstateに入力されたJSONがそのままLambdaに渡り、Lambdaの出力が次のstateに渡ることになりますが、ASLの中でJSONを定義し直したり、JSONPath を使って抽出・変形することもできます。設定が可能な箇所を以下に示します。 基本的な書き方(SAM) Step FunctionsはAWSコンソールからGUI形式で開発することもできますが、実際の開発ではAWS SAMなどを使ってコードとして記述した方が良いと思われます。SAMで開発する時の書き方を説明します。 処理を行うLambdaを書く SAMテンプレートにAWS::Serverless::Functionリソースを定義する state machineを定義するためのASLをJSONまたはYAML形式で書く 3-1. 2で定義したLambdaのARNは変数置換(substitution)が可能です template.yamlにAWS::Serverless::StateMachineリソースを定義する 4-1. ASLでの変数置換(substitution)を定義します。2のLambdaのARNを参照します。 コピペミスや、ARN(!GetAtt リソース名.Arn)ではなく論理名(!Ref リソース名)を書いてしまう誤りが起こりがち 4-2. Lambdaを呼び出せるようなRoleを定義します # main.asl.yaml StartAt: Task1 States: Task1: Type: Task Comment: | 2.で定義した AWS::Serverless::Function を呼び出します。 Resource: ${TaskFunctionArn} End: true # template.yaml(一部) TaskFunction: #2. Type: AWS::Serverless::Function ~省略~ BatchStateMachine: Type: AWS::Serverless::StateMachine Properties: statemachines/main.asl.yaml DefinitionUri: statemachines/main.asl.yaml DefinitionSubstitutions: #4-1. TaskFunctionArn: !GetAtt TaskFunction.Arn #3-1. Role: !GetAtt BatchStateMachineRole.Arn #4-2. BatchStateMachineRole: #4-2. Type: AWS::IAM::Role Properties: AssumeRolePolicyDocument: Version: '2012-10-17' Statement: - Sid: StsAssumeRole Effect: Allow Principal: Service: states.amazonaws.com Action: sts:AssumeRole Path: / Policies: - PolicyName: InvokeLambdas PolicyDocument: Version: '2012-10-17' Statement: - Effect: Allow Action: - lambda:InvokeFunction Resource: "*" Lambda以外のサービスと連携(SNSで通知) LambdaはResourceにARNを書くだけで連携できますが、Lambda以外のサービスを呼び出すこともできます。以下はSNSで通知を行う例です。 Publish Success to SNS: Type: Task Resource: arn:aws:states:::sns:publish Comment: | SNSでバッチ処理成功を通知する。 件名や本文には固定の文字列だけでなく payload(の一部)を指定することもできる。 Parameters: Subject: Batch job succeeded Message: $.result TopicArn: $SuccessTopicArn End: true State Machineの分割 状態遷移の数に制限があったり、ASLが長すぎて読みづらい、複数のstateで発生する例外をまとめて一箇所でキャッチしたいなど、いくつかの理由からASLを分割してサブルーチンのように呼び出す場合があります。 # main.asl.yaml Process Purchases: Type: Task Resource: arn:aws:states:::states:startExecution.sync # StateMachineを同期的に呼び出す組み込みTask。後ろの`.sync`がポイント Parameters: StateMachineArn: ${PurchasesStateMachineArn} # 呼び出すStateMachineのARN Input: # StateMachineにわたすPayload updated.$: $.updated from.$: $.from sales_detail.$: $.keys.sales_detail ResultPath: null # StateMachineからのoutputは入れ子が深く使いにくいので破棄してしまう Catch: # 呼び出したStateMachineのどこかで例外が発生したらここでまとめてキャッチできる - ErrorEquals: ["States.TaskFailed"] Next: Publish Failure to SNS End: true StateMachineからStateMachineを呼び出すにはStateMachineのRoleにポリシーが必要です。詳細は https://docs.aws.amazon.com/ja_jp/step-functions/latest/dg/stepfunctions-iam.html に説明されています。 入出力 {Input|Output}Pathの指定方法 以下のパターンを使い分ければおおよそ大丈夫かと思います。詳細はリファレンスを参照。 加工前 Path 加工後(Python object) {"input": "somevalue"} "$" {"input": "somevalue"} {"input": "somevalue"} null None {"input": "somevalue"} "$.input" "somevalue" {"parent": {"child1": "v1", "child2": "v2"}} "$.parent.child1" "v1" | | | [1, 2, 3] "$[0]" 1 ResultPathの意味 InputPathやOutputPathの指定は、入力されたJSONのどの要素を取り出すかを意味しますが、ResultPathは、stateから出力されるJSONのどこに結果を挿入するかを指定します。以下の3つの使い方があります。 ResultPath: $ $はJSONのroot要素を意味します。つまり入力されたJSONを破棄して結果で上書きします ResultPath: null 逆に挿入先を指定しないということは、結果を破棄し入力されたJSONをそのまま出力する意味です 入力されたJSONの要素に結果をマージする ResultPath: $.resultは、入力されたJSONに"result"という要素を追加します。 3の入力例 { "job_id": 1, "process_at": "2022-04-01T00:00:00+09:00" } 3の出力例 { "job_id": 1, "process_at": "2022-04-01T00:00:00+09:00", "result": { "status": 200, "key": "processed.json" } } {Parameters|ResultSelector}の指定方法 出力したいJSONをそのまま書けばよいのですが、入力されたJSONを参照する時だけプロパティ名の末尾に.$を付けるのがポイントです。 同じく詳細は https://states-language.net/spec.html#payload-template を参照。 # 指定例 Parameters: flagged: true parts: first.$: $.vals[0] last3.$: $.vals[3:] 同期的な制御 ファイルの分割処理 Map stateは、JSON配列の要素ごとの処理を記述することができます。可能な場合は各タスクは並行に実行されるので、ループと言うよりMap-ReduceのMapに相当します。Mapへの入力が [1, 2, 3]の場合、Map下のIterator先頭のstateは1, 2, 3をそれぞれ受け取ります。他のパラメータが必要な場合、ItemsPathを使って配列を参照するJSONPathを指定するとともに、MapのParametersに子のTaskが受け取るJSONを定義することができます。 よくある使い方は、Lambdaのメモリまたは実行時間の制約のためデータを分割処理する場合です。 # ファイルの分割処理 1.Split Users in Files: Type: Task Resource: ${SplitUsersInFilesFunctionArn} Comment: | 入力されたファイルを固定行数で分割してS3に保存。 input: key_users(str): 処理するファイルを取り出すS3キー output: s3_keys(array of str): 分割したファイルのS3キー ResultPath: $.s3_keys # <-- ここに配列を入れる Next: 2.Import Users } 2.Import Users: Type: Map ItemsPath: $.s3_keys # ここから配列を取り出す Parameters: job_id.$: $.job_id # バッチ全体の共通変数 s3_key.$: $$.Map.Item.Value # Iteratorが受け取る配列要素(ItemsPathで指定)を参照する ResultPath: null # 実行結果は捨てる MaxConcurrency: 1 # 並行実行させない場合単なるループ処理 Next: 3.Another process Iterator: StartAt: Load Database States: Load Database: Type: Task Resource: ${LoadDatabaseFunctionArn} Comment: | 入力されたファイル一つをデータベースにロードする。 input: job_id(int): ジョブID s3_key(str): 処理するファイルを取り出すS3キー output: なし End: true 3.Another process: # 省略 固定回ループする ItemPathは、State間で受け渡されるJSONの一部を指定することができるのみで、固定要素の繰り返しを書くことができませんが、Passを組み合わせると実現できます。 Enumerate Reset Data: Type: Pass Comment: | ループ変数を生成 input: job_id(int): ジョブID output: types(array of str): 処理するデータの種類 Result: ["customers", "purchases", "purchase_items"] ResultPath: $.types # 上の配列をこのPathで参照できるようにする Next: Reset Data Reset Data: Type: Map ItemsPath: $.types # ループで回したい要素 Parameters: job_id: $.job_id type.$: $$.Map.Item.Value ResultPath: null # 結果は捨てる End: true Iterator: StartAt: Revert Data States: Revert Data: Type: Task Resource: ${RevertDataFunctionArn} Comment: | 指定された種類のデータをリセットする input: job_id(int): ジョブID type(str): 処理するデータの種類 output: なし ResultPath: null End: true カウンタを使ったループ Stepfunctionsで Choiceが分岐を書けるのでループを実現することはできますが、複雑なので基本的には Mapを使うことを考えたほうが良いと思います。 https://docs.aws.amazon.com/ja_jp/step-functions/latest/dg/tutorial-create-iterate-pattern-section.html 入力が空だったら終了 Concatenate: Type: Task Resource: ${ConcatenatePurchasesFunctionArn} Comment: | 日次に分割されたファイルを結合する input: job_id(int): ジョブID keys(array of str): ファイルを取り出すS3のキー output: key(str | null): 結合した結果を保存したS3のキー。入力されるファイルが0件ならnull ResultPath: $.key Next: Test Empty Data # 処理するデータが空なら終了させたい Test Empty Data: Type: Choice # 分岐を書く Choices: - Variable: $.key # 評価した値のPath IsNull: true # 評価式 Next: Return If Empty # 当てはまった場合の遷移先 Default: Convert Date # 全ての Choice要素 の評価が失敗した場合の遷移先 Return If Empty: { Type: Succeed } # 終端のState。Succeedは何もせずここで状態遷移が正常に終了したことを表す Lambdaの実行結果で分岐する Step FunctionsはLambdaの例外をキャッチして分岐することもできますが、Lambdaの出力結果で処理を継続するか失敗させるかを判断したい場合はChoice stateで分岐を書くこともできます。 Tell Status : Type: Task Resource: ${TellStatusFunctionArn} ResultPath: $.result # {statusCode: 200} または {statusCode: 500} Next: Check Status Check Status: Type: Choice Choices: - Variable: $.result.statusCode <-- ここで取り出す NumericEquals: 500 Next: FailState Default: SuccessState SuccessState: { Type: Succeed } FailState: { Type: Fail } 非同期処理 子のStateMachineの完了を待たない 別のStateMachineを呼び出す方法については「State Machineの分割」で説明しました。子のStateMachineの完了を待ちたい場合が多いですが、待たずに終了してしまうこともできます。 Delegate: Type: Task Resource: arn:aws:states:::states:startExecution # 非同期実行 Parameters: StateMachineArn: ${IntegrationStateMachineArn} Input: updated.$: $.updated job_id.$: $.job_id End: true SNSやEvent、SQSから復帰する StateMachineから明示的にLambdaやStateMachineを起動せずにSNSなどで間接的に処理を起動する場合、普通はそのまま制御が戻ってきませんが、必要であればコールバックしてもらうことができます。 https://docs.aws.amazon.com/ja_jp/step-functions/latest/dg/callback-task-sample-sqs.html に解説されていますが、Stepfunctionsから制御の外れてしまったLambdaからトークン付きのコールバックを待ち受けることができます。 実装例 初期化バッチが特定のS3バケットにデータを投げると、自動的に取り込み処理が走ります。取り込みが完了すると初期化バッチに処理が戻り、別の処理を続けます。少々複雑な例ですが、トークンを複数のLambda間でリレーできます。なお、LambdaのコードはPython3.8ランタイム向けのものです。 # main.asl.yaml StartAt: Upload Datalake States: Upload Datalake: Type: Task Comment: | S3バケットにファイルをアップロードする。 アップロードした後はバケットのOnPlaceイベントで別のLambdaが呼び出される。 そちらの処理が終わるとtask_tokenをもってコールバックされて次のTaskへ遷移。 Resource: arn:aws:states:::lambda:invoke.waitForTaskToken HeartbeatSeconds: 60 # https://docs.aws.amazon.com/ja_jp/step-functions/latest/dg/connect-to-resource.html#wait-token-hearbeat Parameters: FunctionName: ${UploadFunctionArn} Payload: task_token.$: $$.Task.Token Next: Do Something # 省略 BucketXInput: # ファイルを置くバケット Type: AWS::S3::Bucket Properties: NotificationConfiguration: TopicConfigurations: - Event: 's3:ObjectCreated:Put' Topic: !Ref TopicXOnPlaceFile TopicXOnPlaceFile: # 通知内容 Type: AWS::SNS::Topic FunctionPermissionXOnPlaceFile: # SNSきっかけでLambdaを起動する場合に必要 Type: AWS::Lambda::Permission Properties: Action: lambda:* #InvokeFunction FunctionName: !GetAtt FunctionXOnPlaceFile.Arn Principal: sns.amazonaws.com SourceArn: !Ref TopicXOnPlaceFile SubscriptionXOnPlaceFile: # SNS::TopicにLambdaをひもづける Type: AWS::SNS::Subscription Properties: Endpoint: !GetAtt FunctionXOnPlaceFile.Arn Protocol: lambda TopicArn: !Ref TopicXOnPlaceFile FunctionXOnPlaceFile: # ファイルが設置されたときに呼ばれる関数 Type: AWS::Serverless::Function Properties: CodeUrl: src/ Handler: on_place.lambda_handler # 省略 InvokeConfigXOnPlaceFile: # FunctionXOnPlaceFileの実行が成功・失敗した場合にSNS通知する設定 Type: AWS::Lambda::EventInvokeConfig Properties: FunctionName: !Ref FunctionXOnPlaceFile MaximumRetryAttempts: 0 DestinationConfig: OnSuccess: Destination: !Ref TopicXOnSuccess OnFailure: Destination: !Ref TopicXOnFailure # 以下省略 Qualifier: "$LATEST" TopicXOnSuccess: Type: AWS::SNS::Topic SubscriptionXOnSuccess: Type: AWS::SNS::Subscription Properties: Endpoint: !GetAtt FunctionXOnResult.Arn Protocol: lambda TopicArn: !Ref TopicXOnSuccess FunctionXOnResult: # 関数の処理が成功あるいは失敗したときに呼ばれる関数 Type: AWS::Serverless::Function Properties: CodeUrl: src/ Handler: on_result.lambda_handler # 省略 # src/main.py def lambda_handler(event: LambdaEvent, context: LambdaContext) -> None: result = parse_sns(event) print("do something") if result.task_token is None: return # 常にstateMachineに戻る必要はない try: # TODO 失敗時にsend_task_failureしたほうが良い sfn_client = boto3.client("stepfunctions") sfn_client.send_task_success( taskToken=result.task_token, output=result.to_json() ) except Exception as e: print(e) def parse_sns(event: LambdaEvent) -> ResultOutput: # ResultOutput は、on_place_file Lambdaの戻り値をラップしたdataclass record = event['Records'][0] message = json.loads(record['Sns']['Message']) payload = message["responsePayload"] return ResultOutput.from_dict(payload) コールバックするための権限が必要です。on_result lambda のRoleに以下Policyを追加します。 - PolicyName: StateMachineCallback PolicyDocument: Version: '2012-10-17' Statement: - Effect: Allow Action: - states:SendTaskSuccess Resource: "*" おわりに 私たちがプロジェクト内で使っているパターンはおおよそこんなところです。最後にStep Functionsを使うときのポイントをまとめます。 ASLはYAMLで書くのがおすすめ カッコやクォーテーションを書く量が減る 行コメントも書ける 繰り返し処理は、まず Map の利用を考える Mapはデフォルト並列実行しようとするので注意 大きくなってきたらStep Functionsを分割する 見通しを良くするため 状態遷移数の上限に引っかかることもある Payloadの加工を良く間違うので、ワークフローを流れるJSONの構造を先に決めておくと良い pydanticを使ってタスク間で共有するJSONをPythonのクラスに対応付けておき、Lambda間で共有する この方法がまとまったらまた記事を書くかもしれません 複雑なワークフローを組む場合、Lambdaで時間がかかる処理を書く前にTask間の入出力を確かめておくと良い Pass stateを使って状態遷移だけ作っておく 中身のない入出力だけのLambdaを定義する

プロダクト開発におけるプロジェクトマネジメント

TECHSCORE
2022-05-26 11:00:00
当社が提供しているSynergy!(顧客管理・CRMシステム)の開発プロジェクトのPMを担当しています。 今回は主にプロダクト開発の進め方について、これまで試行錯誤してきた内容を書きたいと思います。 下山 倫央(シモヤマ トモヒサ) 2007年に入社後、SI案件の営業やプロジェクトマネージャーを経て、現在はSynergy!のプロジェクトマネージャーとしてプロダクト開発に携わっています。 最近は子供中心の生活です。毎日2人の娘に癒されています。 プロダクト開発の進め方 以前のプロダクト開発は、企画や仕様を決める作業や、開発を実施する作業など、各工程で役割を分担する進め方で行っていました。 以前の開発フロー概要 企画された機能に対してデザイナーがワイヤーフレーム/デザインカンプ*1、画面仕様書を作成 PMがレビュー エンジニアなどの関係者にワイヤーフレーム/デザインカンプ、画面仕様書の説明を実施 開発着手~テスト~リリース ただ、この進め方だと、 仕様が完全に決まらないと開発が進まない ⇒エンジニアが稼働できず、リソースを最大限活用できない PMとデザイナーだけで仕様を検討している ⇒エンジニアなどの関係者との仕様の認識ずれや仕様検討の後戻りが多い デザイナーがワイヤーフレーム/デザインカンプ、画面仕様書を作成している ⇒仕様確認や画面仕様書の修正など、デザイナーの負荷が高い というような課題が出てきました。 そこで、PM、エンジニア、デザイナー、QA(Quality Assurance)などプロジェクトに関わる関係者が一緒に仕様を検討しながら開発を進めるフローに変更しました。 現在の開発フロー概要 PMが仕様検討のもとになるPBI(プロダクトバックログアイテム)を作成※この時点でエンジニアに仕様の調査や確認を依頼することもあります デザイナーがPBIを元にワイヤーフレーム/デザインカンプを作成 PM、エンジニア、デザイナー、QAでPBIとワイヤーフレーム/デザインカンプを元に仕様検討を実施(リファインメント) 仕様検討結果をPBI、ワイヤーフレーム/デザインカンプに反映 PMが画面仕様書を作成 エンジニアがタスクを洗い出す(プランニング)※PBIとタスクをGitLabのissue boardを使ってカンバン運用*2しています 開発着手~テスト~リリース 開発フローを変更して良かったこと 現在私が担当しているプロジェクトではフローを変更したことにより、下記のような効果がありました。 エンジニアを含め関係者全員で仕様検討を行うため、エンジニアのリソースも最大限活かせる さらに、認識のずれや仕様検討の後戻りが少なくなり、仕様検討の過程も記録することで 関係者全員で振り返ることができるようになった どこかの役割に負荷が集中することなく、進捗がスムーズになった これまでは、「PM・デザイナーが仕様書を作成して、その仕様でエンジニアに開発を発注する」という感じがありましたが、プロジェクトの関係者が一緒に仕様検討を進めることで、以前に比べチームとしての一体感が生まれてきたと感じています。 運用していくうえで見えてきた課題 ただし、良いことばかりではなく、新たな課題も見えてきました。 PBI単位で仕様を検討していくため、将来の全体感が見えない デザインに関しては直近リリースを行う機能だけではなく、今後リリースされる機能も含めて整合性をとって設計する必要があるため、現在の進め方には課題があります。 一部、将来リリース予定の機能をデザイナーが前倒しすることにより対応している箇所もありますが、この点については今後対応方法を検討する必要があると考えています。 複数のプロジェクトが稼働しているが、プロジェクト間で運用に少しずつ違いが出てきた 運用を変更してから1年ほどたちますが、下記の点についてプロジェクト間で差異がでてきました。 PBIに記載する内容 スケジュール管理方法 PM、エンジニア、デザイナーの役割 リリース機能に対するフィードバックやバックログの管理方法 各種会議体のファシリテーター など この件に関しては、明確なルールが決まっていなかったことが原因ですので、各PMが集まって情報交換を行い、ルール決めや運用方法の改善に取り組んでいます。 また、各種フォーマットを整備し、プロジェクト間で運用に違いが出ないような取り組みも進めています。 今後について 現在の運用が最適とは考えていません。 仕様決定のプロセス、プロジェクト間の情報共有、各職種間のコミュニケーションなど、まだまだ改善が必要なものがあります。関係者でプロジェクトの振り返りを実施し、当社にとってより良い運用方法を模索していきたいと考えています。 *1:ワイヤーフレームを元に作成したデザインの完成見本(色、フォント、レイアウトが決定しているもの) *2:タスクごとにカード(カンバン)を作成し、作業工程や進捗状況ごとにボードで管理する運用方法

Synergy!のシステム障害における情報共有の改善プロジェクト

TECHSCORE
2022-05-19 11:00:00
川島 吉久(かわしま よしひさ) 2004年入社。 Javaプログラマから始まり、SE、プロジェクトマネージャー、テクニカルサポートを経て、現在はSynergy!のプロダクトマネージャー。 当社はメール配信やフォーム作成のできるクラウドサービスのSynergy!を提供しており、Synergy!にシステム障害が発生すると、お客様から様々なお問い合わせをいただきます。 原因は何か、いつ復旧するのか、フォームに登録はできるのか、予約しているメール配信は予定通り行われるのか、配信途中のメールはどういう状況なのか、APIはエラーになっていないか、データ連携は問題ないか、などなど。 それらに正確かつ迅速に回答すべく、障害発生中の情報共有における課題改善に取り組んでいます。 情報共有の流れ 障害発生時、当社では主に エンジニア 原因調査や復旧、影響調査を担当します 障害対策PM(プロジェクトマネージャー) 障害発生時の情報集約を担当します カスタマーサポート・営業 お客様からのお問い合わせに回答したり、障害状況をお知らせします の役割に分かれて、 エンジニア → 障害対策PM → カスタマーサポート・営業 の流れで調査状況、復旧の進捗などを情報共有します。 筆者は障害対策PMを担っています。 課題と改善 これまで何度か障害対策PMを担ってきましたが、対応する中でいくつかの課題が顕在化したため、改善案を検討しました。 エンジニアによる復旧作業や影響調査などの進捗状況が分かりにくい こちらは、エンジニアと障害対策PM間のコミュニケーションの課題です。 復旧作業や影響調査が完了した際にはエンジニアが報告用チャットで障害対策PMに連絡してくれるのですが、障害が長引く場合は次の対応を準備したり、対応の優先順位を検討するために進捗状況も知りたいところです。 オフィスに出社していたころは、エンジニアの集まっているところに寄っていけば状況を把握できたのですが、在宅勤務が中心となってからはエンジニアごとに別々のチャットで相談したり調査・復旧を進めているため、「エンジニアの集まっているところ」を知ることが難しくなってしまいました。 障害対策PMとしては、だれがどのチャットで何を作業してくれているのか、調査や復旧の進捗状況が分かりにくい状態でした。 そこで、定期的に情報を共有してもらうオンライン会議を開くことにしました。これにより、「調査完了」や「復旧完了」などの完了連絡だけでなく、「今はまだ原因究明の目途がたたないが、ここが怪しいのでこれから調べるつもり」や「あと30分くらいで影響調査は終わりそう」などの途中経過を知ることができるのではないかと考えています。ただ、開催頻度を高めすぎると調査や復旧の手を止めてしまうことにもなりかねないので、どのくらいの頻度で開催するのが最適なのかはこれから試行錯誤していく予定です。 最新情報を追いかけにくい 次は営業・カスタマーサポートと障害対策PMとのコミュニケーションの課題です。 こちらもチャットを利用して情報を共有するのですが、質疑応答などの会話が進むとどうしても大事な情報が流れていってしまって、何が最新情報なのか、重要な情報を追いかけにくい状態になりがちでした。 そこで、当社で利用しているナレッジ共有ツールDocbaseを利用して、常に最新情報を更新するページを設けることにしました。また調査や復旧の進捗状況もここに記録していくことで、後から障害報告書にまとめるときにも情報が参照しやすくなります。 調査結果をまとめるのに時間がかかる 最後は障害対策PMの課題です。 エンジニアがエラーログなどから影響調査してくれた結果を、お客様からのお問い合わせを対応するカスタマーサポート・営業に共有するのですが、ログの集計結果だけではアカウントIDしか情報がないため、そこにお客様名や担当営業などの情報を追加します。その作業を障害対策PMが担っているのですが、手作業なため共有までに時間がかかっていました。 そこで、エンジニアの調査結果(抽出項目や集計軸、表示する順番など)を定型化してもらい、追加するお客様情報も自動で参照できるよう影響調査シートのフォーマットを固定しました。 まだすべての機能について定型化できていないのですが、これまでより大幅に時間短縮できる見込みですし、手作業のミスもなくなると考えています。 また、エンジニアの調査結果を定型化するため、調査コマンド自体も定型化されることで、副産物として調査の属人性を排除することもできそうです。 最後に 障害は起きないことが一番ですが、色々な要因があり完全になくすことは難しいため、発生してしまった場合はできるだけ早く復旧することを目指してエンジニアたちが頑張ってくれています。 その努力を少しでも活かせるように障害対策PMとしては、引き続き迅速・正確なコミュニケーションを目指します。

新人エンジニアに伝えたいこと - エンジニアリングを楽しむための3つのコツ -

TECHSCORE
2022-04-21 11:00:00
こんにちは、CTO の馬場です。 4月です。今年も当社に7名の新卒が入社しました。振り返ると、私は毎年新卒の総合職の方向けに話す機会をもらっているのですが、技術職の方向けに話す機会がないんですよね。なぜだ。 ということで、当社の技術者に期待することを書き記したいと思います。 馬場 彩子(ババ アヤコ) 2001年入社のシナジーマーケティング最古のエンジニア(ほんとは2番目)。 私が新卒で会社に入社したのは1999年。前世紀です。2000年になるとコンピューターが誤作動して世界が破滅する、という「Y2K問題」というのがあり、年末年始待機していたことを覚えています。懐かしい。 すきなものはビールとカニ。きらいなものはチーズ。 「学習」をアップデートする ひとことでいうと、みなさんに期待することは学習をアップデートすることです。ようやく学校を卒業したのにまた「学習」か……早く人や社会に貢献することをしたいんだ...… という方。実は、「学習」という言葉は、この10年でかなり意味合いが変化した言葉です。*1 以前の学習といえば、先人たちが発見した正解の知識を自分にインストールすることを指しました。学校では、授業を受け、演習をこなし、テストを受けて習熟度を測る、このような学習を実施してきたと思います。もちろん、知識は財産になります。一般的に暗記できるような事実だけでなく、視点・観点やロジックですら、知識として身につけることができます。ただし、 VUCA の時代においては、みなさんにお願いする仕事のほとんどは「誰もやったことないこと」「正解がわからないこと」だったりします。教科書の後ろの方のページをみても解答例がないような問題に、どうやって立ち向かったらいいのか。その試行錯誤、暗中模索の足掻き方と足掻くだけの筋力を身につけることが、「学習をアップデートする」ことです。 3つの行動指針 じゃあ具体的にどうしたらいいのか、というと、3つあります。 わからないこと、できないこと を楽しむ 目の前の人を理解する 自分の意志を表明する わからないこと、できないことを楽しむ 新卒のこの時期は、新人研修などではじめてのことを山ほど体験しているころだと思います。はじめてのことって上手くできないですよね。私は、以前は(いまも?)かなりの負けず嫌いだったので、他の人と比べてできないことは避け、できそうなことや慣れ親しんでいることを繰り返しがちでした。わからない、できない、知らない、やったことないことって本当に居心地悪い。身につけたスキルで楽々暮らしていきたい。 ただ、この2年ほどの当社の開発では、やったことないことしかやってないんです。世界がどんどん変わっていく中、前例が役立たずになったり、やっていることが通用しなかったり、通用しなくなることが明らかになってきたりしています。現サービスを維持するという保守的な目標を立てたとしても、我々の技術をどんどん変えていく覚悟が必要です。みなさんはそんなチームにこれから配属されるので、ずっと「わからない仕事」、「やったことない仕事」と向き合うことになります。ふふふ。 なので、はやく「わからない」「やったことない」をてなずけて、楽しめるようになってほしいと思います。振り返ると、私自身、聞いた途端「これ、無理」と即答するような、目の前になんのとっかかりもないつるっつるの壁が立ちはだかっていると錯覚するような、そんな無茶振りこそ、あとに忘れられないことになったりしています。そして自分がどんどん成長していくんで、とても楽しいんですよ。 有名なタモリさんのセリフもありますので、ぜひ怯まないでChallenge してください。 自分の中で『これくらいの力がついたら、これくらいの仕事をしよう』と思っても、その仕事は来ない。必ず実力よりも高めの仕事が来る。それは「チャンス」だから、絶対怯んじゃだめ。 目の前の人を理解する そんな誰もやったことない仕事に対して、どうやって最初のとっかかりを見つけたらいいのかというと、まずは課題を深く理解することです。 私たちは、ソフトウェアを提供することによりお客様の課題を解決することで、お金をいただいています。とはいうものの、いつでも先の先の先のお客様に想いを馳せろ、というのは難しいですよね。理解するってそんなに簡単なことではありません。 新卒エンジニアであれば、おそらく最初は先輩や上司から仕事を依頼されることが多いでしょう。なので、まずは目の前の仕事を依頼してきた人が、なぜこのタイミングでそのタスクをあなたに完了させてほしいと思ったのか、考えましょう。 このとき、相手のことを考えるだけでは不十分です。相手の立場になって、相手になりきって考えてみることがコツです。 これを、Synergy!プロダクトオーナーの岡村さんが「憑依させる」とよく表現するんですよね。自分以外の、立場も知識も違う人の思考の流れをトレースするイメージです。私もすぐ自分の思考にすっと流れてしまうのですが、本質を捉えるためにも意識したいことです。 自分の意志を表明する さて、最後はアウトプットです。わからないという不安を乗り越え、依頼の本質を理解するために一回思考したら、きっとなんとか答えをひねりだすことでしょう。でもそれはかなり頼りないアウトプットにみえると思います。これで本当にいいのか、なにか決定的に間違えてるんじゃないのか、時間いっぱいまで完璧に近づけようと、同期に聞いてみたり、Google で調べてみたりしてしまうこともあると思います。 でも、仕事に唯一無二の正解は存在しません。そして、正解のない世界では、スピーディにベターな方法を選択して試していくことが求められます。そのためには、チームで協調して知恵をしぼるんです。自分一人でやらなくていい。ただ、「わからないので、先輩に答えを聞く」も違います。なぜなら、あなたも知恵をしぼるチームの一員だからです。自分の理解から「答えはこうなんじゃないか?」という仮説をつくり、自分に仕事を依頼した人にぶつけてみましょう。 メンバーそれぞれが意志をもち、それを表明していくことにより、チームが相乗効果を発揮できるようになります。新人のうちは意見を求められることは少ないかもしれません。ただ、考えをまとめること、それを相手がわかるように伝えることは、それぞれスキルがいることです。知識を身につけたら、自然と自分の意志を言語化できるようになるわけではないのが、難しい。そのためには、「自分はどう考えるのか」、常に自分に問い続けること、人に話してみて、フィードバックを得ることです。経験と知識が自分の中でぐぐっとつながって広がっていきますよ。 学ぶことは楽しい 今回新卒エンジニア向けに学習について書きましたが、学習のアップデートは決して簡単なことではありません。むしろ「こうやったらうまくいった」を蓄積してしまっている我々ベテランの方が、学習プロセスそのものをアップデートすることは難しいかもしれません。 それでも、昨日、1ヶ月前、1年前の「できない」「わからない」が「できた」「わかった」「動いた」に変わるのは最高に楽しい体験で、それがエンジニアリングだと信じています。 そんな体験が少しでも増えるよう、私自身も大小さまざまな学習、チャレンジにとりくんでいきたいと思っています。この記事が新卒のみなさんの豊かなエンジニアライフのスタートの手助けになれば幸いです。 シナジーマーケティング株式会社では一緒に働く仲間を募集しています。 *1:参考図書 みんなのアンラーニング論 組織に縛られずに働く、生きる、学ぶ

社内でデータ分析基盤の勉強会を開いています

TECHSCORE
2022-03-09 11:00:00
この記事では、当社内で実施している技術勉強会について紹介します。 西尾 義英(ニシオ ヨシヒデ) 開発から離れていた時期もありましたが最近プロダクトづくりに戻ってきました。 データを活用できる製品・基盤づくりがテーマです。 過去の連載はこちら 西尾です。自社サービスで扱うデータを収集して加工・分析する仕組みを作る為、機械学習を利用した新サービスの開発を行っています。AWS上で作っているのですが、たくさんあるサービスをどう組み合わせたら良いか、また製品で使えるだけの可用性、その他品質を作り込む方法など、知識不足で課題が多いです。社内の知見を集められるようにデータ分析基盤の勉強会を行おうと考えました。 この勉強会は、データ分析基盤というものについての理解(Why,What,How)を社内に広めるきっかけとなることを期待しています。ゆくゆくは当社に必要なデータ分析基盤を構築・運用できる人材の育成や、部門間の情報共有につながればと考えています。 始める前は、機械学習を全社的に取り扱っているわけでもなく、当社の主力商品の開発チームも多忙な時期だと聞いていたので、どれくらい人が集まるか不安でした。ある機会に全社に呼びかけを行ったところ、未経験だが興味があるというメンバーがおり非常に勇気付けられました。本記事はここから彼にバトンタッチいたします。 横田 真一(ヨコタ シンイチ) 熟練の先輩エンジニアに囲まれて日々精進を続ける、しがないインフラエンジニアです。物語の冒頭によくある「元気だけが取り柄です!」みたいなキャラ説と同じ括りにしたくないのですが、好奇心だけが取り柄です。 バックグラウンド、勉強会をやろうと思った理由 第3次AIブームの火付け役となったディープラーニングの情報をネット上で目にする機会が増えたこともあって、徐々に機械学習やデータ分析基盤に興味が湧いてきました。とは言っても正しい知識は全くありません。無知の知の心構えは有るにしても「これじゃいけない。」という焦りと「本当はどういうもの?」という好奇心はありました。そこで、機械学習、DWH、MLOpsなどを扱っている西尾さんにお声がけしたところ、「データ分析基盤勉強会」という名前で会を発足することになりました。 勉強会で何を学んでいるか 勉強会は以下の目的に沿うようテーマを決めて、隔週で行いました。 データ分析とは何かを理解する なぜデータ分析が必要なのかを理解する データ分析をどのように実施するのかを理解する MLOpsとは何かを理解する AWSを利用してデータ分析基盤を構築・運用する方法に関する基礎知識を身につける 勉強会の発表者は持ち回り制です。勉強会の最後に決めた次回のテーマに沿って、習得済みの知識や、発表に向けて新たに学んだ知識を発表するという形を取りました。テーマを大きく分類すると以下の通りになりました。 機械学習に対する正しい基礎知識 AWSの機械学習及びデータ分析基盤のサービス内容と、活用例 ハンズオン会 社内での実例を知る 他の参加者の方は「機械学習に対する正しい基礎知識」という分類に属するテーマを中心に発表されていたのですが、これは私のような初学者が陥り易い「機械学習自体だけに興味が集中しがち」な状態を正すのにおおいに役立ちました。機械学習を利用したソリューションを構築しようと考えたとき、システム全体として機械学習が担う部分はごく僅かであり、その周辺の仕組みやデータの変換、移行、管理の仕方など色々学ぶ点は多く、実際に手を動かしてみたい衝動に駆られることもありました。 私は主に「AWSの機械学習及びデータ分析基盤のサービス内容と、活用例」という分類に属するテーマを中心に発表を行いました。具体的には「AWSの機械学習サービス紹介」「SageMaker の利用レポート」といった内容です。準備として、AWS サービス別資料を読み漁るのと同時に個人用アカウントでハンズオンに取り組み、自分なりに理解を深めてから、その情報を資料化して勉強会で発表するという方法を取りました。 ただ、ピンポイントで個々のサービスの知識を「点」として得ても、実務で使えるような「線」としての知識に上手く繋げられなかったので、AWS資格である「Certified Data Analytics - Specialty」の勉強を始めました。資格勉強は知識ゼロの人を対象に段階的にかつ体系的な知識を無理なく身に着けられるので、AWSのデータ分析基盤のサービスを実務で使えるようになるためにはこの勉強法が一番合っていました。 勉強会は1年続いた。モチベーションの維持など 勉強会は約1時間で前半は発表、後半は発表された内容で議論や事例を肉付けして、質疑応答を行うというよくあるパターンです。実際に業務で機械学習を扱っていない私にとって、勉強会参加者の体験談などは非常に興味深く、機能を学ぶだけでは得られない疑似体験のようなものでした。これがモチベーションの維持に大きく役立ちました。 次はこういうことを学びたい(個人的に) まずはAWSを組み合わせて一つのサービスを作り上げることを動機とした勉強に、AWS Certified Data Analytics - Specialty を選んだので取得するまで続けます。機械学習が、ソリューション全体で担う部分はごく僅かとはいっても、難解で膨大な知識が必要な分野であることは間違いありません。それゆえ、「ソリューション全体を作り上げること」、「機械学習自体」の2面での知識が必要になります。まずは、機械学習自体の学びもしたいと考えていたところ、Kaggle Expert の称号を持つ勉強会参加者がいらっしゃいまして、その方に Kaggle *1 を紹介してもらいました。せっかく紹介してもらったので、最も有名な「機械学習を使用して、タイタニックの難破船を生き延びた乗客を予測するモデル作成」をやり始めました。まだやり始めたところなのですが、実際に手を動かすことと、知識を得ることを整理すると理解しやすかったです。 勉強会で今後活かしていきたい内容(会社として) 私はインフラエンジニアとしてSynergy!のプラットフォームを管理する部署に所属しています。今はデータ分析基盤の知識は必要ないのですが、今後機械学習を用いた製品の展開がなされたら必要になると考えています。自部署内でも、ログ分析、障害予測、予測に基づいたメンテナンス提案なんかを定常業務に織り交ぜるなど、機械学習を取り入れることで業務負担を軽減できるはずです。 一年前は「AI」と言われて真っ先にターミネーターが思い浮かぶレベルだったので、今や Kaggle デビューを決意するに至った勉強会に感謝しかないです。会社のデータ分析基盤や機械学習の浸透に一役買っていきたいです。 *1:Kaggle:企業や研究者がデータを投稿し、世界中の統計家やデータ分析家がその最適モデルを競い合う、予測モデリング及び分析手法関連プラットフォーム及び運営会社を指します。

2021年度の新卒エンジニア向け技術研修を紹介します

TECHSCORE
2022-01-06 11:00:00
シナジーマーケティングでは2015年からエンジニアの新卒採用をしています。 当社では毎年、エンジニア全員で試行錯誤しながら新卒エンジニアの育成をしています。 この記事では、新卒エンジニア向け技術研修の中から講義の内容についてご紹介します。 松田 直哉(マツダ ナオヤ) 2020年シナジーマーケティングに新卒入社。 自然派エンジニアを目指して頑張ってます。 山登り/ダイビング/ボルダリングが趣味です。 当社の新卒エンジニア研修について シナジーマーケティングでは、新卒エンジニアがスムーズに業務に入っていけるよう、毎年研修を行っています。主に新卒2~3年目社員が「トレーナー」として研修を担当し、4年目以降の社員がそのサポートを行っています。これには以下の狙いがあります。 1年目社員(研修を受ける側)にとって 2~3年目社員は身近なのでコミュニケーションがとりやすい 次年度以降の業務をイメージしやすい 2~3年目社員(研修を提供する側)にとって 自身が新卒の時に失敗したことやつまずいたところのカバーをしやすい 指導するにあたって、これまで以上に技術の理解が必要になり、復習することで理解が深まる チーム運営やタスク管理の能力が身に付く シナジーマーケティングではリモートワークを積極的に活用しています。そのため今年の研修はほとんどリモートで実施しました。 新卒エンジニアは入社後、部署を問わず、共通するスキルや社内ルールなどを学ぶために社会人基礎の研修を受講します。その後、エンジニアとしての基礎を学ぶために外部の研修を受講します。外部研修が終わり次第、我々が内製化している新卒エンジニア向け技術研修に参加してもらいます。 社会人基礎研修 電話対応の行い方 /名刺交換の行い方 / 日報の書き方 社会人としての話し方 / プレゼンテーションのテクニック など 社外研修 Java技術研修(2020年度の実施内容) 変数、if文、for文など言語共通の技術 / オブジェクト指向 / データベース システム開発の工程 など 社内研修 講義(後述) 演習 Linux / データベース / WEBアプリケーション Docker / Git など 実践研修(OJT) 技術や社内ルールなどの知識がある程度蓄積された段階で、実業務を通じて実践的なことがらを学びます。 講義は1週間に2回程度、1回あたり30〜60分で行いました。 講義内容 この章では 講義名と内容の紹介、新卒へ伝えるための工夫点を記載しています。 講義ではシステム開発全体のことを知識として学んでもらいます。研修が終了すると新卒エンジニアはバックエンドやフロントエンドのチームに配属されます。更にその後はプラットフォーム、QA、PMと多様なポジションの業務を担当する可能性もあります。その準備のために、直近で必要になる技術だけでなく、どのポジションについても活躍できる人材となるために必要な技術は何かという観点から、これらの講義を選定しました。 講義名 内容、工夫点 Linux 基礎的なコマンド / 使用した業務例の紹介を交えて、実際に使用した業務や使うであろうシーンを記載して、用途を想像しやすいように Git(バージョン管理システム) バージョン管理システムとツールの違い、基礎的なコマンドと業務で使用するコマンドなど幅広く データベース 比較的初歩の概念(ACID特性、制約など)を多く含めて、初学者でも入り易く分かり易いように Webアプリケーション フレームワークや実際のコードについて セキュリティ 情報セキュリティや暗号技術のコアとなる要素について ネットワーク/Web基礎 TCP/IP、DNS、HTTP、REST などについて基礎的な解説 プロジェクト管理/開発手法 システム概要や設計などのドキュメント、PMやPLの役割、Issueやチケット管理、見積の精度を社内での使用方法を交えながら解説 マイクロサービス マイクロサービス、モノリシックという概念に加え、Docker、Kubernetesなどの技術について マイクロサービスはSynergy!開発において重要な手法であるので、Synergy!での具体的な適用方法や、歴史的な経緯についても解説 API 一般的に使用されているAPIの規格や認証方法について 1点を細かく解説するのではなく、あえて広めに触れることで、各自で掘り下げる余地を残すように解説 フロントエンド HTML、CSS、React、Angular などについて フロントエンドエンジニアの業務について1日の流れなどを混ぜて、1年後の自分を想像できるように、また、知識と業務の関係性などについて解説 運用・保守 保守と開発の違い、保守の監視ツールや脆弱性調査の方法を過去の事例を交えながら 品質管理 業務にすぐに生かせる具体的なテスト技法だけでなく、なぜ品質が大事なのかイメージしやすいように、障害事例を解説 クラウド(AWS) AWS Solution Architect Associateの試験範囲をもとにAWSの主要な機能や、はまりやすいポイント、コストなどについて まとめ 去年は2人で講師役を担当していましたが、今年は多くの人に講師役を担当してもらいました。 それぞれの得意分野を生かした講義内容となり、また、準備時間も多く取れるので、正確かつわかりやすい講義、資料ができたと考えています。質問などを通じて、良いコミュニケーションも生まれました。 改善点は、全ての講義を対面で行っており講義にさける時間も限られているため、深堀ができていないことです。 来年はいくつかの講義をビデオ収録し、講義数を増やしていければと考えています。 最後に 私も昨年の新卒研修をリモートで受けました。リモートワークの環境にも徐々に慣れてきたから大丈夫だろうと少し思っていましたが、始まれば上手くいかないことの連続でした。同じような資料を複数作成したり、研修課題を提出されてから課題の文章が悪かったことに気づいたり、進捗管理で把握できていない部分があったりと周りに助けを求めることがありました。ただ、先輩達からのアドバイスや新卒からの報告で大きなミスはなく伝えなければいけないことは伝わったのではないかと感じております。今年の反省を活用し、来年はさらに業務に必要な多くのことが伝わるように体制や資料をアップグレードしていきます! 一緒にシナジーマーケティングを盛り上げませんか? 現在、シナジーマーケティングでは一緒に働くエンジニアを募集しています。この記事を読んでシナジーマーケティングに興味を持ってくださった方は、ぜひこちらの採用サイトをご覧ください。

CTOが振り返るシナジーマーケティングの2021年

TECHSCORE
2021-12-20 11:00:00
2020年にCTOになって早二年。なんとか(おそらく)2021年もCTO として年末を迎えることができそうです。去年はいろいろはじめたもののまだまだ目に見えるものがなかったのですが、今年は変化の手触り(もふもふ?ごつごつ?)を感じられるよい年になりました。今年もシナジーマーケティングのエンジニアリングを振り返ります。 馬場 彩子(ババ アヤコ) 2001年入社のシナジーマーケティング最古のエンジニア(ほんとは2番目)。 オットと二人の息子と四人暮らし。息子、今年の誕生日は友だちと旅行にいくらしい。成長。でもちょっとさびしい。バースデーだからといっていつも特別なにかをしているわけじゃないけど。 すきなものはビールとカニ。きらいなものはチーズ。 シナジーマーケティングの2021年 Synergy!の2021年 Synergy! ではインフラのクラウド移行と、アプリケーションのモダナイズを実行しました。 インフラのクラウド移行は、2020年のアプリケーションのマイクロサービス化(コンテナ化)からスタートしました(そのときの話はこちら)。100以上あるサーバのコンテナ化をこつこつ進め、計画より遅れたものの2021年7月には作業を完了しました。 並行してAWS上の環境を構築していたのですが、2021年10月から移行を開始しました。2021年12月現在では、データベースの半分をAWS上に配置しており、AWSとオンプレのハイブリッドな環境でサービスを提供しています。引き続きデータや機能の移行を実施していき、2022年3月にはAWSへの移行が完了します。 クラウド移行、といっても、ふたをあけてみれば、ネットワーク、データベース、MTAから監視・ログシステム、CI/CDまで、アプリケーションコード以外(ほんとはアプリケーションコードもパフォーマンスチューニングでちょっと)の、すべてのシステムを再構築しています。移行期間中も大きな問題なく稼働しています。すごいです。 また、2005年にリリースしたフォームやデータベースの機能を「使いやすさを徹底的に考えた画面デザイン」でモダナイズするプロジェクトも進めています(そのときの話はこちら)。 フォーム Before(左) After(右) フォームの設定はすぐに画面右側のリアルタイムプレビューに反映されます データ検索 Before(左) After(右) 行動履歴を条件にした検索、ANDとORを組み合わせた複雑な検索も可能に データ表示 Before(左) After(右) ひとつの画面で顧客のさまざまなデータを閲覧可能に フォームもデータベースも多くのお客様に利用されている機能です。Synergy! はローンチから17年間、改変しながら提供し続けた結果、隠れ仕様が隠れミッキーなみに潜んでいる中、エンジニアが丁寧にシステムを分析、理解し再生していきました。終わりがみえてきた?!これもすごい。 プロダクトマネジメントに注力、新しいチャレンジも 今年はSynergy! の プロダクトマネジメント の整備にもチャレンジした一年でもありました。企画、PMM(GTM)、(社内)啓蒙の3機能を重点的に、再現可能なプロダクトマネジメントのフレームをつくろうと奮闘しました(奮闘記はこちら)。Synergy! のプロダクトとプロダクトマネジメントの深淵さと広大さに圧倒されながらも、yappli 連携などのいくつかの機能をリリースしたり、プロダクトの今を伝える社内情報共有のページをつくったり、プロダクトのアイディア・仮説を量産するプロジェクトを実施したり、プロダクトの意志をつむいでいく活動を実施することができました。 また、新しいサービスを2つローンチしたこともシナジーマーケティングのエンジニアリングにとって非常に大きな出来事でした。ひとつがSynergy! BCS、ブランディングを支援するクラウドサービスです。もうひとつがen-chantです。去年策定した新規ビジネス開発フレームに沿ってローンチした最初のサービスです。このときのことは以下の記事で紹介しています。 blog.techscore.com また、その影でチャレンジしたがローンチしないという判断をしたサービスもあります。その判断をしたところも含めて、最初から最後まで当社で経験のないところにがしがしと獣道をつくってくれた取り組みだったと思います。詳しくは以下の記事で。 blog.techscore.com 思い起こすと去年の今ごろは世になにも出ていなかったんですよね。AWSインフラもなかったし、新しいフォーム機能もデータベース機能もなく、新サービスもなかった。やばい、本当に今年はいっぱいやったなあと思います。 ファンとともにSynergy を創造する 2021年のシナジーマーケティングはビジョン、ミッションの改定 からスタートしました。キックオフでは、全社ミッション「 Create Synergy with FAN 」にあやかり、現状のSynergy! というプロダクトに囚われることなく、我々のプロダクトを作ろう( = Create Synergy! )と話しました。 今期の開発は、前例や過去事例で思考停止せず、さまざまなものを能動的に解釈しなおし作り替えることができた一年となりました。システムも組織も情報(データ)が活発にとびかう健全な状態になってきたと感じます。 まだ終わっていないプロジェクトもありますが、来期の妄想を始めています。 まず、Synergy! です。 Synergy! は 間違いなくシナジーマーケティングの事業の幹だと考えています。17年サバイブしたからこそ、今は10 → 100のフェーズにいます。この段階に全てのサービスがたどり着くわけではなく、とても誇らしいのですが、もちろん前人未到の領域でもありません。もう一歩を踏み出すときです。Synergy! のインフラもアプリケーションも、よりCustomer Engagement を高める「使いやすい」ツールとして進化させたいと考えています。 また、来期はSynergy! バックオフィスシステムの刷新も目論んでいます。事業においてバックオフィス機能はとても重要な箇所です。Synergy! 自身の顧客体験、FAN体験をよりよくするために、取り組んでいきたいもののひとつです。 もうひとつ、新サービスは、ビジョン(人と企業が、惹かれ合う世の中へ。)・ミッション(Create Synergy with FAN ) をよりダイレクトに体現するサービスであってほしいです。今年リリースしたサービスも成長させたいですし、さらに新しいサービスもローンチしたい。事業の枝をしっかり広げていきたいと考えています。 こんなこといっていますが、今年も私自身は旗を振っていただけで、実際のところはよくできたチームが次のフェーズに成長して、終わろうとしています。来年もやっぱり期待しかないですね。引き続きよろしくお願いします。

エンジニアリングマネージャーが新規事業開発にチャレンジして得た気づきと学び

TECHSCORE
2021-12-17 11:00:00
この記事は Engineering Manager Advent Calendar 2021(その2) の18日目の記事です。 シナジーマーケティングではいくつかの新規事業開発に取り組んでいます。2021年8月にen-chantリリース時の開発についての記事がありましたが、en-chantと同時期にもう一つ新規事業開発に取り組んでいました。取り組んでいた、と過去形にしているのはすでに撤退判断をしたためです。この記事では、エンジニアリングマネージャー(以下、EM)の私がプロダクトオーナー(以下、PO)として新規事業開発をすることになった経緯や取り組んだプロセス、そしてチャレンジして得た気づきと学びについて書いていきます。 小野寺 俊也(オノデラ シュンヤ) 2015年3月入社のエンジニア兼エンジニアリングマネージャー コーヒーが好き 最近のお気に入りは「冷やしピーマン」です。生のピーマンを氷水で一晩冷やしただけで苦味が抑えられて、さらにパリッとした食感もより強くなります。何をつけてもおいしいのですが、一番好きなのは塩です。 目次 新規事業開発をするに至った経緯 新規事業開発の顛末 体制 最初の事業企画プレゼンまでにやったこと 仮説検証でやったこと(LPテスト) 仮説検証でやったこと(社内MVPテスト) そして撤退判断へ 振り返り どう仮説を検証するかを考えてすぐ動く POは意思決定の連続 頭の中はかんたんに伝えられない EMがPOとして新規事業開発をする強みと弱み 新規事業開発チャレンジのその後 新規事業開発をするに至った経緯 はじめに、新規事業開発をするに至った経緯をかんたんに説明します。 私が所属するビジネスクリエーション部では名前の通り新規事業開発をミッションとしています。2020年4月頃に管掌役員から新規事業に関わる技術調査依頼のミーティングがセットされました。このミーティングでアイデアを出してみたところ、POとして事業開発を任せてもらえることになりました。 これまでEMとして働いてきた私が、事業開発にチャレンジしたのには2つ理由があります。 1つはEMとしてメンバーの活躍の場、成長の機会を創りたかったというものです。ありがたいことに私のグループには技術力も一定ありながら事業貢献への意識が強いメンバーが若手からベテランまで揃っており、いま進行中のサービスを3、4年安定して提供できている状態でした。新たな活躍の機会を作り、新しい人を迎えいれながら次の仕事をお願いするようなことをしたいと考えていましたが、当時はいくつか新規事業の種があったもののまだ開発フェーズではなかったため、私も事業開発をすることで開発フェーズに進める可能性を増やせるのではないかと考えたのが1つ目の理由です。 もう1つは個人としての純粋なチャレンジです。同じことをずっと続けるのが苦手な私は機会があればちょっと違う仕事をしてきました。当時はEMになってから3期目で、EMとしてもまだまだ未熟ではありますが、別の領域であるPOにチャレンジしたい思いが勝ったというのが2つ目の理由です。 新規事業開発の顛末 では、どういうことをして、なぜ撤退という判断をしたのか、というのを紹介していきます。 今回の事業開発のタイムライン 体制 今回の事業開発は私、エンジニア、デザイナーの3人で取り組みました。 最初の事業企画プレゼンまでにやったこと 事業開発を進める最初のマイルストーンとして2ヶ月後の管掌役員プレゼンがありました。どうプレゼンするのか検討もつかなかったため、まずはとにかく世の中の新規事業開発、スタートアップの情報を調べました。幸いなことにいろいろな方がプレゼン資料やその作り方を公開してくださっています。スタートアップピッチの資料をググるとAirbnbなどの海外企業の事例が多く見つかります。ですが、海外企業の事例はどうしても遠くに感じてしまうので日本企業の情報がないか探してみたところ、マザーズ上場企業の「成長可能性に関する説明資料」やTechCrunchのスタートアップバトルイベント、ICCのスタートアップ・カタパルトといったピッチ・コンテストで多くの事例を見つけることができました。最終的に 「Airbnb の初期ピッチ資料は YC の 3 分ピッチテンプレート通り」 に沿って検討・調査をすることにしました。 プレゼンの大筋のイメージができたあとの2週間は、エレベーターピッチやスケッチを書いてあとの2人に壁打ちをするというのを繰り返しました。何度かやりとりするうちに、少し筋の良さそうな仮説ができてきたので社内インタビューを実施して仮説の精度をあげていきました。私以外の2人はUXプロセスの経験があり、あっという間にインタビュー計画ができあがりました。インタビューの結果を受けてアイデアの修正を行い、架空のペルソナをつくりつつメンバー間の認識共有をしました。他にもベンチマークとなりそうなサービスの調査をしたり、仮説検証計画をMVPキャンバスに当てはめて作ったりしました。 チーム内でのターゲットの認識を揃えるためにペルソナを作成 どうにか作った資料でプレゼンをした結果、仮説検証を進められることになりました。 仮説検証でやったこと(LPテスト) いかに本質的な検証をするかが重要、と多くのスタートアップの書籍に書かれていたので私もどんな方法がとれるのかいくつか調べました。(この時点で本質的な検証が重要だとわかっていたつもりだったのに...) その中で採用したのが、サービスが実在しているかのようなLPをつくり、ウェイティングリストにメールアドレスを登録してもらえるか、という市場の反応を見る検証方法でした。ストーリーマップ、上位下位分析、UXDコンセプトシートなどのコンセプトワークをしながら、どういった訴求にするのか、どうすれば実在するサービスだと思ってもらえるか、検討しました。そして、これらのワークを元に要求と機能を突き合わせて訴求内容を絞っていきました。コンセプトワークは1つ数時間程度で終わるものなのですが、メンバーそれぞれの頭の中にあるイメージは違っていることが多かったのでコンセプトワークを通じてすり合わせるのはとても有効でした。 LPでの検証結果はというと、Twitter広告4万円の出稿でCV 3件でした(CPAは...orz)。これでわかったのはペルソナに近いターゲット層がTwitterにどのくらいいるかというポテンシャルくらいで、他に得られたものはありませんでした。後々ペルソナに近い属性をもつメンバーが1名ジョインしてくれた際に、TwitterよりもInstagramをよく活用していることがわかったので、Instagramで試していたらまた違った学びがあったかもしれません。 蛇足ですが、LPを公開するためにサービス名を考えて商標登録やドメイン取得などもしました。今となっては本質的ではない不要なプロセスだったと反省しています。 仮説検証でやったこと(社内MVPテスト) 今回の新規事業開発ではスマホで使えるツールアプリを作ろうとしていました。今いるメンバーはスマホアプリの開発経験がなかったので、Reactができるエンジニアに加わってもらってReactNative/AWS Amplifyで実現可能性調査を目的とした開発をしつつ、実際に使ってみながらフィードバックをもらえるように社内MVPテストをすることにしました。なんとかReactNativeでの開発ができ、1ヶ月ほど社内MVPテストをしました。アプリならではの仕様に何度もつまづきましたが、結果的にすばやく修正を繰り返すことでテストをやりきりました。 テスト後に実施したアンケートとインタビューから、ユーザーに強い課題・強い要求がないことがわかりました。MVPテストの結果を受けてピボット案を検討していたところ、ふと、既存のアプリを使えば今回のMVPテストと同じ体験の検証ができることに気づきました。すでにあるアプリを使うだけなので社内MVPテストよりもっと早くもっと簡単に。事業開発当初から最小限に、最小限に、と思っていたのにも関わらず、アプリを作って検証してしまっていたのです。もちろん実現可能性の検証をすること自体は良かったのですが、体験の仮説検証自体はもっと早い段階でできたということに気づいたときには内心かなりショックでした。本質的な検証が大事だということは常に意識していたのに、実際にはできていませんでした。 そして撤退判断へ 初期仮説の失敗を受けて別のアイデアをいくつか考えましたが、どれも強いペインではないという結論になりました。また、当初のアイデアがソリューションから考えてユーザーを決めてしまっていたため、ソリューション仮説が外れた状態からピボットすることもできそうにありませんでした。サービスの利用者が一定増えることで成立するビジネスモデルを想定していたのですが、最初のユーザー獲得に対して予算投下したらどうにかできそうだという見込みも立てられませんでした。 振り返り 新規事業としては撤退という結果になってしまいました。それ以上に、新規事業開発のプロセスとしてもかなり失敗してしまいましたが、それでもいくつかの気づきや学びがあったのでご紹介します。 どう仮説を検証するかを考えてすぐ動く 新規事業開発のあらゆる書籍、サイトなど、至るところに「仮説」という言葉がでてきます。事業アイデアを考えているときは作り上げていく楽しさと同時に、本当にこれでいいのだろうかという不安がつきまとっていました。ここで失敗だったのは、アイデアを練り上げるフェーズに多くの時間を使ってしまったことです。もちろんアイデアを考えるには時間がかかってしまうのですが、最初のアイデアの確からしさをすぐに検証できなかったことが問題でした。頭の中でいくら考えて練り上げていっても所詮は自分の頭の中のことなので何一つ進展していないのと一緒なのだと思います。とにかく早い段階で想定ユーザーに持っていくのが大切で、ずさんなモノを見せる勇気が必要だと感じました。どう仮説を検証するかを考えてすぐ動くことの大切さに気づきました。 POは意思決定の連続 世に出したわけではないのでそれほど重要な意思決定はしていないのですが、事業開発は意思決定の連続でした。いままではPOにEMとして情報を渡しつつ最終意思決定をしてもらっていましたが、いざ自分がPOになってみると材料が揃いきらないままに意思決定をすることがとても不安でした。頭ではわかっていたつもりでしたが、POになってみて意思決定の大変さを学びました。 頭の中はかんたんに伝えられない 意思決定をするにあたって自分なりにロジックを組み立てるのですが、その過程は筋が通っているときもあれば、実は四六時中考えているものをこねくりまわしてつなげたものも混ざっていたりします。そして、こねくり回していることはなかなか自覚できないのが厄介で、筋を通して話しているつもりでもなかなか伝わらないということが何度もありました。幸いにしてメンバーがはっきりとわからないと言ってくれるので、齟齬があるまま進むということはありませんでした。こうした状況を避けるために、コンセプトワークはとても有効だと思います。数人が長い時間集まってやるので高コストに感じてしまいますが、ワークを通じて多面的に頭の中をアウトプットしつつ全員で共通認識を作れるのでコスパがいいと思います。 EMがPOとして新規事業開発をする強みと弱み 私がEMからPOになってみて感じた強みと弱みです。あくまでイチEMの例としてご覧ください。 強み ・仮説検証方法の引き出し:これまでの開発経験からどう作れば早くつくれるかというのは考えやすかったです。また、スクラムやMVP開発、UXプロセスなどエンジニアとして学習していたことが新規事業開発でも使えるものが多かったです。 ・開発難易度の想定:開発観点での実現可能性の見積もりはこれまでもやっていたことなので、そのまま強みとなりました。 ・実装要因:ちょっと開発の手が足りなかったり、LPを作ったり、といった場面で自分も手を動かすことでスピードを上げることができました。 弱み ・社外との関係性の少なさ:BtoBのアイデアについて意見をもらうべく企業にインタビューをしたのですが、私個人としては全くもってアテがなかったので営業社員に協力をしてつないでもらいました。 新規事業開発でPOをやるにあたってはEMだろうが他の職種だろうが、その時々で得意な領域や不得意な領域があるものだと思うので、すぐにヘルプを求めたり、体制づくりで自分の苦手を得意とする人に入ってもらったりするなど、どうにかして取り組むしかないのでしょう。 新規事業開発チャレンジのその後 撤退後、社内で新規事業へのチャレンジを促進するための座談会があり、失敗談として今回の記事に近い発表をしました。当初30分ほどの予定でしたが50分近く話してしまいました。少しでも学びを共有したかったから、というのは言い訳でタイムマネジメントができていなかっただけです。 座談会が終わってから数日後、他部署の方からちらほら開発ではない内容の相談してもらえるようになりました。これまではEMとして開発に関わる話をすることがほとんどでしたが、新規事業開発にチャレンジしたことで開発やEM以外で貢献できるものがあるのかもしれないと思えるようになりました。 この記事全体を通してEMとしての要素はほとんどなかったので最後にEMに関連することを書いて終わろうと思います。 もしPOや新規事業開発にチャレンジするかしないか悩まれているEMの方がいれば、ぜひチャレンジすることをおすすめします。そのままPOとして成功するのも素敵ですし、たとえ失敗してもPOというEMとは少し異なる視点で取り組んだ経験にはきっとEMとして活かせるものがあるはずです。

お世話になっているOSS開発者のスポンサーになりました

TECHSCORE
2021-10-28 11:00:00
2021年8月からシナジーマーケティングではOSS*1開発者、組織への寄付を始めました。 この記事では寄付をする(スポンサーになる)までの経緯と活動を紹介します。私は寄付をする際に必要な情報の調査、社内手続き、実際の寄付手続きを担当しました。 五十嵐 諒(イガラシ リョウ) 2021年4月入社のエンジニア。 毎日マクドでも飽きない。酒とゲームが好きです。 最近はサプリを摂りまくって免疫力を高めてます。最強です。 シナジーマーケティングでのOSS活用事例 シナジーマーケティングのプロダクト開発では多くのOSSを活用しています。 例えば、 Synergy!の土台を支えるコンテナオーケストレーションシステムとしてKubernetes オンプレミスへのKubernetes導入を振り返る - TECHSCORE BLOG 検証用のスマホをリモート化するSTF 出社不要!? 検証機をリモート化してストレスフリーに - TECHSCORE BLOG ユーザインタフェース構築のためのJavaScriptライブラリとしてReact Synergy! における Web フロントエンド開発の軌跡と将来の展望 | TECHSCORE BLOG このように、多くのOSSに支えられており、欠かせないものになっています。 寄付の動機 OSS開発者への寄付が簡単にできるということを知ったのをきっかけに、開発者に対する尊敬、感謝の意を行動で表すため、また継続的な開発をしてもらうための支援として寄附をすることにしました。 なお、これは社内Slackの雑談チャンネルで発案されたものが採用され、こうして全社の活動になりました。 寄付先の選定 寄付をするにあたり、まず大方針を決めました。 プロダクトを開発、運用する際に使用しているすべての OSSが対象 シナジーマーケティングとして外部に提供しているプロダクトで利用しているもの プロダクトに直接は含まれてはいないが、開発、デプロイなどで利用しているもの 大人数で開発しているものより、少人数で開発しているものを優先 予算はひとまず 10 万円 / 年 はじめてのことで何もわからないので、これはえいやで決めた予算です 継続して支援したいという思いを込めて、一括ではなく毎月払い 金額や期間については寄付される側の方で設定されるため、希望の金額・期間にできない場合もあります 寄付をするOSSの候補は社内のSlackで募集しました。 候補の中で寄付を募集していたものは2つありました。両方に寄付をしても予算内に収まるため、どちらにも寄付することにしました。 候補に上がった OSS に対し、 寄付を受け付けているか Web 上で簡単に寄付をすることができるか の観点で調べたところ、寄付を受け付けている OSS の数は多くはありませんでした。なんとなく(根拠はありませんが)もっと多くの OSS が寄付を受け付けていると思っていましたので、驚きました。 Evans Evansとは、gRPCクライアントツールです。gRPCサーバのRPCメソッドを呼び出して動作確認をする際などに利用されます。 多くのgRPCクライアントツールがある中で、当社エンジニアが普段使っているものです。 gRPC の CUI のクライアントツールを調べてまとめてみた | TECHSCORE BLOG こちらはメルペイのエンジニアの方が開発しているようです。個人で開発をされているため、今回の寄付が、今後の開発に少しでもお役に立てばいいなと考えています。 OpenAPI Generator OpenAPI Generatorとは、OpenAPI SpecificationというRESTful API仕様の記述フォーマットに従ったAPI仕様書を基に、APIクライアントのコード、スタブサーバのコード、コンフィグレーションファイル、ドキュメントを自動で生成できるツールです。 Synergy!のメールAPIのインターフェースはOpenAPI Specificationのフォーマットで公開しています。この API 仕様書の開発や生成に OpenAPI Generator を使用しています。 Synergy! のメール API を使ってメール配信を行う | TECHSCORE BLOG 寄付の方法 Evans には GitHub Sponsors を使って、OpenAPI Generator には Open Collective を使って寄付をしました。いずれもそれぞれの GitHub ページでの指定に従っています。 両方ともOSSに寄付ができるプラットフォームです。 GitHub Sponsors 寄付をする方法はとても簡単ですぐにできます。 対象のOSSにあるこのボタンから進めていきます。 手順はGitHub公式ドキュメントに載っていますが、見なくても画面の案内に従えばできるくらい簡単だと感じました。 Open Collective OpenAPI GeneratorではGitHubでSponsorボタンをクリックすると外部サイト(Open Collective)に遷移します。 Open CollectiveでもGitHub Sponsorsと同様に寄付は簡単で、金額や期間、支払情報などを画面に従って入力していくだけで完了できました。 寄付完了 GitHub Sponsorsで寄付をしたらアカウントのページのSponsoringタブで確認できます。 https://github.com/orgs/SynergyMarketing/sponsoring Open Collectiveの場合はアカウントのページのContributions(貢献)というところで確認できます。 https://opencollective.com/synergy-marketing#category-CONTRIBUTIONS 最終的な今回の寄付の内容は以下のようになりました。 OSS 金額 頻度 Evans $1 毎月 OpenAPI Generator $45.54(約5000円) 毎月 ※Evansの開発者は受け付ける寄付額を $1 に指定していました。 おわりに GitHub Sponsorsの存在を知ったことをきっかけに社内活動が始まり、ひとまず2つのOSSのスポンサーになりました。 企業としてのアカウントの持ち方、支払関係の設定や扱い等の調査や、社内の手続きがとても大変でした。利用規約をしっかり読んだり、社内のあっちこっちへ連絡を取って、いろいろ申請して... 会社として何かをする時はこうやってしっかりやらないといけないんだなと、とても勉強になりました。 GitHub SponsorsとOpen Collectiveでの寄付自体はどちらも直感的な操作で、ポチポチするだけで数分でできてしまうとても簡単な作業でした。 シナジーマーケティングでは今後もOSSへの寄付を続けていきたいと思っています。OSS開発者の皆さんのお役に立てれば幸いです。 *1:ソースコードの使用や改変等が無償で自由にできるソフトウェア

先輩たちを目標に邁進中。新卒2年目エンジニア、同期5人でこれまでの1年半を振り返る

TECHSCORE
2021-10-14 11:00:00
2020年4月に新卒入社したエンジニアは5人。 入社から1年半で経験したこと、目標にしている先輩のこと、これからやってみたいことなどを同期5人で語ります。 2020年4月新卒入社のエンジニアたち 登場人物 岸本 大河(クラウド事業部 第二プロダクト開発G、写真右下) Synergy!のgiftee連携機能の開発やNEWT(後述)DBのサーバサイドの実装を担当。 岸本 和哉(クラウド事業部 第四プロダクト開発G、写真右上) フロントエンドのチームに所属し、保守・バグの修正・要望対応などが主な業務。新卒1年目向けの研修や講義など育成関連の業務も担当。 松田 直哉(クラウド事業部 第三プロダクト開発G、写真左上) Synergy!のファイル管理機能やフォームのカスタマイズなどを担当。他に技術職新卒のOJTなども担当。 松木 自然(クラウド事業部 第一プロダクト開発G。写真左下) Synergy!LEADとLINEのバックエンド保守開発を担当。FROG(後述)のメンバーとしてチームで管理している移行業務を担当。 聞き手:小林 連(クラウド事業部 第三プロダクト開発G、写真中央上) SIチームに所属し、複数の案件の保守対応や要望対応を担当。新卒の営業向け座学講座・育成などにも従事。 名字が同じメンバーがいるからか(?)、普段から名前で呼び合っている5人。この記事でも雰囲気をそのままお届けします。 それぞれの環境ですごした1年半。かつての不安や苦労が今の業務に生きている 小林(以下、連): 入社してもう1年半ですね。配属されて1年ちょっとですが、 それぞれどんな仕事をしましたか? 岸本 大河さん(以下、大河): 入社後の研修が終わってすぐgiftee連携機能(後述)の実装を担当しました。その後、Kubernetesへのアプリケーション移行を担当して、今はNEWT*1 DBの実装をしています。 岸本 和哉さん(以下、和哉): 去年の夏にインターンシップの企画と当日対応を担当しました。その後バックエンド業務で特定のお客様が利用するSynergy!連携機能の開発を担当し、その後はOrangeチーム*2で保守をしたり、新卒育成に関わったりしながらフロントエンド業務をしています。 松木 自然さん(以下、自然): 和哉くんと一緒にインターンの受け入れをして、その後オンプレミス環境のKubernetes化に従事しました。現在はSynergy!LEADやLINEのバックエンドの移行、Synergy!LEADのフォーム新機能の開発などをしています。 松田 直哉さん(以下、直哉): 最初に取り組んだのはSalesforce見積資料の改修で、グループが変わって社内のマネジメントシステムの改修をしました。現在はFROG*3の全体テストとカスタマイズ案件を中心にやっています。 連: 入社後、4月は総合職の同期と一緒に研修、5~6月は技術職研修があって僕たち5人はしばらく一緒でしたが、その後はNEWT、FROG、SI、育成など結構バラバラの業務をしてましたよね。僕自身は研修が終わって1~2ヶ月ほどSynergy!のテスト業務をして、その後SIのチームに入って今に至ります。その中でインターンの受け入れをしたり、営業職に対する技術的な知識をつけるための座学研修やOJTなどを担当しました。 みんなは今話してくれた業務の中で、 一番印象に残っている仕事ってどれですか? 大河: 僕はgiftee連携の実装です。苦労したことや工夫したことは以前ブログに書いたとおりですが、この仕事をしたとき初めてSynergy!の中身を触ったんです。知識も無くて何から始めていいのかもわからなかったけど、このときの経験が今のNEWTの業務に生きてると思っています。 自然: 僕はインターンの受け入れですね。どんなことをしたのかは僕もブログに書きました。コロナの影響で実施形態を考え直したり、企画も今までにない内容だっりで、「これまでと同じ」ということがなくて、和哉くんと時には言い合いもしながら準備しました。インターン参加者が期間内にアプリケーションを完成できるか不安でしたが、結果きちんと完成し、インターン生も喜んでくれました。苦労は多かったけどやってよかったと思っています。今の業務では新卒1年目の後輩たちと関わる場面はないですが、和哉くんや連くんのように新卒育成に関わる機会があれば、この経験が生かせるんじゃないかと思っています。 連: インターン受け入れは僕も印象に残っています。自然くんが担当したインターンとは別で、HAL大阪の学生さんを1ヶ月間受け入れる就業型インターンシップを直哉くんと一緒に担当しました。いろいろ迷うところもありましたが、参加者が「最高だった」と言ってくれて嬉しかったです。 成長しながら足りない部分と向きあう 連: この1年でいろんな業務に関わらせてもらいましたが、やっぱりまだまだ足りないと感じることが僕は多かったです。みんなは 自分に足りないと感じる部分ってどこですか? ちなみに僕は知識が足りないと思っています。技術面もそうだし、あとは用語もですね。出てきた単語がわからなくて、その場で会話を咀嚼できないこともあります。 自然: いっぱいありますが、特に感じるのはスケジュール管理です。去年と比べて業務が圧倒的に増えて、一つのタスクに集中することより、複数のタスクを並行して進めることが多くなっています。全体のスケジュールが決まっているなかで、自分が管理しているタスクを自分でスケジューリングして進めていくべきなのに、それが出来ていなくて先輩に助けてもらっている状態です……。あとは問題の切り分けです。例えば障害が発生した場合、ログを見に行って、問題を切り分けて原因を特定する流れだと思うんですが、これはまだまだ出来ていないです。 大河: 人にものを伝える能力と自分からタスクを作る能力がまだまだだと思います。今はタスクをもらって、それを分解して仕事を進めていますが、これから後輩が出来たら仕事を教えたりタスクを振ったりする必要があります。ここはこれから鍛えていきたいです。 連: 足りない部分を挙げだすときりがないですよね(笑)。今度は逆を聞きたいです。 この1年で成長したことや、強みだと思えることはありますか? 大河: 学生時代含めこれまで少人数での開発しかしてこなかったんですが、入社して大人数・大規模なプロジェクトに関わることで、技術力や報連相など、基本的な能力が身についたと思います。 直哉: 相手の顔色を気にせず言いたいことが言えるのは強みだと思っています。ただ、オンラインでのコミュニケーションはやっぱりオフラインとは違うと感じていて、普通は1年間一緒にいれば、言葉の選び方や言い回しとか、相手に合わせたコミュニケーションがなんとなくわかってくるけど、オンラインだと全くわからないので難しいなと思います。 和哉: 強みかどうかはわかりませんが、以前先輩に「気づきが多いね」と言ってもらえました。フォームやバグなど些細なことに気づくことが多いらしいです。元々そういうところに気づきやすかったのか、成長して気づけるようになったのかはわからないんですが……。 連: 和哉くん目線で、僕たちについて気づいたことがあれば教えてください! 和哉: 連くんはすごく冷静だと思います。本人が「パニックだ!」とか言ってるときでも全然パニックに見えないというか、穏やかなまま何なくこなしているように見えます。大河くんと自然くんは新しいものを取り入れる力がすごいと思っていて、それが二人の技術力になっているのかもしれないなと感じています。直哉くんは切り込み隊長で、例えば僕が気になってるのに聞けないような場面でも直哉くんは色んな人に率先して聞いてくれます。だから一緒に仕事がやりやすいです。 連: ちょっと恥ずかしいですが、自分では足りないところに目が行きがちなので、こうして言ってもらえるのは嬉しいですね。 常に相手目線の人、技術力があって頼られている人。そんな先輩たちを見習いたい 連: この1年たくさんの先輩からいろんなことを教えてもらったけど、特に この人が目標!という先輩はいますか? 直哉: 川島さんです。入社後しばらくメンターをしてもらっていたのですが、とにかく説明とか例えがすごくわかりやすいんです。どうしてわかりやすいのか考えてみると、相手目線で物事をみているからだと思います。常に相手目線。しかも喋り方がすごく柔らかくて、画面越しでも人の良さが見える気がします。 大河: 僕は学生時代に寺岡さんに会って入社を決めたので、そのときからずっと、寺岡さんが僕の目標です。圧倒的な技術力があって、マネージャーとして話もわかりやすいですし、色んな面で見習っていきたいです。 自然: 白川さんです。配属されてからずっと白川さんと一緒に業務しているのですが、フロントエンドとバックエンドをフルスタックでできるところや、問題解決能力が高いところに憧れています。育成という面でも、僕が何か質問したときには、直接教えるのではなく自分で答えにたどり着けるように導いてくれますし、そのための時間をしっかり取ってくださっています。だから白川さんのもとで業務できている有り難さを感じますし、白川さんに聞いたらわかる、という安心感もあります。おそらく周りの人たちもそうで、本当に頼られている存在なので、自分もそうなりたいと思います。 連: それぞれの目標目指して頑張っていきたいですね。最後に、 これからやってみたいこと、後輩へのアドバイス・メッセージがあればぜひ教えてください! 和哉: これまでは一つの業務に従事するというよりはいろんな業務に関わらせてもらってきました。今後はフロントエンド業務をがっつりやってみたいと思っています。現時点ではフロントエンドとバックエンド、どちらが好きなのか自分でもよくわかっていないんです。「自分はこっちに行きたい」というのを見極めるためにも、一度フロントエンドを集中的にやりたいです。 直哉: AWS関連の業務をやってみたいです。将来性があると感じるし、AWSを使用したサービスも増えています。今後技術が進化していってもついていきやすいのではと思っているからです。 後輩にアドバイスできるとしたら、「困ったら助けてくださいって早めに言おう」ってことです。オンラインだと一人で何時間も悩んで時間を無駄にしてしまうので、早めに助けてもらうのが良いと思います。 大河: 1年目の皆さんとは今のところ接点がないんですが、来年には一緒に業務することが増えると思うので、そのときには楽しく仕事がしたいなと思います! 自然: 何でも相談できる先輩を一人見つけてほしいです。仕事をする上で悩んだりそれをなかなか言い出せなかったりといった場面があると思いますが、そんなときに周りを気にせず相談できる人が一人でもいると良いのかなと思っています。 連: みんなと重なる部分もありますが、僕は早い段階から先輩たちとラフなコミュニケーションを取ってほしいなと思います。真面目な人ほど最初は肩肘張って頑張ってしまうと思うんですが、それが続くと自分も相手も気を遣い続けないといけなくてしんどいですよね。。「親しき仲にも礼儀あり」と言いますが、もちろん礼儀は忘れず、でも気軽に、僕たち含め社内の先輩とコミュニケーションが取れれば良いんじゃないかと思います。 今日はみんな話を聞かせてもらってありがとうございました。これからもたまに集まって情報交換や近況報告をしましょう! 僕たちやシナジーマーケティングに興味を持ってくださった方は、ぜひエンジニア採用ページものぞいてみてください。未来の後輩をお待ちしてます! *1:NEWT(ニュート):シナジーマーケティングの主力製品である「Synergy!」のモダナイズプロジェクトの一つ。ローンチ以来変えずに運用してきたフォームやデータベースの機能を、2020年代の環境に合わせて再生するプロジェクト。 *2:Orangeチーム:Synergy!のファイル管理機能を担当するチームのこと。他に、Synergy!LEADやLINEなどを担当するBlueチーム、SIを担当しているGreenチームなどもある。 *3:FROG(フロッグ):NEWTと同じくSynergy!モダナイズのプロジェクト。Synergy!システムを柔軟性と拡張性に優れたクラウドに移行することにより、将来のサービスの進化に備えるプロジェクト。

6年目エンジニアが初めて開発リーダーとして新サービスを立ち上げた話

TECHSCORE
2021-08-30 11:00:00
2021/7/1に、当社初のtoC向け事業サービス「en-chant(エンチャント)」をリリースしました。 en-chantは、ファンの日常生活をスポーツチームの応援につなげることができる、新しい応援の形のサービスです。en-chantではファンがプロジェクトに参加することで、ファンの代わりにスポンサーからチームへ応援金が渡る仕組みを提供しています。 en-chantとは(詳しくはこちら) 私はen-chantの開発リーダーとしてジョインし、サービスコンセプトから要件定義/設計への落とし込みや、開発チームのマネジメントを主に行いました。この記事では、初めて新規事業の開発に携わった私が、感じたこと、気づいたことについて書いていきます。 土屋 江里佳(ツチヤ エリカ) 2016年シナジーマーケティングに新卒入社。 当社のメインサービス「Synergy!」の開発に携わったことのない稀な存在。 趣味は休日に動物園や水族館に行くこと。 開発スケジュール en-chantの開発にあたり、いつ頃どのようなことをしたのかをざっくり図で表してみました。 en-chantのプロジェクトは2020年8月ごろからスタートし、はじめはビジネスサイドの2名でサービスの企画検討を行いました(企画のエピソードはこちらをぜひご一読ください)。ある程度企画が固まった2020年11月ごろに私がジョインし、2021年1月にエンジニア2名がジョインしました。 図中(2月後半ごろ)の「セキュリティ基準・個人情報取扱基準の見直し」について補足しておくと、当社はこれまでtoBサービスのみを提供してきたため、今回のen-chantの開発を機に、toC観点で基準等を見直し整理しました。 全体の工期は約11ヶ月、そのうちサービスの企画が3ヶ月、調査や設計、検証等が6ヶ月、実装とテストが2ヶ月弱というスケジュールになりました。 ここから、en-chant開発を通じて得た学びをいくつかピックアップしていきます。 学んだこと、感じたこと プロジェクトの用語とターゲット サービスの企画段階で大まかに実現したいことが決まっていたため、要件定義も設計も早めにまとまりそうだと思っていました。しかし、メンバー間でミーティングを続けても、どこか腹落ちしないようなことが増えてきました。具体的には次のようなことが起きていました。 同じ言葉でも、メンバーによって意味合いが微妙に違っている。「自分はこんなつもりで話していました」というコミュニケーションが発生している。 メンバーによって、想定するユーザーの行動に違いがある。例えば、ある機能を組み込むことを考えているときに、エンジニアのAさんは「この画面遷移でユーザーは迷いなく操作できるだろう」と考える一方で、ビジネスサイドのBさんは「ユーザーがこの画面に到達したときに次のアクションで迷ってしまうだろう」と考えている。 よくよく話し合って結論を出しても、日が経つとこの設計で本当にいいのか疑問に思う。意見がブレやすい。 1つ目の対策として、単語とその意味をドキュメントで明記し、プロジェクトチーム内の共通言語として使うことを徹底するようにしました。単語の意味が些末な違いだったとしても、認識齟齬が起きるきっかけになってしまいます。コミュニケーションでつまずきがあったものの、早い段階でその機会を減らすことができたのでとてもよかったです。 2つ目と3つ目は複数の要因があると思うのですが、主な原因はターゲットとなるユーザー像の作り込みが甘かったことだと考えています。 今回の開発ではUXリサーチ会社の選定が必要になり、その分ユーザーインタビューの実施が後ろ倒しになったため、自分たちの想像だけで作成した簡易的なペルソナに後づけで情報を加える形になりました。要件定義や設計の議論をする段階でインタビューが終わっていれば、事実に基づく情報を使ってユーザーの特徴を固められていたかもしれません。 また、スケジュールの都合上、今回はユーザーインタビューを3人の方に実施しました。結果、ターゲットとなるユーザーの傾向が大まかに見られたものの、もう少し多くの人にインタビューを実施していれば、よりはっきりとした特徴をつかめていたかもしれません。 今回の開発を通じてtoCとtoBサービスの違いを感じたのですが、toBサービスは具体的な利用用途が決まっていることが多くユーザー像が固めやすい一方で、toCサービスの場合は利用ユーザーの対象がtoBよりも広く、ターゲット像がブレやすいと感じました。ターゲットの特徴をより深掘りして、全員で共通認識をもてるように心がけたいです。 初期リリースのスコープ 設計完了まで遅れていたものの、2月半ばの時点で主要な機能は固まってきていたので、ワイヤーフレームの作成などと並行してプロトタイプを作成していました。 プロトタイプが形になり、実際に動いているモノを見ると嬉しいし、アイディアが沸きやすくなります。POからも「あの機能も追加できる?」など要望が上がってきやすくなり、開発も(もちろん内容によりますが)できると回答していると、じわじわ機能要件が膨らんでいきました。 結果、追加する機能が大きくなりすぎ、2021年5月時点でこのままだと初期リリース日の7月1日に間に合わないことが発覚しました。 そこで、初期リリースの時点でen-chantというサービスがどうなっていれば良いか、改めてプロジェクトメンバー内で話し合い、その時点で不要な機能は追加機能としてリリースすることにしました。結果、無事に初期リリースを迎えることができましたが、ギリギリの調整になってしまったため、初期リリースのスコープを明確にしておくべきでした。 チームビルディング en-chantではチームビルディングとして次の2点を実施していました。 (1) 週に一度、チームメンバー全員でOKR*1を確認する。 自分のしていることが目標に貢献するのか見直すきっかけになりました。開発だけでなく、ビジネス側の目標も確認することで、チームの全体の指針にブレが生じにくくなりました。 (2)朝会や週定例は短い雑談をする。 業務のみの会話はどうしても硬いコミュニケーションになってしまいます。少しの雑談でも話やすい「場」ができ、心理的安全性を高めることができました。 逆に、研修やワークショップといった交流は行いませんでした。メンバーがほぼ同じ部署で、元々ある程度交流があったためです。 開発する上で意見の衝突はもちろんありましたが、全体を通じて建設的な議論ができたと思います。また、リリース後にチーム全体で振り返りを行ったのですが、「あれはよかった」や「次はこうしたい」など、お互いへの称賛や次のトライを前向きに検討できていたので、働きやすい関係が築けていたかなと思いました。 社内の横のつながり en-chantを開発するにあたり、専従メンバーの5人だけではなく、部署の垣根を超え30人以上の方に協力していただきました。協力いただいた内容は次の通りです。 UI/UXデザイン ロゴ/ブランドデザイン HTML/CSSコーディング ユーザーテスト 社内インタビュー レポーティング 規約/特許関連の整理 問い合わせ/オペレーション/請求関連の設計 テスト PMO Synergy!の設定 ※en-chantでは当社のサービス「Synergy!」を利用しています。 お客様紹介 新規事業開発をはじめてみると、思いがけないタスクが出てきたりと想像以上にやることが多く、専従メンバーだけでは2021/7/1のリリースには間に合わなかったと思います。協力していただいた社内の方にはとても感謝しています。 初期リリースが終わって 私がen-chantの開発にジョインしてからリリースまで約8ヶ月ありましたが、本当にあっという間に時間が過ぎていきました。毎日の変化が大きい新規事業の開発は忙しかったですが、メンバーや環境に恵まれたこともあり忙しさを楽しみつつ取り組むことができました。 また、ここまで反省を含めて色々と書きましたが、決してネガティブな気持ちはなく、「あ、今のこの状態は黄色信号だぞ!」と気付けるタイミングを体験できたのは、とても良い経験になりました。 もし、同じような状況で新規開発があったとして、「今よりもうまくできるか?」と質問されれば、自信を持って「はい」と答えることができます。スキル的にもまだまだですし、勉強しないといけないことはたくさんありますが...(笑) これからはen-chantがより大きく育つよう、尽力していきたいと思います! 一緒にen-chantを盛り上げませんか? 現在、私たちのチームではUXデザイナーを募集しています。この記事を読んでen-chantに興味を持ってくださった方は、ぜひ↓の記事もご一読ください。 一緒にen-chantをより良く、より大きくできる仲間を募集しています! *1:目標の設定・管理方法のひとつ。en-chantではチームで定めた目標(Objectives)に向けて、ビジネスと開発それぞれの観点で主要な結果(Key Results)を達成できるように動いていました。

副業のハードルがぐっと下がる、グループ会社のスペースエンジンで副業をはじめました

TECHSCORE
2021-07-29 11:00:00
2020年11月から株式会社スペースエンジンで副業をしています。この記事では、副業を始めたきっかけやそこで得た気付きを紹介します。 西岡 壮太郎(ニシオカ ソウタロウ) 2018年10月入社のフロントエンドエンジニア。 ReactやReact Nativeでの実装を担当しています。 筋肉系エンジニアを目指して、大阪⇔東京間を自転車で移動したり、週4回の筋トレをしたりしています。 トライアルへの参加をきっかけに副業開始 シナジーマーケティング(以下シナジー)では、社員の成長やチャレンジを後押ししたいという思いから、2021年3月に副業をオープン化しました。それに先立って、ペイフォワードグループ内での副業トライアルが実施されました。 私は2020年11月より、その副業トライアルのメンバーとして株式会社スペースエンジンが提供するサービス orosy(オロシー) の実装に参加しました。 orosyは、D2C・オンラインブランドに特化したB2Bの卸仕入れマーケットプレイスです。 フロントエンドエンジニアの募集でしたが、必須スキル(Nuxt.jsの利用経験)に対してマッチはしていなかったので、迷惑にならないか技術的な不安がありました。その不安を解消するために、カジュアル面談を組んでいただいて、スキルのマッチも含めてのトライアルという形で参加しました。 副業トライアルから現在まで 副業トライアル 副業トライアル時点では、いくつかのルールが設定されていました。 期間は1ヶ月間 月の作業時間は20時間まで シナジーの業務時間として業務にあたる 副業を実施する事での本業(シナジー業務)への影響や、技術的な不安の解消を目的としてのトライアルのため、シナジーの業務時間としてスペースエンジンの業務に参加しました。そのため、シナジーの業務が終わった後に残業のような形で副業を行うイメージが近いかもしれません。 スペースエンジンでは、主にNuxt.jsを使ったレイアウト調整などorosyのフロントまわりの修正を行いました。 シナジーでの業務ではReactを利用しているため、一日の終わりの良い頭のストレッチになったことを覚えています。 現在 2021年1月から正式な業務委託契約を結び、スペースエンジンからお給料をいただいて開発に従事しています。 トライアル時のようなルール設定は無く、働き過ぎによる影響をシナジーの業務に与えないという約束ごとがあるのみです。ですので、グループ会社間での副業という実感は少ないですが、タスク管理の手法や技術面などの共有やこの記事のようなコラボレーションを行う事ができています。 6ヶ月間の気付き 2020年11月からの副業トライアル、2021年1月からの正式な副業の開始から半年過ぎて、良かった事、シナジーに持って帰りたいものについて挙げていきます。 グループ内副業のハードルの低さ 1つ目は副業を開始するまでの、心理的、工数的ハードルの低さです。 個人で副業を開始するためには以下のような手順が必要であり、私は副業に興味があったものの、実際に副業を始めるまでには至りませんでした。 応募する募集企業の選定。 企業への応募、面接。不採用の場合はこれを繰り返す。 業務開始と実業務とのスキルマッチの確認。 副業トライアルでは、グループ内企業からの募集という心理的ハードルの低さや、1ヶ月間のトライアル参加でのスキルマッチの確認など、上記のハードルが無くなった感覚に近いものがありました。 この機会が無ければきっと今も副業を始めていなかったと思います。 業務時間の自由度 2つ目は業務時間の自由度です。 他社の副業募集を見てみると、最低週16時間の稼働時間が必要な場合が多く、生活スタイルによっては時間確保ができない場合も多いでしょう。 私も最初は月30〜40時間程度の稼働ができると考えていましたが、今現在では月15〜20時間程度の稼働しかできていません。 とはいえ、もっと働きたい希望もあるため自身の時間の使い方の反省が続いています… という風に、働きたい時は働けるし、働けない時は少ない稼働時間でOKと、とても自由な働き方をさせてもらっていると感じています。 チケットの切り方 最後に担当タスクの工数の小ささです。 スペースエンジンでの副業を始める前までは、「副業先のプロジェクトに関わる=とても大きな仕事を任される」という先入観がありました。しかし実際はボタンのデザイン改修からInstagramとの連携など、自身の裁量や技術レベルに合わせての業務が行えています。 この様な自身の状況にあわせたタスクを選択できることによって、前項の副業トライアルや現在の月20時間稼働が実現できています。 これは、得意な領域や複数プロダクトでメンバーが活躍するために、シナジーでの業務でも改めてタスクの細分化について考えさせられる内容でした。 まとめ 副業を始めてみて 副業トライアルから、現在に至るまでを振り返りました。 この記事を書く前は「思っていたより副業ってハードル高くない」と、ざっくりとした感想しか持っていませんでしたが、記事を書きながら現在の働き方、トライアルの受け入れを振り返ると、スペースエンジンにはとても良い機会と環境を提供してもらっていると感じます。 最後に、スペースエンジンの代表でエンジニアの責任者である野口さんからコメントをいただいていますので、是非ご覧ください。 スペースエンジン代表 野口さんから 副業が両者にとってうまく機能するためには「互いの“副業への慣れ度合い”の把握」と「期待値をのすり合わせ」が非常に重要です。 そのため稼働時間が短い、スキルに不安があること自体は問題ではありません。それを副業先へはっきりと伝えましょう。 そして会社と副業者が、それぞれ達成したいこと、稼働時間、スキルから両者とって良い経験になるように務めることができれば無理のないパートナーシップを構築することができると思います。 orosyは新たな資金調達を終え、メンバーの採用を開始していますので、転職を検討されているご友人がいらっしゃれば是非ご一報ください。 エンジニア募集中! シナジーマーケティング、スペースエンジンでは一緒に働くエンジニアを募集しています。 ご興味のある方はシナジーマーケティング エンジニア募集サイト、スペースエンジン エンジニア募集サイトからご応募お願いします。

シナジーマーケティング エンジニア大調査2021

TECHSCORE
2021-06-17 11:00:00
シナジーマーケティングには約80名のエンジニアがいます。 CTOである馬場をはじめ、採用サイトや人事ブログに登場している社員もいますが、紹介できているのはほんの一部です。 そこで今回、シナジーマーケティング初となるエンジニア向けアンケートを実施しました。エンジニアたちの経歴、仕事の進め方やこだわり、さらにはプライベートのことまで、「シナジーマーケティングのエンジニアってこんな感じ」をまるっと紹介します。 【アンケート概要】 実施期間:2021年5月11~24日 対象:シナジーマーケティングのエンジニア 回答数:46 新人からベテランまで。多種多様なエンジニアたち まずはエンジニアたちの現在の職種、そして経歴や社歴について紹介します。 Q:あなたの職種を教えてください。(複数回答可) Q:あなたはエンジニアとして働いて何年目ですか?(企業への所属有無に関わらず、エンジニアとして働いた通算年数) Q:あなたはシナジーマーケティングで何社目ですか? ご覧の通り、エンジニアとしての経験年数では新人、中堅、ベテラン勢とまんべんなくいることがわかります(平均値は10.5、中央値は10)。ちなみに経験年数が3年未満のいわゆる若手社員は9名でした。社歴を見ると2社もしくは3社目の人で半数を占め、次いで1社目と4社目、それぞれ同じくらいの割合でいることがわかりました。「6社目」と答えたある社員に話を聞いてみると、エンジニアとしては15年目で、その中では当社が一番長いとのこと。長く働いてくれている理由として、制度面での働きやすさ、目の前の業務以外について提案できる環境、人の良さなどをあげてくれました。 また直前の職種を聞いてみると、多かった回答はやはりソフトウェアエンジニア。当社の主力製品であるSynergy!の開発に携わるエンジニアが多いので納得の結果です。ソフトウェア以外のエンジニアだった人やエンジニアでなかった人も少なくなく、中には「直前の前職」ではないですが以前探偵だったという異色の経歴を持つ人も。さまざまなバックグラウンドの人が集まっていることがわかりました。 誰かの役に立つことが嬉しい 続いて、仕事をする上でのスタンスや当社の良いところ&悪いところを聞いてみました。 仕事をしていて嬉しいと感じるときは、 エンジニア以外の方にありがとうをもらったとき お客様の課題解決に貢献できたとき お客様や仲間に感謝されるような仕事ができたとき、想定以上に早期解決ができたとき 誰かの役に立てたと思うとき、自分が成長したと感じるとき 自力で業務をやり切ったときや知識や経験が活かされたとき 自分で作ったものがリリースされ実際に動いているのを見るとき など、お客様など誰かに感謝されるのが嬉しいといった内容の回答が多く見られました。 また、これまで勤務した会社と比べたときにシナジーマーケティングの良いところとして、 人が良い 一人ひとりのスキルが高い 最新の技術を積極的に取り入れている 労働時間に無理がない(残業前提で予定を組まない) ばらばらではなく目標に向けて邁進している などの回答がありました。一方で悪いところとして 特定の人しかわからない、メンテナンスできないような状況がある 新人向けの教育体制や資料が薄い 優しすぎる、大人しい(もっとチャレンジしても良い) 業務の負担が偏っている 情報管理にかかわる制約が多い などの回答がありました。「人が良い」と多くが感じている一方で、それを「優しすぎる」と感じて、もっとガツガツしてもいいのでは?と考えている人もいるようです。また、社歴が長いあの人しかわからない……という問題はエンジニアに限らず各所にあり、そうした状況を改善する(そして未来の自分たちが困らないようにする)ために、最近は積極的にテキストで情報を残す人が増えてきています。 テレワークで仕事もプライベートも充実 最後にテレワーク体制でエンジニアがどう感じているのか、またこの1年で買ったおすすめのアイテムなどを紹介します。 以前「コロナで突然の(全員)在宅勤務。そのときエンジニアは?」の記事でも紹介したとおり、当社はコロナをきっかけに半ば強制的に在宅勤務をスタートしました。その後試行錯誤を重ね、2021年1月に在宅勤務(現在はテレワークという名称に統一)を正式に制度化しました。 現在もテレワーク中心の勤務状況が続いているなかで、プラス/マイナスと感じる点をそれぞれ聞いてみました。 <プラス> 通勤に時間や体力を奪われない 会議室問題からの解放 集中できる環境を作りやすい 分報でのつぶやきでコミュニケーションが生まれる <マイナス> 社員との雑談が気軽にできる場がないので、そういう部分ではコミュニケーションロスを感じる 運動不足 周りのタスクが見えづらいので若手へのフォローなどが難しい オンオフの切り替えが難しく、ずっと仕事をしてしまう プラス面では通勤時間がなくなったことによるメリット(家族と過ごす時間が増えた、趣味の時間を持てる、睡眠時間を確保できるなど)をあげる人が多くいました。また、出社すると会議室の予約や移動が必要となる、いわゆる「会議室問題」がこれまでエンジニアたちにストレスを与えていたことも明らかになりました。 また、最近買ったおすすめアイテム(サービス)としては 机&椅子 PC周りの小物(モニター、マウス、キーボード、ワイヤレスイヤホンなど) 映像配信サービス(Amazon Prime、Netflixなど) 家電(コーヒーミル、食洗機、オーブンレンジなど) 食関連(生協、Oisix、PostCoffeeなど) などの回答があり、自宅での業務の効率化や、おうち時間を楽しむために選んだモノやサービスが多くあげられました。 まとめ:まじめ&ポジティブな人多し 今回は当社で初となるエンジニア向けアンケートの結果を紹介しました。 経歴は本当に人それぞれで偏りがなく、エンジニアが互いに尊重し合いながら業務をする土台になっているように感じました。 また当社の悪いところやテレワークでマイナスと感じる点など、マイナスの側面を聞く設問では、匿名アンケート(名前は任意)にも関わらず思いっきり文句ばかりを書く人はおらず(笑)、「こうすればもっと良くなる」や「XXに気づけて良かった」など、マイナス面とその改善点・反省点をセットで回答する人が多くみられました。エンジニアに限らず、当社は「まじめ」とか「ポジティブ」と言われる人が多いですが、アンケートでも当社の特長があらわれる結果となりました。 ここではすべて紹介できませんでしたが、今回初めてアンケートを実施したことでわかったこともたくさんありました。これからもエンジニア一丸となって、お客様や世の中にとってよりよいサービスが提供できるように邁進していきます! もっとシナジーマーケティングのエンジニアについて知りたい、という場合は採用サイトからお気軽にご連絡ください!

開発リーダーとしてチームビルディングのためにやったことを振り返る

TECHSCORE
2021-05-20 11:00:00
はじめまして、フロントエンドエンジニアの田中です。 2月にリリースした Synergy! フォーム機能 リプレースのβ版のフロントエンドチームリーダーを任されました。 リーダーという役割は初ということもあり悪戦苦闘した日々を振り返りたいと思います。 本記事はプロダクトマネージメントの手法などの話ではなく、リーダーとしてどんな気持ちで何に注力し、どんな行動を取っていたかという話です。 田中 賢樹(タナカ マサキ) 2019年6月入社のフロントエンジニア。 職場環境改善が大好物。 漫画/ゲーム/酒が好きです。 コロナで飲食店がすぐ閉まるのでつらい日々を送ってます...クラフトビール飲みたい🍺 ​ このプロジェクトは Synergy!リリース当初から稼働していたフォーム機能を現在のモダンな技術でリプレースするというプロジェクトです。 フォーム機能は、フォームを作成し公開/非公開などの設定をする管理機能、作成されたフォームを実際に利用するコンシューマ機能に分かれています。私は管理機能のチームに所属し、フロントエンドエンジニアは私を含め5人体制でした。 Synergy!のフロントエンドは機能毎にリポジトリが分かれており、その多くはAngularが使われていますが、今回技術選定をするにあたってReact(Next.js)を選択しました。 様々な理由がありますが、大きなものは以下の2点です。 Angularは約半年に一度メジャーアップデートされるため、これに対応し続けることが苦しかった 私含めメンバー全員が別の技術に触れたかった 過去の資産が使えないデメリットはありますが、それ以上にメンバーのモチベーションを高め、生産性を上げることを選択しました。 チームとして目指したこと 今回特に目指したことは、メンバー全員が実装に集中でき成長できる環境作りです。 リーダーとしてフロントエンドメンバーの窓口になること以外、開発の進め方などは私個人に任されていました。 そこで、自分が開発者として働きたくなるような環境を作ることを目指しました。 それは、開発者が実装に集中できて、かつチーム全体で技術的に成長しあえる環境です。 実装のことだけに集中して思った通りの実装ができた時の快感はたまらないですよね? リーダーとして心がけていたこと 今回私が心がけていたことは常にオープンであることです。 具体的にはいつどこで声をかけられても即レスすること、声をかけやすいように忙しさや疲れ、苛立ちなどを極力見せないことを心がけました。 私はチームで一番良くないことは、「一人で悶々と考え、時間を浪費してしまうこと」や「不満や疑問を言い出せずにため込んでしまうこと」だと考えています。些細なことでもとりあえず田中にぶつけてみれば話が前に進む、という印象を持ってもらうように努めました。 実際に何をしたのか 開発前1on1 メンバーはそれぞれ得意分野も違うし目指しているものも少しずつ違います。開発前に1on1をし、どこでバリューを出したいか、何にチャレンジしたいかなどをヒアリングして、チームとして共通認識を持つように努めました。 事前学習期間を設ける 今回はReactで開発することになりましたが、私以外のメンバー全員ほとんど未経験なので、約1週間の学習期間を設けました。やってもらったことは利用する技術のマニュアルやチュートリアルの確認です。意図は実装力をつけることではなく、どんなことができてどこに情報があるのかということを知ってもらうことです。 ライブラリ更新の自動化 開発中はライブラリの更新をいつするのかという課題があります。Synergy!のこれまでの開発でもこの課題に悩まされてきました。時間が経ってからいざ更新しようと考えても、色々なところが壊れてしまってサッと対応できず、想定外のリソースを取られてしまいます。 こういった課題を解決するために、ライブラリの更新を自動化するRenovateを導入しました。毎日自動的に更新の有無がチェックされ、自動的に更新、テストが行われます。テストに通らない場合でも、差分が少ないので小さな工数で対応することができました。これにより環境がどんどん古くなっていくという不安がなくなりました。 ページや機能毎の担当制を廃止 Synergy!のこれまでの開発では、ページやその中の大きめの機能毎に担当を分けて開発を進めていました。これは担当者がページや機能全体の責任を持ち、自分のやり易いように作るように考えられたもので、チーム内のコミュニケーションコストも低く着手までは早いです。 ただ、この方法はコードが属人化し易く、仕様の把握も自分の担当箇所のみで他の仕様に興味を持ちづらいという欠点があります。 また、チーム内のコミュニケーションコストは低いものの、他チームまで含めると関係人数が多くなり全体的なコミュニケーションコストは高くなります。 上記理由から担当制は廃止しました。その代わり issue作成時に変更の詳細まで記述する 1週間毎にmilestoneを設けて、issueを整理する メンバー全員でissueを消化する という方針にしました。 担当制を廃止しても、自分が実装した内容に近しいissueばかり拾われて結局属人化するかも、という懸念がありました。 多少そのような傾向はありましたが、メンバーは未経験なものも含め、様々な領域のissueを消化していました。 リーダーはissue作成やコードレビューに徹底して、コードを書くことを諦める せっかくマージリクエストを出してもレビューが遅いと次のissueに集中しづらい状況になってしまいます。 普段からフロントエンドチームは担当プロジェクトに関係なく全員でコードレビューを行っていますが、各々がタスクを抱えているためレビューするまでに時間がかかる事も多いです。 そのためリーダーは即レビューを徹底しました。 これは開発メンバーの生産性を上げることにもつながりますが私自身、プロジェクトのコードがどうなっているかを完全に把握することができました。 しかし、リーダーとしてissue作成に加え、即レビューを徹底すると、それだけでいっぱいになってしまうことが予想できたため、自分自身はコードを書くことを諦めました。 結果として中途半端な対応にならずにサポートに回れ、メンバーの生産性、品質に貢献できました。 Slack通話の活用 コロナの影響で完全リモートの環境になり、基本的にチャットベースでコミュニケーションを取りますが、画面を共有しながら話した方が圧倒的に早い場面はとても多いです。 しかし、その度にわざわざスケジュールを確認してWebミーティングを設定するのも手間がかかります。 そこで活用したのがSlack通話です。 プロジェクトチャンネルやメンバーの分報などでちょっと話せますか?など一言いれた後にそこで通話を開始、画面を共有しながらペン機能を活用し、時に別のメンバーがフラッと入って来て別の視点から意見を出してくれたりと同じオフィスにいる場合とあまり変わらないシームレスなコミュニケーションをとることができました。 実際運用してみて まず、当初のスケジュールを伸ばすことなくリリースを迎えることができ、チーム内のモチベーションが終始とても高かったように思います。 コードから属人性がなくなり、バグ対応なども実装者が誰であれ手の空いているメンバーが率先して対応できる体制ができました。 また、現在はセカンド、サードリリースに向けてメンバーを再編成して開発が進んでいますがリファクタリングなども活発に行われ、開発速度も日々加速しているように感じます。 振り返り 今回心がけたことは以下の3点です。 要件を把握してissue化する。 迅速にレビューする。 突発的な相談の一次窓口になる。 最初はこれらすべてにカンペキに対応しようとして、私自身がキャパオーバーになってしまうこともありましたが、メンバーからのフォローに救われました。 要件のまとめ方、issue化のやり方、レビューどれも仕組み化することで改善できることがかなり多かったです。 現在、セカンド以降の開発ではそれらの課題を仕組みで解決する試みを進めており、人数は減りましたが、よりスムーズにプロジェクトが進んでいます。 まとめ 技術的負債を返済するためのプロジェクトに、スケジュール的な余裕がなく新しい負債を作ってしまったという話はよくあると思います。 今回私のやった事はベストな対応ではなかったと思いますが、セカンド開発を見る限り成長し続ける新しいフォーム機能の土台として世に送り出せたのではないかと思います。 今後もより良いプロダクト、より良い開発環境を作り続けたいと思います。

TECHSCORE BLOGをリニューアルして1年の振り返り

TECHSCORE
2021-04-15 11:00:00
TECHSCORE BLOGをリニューアルしてから早いもので1年が経ちました。この記事では1年間の活動を振り返り、特にやってきたこと・良かったことについて紹介します。 河野 健太朗(カワノ ケンタロウ) 気づけば在籍10年目となってしまいました。 趣味はけん玉とカメラです。最近はミラーレスカメラでの動画撮影に取り組みつつあります。 執筆者のサポートを充実させる リニューアル以前は基本的に執筆に関して、執筆者で記事の内容からスケジュール管理まで行う必要があり、負担が大きいものでした。そこで、リニューアル後は体制を新たにして運営チームが積極的に執筆に関与するようにしました。具体的には以下のようにワークフローや資料を作成しました。 執筆前の打ち合わせから公開までのワークフロー スケジュール管理や記事内容のすりあわせのテンプレート レビュー方法の整理 記事の方向性や大まかなフォーマット よりよい執筆体制が組めるよう記事ごとに試行錯誤しています。 年間23本公開した 月2本を目標としており、結果年間で23本の記事を公開できました。この数字は他社のテックブログやリニューアル前と比較すると決して多い数ではありませんが、できるだけコンスタントに公開できるようにしようと立てた目標です。実際やってみると今の体制では月に2本公開していくのが精一杯という感じでした。運営チームのメンバーはみな兼務で、特定の担当者に偏りがちでもあり運営の業務はけっこう難しいなと改めて認識しました。 記事のスタイルがなんとなくできてきた 1年を通してやってきた中で「こういう記事の書き方が良さそう」というのが見えてきました。 記事を書く前に、執筆者と運営のチームで認識合わせのためにミーティングを必ず行うようにしています。記事を書いてもらってから、書いて欲しかったこと書きたかったことが食い違わないようにするためです。その際、具体的なアドバイスとして「ポジティブな表現を心がけましょう」ということを強調しています。特に何かのテーマで振り返りを行うような記事だと「こうすれば良かった…ここは失敗だった…」といったネガティブな表現になりがちなためです。(この記事もそういうつもりで書いています!) また記事の冒頭にある自己紹介欄も、執筆者の人となりを知ってもらえればということで設けることにしました。記述は強制的ではありませんが、いまのところ皆さん何かしら書いてもらっています。記事を書いた人のバックグラウンドがちょっとでもわかれば、記事に親しみが持てるのではないかと思います。 いろんな人との関わり リニューアルしてからは会社のテックブログというスタンスで活動できたため、製品の機能のリリース、開発プロジェクト、チームの取り組み、自社の研修などを記事として取り上げることができました。それらの執筆やレビューなど含めて社内では約30人に関わってもらいました。弊社だけではなくクロノス様(技術研修)やアマナ様(OPTMS CONTENTS)、イルグルム様(エンジニア交換留学)には記事のレビューを行っていただきました。 運営チームではエンジニア以外の参加があり、その観点から企画やレビューの幅や質が向上したと感じました。 テレワークでミーティングがスムーズになった テレワークによって会議室を押さえる手間がなくなり、東京・大阪での拠点間のギャップや、部署間のギャップを意識せずコミュニケーションがとれるようになりました。意図してそうなったわけではありませんが、ミーティングがスムーズになったと感じます。 今後に向けて 1年間やってきましたが、昨年末はアドベントカレンダーを実施しなかったり、もうちょっと突っ込んだ技術の紹介をするような記事が出せなかったりと課題はあります。とはいえ、まずは長く続けていけるよう自分たちのペースでやっていこうと思います。

出社不要!? 検証機をリモート化してストレスフリーに

TECHSCORE
2021-04-08 11:00:00
シナジーマーケティングでは検証の目的でスマホの実機を複数台所有しています。 コロナ禍で社員がリモート勤務になったので、スマホにもリモート勤務をしてもらうことにしました。 この記事では、スマホ検証機リモート化の検討から導入までを紹介します。 稲垣 直子(イナガキ ナオコ) 2015年1月より、主に Synergy!の QA(Quality Assurance)を担当しています。 品質に関わる仕事を10年以上しているせいか、プライベートでもバグを検知します。 愛犬、愛猫に癒される日々を送っています。 最近は運動不足を自覚し、健康のために毎日ラジオ体操を始めました。 出社しなくてもスマホ検証機を使えるようにしたい 新型コロナウイルス感染症の拡大防止対策の一環として勤務体制が変更になり、2020年2月末頃から在宅勤務をすることが増えました。 私の所属しているQAチームは、Synergy! 全般のテストをしています。 業務では頻繁にスマホ検証機を使いますが、検証機はオフィスにあるため、利用する際は出社しなければなりませんでした。 電車に乗って人の多い場所に行くことは、感染のリスクも高くなりますし、移動時間もかかります。 交通費だってかかります。 スマホ検証機をリモートで操作できるようになれば、出社の必要もなくなるんじゃないか? 満員電車に乗る必要もないし、通勤に時間を取られることもなくなります。 これは是非実現させたい!!と思い、スマホ検証機のリモート化を検討し始めました。 スマホ検証機リモート化方法の検討 スマホ検証機をリモートで操作できるクラウドサービスは色々ありますが、やりたいことができるのか、まず調査を始めました。 Synergy!はCRMシステムであり、伝える手段として「メール配信」「LINEへの配信」「Web」など、情報を集める手段として「フォーム」「アンケート」など様々な機能があります。 まず、機能要件を洗い出しました。 LINEのメッセージが受信できる アプリプッシュ通知が確認できる キャリアメールが使用できる フォームが表示できる 開発アプリのインストールができる リモートでスマホの検証ができるサービスは、Remote TestKit、AWS Device Farm、kobiton、MOBA Cloud など、色々ありました。 しかし、キャリアメールを利用できるサービスを見つけることはできませんでした。 Synergy!には、データベースに入っているメールアドレスに対してメールを配信する機能があります。 データベースには、キャリアメールも存在するため、私たちもキャリアメールの検証が不可欠です。 上記のようなサービスを利用することで便利になるのは間違いないですが、キャリアメールの検証のためには現在契約しているスマホ検証機も維持する必要があります。 それでは単純にコストが高くなってしまうので、他にも調査を進めたところ STF を見つけました。 STF(Smartphone Test Farm)とは STF はクラウドサービスではなく、オンプレミスにリモートスマホ環境を構築できるOSS(オープンソースソフトウェア)です。 元々は、株式会社サイバーエージェントで開発されたもののようです。 既にある社内のスマホ検証機を活かすことができるので、機能要件は満たせます。 無料で利用できるということだったので、STF を使ってスマホ検証機リモート化をしてみることにしました。 ※ 利用する場合は、ライセンス をご確認ください STF構成図は、下記のようになっています。 STF構成図 ADB(Android Debug Bridge)は、デバイスと通信するための多用途のコマンドラインツールで、adb コマンドを使用してアプリのインストールやデバッグなど、さまざまなデバイス操作を実行できます。 RethinkDBは、リアルタイムWeb向けに設計されたオープンソースのJSONデータベースです。 Docker Image は用意されていたものを使用したため構築に苦労はしませんでした。 工夫した点は、認証です。 STFにログイン画面はありますが、適当なユーザ情報でログインができてしまいます。 そのため、Google OAuth認証を使うことにしました。 誰が利用しているのか明確にわかるようになり、毎回手動でログインする手間をなくすことができました。 スマホ検証機は、物理PC(Linux)にUSBケーブルで接続していきます。 USBケーブルは、充電のみのものとデータ転送できるものがあります。 充電のみのUSBケーブルでは、STFは使えないためUSBケーブルを買い足しました。 スマホ検証機は、スマホ保管庫に入れて管理しています。 スマホ保管庫 現在は11台のスマホ検証機が接続されています。 スマホ保管庫に入れる検証機は、必ずバイブなしのサイレントモードにしましょう。 通知音やリモートで操作される度に音がすると、スマホ保管庫周辺の方の迷惑になります。 (出社している人から、何度も「鳴ってるよ」と連絡をいただきました。ごめんなさい。) STFの画面は、下記のようになっています。 端末リスト画面では、接続されている検証機がどのような状態か知ることができます。 端末リスト画面 リモート操作画面は、実際に端末を操作する画面になります。 スマホ画面のタップ、スワイプなど直感的な操作ができます。 リモート操作画面 リリースの前後ではスマホでの検証が必要になります。 以前は出社して検証をしたり、検証機の持ち帰りや返却のために出社をしていました。 スマホ検証機をリモート化したことにより、QAチームの出社率は下がり、QAチーム以外のメンバーへの貸し出しも容易に行えるようになりました。 利用は他部署にも 無事検証機のリモート化が実現し、これは他部署にも使ってもらえるかもと思い全社に案内してみたところ、利用者が増えてこんな声をもらいました。 「PCのキーボードから入力ができるから、実際のスマホより操作が楽」 「キャプチャを自分のPCに簡単に保存できるので、エビデンスがとりやすい」 「QAチームのつくった検証機のリモート化めっちゃいい!前はこのために出社してたから。ありがとう!」 もともとは自分たちの業務のためにスマホ検証機のリモート化をはじめましたが、結果的に他の部署の方にも喜んでもらうことができました。 現在は、他の部署のスマホ検証機もリモート化しています。 スマホ検証機をリモート化したことで、出社が必要なくなっただけでなく、自宅や他拠点からの利用も可能になりました。 はじめに想定していたより、大きなメリットがありました。 さいごに スマホ検証機をリモート化したことにより、下記の実現ができました。 いつでも、どこでも、テスト可能な環境ができた (新たなサービスを契約したわけではないので)コストは増加していない (スピード感を持ってテストが行えるため)時間短縮になった 品質の仕事をしていると「KAIZEN」という言葉を良く使うのですが、Quallity、Cost、Deliveryという視点から見ても、スマホ検証機リモート化は良い「KAIZEN」だったのではないかと思っています。 QAチームは、仕様レビュー、テスト設計やテスト実施などを主に行っていますが、品質に関わることであれば何でもします。 VUCA(ブーカ)と言われる先の見えない時代、これが正解だ!と最初からわかっているものはないと思います。 時流を読んで時流に乗った新しいことを取り入れたり、挑戦したりすることはとても意味のあることだと考えています。 シナジーマーケティングは、自由にやらせてくれる風土があります。 与えられた仕事だけでなく、「今が最善とは限らない」と常に考え、小さなことでも「KAIZEN」していきたいと思います。 シナジーマーケティングでは一緒に働くエンジニアを募集しています。

株式会社イルグルム様との企業間エンジニア交換留学に行ってきました

TECHSCORE
2021-02-25 11:00:00
企業間エンジニア交換留学として株式会社イルグルム様に留学してきました。 この記事では、留学の経緯や内容、そこで得た気付きを紹介します。 末廣 雅利(スエヒロ マサトシ) 2004年入社のシナジーマーケティング最古参のインフラエンジニア。 学生時代から日常的に Linux を愛用。気がついたら Linux 歴が 25年を越えていました。好きなディストリビューションは Debian。 妻と猫との三人暮らし。趣味はマラソンとトレイルランニングですが、コロナ禍で家にいることが多くなったのでピアノを習い始めました。 企業間エンジニア交換留学 当社 CTO の サービス・プロダクトを進化させられる組織になるためには、今もっている知識・経験を整理し習得するだけでは不十分 まだ知らないもの・出会ってないものに触れる「探索」のプロセスが必要である 探索に必要なのは「弱いつながり」である という思いから、人との出会い・交流を促すため、株式会社イルグルム様との企業間エンジニア交換留学を実施することになりました。 実は、株式会社イルグルム様とは 2018年に交換留学を実施しています(こちら、こちら)。このときはアプリケーションエンジニアが留学したということもあり、今回はインフラエンジニアである私に白羽の矢が立ちました。私は転職経験がなく、他社のインフラエンジニアがどのように働いていらっしゃるのか興味もあったので、留学にチャレンジしてみることにしました。 留学内容 留学の受け入れ先は「みらい基盤課」です。株式会社イルグルム様の主力プロダクトであるアドエビスをインフラ面で支えていらっしゃる部署です。 留学期間は1週間。初日はオフィスに出社したのですが、コロナ禍ということもあり翌日からは完全リモートでの留学となりました。 短期間で具体的な成果を出すのは難しいことから、活動はミーティングがメインでした。半分の時間がミーティング、残りの時間はミーティングのためのインプットや1日の活動の振り返りに充てました。 参加させていただいたミーティングは以下のとおりです。 部門やプロジェクトの定例ミーティング みらい基盤課メンバーとの 1on1 みらい基盤課課長との 1日の振り返り 1on1(毎日) アドエビスのシステム概要や運用業務に関するレクチャ みらい基盤課の課題に関する意見交換 私はあまり人と話さない質なので、この一週間で半年分くらいの会話をしたのではないかと思います。 留学で得た気付き 以下、留学で得た気付きを思いつくままに挙げていきます。 研修資料の充実 まず、研修資料がよくできていて分かりやすいことに感心しました。初日の半日ほどでアドエビスのシステムについて理解できました(ダニング=クルーガー効果かもしれませんが、早い段階で全体像が把握できたと思えるのはいいですね)。聞くところによると、新入社員向け資料整備プロジェクトを立ち上げてかなりの工数をさかれたとのこと、その後もプロジェクトメンバーを入れ替えながら更新されているとのことで、大いに見習うべきと思いました。 運用業務の効率 次に、運用の定常業務にかけている工数が当社の 1/5 程度であることに驚きました。システム規模は大差ないし、運用定常業務の定義が大きく異なるわけでもなさそうなので、どこに違いがあるのか関心を持ちました。この差を説明するには足りないのですが、当社と異なる点としては以下が浮かび上がりました。 数年かけて運用業務を整理し、手順を作って定常業務化されてきたこと 定常業務の時間枠を決めていること 割り切って廃止した業務があること 我々の状況を振り返ってみるに、慣習で続いている業務や歴史の積み重ねで重厚になったプロセスや手順が足枷になっているのではないかと思います。これまでも業務を見直してきましたが、もう一歩踏み込んでみてもよいかなと思いました。 セキュリティエンジニア みらい基盤課にはセキュリティ系の技術コミュニティで活動されているセキュリティエンジニアの方がいらっしゃいます。当社では WAF の導入・運用に苦労してきたので、どうすべきだったのか相談に乗っていただきました。1on1 の時間を全部使ってセキュリティに取り組むスタンスからはじめて、いろいろ教えていただきました。 その他 開発部門の全体ミーティングでは、各部署からの報告でそれぞれの部署メンバーの持ち回りで発表しているのが印象的でした。他部署のメンバーを知る機会になるのでよい方法だと思いました。また、ファシリテータの方の性格によるのかもしれませんが、和気藹々とした雰囲気のよいミーティングでした。 組織や業務上の課題についての意見交換では、当社でも同様に抱えている課題ばかりで共感しきりでした。 我々の経験も踏まえて話しましたが、やはり同じところに悩みがありますね。 留学で残せたかもしれないもの 逆に、留学中の対話の中でいくつか興味を持ってもらえたのではないかと思えることがあるので挙げておきます。 感想戦 将棋などでは対局後に指し手を再現しながら検討する感想戦というのがあります。この感想戦になぞらえて、技術的な観点から障害対応を振り返って経験の共有と学びにするという活動をしていました。ネーミングが前向きであること、反省ではなく技術を検討するための振り返りであることから技術者にとって取り組みやすい活動だったと思います。過去形になっているのは、日々の業務に追われてしばらく実施していないためです。この反省も踏まえて、資料の準備に時間をかけることなくライトな形で実施するのがよいこともあわせて紹介しました。 Reunir Reunir は当社独自のサーバ情報収集フレームワークです。名前はスペイン語で「集める」という意味の動詞からつけました。 各サーバに配備した Agent がサーバの情報(OS、各種リソース、導入済パッケージや稼働しているサービスなどの情報)を定期的に収集して Elasticsearch に投入します。Redash からその Elasticsearch を検索することにより集めた情報を利用します。脆弱性対応などで対象となるサーバを割り出すのに膨大な工数がかかった過去の苦い経験から作りました。先日の dnsmasq における「DNSpooq」脆弱性 の対応でも活躍してくれました。 技術力とは何か とある方との 1on1 で「技術力とは何だと思うか」という話題になりました。 私の回答は「技術力とは想像力である」です。 私自身、何かに失敗して「そこが問題になるとは気付けなかった。技術力がないな」と思い知らされることがあります。技術的にヤバそうな匂いを嗅ぎ分け、最善手を見出すことができるのが「技術力がある」ということなんだと思います。技術力とは何かを具体的に説明しているわけではないのですが、このように応用できる形で身につけてこその技術力だと思っています。 参加してみて 人と話すことが苦手でミーティング三昧は辛いだろうなと覚悟していたのですが、留学に関わってくださったみなさんがフレンドリーで想像していた以上に対話できました。当社と似ている点、異なる点、いろいろ勉強になりました。有意義で貴重な経験をさせていただきました。 唯一心残りなのは、ある方との 1on1。事前にいただいたお題が「新人なので、これからのインフラエンジニアに必要なことを知りたい」だったので「それはプログラミングです!」という回答を用意して臨んだら、その方がバリバリのプログラマーだったのには焦りました。頭がまっ白になってしまい、その後、何を話したのかも覚えていません。相手の方にとってあまり有意義な 1on1 にならなかったのではないかなと思います。申し訳なかったです。もしも、次に機会があればもう少しマシなお話しができればと思います。 コロナ禍でほとんどリモートでの留学でしたが、「弱いつながり」だけど確かなつながりを持つことができました。これを機にさらにつながりを増やしていければと思います。 さいごに シナジーマーケティングではクラウド基盤エンジニアを募集しています。「面白そう」と思った方、まずは話を聞きたいという方は、こちらからご応募ください。

データサイエンス分科会活動共有会🔬を開催しました

TECHSCORE
2021-02-16 11:00:00
シナジーマーケティング CTO の馬場です。2020年の年末、社内向けにデータサイエンス分科会の活動共有会を開催しました。 馬場 彩子(ババ アヤコ) 2001年入社のシナジーマーケティング最古のエンジニア(ほんとは2番目)。1番目が西尾です。 CTO になって早一年。ようやくCTOを名乗るときに噛まなくなりました。 カニLOVER🦀。先週末食べたばかりなのに既にカニロス。 データサイエンス分科会とは データサイエンス分科会は、データサイエンスのシナジーマーケティング事業貢献を目的に2020年8月に発足しました。デジタルマーケティングを展開する当社のデータサイエンスへの取り組みは10年以上と古く、OPTMS CONTENT など世に提供されているサービスもあります。企業と人とをつなげるためのさらなるデータ活用方法を探究すべく、ベテランデータサイエンティスト西尾、期待の新星桂川、そしてCTO 馬場の3人で密やかに活動をしていました。 共有会 サイエンティストだけでは事業に結びつけることはできません。技術を活用し、事業をさまざまな人と共創する土壌をつくりたい。そんな思いから、2020年12月に活動共有会を開催しました。 共有会では3人それぞれが、当社のデータサイエンスへの想いを語りました。 まず、私が過去のデータサイエンス事業を踏まえ、当社のデータサイエンス戦略の課題と今後の取り組みについてお話ししました。 次に、西尾が現在取り組んでいるデータサイエンス事業(OPTMS CONTENT など)と、そこで得たシステムの展望について語りました。 最後に桂川がメールマーケティングをエンパワーメントしたい、という想いについて話しました。三者三様、それぞれの個性もみえた発表だったと感じます。 ここで、当日の桂川の発表の一部を紹介します 桂川 大輝(カツラガワ ダイキ) 2019年新卒入社のエンジニア。最近、自然言語処理の門を叩きました👊 断捨離の門も叩いています。 マーケティングの民主化を実現する 桂川です。共有会当日は、「シナジーマーケティングにおいて貢献したい『マーケティングの民主化』」と題して、具体的な案や取り組みについて発表しました。 はじめに、「マーケティングの民主化」とは何かを紹介します。私が考える「マーケティングの民主化」とは、誰もが(どんな企業でも)高品質なマーケティングを実現できる社会を意味します。具体的には、マーケティングにおいて次の2点を進めることだと思っています。 作業の型化・自動化をし、マーケティングに継続的に取り組めるようにする 企業や担当者の間に存在する知識の格差を緩和し、初心者が「できなかったこと」を「できること」にする CRM施策を機能として利用できるようにする シナジーマーケティングも「マーケティングの民主化」に貢献していると思います。 例えば、企業と消費者がコミュニケーションするCRM施策を、クラウドサービスであるSynergy!の一機能として提供することで、誰もが施策を実行できるようにしています。 施策を機能として利用できるようにした例として、「ABテスト機能」があります。この機能のリリースにより、 すでにSynergy!でABテストを実施していた人:ABテスト実施にかかる手間の削減 ABテストを実施していなかった(知らなかった)人:ABテストの実施 が可能になりました。 このように、施策を機能化することで誰でも利用できるようにする、という点においては、Synergy!は「マーケティングの民主化」に貢献していると言えます。 他に貢献できる余地はあるのか そんなSynergy!ですが、マーケティングにおけるどんな工程に貢献しているのか整理します。ここでは、メール配信に焦点を当てて考えてみます。現状、利用者が検討・決定していると思われるのは以下の工程です。 目的・ターゲットの設定 配信内容の決定 メール詳細の決定 そして、Synergy!が配信自体を実行しています。 この時、利用者に依存する工程を削減し、貢献できる余地はあるのでしょうか?(“誰もが”を増大することができるのでしょうか?)私は、「メール詳細の決定」について、Synergy!がサポートできるようになると考えます。 メール配信をする場合、内容によってそのメールの効果(開封率など)が変わります。例えば、SuperOfficeのレポートによると、配信タイミング、件名の文字数、件名に入れる文字の種類などによってメールの開封率が変わることがわかっています。つまり、このようなこの経験者しか知らないメール作成の知識があれば開封率の高いメールを作成し届けることができます。 そこで、Synergy!で、「メール詳細の決定」の工程のサポートを機能で実現できないかと思いました。 これを実現するためには、まず経験者の知識をルールとして正しく理解する必要があります。 経験者の知識を機能にするために 経験者の知識を機能にするためには、次のような工程が必要です。 経験者の知識の理解 コンピュータが理解できる定量的なルールの発見 Synergy!の機能として実装可能に ここで特に難しいのは、「コンピュータが理解できる定量的なルールの発見」です。経験者の知識は複雑で定量的なルールの発見は困難です。例えば、メール詳細の特徴について、どんな件名・配信時間がいいのか、それが開封/クリック率といった効果へどれだけ貢献するのか、なんとなく説明できるものの、定量的なルールまで落とし込むことは難しいと考えられます。特に、ルールは定量的なものでないと機能としてコンピュータの行動の指標にできません。それゆえ、経験者の知識をルール化する手法が必要となります。 経験者の知識のルール化を実現する手法として、機械学習が挙げられます。機械学習とは、コンピュータが大量のデータを学習し分類・予測などに利用する技術です。 また、定量的なルールを自動的に構築することができます。定量的なルールを発見することで、ルールを定性的に理解できないコンピュータでも、ルールに基づいた行動の再現が可能になります。 そして、人間が潜在的に加味しているが、説明できない隠れたルールを発見することもできます。これを定量的に発見することにより優れた分類・予測が可能になります。つまり、データと機械学習により経験者の知識をルール化することができます。 例えば、メールの開封有無を予測することができれば、事前に対策をとることができます。メールの開封有無を予測するためには、「いつ、誰に、どんな内容で配信されたか」といった特徴とメールの開封有無の関係をルール化する必要があります。このようなルールを算出するためのデータとして、実際に配信されたメール群(配信履歴)、特にメールの特徴とメールの開封有無が考えられます。つまり、データと機械学習により「いつ、誰にどんな内容でメールを配信すれば開封されやすいか?」という経験者の知識のルールを発見できます。 まとめると、マーケティングの民主化とは、作業の型化・自動化、そして知識の格差の緩和を通じて、誰もが(どんな企業でも)高品質なマーケティングを実行可能にすることです。現状、CRMを機能として誰もが利用可能にしているという点において、Synergy!、そしてシナジーマーケティングはマーケティングの民主化に貢献しています。今後、それをさらに進めるための次のステップとして、機械学習を活用した経験者の知識のルール化・機能化することを提案しました。 フィードバックを糧に 再び馬場です。上記で紹介した桂川の発表は、当日も「機械学習のサービス実装のイメージが湧いた」と好評でした。オンラインで開催した共有会でしたが、技術を扱う部署からお客様に直接関わる部署などさまざまな部署から50人ほど参加した上、後日公開した録画を視聴した、という人もおり、この分野への関心と期待を感じました。 ただ、我々なりに丁寧に説明したつもりだったのですが、「難しかった」という意見も少なくありませんでした。アイディアを引き出すには、データサイエンスで何ができるのか、できないのかを理解する(してもらう)ことが非常に重要です。啓蒙活動も続けていかなければいけないと感じました。 今後 当社は今年、ビジョンとミッションをリニューアルしました。 VISION 人と企業が、惹かれ合う世の中へ。 MISSION Create Synergy with FAN デジタルマーケティングでファンとの相乗効果(Synergy) を創る、というミッションを実現するには、データの活用が不可欠で、データサイエンス分科会はその技術的基盤となりたいと考えています。今年もよろしくお願いいたします。

「インセプションデッキを1日で仕上げる」に取り組んだ話

TECHSCORE
2021-02-11 11:00:00
2021年1月、シナジーマーケティングが提供する CRM サービス Synergy! の新オプションとして画像投稿機能をリリースしました!🎉🎉 この記事では、画像投稿機能をさらっとご紹介しつつ、この開発プロジェクトの立ち上げで取り組んだ「インセプションデッキを1日で仕上げる」についての感想をまとめます。 石田 一博(イシダ カズヒロ) 2018年11月中途入社 車が(運転するのも見るのも)大好きな化石タイプのおじさんに片足を突っ込んだおっさんです。 好きな食べ物はラーメン。苦手な食べ物はキウイ。 画像投稿機能 画像投稿機能とは、その名のとおり、Synergy!のフォームから画像を投稿できる機能です。 例えば、写真を添付して応募するようなキャンペーンなどに利用することができます。 投稿された画像はデータベース検索で顧客情報と紐付けて確認することができますし、投稿ファイルを一括でエクスポートすることもできます。 ※ 画像だけでなくドキュメントファイルも投稿できます。 これまでは「ファイル投稿フォームオプション」という名称で、当社でカスタマイズを請け負って制作していた機能ですが、これが管理画面から設定できるようになりました。 お客様(企業担当者様)からすれば、要件を伝えて、見積り内容を確認して、発注して…、という手間のかかる手続きが不要になりますので、「画像投稿したい」から「画像投稿できた」までの期間を短縮できます。 当社としても、要件を確認して、見積りをして、要員のスケジュールを確保して、カスタマイズして…、がなくなりますので、まさにWin-Winな機能なのです。 と、機能についてはここまでにして、ここからはプロジェクト初期の取り組みについて紹介します。 インセプションデッキの活用 もともとファイル投稿フォームオプションは、Synergy!の人気オプションの一つとして存在していました。 つまり、製品の機能として組み込まれてはいないものの、サービスとして既に提供している実績がありました。 もっと言えば、裏側の仕組みは既に存在していたわけです。 それをどうやってSynergy!の機能に組み込むのか、いつリリースできるのか、が焦点でした。 そして、時間をかけずにスモールスタートで始める、これも社内から求められていました。 初期段階では、従来の企画プロセスにのせてスケジュールを組み、企画だけで1ヵ月~1ヵ月半程度かかかる計算でした。 走り出しから「時間をかけずに」の壁に阻まれてしまったのです。 そこで、アジャイル開発のツールとして知られる「インセプションデッキ」を使ってみよう、となりました。 インセプションデッキは、アジャイルサムライという書籍で紹介されている、プロジェクトの内容を明らかにするツールです。 (インセプションデッキのテンプレートも公開されています。) 通常は数日から2週間程度かけてつくるインセプションデッキですが、これを関係者で集まって1日で仕上げよう! とチャレンジすることになりました。 当時は新型コロナの感染状況が少し落ち着いていたこともあり、会議室に集まってわいわい議論したのは良い思い出です。(※ディスタンス、飛沫、消毒、換気には細心の注意を払いつつ…) その1日で目指すゴールは プロジェクトに対する共通認識を全員で持つこと すぐに開発に取り掛かれるよう機能一覧をまとめること でした。 人は欲深い生き物ですので、インセプションデッキだけに満足せず、翌日から開発に着手できるよう機能一覧を作ってスコープの確定までやり切りました。 メンバーはPM、デザイナー、エンジニア、GTM(Go-To-Market)担当がメインで、そこにCTOと製品の歴史、仕組みに詳しいメンバーにも参加してもらいました。 参加メンバーをどこまで広げるかは色々な考え方があると思いますが、個人的には短期間で物事を決めて進めたいのであれば、Goを出せる人、リスクを冷静に判断できる人を巻き込むのが、とても有効だと思っています。 当然、事前の準備も大切です。 このミーティングまでに分担して現状分析をしましたし、エンジニアには実現イメージを膨らませておいて欲しいとお願いし、当日持ち寄って議論の材料にしました。こういった準備も結論までの時間短縮に役立ちました。 当日はインセプションデッキを作りながら、「これは機能一覧を仕上げてからもう一回考えよう」など、柔軟にアジェンダを組み替えながらメンバー全員で仕上げていきました。 午前11時から午後6時まで、休憩を挟みながら計6時間ほどかけて完成しましたが、あっという間の楽しい時間でした。 甘いものを用意すると、より捗るかと思います🍪 開発に着手できれば、あとは従来の確立された開発プロセスに沿って物事が回り始めます。 走り出しをコンパクトにするために、インセプションデッキは優れたツールだと実感しました。 もちろんこの取り組み方が、あらゆるプロジェクトで有効だとは思っていません。 今回のプロジェクトの特徴として 既に実績のある実現方法(処理方式)を用いる 業務フローも既存の仕組みに相乗りできる という点が挙げられます。 ゼロからの企画、構築であれば、実現方法やリスクの議論に相応の時間がかかるでしょう。 今後の展望 そんなチャレンジを経てリリースした画像投稿機能ですが、まだまだ生まれたての赤ちゃんです。 (裏側は実績のある仕組みなので、妙に老け顔の赤ちゃんかもしれませんが) ユーザビリティの面で改善すべき点はあるでしょうし、裏側の仕組みも最適化できると考えています。 今後はフィードバックを集め、より良い機能を目指して進化していきたいと思います。 また、開発プロセスとしても他のプロジェクトに生かせる取り組みだったと思いますので、良いところを当社の仕組みに取り入れていきたいと思います。

AWS ソリューションアーキテクト – アソシエイトへの道

TECHSCORE
2021-01-28 11:00:00
2021年1月にAWS 認定 ソリューションアーキテクト – アソシエイトを取得しました。 昨年AWS のトレーニングを受講し、その他の教材も利用しながら知識を習得してきました。この記事ではその学習過程や内容について紹介します。 山口 正寛(やまぐち まさひろ) 2014年より基盤の構築運用に携わっています。 辛いものが好きで、チャレンジと後悔を繰り返してます。趣味と呼べるほどではないですが、ランニングをコツコツやってます。 学習のきっかけ 私は普段プラットフォームエンジニアとして働いており、{物理,仮想}サーバの{構築,運用}の経験があります。AWS に関しても業務で取り扱った経験があり、 EC2を使ったサーバ構築 S3とCloudFrontを組み合わせた静的なwebページの公開 Route 53を使ったDNSの管理 など、従来インフラと呼ばれていたようなところの利用経験があります。しかし、 RDSやDynamoDBといった完全マネージドなサービス Lambdaのようなサーバーレスコンピューティング については利用経験がありません。 昨年後半、会社でArchitecting on AWSの受講者を募っており、今後のプロジェクトで必要になる知識を身に着け、知見を広めることができると思い手を上げました。(自己負担0円で3日間のトレーニングを受けれてHappyです。) ソリューションアーキテクト – アソシエイト(SAA)とは 「AWS ソリューションアーキテクト – アソシエイト」とは AWS が提供しているクラウドの専門知識認定の一つです。 AWS 認定は分野とレベルによっていくつかに分かれていますが、上述したような自分の経験、知識、また将来目指したい方向性を鑑み、アーキテクト分野、アソシエイトレベルの認定に挑戦することにしました。 SAAは実務経験と幅広い知識が求められる、AWSを利用する技術者として自身のスキルを把握するには格好の試験だと思います。 トレーニングの受講 Architecting on AWS は座学とハンズオンの両方からなるトレーニングとなっています。S3を使った静的ウェブサイト構成から始まり、EC2、EFS、RDS、Route 53、VPC、ELB、AZ、サブネット、Auto Scaling、Memcached などのサービスを活用してシステムを構成する学習を行いました。 システム構築を進めていく中で 管理に用いるサービス(IAM、CloudWatch、Cost Explorer、CloudTrail、VPC フローログ、Systems Managerなど) 構築のためのサービス(CloudFormation、AWS クイックスタートなど) 疎結合アーキテクチャに用いるサービス(SQS、SNSなど) と、多くのサービスについても学習することができました。 今まで使ったことがあるもの、名前は聞いたことがあるけど使ったことがないもの、どちらも使う機会がありました。 (幸いにも全く聞いたことのないサービスは出てこなかったので、躓くことは少なかったです。) 実際に手を動かして、システム構築に対しての知見・スキルが向上した手応えを感じました。 受験することになった 3日間のトレーニングを受けたのだから、ソリューションアーキテクト – アソシエイトを受験、取得してみようという流れで受験することになりました。 トレーニングを受けて手応えを感じていましたし、試験問題サンプルの内容も理解し正解することができていたので「このまま行けるんじゃないか」なんて思ったりしていました。 模擬試験受けてみました とはいえ、本試験は15,000 円(税別)もするので、模擬試験 2,000円(税別)でまずは様子見してみました。 結果から言って、模擬試験は受けてよかったです。 試験の内容はNDAがあるので触れることはできないのですが、パソコンを使った試験で、紙の問題用紙を読む試験とは感覚が全く違いました。 サイトに公開されている試験問題サンプルは甘いです。模擬試験の問題は、サンプル問題と違って文章がもっと長く、内容も少し難易度が高いように感じました。 結果は、、、はい。模擬試験で合格ラインを下回っておりました。 どこがダメだったのかというと、トレーニングでは、どういう用途のときにそのサービスを使うのかといった学習はするのですが、そのサービスについて深堀りして学ぶということができていませんでした。(3日ですごい数のセクションなので仕方ないです。) 試験勉強始めました 模擬試験でどこが足りないかを掴むことができたので、試験に向けての学習をはじめました。 私の場合、以下のようなコンテンツを利用して学習に取り組みました。 AWSの用意するトレーニングライブラリや、書籍:AWS認定アソシエイト3資格対策で知識をさらに深め、チュートリアルを利用して実際に手を動かしてみました。 トレーニングのときにも思ったのですが、実際に自分で手を動かしてみると理解が深まると感じました。 AWSのアカウントを作成すると無料利用枠が付与されるので、無料で色々と手を動かしてみることができますし、AWSの用意するトレーニングライブラリも無料で利用できるコンテンツが豊富に用意されていました。 無料で使えるものを使って、効率的に学習することができたと思います。 本試験受けてきました 模擬試験同様、本試験もNDAがあるので内容には触れられませんが、注意点を共有できればと思います。 本人確認書類は2点必要! ピアソン - 本人確認書類について に書かれていた(全然読んでなかった)のですが、運転免許だけではダメでした。 たまたまクレジットカード持っていたので事なきを得ましたが、2点必要なので気をつけてください。 会場についたらおさらいする時間はない 時間に余裕を持って会場入りしたのですが、到着すると受付に案内され、あっという間に手続きが完了します。 手続きが完了すると、予約していた開始時刻にならずとも試験端末に案内されたので、最後のおさらい(詰め込み)は会場到着までに済ませておくと良いと思います。 成績はその場ではわからない 最後に受付で紙を受け取りました。そこに成績が印刷されているのかと思っていたのですが、「結果が出たらメールでお知らせします」といった内容の紙でした。 コンピュータ試験はその場で結果発表だと思っていたので、結果が確認できるまではドキドキしていました。(渡された紙には結果が出るまで最長5営業日とありましたが、翌朝には確認できました。) さいごに ソリューションアーキテクト – アソシエイトの試験学習を通して、今まで使ってきたEC2、S3といったサービスについてより知識を得ることができました。また、複数のVPCやAZを使った冗長化、Systems Managerを使ったシステム管理など、基盤を構築し運用する上で必要なことを多く学ぶことができました。 今後のプロジェクトでは、今回の学習した知識を基に、安心・安全でかつコスト効率に優れた、良い基盤の構築・運用に貢献できればと思います。 AWSに限らずですが、技術は日々進歩しているので今後も学習を怠らず技術力を高めていきます! シナジーマーケティングではクラウド基盤エンジニアを募集しています。

CTOになってはじめての1年を振り返る

TECHSCORE
2020-12-10 11:00:00
この記事は CTOA Advent Calendar の11日目の記事です。 2020年1月に シナジーマーケティング のCTOに就任し、1年が経とうとしています。本当はCTOA(CTO 協会)Advent Calendar のさまざまな記事にあるような、組織論や技術論を知的にかっこよく語りたかったのですが、書き下ろせるほど整理されたなにかが私の中にはありませんでした。ただ、年初より世界が一変したこともあり、去年まで一エンジニアだった私にとっては多くのはじめての体験と新たな発見があった1年でした。そんなこんなを徒然なるままに綴りたいと思います。 馬場 彩子(ババ アヤコ) 2001年入社のシナジーマーケティング最古のエンジニア(ほんとは2番目)。 オットと二人の息子と四人暮らし。急に息子が「小笠原、いきたいんだよね。行ったことないから」といいだしたので春休みに行くのを楽しみにしている。 すきなものはビールとカニ。きらいなものはチーズ。 シナジーマーケティングの2020年 シナジーマーケティングはクラウドCRM Synergy! を提供している大阪の会社です。この1年、当社のエンジニアはさまざまなことに取り組みました。 まず、Synergy! のモダナイズの大きなプロジェクトを二つ立ち上げました。 一つは、FROG (かえる)プロジェクトです。Synergy!システムを柔軟性と拡張性に優れたクラウドに移行することにより、将来のサービスの進化に備えます。二つめは NEWT (いもり)プロジェクト 。2005年のローンチ以来変えずに運用してきたフォームやデータベースの機能を、2020年代の環境に合わせて再生します。あわせて、UI統一と「使いやすさを徹底的に考えた画面デザイン」を実現します。この二つのプロジェクトは、海から陸へあがるように、Synergy! を進化させるプロジェクトとなってほしいという願いをこめて、両生類の生き物を命名しました。 各プロジェクトのロゴマーク また、Synergy! では企業と顧客のコミュニケーションをリッチにするような機能( ABテスト 、データベースAPI 、シナリオ 、Jストリーム連携 、giftee for Business 連携 )も多くリリースしました。 新しいサービスの探索にもチャレンジしました。 当社はいままで事業部主導でのビジネス開発が多かったのですが、今期はエンジニア発信でデザイン思考に製品開発したり、当社の新規ビジネス開発フレームに沿って仮説の立案と検証を繰り返していたりと、サービスを産み出し育てていくプロセスでいろいろな試行をしています。 今期はエンジニアリング教育にも真正面から取り組みました。TADPOLE (おたまじゃくし)と名付けられたこのプロジェクトでは、総合職向けIT研修・技術職向け新人研修 から22新卒向けインターンプログラム まで、「エンジニア」「育成」というキーワードで語れるあらゆるものの整備と仕組み化をしました。 当社では古くからデータサイエンスに取り組み、OPTMS などのサービスに還元されていますが、よりデジタルマーケティング をエンパワーメントするためにシナジーマーケティングでどのように取り組んだらいいのか、議論をスタートさせました。 もちろん、TECHSCORE BLOG のリニューアル も今年の成果です。コードに現れないエンジニアの七転八倒・試行錯誤が言語化され、私たちの財産になっていると感じます。 選んだものが作品になる 私は、自分のもてるスキルを駆使して開発したサービスが、世に出て顧客(社会)に利用されることがエンジニアリングの楽しみだと思っています。そんな風に技術で世界を楽しくするよう、コアプロダクトをワクワクする今のテクノロジーで再構築したり、顧客によい驚きを与えられるようなサービスを企画したり、次の技術を模索したり、人財を育成したり、いろいろ進めてきた1年でした。 もちろん実際にエンジニアリングで事業を動かすのは当社のエンジニアです。この中でCTOの役割は人と人とを繋ぎゴールを示すことです。そのため必然的に多くの人に意志を伝えたり、さまざまな人に意見を求められたりすることが多くありましたが、「これだ」「こうしよう」と選ぶことをこわいと感じることもありました。ビジョンだったり方針だったり、自分の選択をぱちっと自信をもって示すことができず、まわりくどくエクスキューズしてしまう。 「なにがこわいのか?」と胸に手をあてて考えてみると、それは失敗ではなかったりします(いや、それももちろんこわいですが)。まさに心理的安全性の4つの不安(無知、無能、邪魔、ネガティブだと思われたくない)を感じているんです。【最高】技術責任者なのに!むしろメンバー時代の方が自由に発言していたと思うくらいです。ただ当社のエンジニアは率直に「馬場さん、それは違うのでは」と言ってくれます。なので、私は、自身の評価は気にせず、指摘や批判された場合も、ただ対策をうつか、選択を変えればよいだけなんですよね。 さて、突然ですが、ブルーピリオド をご存知ですか?息子に「美大、受験したら?」と言って冷たい目で見られるくらい大好きな美大スポ根青春漫画です。この漫画に、大学の授業の課題に悩む主人公に対して美大の猫屋敷教授が「君は作品をつくったことがない」と語る場面があります。 ブルーピリオド / alu.jp alu.jp ブルーピリオド / alu.jp alu.jp エンジニアもサービスを生み出すクリエイターです。問い、吟味して、検証して、繰り返して、選んだ先にしか我々の作品(サービス)がないのだとしたら、不安に反応し選択をさけて、ブレーキをギュッと踏み込んでいる場合じゃないなあ、と思います。頭ではわかっていてもクッと止まってしまうのが人ですけどね。選んで選んで選びまくるのだ。 そんな感じでCTOの最初の1年は終わろうとしていますが、自分への前向きな落胆に比して、当社のエンジニアに対しては期待しかないです。2021年もいろいろ仕掛けを考えているので、いっしょにわいわい楽しみましょう。2020年おつかれさま & ありがとうございました。 シナジーマーケティング株式会社では一緒に働く仲間を募集しています。

giftee for Business 連携機能をリリースしました

TECHSCORE
2020-12-03 11:00:00
2020年11月、シナジーマーケティングが提供する CRM サービス Synergy! の新機能として giftee for Business 連携機能をリリースしました。この記事では機能の説明と開発時の苦労した点や工夫した点、初めて開発に参加した私自身の感想についてお話しします。 岸本 大河(キシモト タイガ) 2020年4月入社の新卒エンジニア 猫が好きで趣味は料理。最近は激辛料理にはまっています。 好きな唐辛子はキャロライナ・リーパーです。 giftee for Business 連携機能とは giftee for Business とは株式会社ギフティが提供するeギフトを活用した法人向けソリューションです。eギフトとはコンビニや有名ブランドの商品を URL 化したもので、URLを送るだけで簡単にプレゼントキャンペーンが実施できるため、配送費や人件費を大幅に削減することが可能です。 今回の機能連携で Synergy! の Web フォーム機能にeギフトを埋め込むことが可能になりました。 フォームの他にもメールや LINE で手軽にeギフトを送ることができるので、Web アンケートの回答率向上などに活用できます。これまでの Synergy! でも実現可能でしたが、フォームの回答者数を予測し、その数に応じたギフトを事前に購入しておく必要がありました。今回実装した giftee for Business 連携機能では、フォーム回答完了時に必要になった分だけ自動的にギフト URL を発行することができるため、無駄がなく費用の削減が可能となります。 giftee for Business 連携機能 開発の進め方 開発期間は9月から11月の約3ヶ月間で、チーム構成はプロジェクトマネージャー、開発リーダー、開発メンバー1名の計3名でした。 基本的に全員在宅勤務をしていますが、開発の2人は週2回出社して開発を進めました(出社の理由は後述します)。オンラインでの全体定例は週1回30分ほど実施し、進捗や今後の進め方等についてお話ししました。 開発は主に Java を使用して実装しました。 私にとって初めてのプロダクトでの機能開発であり、また本格的に Java を使って開発するのも初めての経験でした。 (それまで Java に関しては技術研修の際に2ヶ月程勉強した程度でした。) 担当箇所は主に連携を設定する画面で、フロントエンドからバックエンドまで全般を担当しました。 今回の機能追加では既存部分への影響範囲が広く、その影響調査やテスト等に多くの時間を要しました。そのため当初の想定よりかなり長い開発となりました。 苦労したところ、工夫したところ 前述の通り、今回は影響範囲が大きく、プロダクトの幅広い知識も必要でした。 入社前から Synergy! にユーザーとして触れる機会があったものの、すべての機能を知っているわけではない上に、プログラムや DB の構成などもわからず、開発当初は「何がわからないのかがわからない状態」に陥ってしまいました。 また、在宅勤務が多かったので開発者間のコミュニケーションはテキストベースになります。 「何が分からないのかわからない状態」なので質問内容をテキストで説明するのがとても難しく苦労しました。 開発開始から2、3週間ほどした時期に、開発リーダーのすすめで、週に2時間ほど実際に会って質問する時間を設けました。 テキストベースではまず最初にこちらの状況を説明すること自体が難しかったのですが、口頭では雰囲気や言い淀みなどから相手に状況を察してもらうことができるためか、コミュニケーションの速度が上がるためか、「何がわからないかわからない」まま質問を続けることができました。 質問等を繰り返しているうちに自分の状況を自覚することができ、Slack などのテキストベースで気軽に質問することができるようになりました。 また、実際にコードを一緒に読みながら質問したため、合わせて知っておいたほうが良い知識を学ぶことができ、効率よく理解を深めることができました。 開発終盤では内部仕様の変更、例えば DB 項目の型が変わる、ということもありました。この修正でバグが発生したり、少しハプニングもありましたが、生の開発現場の空気感を実感し、とても良い経験になったかと思います。 また、かなり細かくレビューをしてもらったため、修正必要箇所が的確に分かり、効率よく開発が進められたと感じています。 さいごに 本記事では、11月にリリースした giftee for Business 連携機能について、開発者の立場から振り返り、苦労したところや工夫できたと思うところを紹介しました。 右も左もわからない状態で新規機能の開発に参加し、あらゆる場面で苦労しました。苦労した分だけ学びの機会があり、貴重な経験になったと感じています。 開発当初は「何がわからないのかがわからない状態」で、何から始めればよいかすらわかりませんでした。 質問をしようにも、相手に迷惑をかけてしまうんじゃないかという恐れから、なかなか質問もできませんでした。 開発を進めるにつれ、少しづつ状況や立場が理解できるようになり、積極的に質問ができるようになりました。 質問を重ねることで知識が増え、開発チーム内での考えの差異を埋めることができました。 今回の開発を通して、当社には成長を後押ししてくれる環境が整っていることを改めて実感しました。これからもどんどん経験を積み早く一人前のエンジニアになっていきたいと思います。

2020年度夏の技術系インターンシップを開催しました

TECHSCORE
2020-10-29 11:00:00
シナジーマーケティングでは8月下旬から9月上旬にかけて、技術系学生を対象としたインターンシップを実施しました。 今年は新型コロナウイルスの影響もありましたが、感染防止対策のもとオフラインでの開催となりました。 インターンシップでは当社のサービスである Synergy! の API 機能を利用して、データの可視化やメール配信機能を実装したアプリケーションを作成する体験をしてもらいました。 この記事を通じて、当社のインターンシップについて知ってもらえたら嬉しいです。 松木 自然(マツキ ジネン) 2020年4月入社。 今回のインターンシップでは企画と受け入れを担当しました。 趣味はダンスで、一時期はプロダンサーを目指していた程ダンスが好きです。 最近は健康を気遣って、トマトジュースを毎朝飲んでいます。 目的 概要 実習内容 第1回 第2回 参加者の感想 さいごに 目的 今回のインターンシップを企画するにあたって、以下の3つの目的を定めました。 社内の雰囲気を味わってもらう 手を動かしてものをつくる体験をしてもらう 当社で働くことをイメージしてもらう 参加する学生の皆さんには実際に大阪本社に来てもらい、普段私たちが業務をしている席のそばで実習に取り組んでもらいました。 概要 インターンシップの開催日程は以下になっており、第1回・第2回それぞれ2名ずつ受け入れました。 第1回:2020/08/24(月) 〜 2020/08/28(金) 第2回:2020/09/08(火) 〜 2020/09/11(金) ※第2回は5日間の開催予定でしたが、台風の影響を考慮して1日短縮しました。 5日間のスケジュールはこちらです。 ほとんどの時間をアプリケーション開発にあてましたが、アプリケーション開発の前に、オリエンテーションとして、 自己紹介 社内設備の説明 実習内容の説明 を実施し、今回の開発に必要な前提知識として Web API Markdown に関する技術講義を実施しました。 大まかなスケジュールは上記の通りですが、参加する学生の方々の要望を取り入れ、柔軟にスケジュール調整しながら実施しました。 また、参加者のみでミーティングを行いたいなどの要望があれば、参加者同士だけで話せる空間を用意したり、 個人開発ではなくチーム開発をしたいという意見があれば、チーム開発に切り替えたりなど、 スケジュールや進め方を固定するのではなく、インターン生の意見を取り入れながら実習を進めました。 実習内容 第1回 第1回目の内容は、Synergy! のデータベースAPI(DBAPI)を利用した顧客データ可視化アプリケーションです。 Google Colaboratory(Colab)上で Python を使って DBAPI にアクセスして顧客情報を取得し、NumPy や Matplotlib を使って、データ加工、データ可視化を行いました。 Colab の Forms 機能を使って、登録日や顧客年齢、性別などで可視化条件を絞り込む機能も実装しています。 なお、実習で使用した顧客データはダミーデータを使用しています。 システム構成と成果物はこちらです。 どちらも実際にインターン生が作成したものです。 システム構成 成果物:絞り込み画面 成果物:データの可視化 (ここでは顧客のうち男性と女性の数をグラフで表示しています) 第2回 第2回目の内容は、Synergy! のメールAPIを利用したメール配信および配信結果通知アプリケーションです。 自動化ツールである Zapier 上で Python を使ってメールAPIにアクセスして、メールの配信および配信結果や開封状況の取得を行います。 さらにその結果を Slackで 通知したり、Google スプレッドシートに出力したりします。 また、Google Chrome の拡張機能である Push by Zapier(フォーム形式で Zapier を実行できる機能)を用いてユーザーインターフェースを実装しました。 システム構成と成果物はこちらです。 どちらも実際にインターン生が作成したものです。 システム構成 成果物:Push By Zapier 成果物:左がメール開封前の Slack への通知、右が開封後の Slack への通知 参加者の感想 今回参加してくれた学生の皆さんにアンケート・ヒアリングを実施しました。 そこでの感想を一部紹介します。 スケジュールを柔軟に調整していただけたので、楽しくインターンシップを終えることができた。 実際に、社内に足を運ぶことで雰囲気を味わうことができた。 この状況の中、最大限いろんな社員さんとの交流の機会を準備していただけてよかった。 社員の方々がとても親しみやすく、わからない部分をフランクに聞くことができた。 さいごに 今回のインターンシップでは、DBAPI / メールAPIといった当社の API を使用したアプリケーション開発を体験していただきました。 また、開発体験以外にも、社員の方々と交流する良い機会になったのではないかなと感じています。 コロナという状況もあり、オンラインでの開催も検討しましたが、インターン生からは、「オフライン開催のおかげで実際に働くイメージができた」、「社内の雰囲気を味わうことができた」といった意見をもらうことができたので、結果としてオフラインで開催して良かったと感じています。 次回以降のインターンシップでも、参加する皆さんにとって有意義な時間になるような企画にしようと考えていますので、是非参加してみてください! シナジーマーケティング株式会社では一緒に働く仲間を募集しています。

フロントエンドへのPact導入 - 契約によるAPIのテストを始めよう

TECHSCORE
2020-10-15 11:00:00
先日当社のサービスである Synergy! の新機能として、シナリオ機能をリリースしました。この機能の開発では、フロントエンドとバックエンドの間のAPIの正しさを担保するために、テスト支援ツールであるPactを導入しました。 Pact 導入の先行例はいくつも見つけることができるのですが、フロントエンドに適用した例はあまり見つけられません。今回の記事では、Pact をフロントエンドに導入した一連の流れを紹介します。 的場 寛明(マトバ ヒロアキ) フロントエンドエンジニア。 k8sやCIを積極的に触っていた経験をいかして仕事をしています。 カレーが好きで、豆板醤や甜麺醤など中華系スパイスを使ったカレーを作っています🍛 Pactとは - 導入目的 コンシューマ駆動契約テストの文脈で使われる用語について コンシューマ駆動契約テストとは Pactとは? OpenAPIとの違いはなに? フロントエンドにPactを導入して、Pactファイルを出力するまで インストール Jestの設定 Pactのテストを書く Pactファイルの出力(テスト実行) Pactファイルをデバッグのモックとして使う サーバ起動前の設定(プロキシ) モックサーバの起動の仕方 モックを使ってデバッグを始める まとめ Pactとは - 導入目的 Pactは、「コンシューマ駆動契約テスト(Consumer-Driven Contract testing)」というアプローチに則って、リクエストとレスポンスをテストするためのツールです。APIのリクエストとレスポンスが、使う側と提供する側で仕様の誤りなく実装されていることを確認します。 コンシューマ駆動契約テストの文脈で使われる用語について 聞き慣れない言葉が出てきたかもしれません。コンシューマが駆動する契約のテスト…? 「コンシューマ」がきっかけとして「契約」のテストをするということはなんとなくわかります。ではここでの「コンシューマ」と「契約」とは。 「コンシューマ」はAPIを使う側を指します。ですのでAPI提供側にももちろん名前がついていて、そちらを「プロバイダ」と呼びます。「契約」はコンシューマとプロバイダのあいだでAPIのリクエストとレスポンスをどのようなものにするかという約束です。ここから、本記事でもコンシューマ、プロバイダ、契約という名前を使って記事を進めていきます。 コンシューマ駆動契約テストとは では改めて、コンシューマがきっかけとして行われる契約のテストとは。コンシューマがAPIのリクエストとレスポンスを契約としてまとめます。契約が記述されたものをプロバイダに渡せば、そこにはリクエストとレスポンスが書かれているから、APIがその内容に沿っているかということをプロバイダがテストできます。これがコンシューマ駆動契約テストです。 コンシューマとプロバイダの間で連携して使うものなので、第三者の提供するパブリックなAPIを使ってなにかアプリを作りたいというときに入れるテストではありません。プロバイダと協力して開発できる関係でなければなりません。 Pactとは? Pactはコードを書くことでコンシューマ駆動契約テストを行うツールです。ここまで読んでいてコンシューマ駆動契約テストに興味を持っても、「契約ってどう書けばええねん、専用の言語を学ばなきゃあかんのか?」という状態かと思います。Pactを使って契約を得るためにはいつも使っている言語とテストライブラリがあれば問題ありません。Pactを使ったコンシューマ駆動契約テストの手順を追います。 コンシューマがプロジェクトにPactを導入し、APIリクエストと期待するレスポンスをテストとして記述する コンシューマ側で1のテストを実行して、契約が書かれたファイル(Pactファイル)を取得する Pactファイルをプロバイダに渡し、プロバイダ側のテストに使ってもらう Pactの導入さえ済めば、あとはテストを書いて走らせるだけで契約が書かれたPactファイルが得られます。次の章で、今回のプロジェクトで行った導入手順を振り返っていきます。 OpenAPIとの違いはなに? PactはOpenAPIとよく対比されるようです。似てるようで、かたやAPIのテストツール、かたやAPIの仕様記述フォーマット。 たとえばプロバイダでAPIの返り値となるJSON内の一つのキー名を変更したとし、これがコンシューマであるフロントエンドへ伝わってないとします。 Pactが組み込まれているプロジェクトならば、CIでPactファイルを使ったAPIテストが行われるでしょう。このPactファイルはキー名が変更前のもので契約が定義されており変更後のレスポンスと食い違うため、テストに失敗し、コンシューマに変更が必要なことに気づきます。コンシューマが複数いる場合では、どこから提供されたPactファイルか見れば、契約の確認をすべきコンシューマを容易に特定できます。 OpenAPIが導入されている場合、変更がコンシューマに通知されずコンシューマもそれに気づかないと、リリースまで進んでしまい事故になります。 また、変更を通知するとして複数コンシューマがいる場合は、それぞれのコンシューマが変更に対してアンテナを張るか、プロバイダがコンシューマに対して変更内容を知らせ、変更をそのままリリースして問題ないかそれぞれに調べてもらわなければなりません。 今回導入したプロジェクトではOpenAPIを使って、APIを叩くTypeScriptコードを自動生成していました。この状況ではコンシューマ側が変更後のOpenAPIからコードを生成して、未変更のコンシューマ側コードで型の不一致からビルドエラーが起こりました。こういった仕組みでプロバイダ側のAPIの変更に気づくことはできるかもしれません。ですがそもそもプロバイダから変更を知らされなかったとしたらコンシューマがOpenAPIを更新する必要はありません。コンシューマ側のビルドエラーを頼りにプロバイダのAPI変更検知をするのはすぐれた方法とはいえません。 Pactが正しく入れられているなら、Pactがテストでコンシューマとプロバイダの齟齬が発生することを検知してくれます。もしAPIのコンシューマが複数いる場合には、どのコンシューマとの間でAPIの仕様調整をすればいいかを的確に判断する材料にもなってくれます。 フロントエンドにPactを導入して、Pactファイルを出力するまで 今回導入したプロジェクトではTypeScript、Angular、Jestを使用していました。もしそれらがJavaScript、React、Mochaに変わったとしてもPactは設定すべき内容を押さえていれば、問題なく使えます。 インストール フロントエンドプロジェクトでPactのJavaScript版であるPact JSをインストールします。 npm i -D @pact-foundation/pact@latest Jestの設定 既存のテストとPactのテストを同一設定で同時に実行したくないため、テスト設定のファイルを分けました。プロジェクトルート下にjest.config.jsがもともとあり、それをコピーしてjest.config.pact.jsを作成しました。 既存のテストファイルは*.spec.tsでした。PactのテストファイルはPactのためのものだとわかるように*.pact.spec.tsとしました。 jest.config.jsを使って行うテストではPactのテストを無視してほしいので、下記の設定値を入れました。 testPathIgnorePatterns: ['pact.spec.ts'], jest.config.pact.jsには逆にPactのテストのみ行ってもらうための設定を入れました。それに加え、サーバを使用するので適当なポートを決めてtestURLを入れる必要があります。 testMatch: ["**/?(*.)pact.spec.ts"], testURL: 'http://localhost:8910', ポート番号にPactの語呂合わせである”8910”を入れることをひらめいたときが、このプロジェクトでの私の最高の瞬間でした🌝 Pactのテストを書く たとえばブログ管理システムを開発していたとして、ブログの記事件数を取得できるAPIがあったとします。APIへのリクエストを送るにはパス、リクエストメソッド、Acceptリクエストヘッダなどを決める必要があります。これをひとまず下記のものとして進めます。 ブログの記事件数を返すAPI パス - /api/count-entries リクエストメソッド - GET Acceptリクエストヘッダ - application/json レスポンス - 成功すればステータスコード200で、JSONで{"count": n} このAPIにリクエストを送る関数をcountBlogEntriesという名前で作ることにします。が、今回は先に契約をテストとして書いてしまいましょう。 記述内容は大きく分けて以下の3つです。 (1) Pactクラスを使ってプロバイダのモックを定義 (2) APIを叩くテストの事前処理、事後処理、最終処理を定義 (3) 契約の記述(プロバイダにどういうリクエストが来てどういうレスポンスを返すか定義) (4) 実際にリクエストを出してみてレスポンスを検証 import { Pact } from '@pact-foundation/pact'; import * as path from 'path'; jest.setTimeout(300000); // (1) Pactクラスを使ってプロバイダのモックを定義 const provider = new Pact({ port: 8910, log: path.resolve(process.cwd(), 'pact', 'logs', 'mockserver-integration-operation.log'), dir: path.resolve(process.cwd(), 'pacts'), spec: 1, consumer: 'some frontend', provider: 'backend' }); describe('ブログのAPI', () => { // (2) APIを叩くテストの事前処理、事後処理、最終処理を定義 beforeAll(async () => { await provider.setup(); }); afterEach(async () => { await provider.verify(); }); afterAll(async () => { await provider.finalize(); }); describe('ブログ記事をカウント', async () => { const expectedResponse = { count: 10 }; // (3) 契約の記述 await provider.addInteraction({ state: 'ブログ記事が10件ある', uponReceiving: 'foobar', withRequest: { method: 'GET', path: '/api/count-entries', headers: { Accept: 'application/json' } }, willRespondWith: { status: 200, headers: { 'Content-Type': 'application/json' }, body: expectedResponse } }); // (4) 実際にリクエストを出してみてレスポンスを検証 it('ブログ記事数を取得する', async () => { const response = await countBlogEntries(); expect(response).toEqual(expectedResponse); }); }); }); (1) まずプロバイダのモックの定義です。Pactのテストを実行すると、APIサーバとして動作するモックサーバが立ち上がります。それをポートの何番で立ち上げ、ログをどうするか、Pactファイルの出力先をどこにするかといったことをPactクラスを使って設定します。使用するポートは先にJestの設定で決めていたので、ここではそれに従っています。 (2) 次にテストが切り替わる度に行われる事前、事後処理と、一連のテストの最終処理の定義です。 provider.setup()でプロバイダのセットアップを行い、テストが実行されたあと、provider.verify()を行うことで、プロバイダモックサーバが期待どおりにリクエストを受け取ったかを確認します。もしリクエストパスなどが誤っていればプロバイダモックサーバはリクエストを受け取っていないためエラーとなり、ここでテストを失敗させます。 provider.finalize()はAPIが予期通り叩かれたことを確認して、最後に契約をまとめたPactファイルの出力を行います。 この事前、事後、最終処理は必須の処理なので、定型的に差し込んでしまいましょう。 (3) プロバイダにどういうリクエストが来てどういうレスポンスを返すかを定義します。 プロバイダモックサーバはメソッドaddInteractionで契約を受け取って、その記述通りの設定でリクエストを待ち構え、記述どおりのレスポンスを返します。リクエストのパスが一文字でも間違えたり、Acceptリクエストヘッダが契約と違うものになっているなら、このテストは契約にそっていないことになるので失敗します。コンシューマ側で誤ったリクエストを送ってしまうコードを書くことを防いでくれます。 (4) 最後にAPIを叩いたときに期待する値を取得できるかテストします。プロバイダモックサーバから契約として記述した通りのレスポンスが得られているか確認します。 今回の例ではリクエストに必要な項目数を絞っていますが、パラメータやクッキーももちろん条件に加えることができます。 テストが書けたら要件が固まっているということで、関数countBlogEntriesを書くことも容易だと思います。この関数のコードをここに書くのは割愛します。 Pactファイルの出力(テスト実行) テストとテスト対象のコードが用意できたら、Pactのテストを行います。プロジェクトルートに作っておいたテスト設定ファイルを使ってテストを始めます。 jest --config jest.config.pact.js テストが成功すると、pacts/の中にJSON形式でPactファイルが出力されます。 テストが失敗した場合は、テストログが出力されているのでそちらを見ましょう。APIリクエストが正しくなかった場合など、失敗原因を詳しく探ることができます。 出力されたPactファイルは、APIのプロバイダに渡します。渡し方としては直接渡すという方法もありますが、Pact Brokerというものを使ってバージョン管理していくという方法がベターです。 Pactファイルをデバッグのモックとして使う Pactのうれしい点は、Pactファイルを使ってモックサーバを立ち上げられる点です。開発に使えるので、立ち上げ方を追っていきます。 サーバ起動前の設定(プロキシ) 同一サーバからHTMLもAPIモックデータも配信するならこの設定は不要ですが、Pact製モックサーバは独立して新たに立ち上げるものだからそうもいきません。プロキシを設定して、リクエストをPact製モックサーバに流れるようにしなければなりません。 Angularではこういった状況を見越してか、プロキシ機能が組み込まれていますのでそれを使います。 まずプロキシ設定をJSONで記述します。どこのパスへのリクエストを、どこのサーバに送りたいかを書きます。 { "/path/to/api": { "target": "http://localhost:8911", "secure": false, "changeOrigin": true } } まだPact製モックサーバを立ち上げていませんが、上記のように書いたのでポートは8911を使うことにします。 次にangular.json内のprojects.*.architect.configurations.mock.proxyConfigに上に書いたJSONを当てます。 "projects": { "some-project": { ... "architect": { ... "serve": { ... "configurations": { "mock": { "browserTarget": "some-project:build:mock", "proxyConfig": "config/proxy/mock.json" } } モックサーバの起動の仕方 モックサーバはDockerを使います。Dockerコンテナ起動コマンドに、事前に出力したPactファイルを所定のディレクトリにマウントするオプションが入っています。 docker run --name pact-mock -p 8911:8911 \ -v \"$(pwd)/pacts/:/app/pacts\" pactfoundation/pact-stub-server \ -p 8911 -d pacts これで契約の内容をモックしてくれるサーバが立ち上がります。 モックを使ってデバッグを始める モックサーバをAngularデバッグ開始時に同時に立ち上げ、モックを使ったデバッグを始めましょう。 docker run --name pact-mock -p 8911:8911 \ -v \"$(pwd)/pacts/:/app/pacts\" pactfoundation/pact-stub-server \ -p 8911 -d pacts && \ ng serve -c mock まとめ この記事でフロントエンドへのPactの導入の手順を追いました。 Pactを導入するため、コンシューマとプロバイダの間の決まり事を契約としてフロントエンドのテストに書きました。テストを実行することで契約が記述されたPactファイルが得られ、これをバックエンドのテストに使うことで、APIを使う側と提供する側の間で、使い方の食い違いが起こることを防げるようになります。 Pactファイルはさらにモックデータとしてデバッグに使うこともできるようになり、開発に役立てることもできました。 契約をテストとして書くコストは、モックサーバを作ってデータをそこに加えていくことと比べるとそれほど大きな差ではありません。そんなテストを書くことで、APIのプロバイダ側でテストに使えるファイルを出力でき、さらにはそれを使ってモックサーバを立てることもできて一石二鳥でした。 APIのコンシューマとプロバイダをつなぐテストを行うための仕組みを提供しつつ、フロントエンドの開発に使えるモックも作ってくれる。この記事が、そんな便利なPactの導入の一助になれば幸いです。

OPTMS CONTENT 推薦アルゴリズム#3 画像のマッチングとベクトル近似最近傍探索

TECHSCORE
2020-10-04 11:00:00
当社がリコメンドエンジンを提供しているOPTMS CONTENT(以下OPTMS)のアルゴリズムを解説する記事(3/3)です。 第1回 プロダクトの概要とプロトタイピング 第2回 メディアのマッチングと記事の分類 第3回 画像のマッチングとベクトル近傍検索 OPTMSでは記事だけでなく、記事に添える画像も販売しています。今回は画像の推薦について解説します。 西尾 義英(ニシオ ヨシヒデ) 開発から離れていた時期もありましたが最近プロダクトづくりに戻ってきました。 データを活用できる製品・基盤づくりがテーマです。 記事と画像のマッチング OPTMSの画面に表示される記事には全て画像がはめ込まれています。これは記事にもともと使われていた画像ではなく、株式会社アマナイメージズ(以下アマナイメージズ)が提供できるストックフォトから記事に合うものを探してはめ込んでいます。 方法 OPTMSで扱うストックフォトには全てキーワードが設定されています。第1回で述べたように、記事は単語の集まりとして数値のベクトルとして表されますから、キーワードを介して記事と画像を比較することができます。これにより、「最も記事に近い画像」を選ぶようにしています。 こんな方法で大丈夫か、最初は心配だったのですが「何となくどうしてその画像が選ばれたかわかる」という程度にはマッチしているようです。 ただ、この方法では異なる記事に同一の画像が選ばれる場合があり、推薦結果中の記事が重複しているように見えてしまう恐れがあります。これを避ける方法はいくつかありますが、現状は単純に「複数の記事間で割り当てられた画像が重複する場合、どちらかを記事ごと隠す」ことで対応しています(別途、記事毎に類似記事を提示できるのでこれで良しとしています)。 なお、記事に対する画像の類似度をまじめに計算すると記事数×画像数の計算が必要です。これを避けるために「近似最近傍探索」という技術を使っています。データベースのインデックスと同じノリですね。複数のアルゴリズムおよびオープンソースの実装がありますが、私たちが採用したのはYahoo! JAPAN研究所が公開しているNGTというライブラリです。NGTについては後述します。 もう一点補足すると、記事のベクトルは英語の単語ベクトルを元にしているので、画像のキーワードも全て英語に機械翻訳しています。逐語訳で十分なので、Googleの機械翻訳APIの安価な方(baseモデル)を使っています。 オウンドメディアと画像のマッチング 上で述べたのは、記事一覧において記事に似た画像を一つ選んで表示するということでしたが、その画像は差し替えることも可能です。ここで、下図右上に表示されている「COR」が83→90に向上していますが、これはユーザーにとっての画像の良し悪しが加点された結果です。 方法 キーワードによる画像のマッチングはどうやら使えそうだと分かったのですが、記事と画像の類似度を見るだけだとユーザーに最適化されているとはいえません。購入した記事・画像を掲載するオウンドメディアと、画像の一致度を加味することにします。メディアと画像の一致度を測る方法としては「テイストキーワード」に注目することにしました。これはアマナイメージズが提供しているEVEという画像検索ツールで使われているもので、「何となくこういうテイストの画像」を検索できるように設計されています。 EVE: https://amanaimages.com/eve/ 上の図では、「テイスト」の近い画像が近くに並んでいます。画像同士の一致度をこのように評価できるなら、画像とオウンドメディアについても同じことができそうな気がします。ただし、実装にあたっては以下の課題がありました。 テイストキーワードの欠損。全ての画像にテイストキーワードが設定されているわけではない オウンドメディアのテイストを計算する方法。掲載された画像の情報を得るのが難しい それぞれ以下のように解決することにしました。 1. テイストキーワードの欠損 テイストキーワードが無くても、(即物的な)キーワードは全ての画像が持っています。よって単純にテイストキーワードを普通のキーワードが予測できると考えました。 テイストキーワードの予測には、fastTextを使っています。Word2Vec を高速に計算できるライブラリですが、ラベル付けされた文章を学習して分類器を作る機能も持っているのでそれを活用しました。fastTextである必然性はありませんが、記事のベクトル化に使っている学習済みのモデルがfastText製だったので採用した次第です。 2. オウンドメディアのテイストを計算する方法 もし、オウンドメディアに掲載された画像が持つキーワードが分かれば1と同様にメディアのテイストが計算できるはずですが、実際に掲載された画像については未知である可能性が高いです。 画像については直接分からなくても、掲載された記事を知ることは簡単です。さらに、記事に似ている画像をストックフォトから選ぶことはでき、それらのテイストキーワードも推測可能です。下図のように、オウンドメディアからクロールした記事に似ている画像をそれぞれ数点ずつ抽出し、各画像のテイストキーワードの分布を平均すると、オウンドメディアのテイスト特徴が得られます。 ベクトル近傍検索 記事と画像のマッチングについて、記事と画像のベクトルを比較すると説明しましたが、これには記事数×画像数分の計算が必要となるため、任意の記事に画像をリアルタイムでマッチングさせることは難しいです。推薦する記事については日次のバッチ処理であらかじめ計算しておくこともできますが、OPTMSでは記事の検索も可能です。検索した記事に画像をマッチさせることも必要でした。調べた結果、「近似MIPSアルゴリズム」あるいは「近似最近傍探索」が求める手法だということが分かりました。 近似最近傍探索とは 近似最近傍探索とは、精度を少し犠牲にして、高速にベクトルを検索する技術です。ディープラーニングの流行とともに、画像や文書といった非構造データを数字の集まり(ベクトル、あるいはテンソルということもある)として扱うことが増えたからか、多くのアルゴリズム・ライブラリが提案されています。最近(2020/7/28)も、GoogleがScaNNというライブラリを自ら発表・解説する記事がありました。 この記事の中で、近似最近傍探索技術の重要性について、以下のように述べられています。 埋め込み(Embedding)に基づく検索は、単純なインデックス可能なプロパティではなく、意味の理解に依存するクエリへの応答に効果的な手法です。 このアプローチでクエリに回答するには、システムはまずクエリを埋め込み空間にマップする必要があります。次に、すべてのデータベース項目の埋め込みの中から、クエリに最も近いものを見つける必要があります。これは最近傍探索問題です。クエリデータベースの埋め込みの類似性を定義する最も一般的な方法の1つは、その内積です。このタイプの最近傍探索は、最大内積検索(MIPS)と呼ばれます。 データベースのサイズは数百万または数十億にもなる可能性があるため、MIPSは推論速度の計算上のボトルネックになることが多く、徹底的な検索は現実的ではありません。総当たりの検索を大幅に高速化するために、ある程度の精度を引き換えにする近似MIPSアルゴリズムが必要です。 ~https://ai.googleblog.com/2020/07/announcing-scann-efficient-vector.htmlより、筆者翻訳 ~ アルゴリズム比較 この種のアルゴリズムを網羅的にベンチマークしているサイトがあります。 また、アルゴリズムの中身については、東大の松井先生がアルゴリズムの解説と共に手法の選び方を解説したスライドがあります。 その他、個人で比較しているブログもいくつかありました。総合的には以下が候補になりそうです。私たちは複数比較できなかったのですが、検討当時のベンチマークでは最高性能に近く、GPUを使用しない予定だったのでNGTを選択しました。 Annoy(2013-)spotify/annoy 最初期に発表されたライブラリで、性能的には高くないようです。ただしこなれていて使いやすいという声があり、実際に活用している企業もあるようです。 近似最近傍探索Indexを作るワークフロー - ZOZO Technologies TECH BLOG NMSLIB(2013-)nmslib/nmslib GPUを使わない前提だと速いらしいです。 事例は見つけられず NGT(2016-)yahoojapan/NGT 検討当時のベンチマークでは最高性能に近く、GPUを使用しない予定だったのでNGTを選択しました。 近傍検索ライブラリNGTと深層学習による類似ファッション検索 #yjbonfire/NGT Yahoo!の近傍探索ツールNGTを使って類似商品APIをつくる - BASE開発チームブログ FAISS(2017-)facebookresearch/faiss GPUを使うので高速らしいです。事例を紹介しているBASE開発チームブログさんが、NGTからFAISSに乗り換えたとあるので気になっています。インデックスファイルのサイズが難点だったとありました。 類似商品APIで使っている近傍探索のツールをNGTからfaissに切り替えたお話 - BASE開発チームブログ ScaNN(2020-)google-research/scann 2020年6月に公開されたばかりの最後発です。パフォーマンスが非常に高いらしいです。 事例見つからず NGTの使い方 OPTMSでのNGTの使い方について説明します。 (再)ビルド NGT自体はC++で書かれていますが、Pythonのラッパーが存在します。pip でインストールすることもできますが、性能的に気になる点(共有メモリ使用)オプションがあったため、ビルドしなおして使っています。 Shared memory use The index can be placed in shared memory with memory mapped files. Using shared memory can reduce the amount of memory needed when multiple processes are using the same index. In addition, it can not only handle an index with a large number of objects that cannot be loaded into memory, but also reduce time to open it. Since changes become necessary at build time, please add the following parameter when executing "cmake" in order to use shared memory. $ cmake -DNGT_SHARED_MEMORY_ALLOCATOR=ON .. ~https://devhub.io/repos/yahoojapan-NGTより~ インデックスとIDの紐づけ NGTのPythonラッパーに検索対象のobject(ベクトル)を登録すると、NGTが採番したIDを返却してきます。検索結果もこのIDが返ってくるのですが、このIDはNGTの都合で決められるものなので、記事を管理している本来のIDと紐づけておく必要があります。そのため、OPTMSではNGTのPythonラッパーをさらにラップしてID変換機能を持たせています。 NGTの使い方 from ngt import base as ngt import random dim = 10 objects = [] # 検索対象 for i in range(0, 100) : vector = random.sample(range(100), dim) objects.append(vector) query = objects[0] # 検索条件(検索対象と同じ次元のベクトル) index = ngt.Index.create("tmp", dim) index.insert(objects) # インデックスに登録。登録したIDのリストが返却される index.save() result = index.search(query, 3) # 類似するベクトルを3件抽出 for i, o in enumerate(result) : print(str(i) + ": " + str(o.id) + ", " + str(o.distance)) object = index.get_object(o.id) print(object) ここまでのまとめ ブログの記事を書くときにどんな画像をアイキャッチに使うか悩んだ経験があるので、記事に合う画像を見つける機能は便利だと思います。今後の課題としては、キーワードに頼らずに画像そのものの特徴を使うことです。 おわりに これまで3回に分けて、記事や画像のリコメンドエンジンの中身と開発までの道のりを説明しました。ここで完成ではなく、まだ入り口に立った段階です。最後に今後の課題をまとめておきます。 ユーザー操作を通じて推薦に影響を与える ユーザーとの対話的なUIを通じてオウンドメディアの方針、例えば読者のイメージを指定する 推薦した記事を購入候補に加えた、など暗黙的な操作 オウンドメディアやその読者の傾向を可視化する 当社のもつ消費者価値観モデル(Societas)などの応用 同業種あるいは異業種のオウンドメディアと比較できると良い オウンドメディアのトラッキングデータを使って、ライセンスドコンテンツのパフォーマンスを最大化する トラッキングの仕組みは当社から提供済み オウンドメディア単体ではなくインターネットのトレンドを考慮する キーワードの示唆を与えるなど 以上に加えて、ユーザーからの意見も取り入れて進化していかなければなりません。今後も機会があればその過程を報告したいと思います。

OPTMS CONTENT 推薦アルゴリズム#2 メディアのマッチングと記事の分類

TECHSCORE
2020-09-29 11:00:00
当社がリコメンドエンジンを提供しているOPTMS CONTENT(以下OPTMS)のアルゴリズムを解説する記事(2/3)です。 第1回 プロダクトの概要とプロトタイピング 第2回 メディアのマッチングと記事の分類 第3回 画像のマッチングとベクトル近傍検索 前回は、記事同士の類似度を用いることで、コールドスタート状態でも記事の推薦が成立することを確かめたという話をしました。今回は記事のカテゴリ分類について解説します。なぜ記事のカテゴリ分類が必要かというと、カテゴリ別にオススメ記事を提示する機能があるということと、それが推薦する記事の方向付けにおいても重要と考えたからです。 西尾 義英(ニシオ ヨシヒデ) 開発から離れていた時期もありましたが最近プロダクトづくりに戻ってきました。 データを活用できる製品・基盤づくりがテーマです。 推薦の方向づけ メディアのマッチング OPTMSを開発・販売する株式会社アマナでは、ライセンスドコンテンツの販売を含む総合的なコンテンツマーケティングプラットフォームであるNewsCredの販売代理およびアドバイザリーサービスも提供しています。 アドバイスを行う方に、ライセンスド記事を選ぶにはどのような手順を取るか伺ってみると、最初はライセンス元のメディアを絞り込むことが多いようです。メディアが扱う話題が自社メディアと近ければ、記事を見つけやすいということがあるでしょうし、メディア毎に対象とする読者層は異なるはずなので、自社メディアの読者と近いメディアを選ぶ方が良いでしょう。例えば同じ話題を扱うとしても一般紙と専門誌では切り口や掘り下げ方、語り口なども違ってくると考えられます。 そこで、推薦アルゴリズムに記事の類似度だけでなく「メディアの類似度」という視点を加えることを考えました。ただ、メディアそのものを表す特徴量は不明です。まず、プロトタイプに用いたサンプル記事の提供メディアの編集方針などを見比べましたが、量・質ともに不十分だったので、発信する記事の傾向をメディアの特徴とみなすことにします。具体的にはメディアが取り上げる話題、カテゴリの偏りを比較することにしました。実際ある方法で計算したカテゴリの分布と、メディアの分類には関連があることは確認しました。 ※表のメディア名は非表示としています 次に、ユーザー企業のオウンドメディアのカテゴリの偏りを計算して推薦結果に反映します。前回解説したプロトタイプでは、推薦対象のオウンドメディアに掲載済みの記事をクロールして推薦に用いたと説明しました。この時クロールしておいた記事のカテゴリを計算・集計すればオウンドメディアの傾向が得られます。 余談ですが、これからサイトを立ち上げるユーザー向けに、サイトの方向性を決めるための対話型インタフェースも計画されていました。搭載は諸般の事情で先送りとなっていますが、ここに私たちの価値観研究の成果を入れる予定でした。つまり、ターゲット読者層の傾向を入力することで、興味のあるカテゴリが推定され、そこからオススメのメディアが決まるというものです。ただし、法人向け(B2Bサイト)を訪問する読者は個人の興味・関心ではなく業務上の必要に迫られて情報収集するはずですから、利用企業の業種、あるいは想定読者の業種・職種・職位といった情報から、興味のある記事カテゴリを推定することになるでしょう。 記事の分類 メディアが発信する記事カテゴリの分布は推薦に使えると考えましたが、肝心の記事カテゴリの定義、ならびに、実際の記事をどのように分類するかは大きな課題でした。調べてみると「標準的な」記事カテゴリというものが無いことに気づきます。各メディアが独自にカテゴリを定義している場合もあるものの、それらを統合するのは困難です。以下では、私たちが採用した記事の分類方法を説明します。 方針 実は当初、Googleのコンテンツ分類APIを使うことを考えました。有償ですが、ライセンスドコンテンツ全量を分類するのではなくメディアごとにランダムサンプリングすれば、費用を抑えられます。ところが、「記事カテゴリ」毎のオススメを表示する機能が新たに追加されたことで、新着記事の一定割合に分類APIを呼び出す必要があるため、独自に実装することにしました。次に、Googleの分類APIが出力するカテゴリを正解とする機械学習を検討したものの、そのカテゴリもOPTMSで使いやすいとは言えなかったので、カテゴリそのものも定義しなおすことにします。とは言え記事の一つ一つを人間が仕分けることは困難ですから、まず教師なしアルゴリズムで記事を分類したのち、分類された記事の集まりにカテゴリ名を与えるというボトムアップ式の手順を取りました。 トピックモデル 教師なしで記事を分類するといえば、トピックモデルの適用が考えられます。トピックとはカテゴリより細かい分類の概念で、LDAという計算アルゴリズムが有名です。LDAは記事が複数の話題(=トピック)を扱っている可能性を考慮に入れ、そのトピックの分布を確率的に推定します。 LDAを使ってトピックを計算してみたのですが、トピックごとに記事を並べた結果を見てもまとまりが感じられません。この状態を言い表す、こんな記事がありました: alphaの値が大きい(= 2.65)トピックであるtopic-8の単語分布を見てみると、比較的あらゆるジャンルの文書で出てくる汎用的な単語が多いことがわかります。一方で、alphaがある程度小さい値(= 0.47)になると、そのトピック(topic-71)の単語分布はある1つのジャンルの単語(ここではレストランに関する単語)によって構成されるようになります。さらにalphaの値が小さい(= 0.019)トピックになると、そのトピック(topic-156)の単語分布は、ある文書特有の単語のみで構成されるようになります。 ~https://seedata.co.jp/blog/tech/264/より引用。ハイライトは筆者~ ハイライトした箇所は「大きすぎる」または「小さすぎる」トピックの特徴を表しています。私が得た結果にも同じように「多くの記事で汎用的に用いられる単語」と「記事特有の単語」に分かれる傾向が見られました。ハイパーパラメータを調整したり、トピックの分布をもう一度クラスタリングすれば解決できるかもしれませんが、そうするくらいなら、最初からクラスタリングしても良さそうです。 記事ベクトルに対するGMM 次に試したのは記事ベクトルのクラスタリングです。最適なクラスタ数を定量的に判断できるアルゴリズムとしてGMMを選び、記事のクラスタをピックアップしたところ、内容的に近しい記事が集まっていると見受けられました。最終的に以下の手順でカテゴリを得ることができました。 記事ベクトルをメディアごとにクラスタリングする GMM:Gaussian Mixture Modelを適用し、BIC基準でクラスタ数を決定 所属記事数5未満のクラスタは除外 クラスタのベクトルを計算する クラスタに所属する記事のベクトル重心を保存する 以後はGMMのモデルは使わず、クラスタのベクトルと記事ベクトルの類似度を使う クラスタを新しく整理したカテゴリに割り振る 各クラスタに所属する記事の件名を10件まで抽出しておき、件名とカテゴリを見比べて人間が判断する ある程度決まったところで、カテゴリの統廃合を議論 最終的に大分類14、小分類60ほどの分類が得られた 定義したカテゴリに記事を分類する手順は以下のとおりです。 対象の記事と「近しい」クラスタを3つ選ぶ クラスタ中心点と記事ベクトルのコサイン類似度の上位から3つ クラスタ数を増やすと一つの記事に複数のカテゴリが割り振られやすくなる。既存の記事で、カテゴリが1種の記事が最多となるように3とした。 得られたクラスタに対応するカテゴリを割り付ける ここまでのまとめ ターゲットとなる読者をセグメントするのに、興味のある記事のカテゴリ特徴を用いるのが自然だと思われます。これにより、記事の掲載元メディアと二次利用先のWebサイトと「読者層の近さ」を測り記事の推薦順位に反映しています。 問題はカテゴリ自体の定義に決定版がなく、現在の記事データセットからカテゴリを見つける必要があったことです。膨大な記事を1件ずつ精査するのは現実的でないので、記事ベクトルのクラスタリング結果を用いることで効率化を図りました。なお、現時点のカテゴリも決定版ではなく今後新しい記事媒体が増えるとともに見直していくことになるでしょう。 ここまで記事の推薦について解説しました。次回は、画像の推薦について説明したいと思います。

OPTMS CONTENT 推薦アルゴリズム#1 プロダクトの概要とプロトタイピング

TECHSCORE
2020-09-24 11:00:00
これは当社がリコメンドエンジンを提供しているOPTMS CONTENT(以下OPTMS)のアルゴリズムを解説する記事です。今回を含めて全3回の連載を予定しています。 第1回 プロダクトの概要とプロトタイピング 第2回 メディアのマッチングと記事の分類 第3回 画像のマッチングとベクトル近傍検索 今回はOPTMSというプロダクトの概要と、基本的なアイデアを説明します。 西尾 義英(ニシオ ヨシヒデ) 開発から離れていた時期もありましたが最近プロダクトづくりに戻ってきました。 データを活用できる製品・基盤づくりがテーマです。 プロダクトの概要 OPTMS CONTENT とは OPTMS CONTENTは、成果予測AIで“最適化されたコンテンツ”(=オプティマイズド・コンテンツ)を提供する、リコメンデーション・プラットフォームです。 ~https://optmscontent.comより~ 一言でいうと、ライセンスドコンテンツを販売するプラットフォームです。ライセンスドコンテンツとは、新聞や雑誌などのメディア企業が専業メディア以外の企業サイト(オウンドメディア)に転載を許可した記事(一部画像も含む)のことです。 記事をライセンスするというビジネスモデルにはなじみがないかもしれません。コンテンツマーケティングの課題はオウンドメディアに掲載する記事の量と質を両立することと言われますが、ライセンスドコンテンツは記事の量を増やす手段として考慮すべき選択肢となっています。 ライセンスドコンテンツが得意とするのは、業界のトレンドなど広く読者を集めるための記事を用意することです。そちらは一定の質が保証されたライセンスドコンテンツに任せることで、記事執筆のリソースを自社の深い専門領域に集中することができるようになります。ただし、大量のライセンスドコンテンツの中からどのような記事を掲載するかの選定は重要で、従来は専門家によるコンサルティングを必要としていました。OPTMSはここをリコメンドエンジンに任せることで、ライセンスドコンテンツ活用のハードルを下げることを狙っています。 サービス提供形態 OPTMSとは株式会社アマナ(以下アマナ)が開発・販売するプロダクトです。私たちはコンテンツの推薦機能をAPIとして提供しています。 ライセンスドコンテンツは当初海外の記事のみをNewsCred*1から提供されていましたが、アマナによって国内出版社との契約を拡げているところです。国内向けのオウンドメディアであれば海外記事は翻訳が必要ですが、翻訳の手配もOPTMSから行うことができます。 記事にはしばしばアイキャッチ用の画像が添えられています。元記事で使われていたものが利用できる場合もありますが、株式会社アマナイメージズで販売されているストックフォトの一部をOPTMSを通じて購入できるようになっています。画像の価格が記事にインクルードされている、実質無料の画像もあります。リコメンドエンジンは画像の推薦も行っています。 開発にいたった経緯 企業と顧客の間の最適なコミュニケーションをデザインする。この課題を共有する多業種多企業が結集し、共に解決策を探っていくR&Dプロジェクトが「価値観・HI コンソーシアム」です。 ~当社プレスリリースより~ 私たちはマーケティングコミュニケーションの最適化を目的とした研究開発活動を行ってきました。特にコンテンツの自然言語処理と、消費者の価値観を定量化する技術に注目しており、以下をリリースしています。 iNSIGHTBOX メールのクリックや購買のデータを自然言語処理によって解析することでコンテンツ制作の支援やターゲティングを行うことのできるプロダクト Societas 消費者の価値観を分析する独自のフレームワーク その後、2017年にはアマナと私たちを含む4社で「価値観・HIコンソーシアム」を立ち上げ、映像・画像・文章などのクリエイティブを顧客の価値観に合わせる手法の共同研究を行っていました。同時期に、アマナにてコンソーシアムとは独立してOPTMSの企画が進められていたところ、「価値観・HIコンソーシアム」でのつながりから、私たちも開発に協力させていただくこととなりました。 プロトタイピング OPTMS が提供したい推薦とは OPTMS CONTENTは、企業やブランドのマーケティング戦略やコンテンツのパフォーマンスデータに基づき、あなたのブランドやサービスとのマッチ度(COR -Content Optimized Rate-)の高いコンテンツをリコメンドします。 ~https://optmscontent.comより~ OPTMS の特長は購入する記事を推薦するという点です。リコメンドエンジンに求められることは大きく2つあります。 掲載するオウンドメディアのコンセプトにあった記事である ターゲット読者が興味を持つ話題か ブランドや企業が伝えたいことに関連するか オウンドメディアの成果が上がるような記事である 広く読者を集める オウンドメディア内の回遊を増やす 最終的に問い合わせなどの行動につながる また、コンテンツは記事だけでなく画像もあります。記事の内容と関連し、サイトの雰囲気とも合う画像を選ぶ必要があります。 方針 コンテンツを推薦する手法はいくつもありますが、提供先のサービスによって使えるものもあれば使えないものもあります。 OPTMSにおいては、ユーザーが記事を採用するのはそれぞれ自社のオウンドメディアに掲載するためであり、同じ記事が複数のメディアに掲載されることは避けたいことです。言い換えると、他ユーザーが購入した記事を参考にする、いわゆる協調フィルタリングは使えないということです。また、コンテンツのパフォーマンス、つまり採用した記事に対する読者の反応データを活用する目論見があるものの、ローンチまでは検証できませんし、各ユーザーの導入直後はいずれにしてもデータがありません(コールドスタート)。記事のパフォーマンスデータが得られない状態でも成立する手法が必要でした。 取れそうな選択肢は、ユーザーのオウンドメディアに掲載された記事と近しい記事を推薦することです。まだオウンドメディアを持たない、サイトをこれから立ち上げるというユーザーの場合は、ベンチマーク先のサイトを探して代用すれば良いでしょう。この方針(内容ベースの推薦)でリコメンドエンジンを実装可能か、プロトタイプを作ることからはじめました。 記事のベクトル化 内容ベースの推薦を行うために、まず記事同士の「類似度」をどのように定義するかを考えます。これは、古典的には文書に現れる単語の出現頻度によって文書を数値(ベクトル)に置き換え、ベクトル同士の類似度を計算するという手順で実現できます。この方法はベクトルが語彙数と同じ程度に高次元となってしまい計算が難しいという問題があり、近年はWord2Vecなど単語や文書を数百次元のベクトルに変換する「Embedding(埋め込み)」という技術が良く用いられるようになっています。Word2Vecは単語をベクトルに変換することですが、文書全体にわたって平均を取るなどすれば文書のベクトルも得られます。OPTMSでは、以下の手法を採用しました。 準備: 単語ベクトルを得る学習済みモデルを入手 → cawl-300d-2M@fasttext 300dとはベクトルが300次元であること、2Mは学習した単語数が約200万であることを表す ライセンスドコンテンツに出現する単語のdf(単語がいくつの記事に含まれるか)を計算しておく ベクトル化: 日本語の記事は英語に機械翻訳する(今のところライセンスドコンテンツのほとんどが英語記事のため) crawl-300d-2Mを記事中の単語に適用して、単語ベクトルを得る 記事中の単語に対するtf-idfを計算して、2.の重み付き平均を取る データの集め方 プロトタイピングを始める時点では、NewsCredからの記事提供基盤が完成しておらず、記事データセットの全体像がつかめていませんでした。また利用するユーザーの想定もできていなかったので、アマナに以下2点を協力いただきました。 サンプル記事として、ライセンス元メディアで公開されている記事URLを約3000件、なるべく幅広いジャンルからリストアップ OPTMSを利用してほしいユーザー企業を数件仮定し、公開中のオウンドメディアをリストアップ 記事本文は、1の記事URL、および2のサイトから記事一覧ページを探しURLのリストを得てからスクレイピングしました。手間こそ掛かりましたが、推薦したいアイテムがインターネットに公開されている情報のため、データ収集難易度は低かったと言えます。 プロトタイプの振る舞い プロトタイプはRのShiny を使って作成しました。プロダクトの実装はPythonを使っていますが、筆者はRの方が慣れていたためです。Shiny とは、データ分析結果のグラフや表をインタラクティブに操作するWebアプリケーションを作れるというライブラリです。内容ベースの推薦がどのように仕組みか関係者に説明したかったので、これを視覚的に見せつつ、使い方が想像できるようなインタフェースも仮組みしています。 さて、記事を推薦する基本的なアイデアとは、まず仮想ユーザーのオウンドメディアからクロールした記事の中心を計算し、次にそれを基準点としてライセンスドコンテンツのサンプル記事のベクトルとコサイン類似度を計算し、最後に類似度が高い順に並べるというものです。 「マップ」タブにはあらかじめサンプル記事を散布図として表示してあり、ここにクロールした記事を重ねて表示します。クロールした記事はサイト固有のカテゴリと、記事の公開日の情報を持っており、これを横のパネルで条件指定することで推薦に用いる記事が増減し、中心点(赤い十字にcenterのラベル)が動きます。中心点が動くと推薦結果が変わります。タブを「記事」に切り替えるとこの時推薦される記事がリストアップされます。 記事の横に表示されているのは、記事にもともと使われていた画像です。プロダクトではストックフォトから記事に合うものをマッチングさせていますが、プロトタイピング時点では後回しにしています。 ここまでのまとめ データに基づくプロダクトの振る舞いはなかなか人に説明しづらいので、目に見えて動くものを作ることが重要だと思います。仮のデータを使い、推薦アルゴリズムも単純なものでしたが、プロジェクトメンバーから好評を得られたので、自信をもって先へ進めることができました。データが無い状態でプロジェクトが始まることも意外と多いので、どうにか別の方法で集めてくるということも学びました。 プロダクトにおいて工夫した点や今後の課題については次回以降の記事で述べたいと思います。 *1:NewsCredはコンテンツマーケティング全般をサポートするプラットフォームで、ライセンスドコンテンツの販売においては先行するサービスです。アマナはNewsCredと日本市場独占パートナーシップを締結しています(参考)。 NewsCredとOPTMSの違いは、OPTMSがライセンスドコンテンツの販売に特化している点、国内出版社の記事を扱う点と、独自にリコメンドエンジンを持つ点です。

技術職新卒社員に技術研修としてJavaを学んでもらいました

TECHSCORE
2020-09-03 11:00:00
2020年度、当社は5名の技術職の新卒社員を迎えました。 入社して1ヶ月ほどは総合職の新卒社員と一緒にビジネスマナーや当社の事業などについて学び、その後、5〜6月にはプログラミング基礎として株式会社クロノスが提供している Java 技術研修を受講しました。 この記事ではこの技術研修を通じて得た気付きなどについて、新卒社員自らの言葉で語ります。 株式会社クロノスでは様々な IT 研修・トレーニング サービスが提供されています。 すべての研修は「現役のエンジニア」が講師を務めており、 ・魚を与えるような研修ではなく、釣り方を学ぶような研修 ・現場で得たノウハウや技術といった経験値を織り交ぜ、使える知識を伝える研修 を目指して、研修内容、教材の工夫が行われています。 昨年から当社で導入していますが、先生が丁寧でサイコーです。 オンラインでも支障はなかったですし、オススメですよ。(管掌役員 岡村より) 目次 研修の位置づけ Java 技術研修の概要 case 1: 松田 直哉(マツダ ナオヤ)の場合 case 2: 岸本 大河(キシモト タイガ)の場合 case 3: 小林 連(コバヤシ レン)の場合 case 4: 岸本 和哉(キシモト カズヤ)の場合 case 5: 松木 自然(マツキ ジネン)の場合 研修受講者(新卒社員)のまとめ さいごに 研修の位置づけ 当社では技術系新卒社員に対し、 早期に戦力化、プロダクトにコミットできる状態になる 2年目以降は自らが新卒社員を研修・指導する立場になる ことを念頭に、1年間の研修スケジュールを策定しています。 お客様に持続的にサービスを提供するにはサービスを支えるエンジニアの量と質が重要であると考え、特に質を担保するために計画的に研修・指導を継続して行うことを重視しています。一部のスーパーエンジニアに依存するのではなく、エンジニア全体の技術レベルを底上げするためには、新卒1年目の研修・指導が肝要となるため、育成プロジェクト「Tadpole」として特に力を入れています。Tadpole はオタマジャクシ、ゆくゆくは立派な Frog に、という願いを込めています。 トレーナーには年齢、経験の近い入社2〜3年目の社員をあてています。これには以下の狙いがあります。 1年目の社員にとって自分と状況が近いので 1年生からコミュニケーションがとりやすい。 キャリアパスをイメージしやすい。 2〜3年目の社員にとって 指導側にまわることでスキルの深い理解が必要になり、復習することで理解がより深まる。 チーム運営やタスク管理の能力が身に付く。 また、1年間の育成期間を3つのフェーズにわけ、それぞれのフェーズで目的を定義し、それにそった研修スケジュールを組んでいます。 最初の Start フェーズでは、エンジニアとしての基礎的な力を習得するために、 内部講師による基礎 IT 技術研修 外部講師による Java 技術研修 を実施しました。外部研修ではアプリ開発、内部研修で基礎と Web システム全体を学習するという位置づけになっています。 Java 技術研修の概要 ここでは今回受講した Java 技術研修の概要について説明します。 まず最初の3週間で Java の基礎、Web アプリケーションの基礎について座学で学びました。 次の1週間で簡単な Web アプリケーションについて実装を行いました。この Web アプリケーションの大枠は事前に実装されていますが、未実装の箇所があり、これを実装することで全体としてひとつの Web アプリケーションとして動作します。 次の1ヶ月間では、チームでの開発について座学で学んだ後、他の会社から参加している研修受講者とチームを組み、チームでの開発を行いました。 そして最後に成果発表を行いました。 なお、新型コロナウイルス感染拡大防止のため、研修はすべてオンラインにて行われました。 case 1: 松田 直哉(マツダ ナオヤ)の場合 情報系大学出身。大学時代の専門はネットワーク。 アルバイトで1年間、PHP(Laravel)での開発を経験。 また、競技プログラミングで C++ を使用。 Java に関しては基本文法の if 文や for 文の書き方を知っている程度。 今回の研修で Java のクラスやオブジェクト指向の概念を初めて学びました。 チーム開発では5人のチームで Java のアプリケーションを作成しましたが、初対面の方たちとのオンラインコミュニケーションは、プログラミングや設計書を共同で作成するうえで、とても大きな障害となりました。 しかし「コミュニケーションが取りにくいならば取らなくても進むようにしよう」と考え、最初にできるだけ役割(リーダー、計画の立案、実行、期日の設定など)をはっきりとわけることで順調に進めることができました。 このことから始めにルールや役割をしっかりと決めることがオンラインのチームで業務を進めていくコツだと学びました。 case 2: 岸本 大河(キシモト タイガ)の場合 情報系大学出身。大学時代の専門はソフトウェア工学で、リバースエンジニアリングやフォワードエンジニアリングについて研究。 Python が好き。 PHP、Java、C、C#、JavaScript、Scala での開発経験がある。 SpringBoot を使って RestAPI を組んだことがあり、Java の基礎的な書き方を知っているが、クラスやオブジェクト指向の概念等は本で少し読んだ程度。 今回の研修では Java の基礎はもちろん、チームマネジメント能力やオンライン特有のコミュニケーション力を得ることができました。 プログラミングが初めてという方が多く参加しており、多少なりとも経験のある自分がチームをまとめる機会が多かったため、プログラミング以外について考えることに長い時間を費やしました。 リモートではどうしても文字でのコミュニケーションが多くなり、その内容が伝わっているのか不安になります。 そこで分報を取り入れて、困っていることや何をしているのかを共有したり、 会議の際にファシリテーターを用意してビデオ通話でも話しやすい空気を作ったりすることで、円滑に開発を進めることができました。 これらの経験により、コミュニケーションが取りやすい場を作り円滑にプロジェクトを進めることが大事だということに気づきました。 また、それがプロジェクトの成功につながるということが分かりました。 これらの力は今の業務にも大きく役立っており貴重な経験となりました。 case 3: 小林 連(コバヤシ レン)の場合 情報系専門学校出身。学生時代は主にJavaを学習。 Web アプリを複数人で作成したことはあるが、知識は基本構文を覚えている程度。 今回の研修を通じて、Java に関する基礎知識だけでなく、今後社会人として必要になるコミュニケーション能力と意識を得ることができました。 研修中に私は3つの大きな壁にぶつかりました。 チーム開発の際、メンバー全員に自ら適時状況報告をするという意識が薄かったため、メンバー同士で認識にズレが起こった。 受講者全員がリモートでのコミュニケーションに不慣れで、打ち合わせや問題解決が円滑に進まなかった。 フロントエンドの経験が無いため、自分のイメージ通りの見た目を追及できずに悔しい思いをした。 それぞれ以下のように対応しました。 チーム内で規則を作り、定期的にチャットのグループで報告するようにした。 朝会を設け、1日のノルマを全員で考えるなど強制的に話す機会を設けた事により、徐々に自然とコミュニケーションを取る回数が増えていった。 今後自身に必要な技術だと思い、現在進行形で空いた時間を利用して自主的に学習を行っている。 これらの問題に取り組んだ結果、対面では気づきにくかった報連相で情報を共有する事の大切さ、文字だけで自分の考えや悩みを適切に相手に伝える工夫、 チーム開発時には最初の環境作りがその後の円滑なコミュニケーションに繋がることなど、多くの学び・気づきを得ることが出来ました。 研修での経験をしばしば思い返して、日々の業務に役立てています。 case 4: 岸本 和哉(キシモト カズヤ)の場合 情報系専門学校出身。 C、C#、Python、JavaScript などを使用して、ゲームやゲーム内 AI を作った経験はあるが、プログラミング言語に関する知識は基本構文を扱える程度。 元々は独学でゲームを作成していましたが、そのときは「自分だけが読めるコード」を書いていました。 機能ごとのクラス分けは行わず、オールフォーワンの精神です。個性豊かな変数名で、コメントだけでは飽き足らず、変数ひとつひとつを別の紙にメモしていたような気がします。 今回の研修では、コードや仕様書の作成の際に「他人の目」を意識することが大切であるということを学びました。 チーム開発において、他人が書いたコードを読む際に迷いが生じたり、個人作業を持ち寄った際に認識がずれていることが発覚するということがありました。 このことから、基本設計が大事であること、特に変数名など共通知識をドキュメントとして残すのが大事であると痛感しました。 ここで学んだように、あとから見た人、ともに作業する人にも理解しやすい、人に優しいコードや仕様書の作成を心がけたいと思います。 case 5: 松木 自然(マツキ ジネン)の場合 情報系専門学校出身。 PHP、Python、JavaScript、Swift での開発経験があるが、主にフロントエンドを中心に学習していたため、バックエンドの知識は浅い。 学生時代は主にフロントエンドを勉強しており、本格的にバックエンドを触るのは今回の研修が初めてでした。 そのため、どこでセッションに値を保持すればいいのか、どこに保持した値を渡せばいいのかなど、データの流れがイメージできず苦労しました。 しかし、研修資料を見返したり、個人開発などの演習を通して徐々にデータの流れがイメージできるようになり、バックエンドを実装することの楽しさを感じることができました。 個人開発研修では、技術面を中心にスキルが向上し、チーム開発研修では、チーム開発で必要になるコミュニケーションスキルやチーム間での細かな進捗報告など、徐々に求められるレベルも高くなり、やりがいのある密度の濃い2ヶ月間を過ごすことができたと感じています。 またチーム開発では、【要件定義書→基本設計書→機能実装→テスト】のように、実際の開発現場に近いフローで開発を進めることができ、開発現場に出る前にエンジニアとしての働き方をイメージすることができました。 2ヶ月という短い期間で、コーディング力・人に教える力・コミュニケーション能力など幅広くスキルを向上させることで、自信をもった状態で開発現場に向かうことができています。 研修受講者(新卒社員)のまとめ 今回の研修では Java の基礎から Web アプリケーションの作成などの実践まで、幅広い内容を学習しました。プログラミングだけではなく、他社からの参加者を含め複数人で協力しながらの開発を経験し、コミュニケーションの取り方やタスク管理などについて学習しました。 研修はフルリモートで行われたため、今まで経験してきた環境との違いに少し戸惑う場面はありましたが、新卒社員全員で協力、工夫し合うことで研修をスムーズに進めることができました。 研修内容としてはインプットすることも多かったですが、それだけではなく、チーム開発や成果発表などを通してアウトプットの重要性に気付かされたと感じています。 さいごに 新卒研修以降も OJT を中心とした育成が続いていきます。 OJT では、その時点で使っている技術や実践的なテクニックなど ad hoc な知識を伝えることに偏りがちです。(悪い言い方ですが)手垢が付く前にきちんと体系化された技術を学んでもらいたいという思いから、外部講師による Java 研修を受講してもらいました。 受講後の新卒社員から研修内容についてフィードバックを受け、先輩社員も自らの知識の古さに気付かされたりと刺激を受けています。 当社にはベテランから若い人まで様々な年齢、バックグラウンドを持ったエンジニアがいます。 エンジニア全員が活躍できるように、エンジニア全員が幸せに働けるように、何ができるか、どうしたらうまくいくか、エンジニア自らで考えて実践する。それを続けることで、幸せな情報社会の実現に貢献することができると考えています。

あえての無茶ぶり!新卒総合職向け開発研修を開催しました

TECHSCORE
2020-08-20 11:00:00
2020年4月、当社には14名(技術職5名、総合職9名)の新卒社員が入社しました。 入社時の区分では技術職・総合職と専門が分かれていますが、実際の業務では相互に関わりあって日々の業務を進めています。そのため、配属先以外の業務について新しく入社した新卒社員にも知ってもらう必要があります。そこで、当社ではローテーション研修を実施し、業務について知ってもらう機会を設けています。 この記事では、ローテーション研修の一環として技術部門で実施した新卒総合職向けの開発研修について、概要とその振り返りを紹介します。 林 慧豊(ハヤシ アキホ) 2019年4月入社のバックエンドエンジニア。 音楽聴いたり読書が好きです。(多読ではないです。) ここ数年は常にショートヘアです。 暑さが出不精に拍車をかけている今日このごろ。 新卒総合職向け開発研修 目的 概要 準備 開発環境の構築手順書の準備 手順書の検証 研修時のサポート体制 いよいよ開始 初日:何ということでしょう…… 2~4日目:開発に着手! 最終日:やり切った! より良い研修を目指して まとめ 新卒総合職向け開発研修 「当社の技術部門ではどんな業務をしているのか」を新卒の総合職の社員にも体験を通じて知ってもらうべく、こんな研修を用意しました。 目的 総合職に配属される新卒社員にも、開発業務について体験を通じて知ってもらいたい。 一番の目的はこれです! 総合職配属となる新卒社員は、技術職が主に行なっている開発業務の現場に直接携わる機会はあまりありません。そこで、共に働く開発者の苦労や喜びを体験してもらい、実業務でも活かしてほしいという思いから、今回は開発業務の中でもプログラミングに特化した研修を行うことにしました。 しかし、準備を始める前には以下のようなそこはかとない不安がありました。 「開発業務を行う」 = 「それに伴う技術知識が多少なりとも必要」 開発業務の一部を体験してもらうことが目的なので、技術を教えることに特化した研修にはしたくない 研修期間は開発環境の準備や成果発表会まで含めて5日間 さらに新型コロナの影響で初のリモートでの研修 「レポート作成などでしかパソコンを使わない」というような、プログラミングにゼロから挑戦する社員も居ると思われる ひょっとして(いや、ひょっとしなくても)無茶ぶりでは……? 果たして無事に進められるのでしょうか? 概要 Webアプリケーションを作ってみよう! 要件/シナリオ とある企業様からデータを管理するシステムを請け負った想定でWebアプリケーションを作る(データの登録・変更・検索・削除が可能なWebアプリケーションの作成) 使用技術など 開発環境はVirtualBoxにOSイメージをインポートする形で用意 OSはCentOS 7 開発ツールはVisual Studio Code 開発言語は、Java(Spring Boot)とHTML/CSS/JS 成果物例 準備 無茶ぶりと分かりつつも、あえてそのような環境にすることで、新卒社員同士で考えたり協力して乗り越えてほしいという思いから、「サポート担当の先輩社員たちはなるべく付きっ切りにならないようにしよう」という方針を定め、準備を進めました。 開発環境の構築手順書の準備 できる限り新卒社員自身で実施できるように、キャプチャを入れるなどして手厚く補足を加えた手順書を用意しました。 手順書の検証 総合職として入社した新卒2年目の社員に協力を仰ぎ、用意した手順書で開発環境の準備を独力で進められるか検証を実施しました。検証の結果、「新卒社員が独力で手順書だけに従って開発環境の準備をするのは、時間的に厳しそうだ」との意見が出ました。同時に「現状以上に手順書の文章を増やしても、ゴールが見えづらくなって余計に混乱する」という意見も出ました。新卒社員間の技術レベルの差異もあるため、一律の手順書で解決するよりも、サポート役をあてて柔軟に対応するほうが良いと考えました。 研修時のサポート体制 質問受付や状況確認のために、新卒社員を3名ずつのチームに分け、それぞれのチームにサポート役を1名つけて研修を進めるようにしました。 あわせて、チームごとのグループチャットを作成し、連絡事項などはそこで共有する形としました。 また、質問の受付や対応については、まずはグループチャットで新卒同士で教えあう形で進めてもらい、それでも解決できない場合はZoomやMeetで画面をサポート役と繋いで個別に対応する方針としました。 いよいよ開始 いよいよ技術部門のローテーション研修開始です。色々と準備はしたつもりですが、大丈夫なのでしょうか……。 初日:何ということでしょう…… 初日は研修のキックオフから始まり、研修目的などの説明をした後で各チームに分かれて開発をするための環境構築を 進める流れです。 環境構築のリハーサルを行っていたこともあり、大丈夫だろうと開始時は考えていたのですが、 リハーサルに協力してくれた社員と新卒社員では1年分の経験の差があります。 そのためか、想定していたよりも難航することとなりました。 まず、用語がわからない アプリケーション開発が初めてという新卒社員が大半で、そもそも日常生活では聞いたこともなければ使ったこともないツールや単語が次々と出てきます。噛み砕いたつもりではいたのですが、今何をしているのかをイメージできない受講者が大半でした。最終的にはサポート役の画面を共有しつつ、一緒になって操作を進めて解決しました。 各自のネットワーク環境の差 全員自宅からリモートで研修を受けているので、中には自宅のネットワーク環境が弱い新卒社員もおり、OSイメージのダウンロードや画面共有によるコミュニケーションがなかなかスムーズにいかず、研修が思ったように進まないことがありました。 このように新卒社員たちは「“?”ばかりの作業」に、サポート役は「技術に深入りせずにどう説明すればわかってもらえるか」にそれぞれ苦戦し、さらにネットワークの問題も障壁となり、想定より時間はかかりましたが、初日のうちに全員が開発に着手できる状態になりました。 2~4日目:開発に着手! 2日目以降は開発に着手していきます。2日目、3日目は初日と同様にサポート役が質疑などに対応する時間が多く、ほとんどペアプロ状態でした。課題資料の中に最低限のCRUD機能を実装するための参考サイトなどについても記述していたため、ある程度は各自で進めてもらえることを想定していたのですが、甘かったようです……。不安を抱えつつ4日目を迎えましたが、3日目までと変わってサポート役が入って対応する時間が減ったため、一安心しました。理由としては以下が挙げられます。 Javaの実装を切り抜けたことで事態が好転 3日目のうちにJavaでの実装を終えてHTMLなどの実装に取り掛かった新卒社員が多くおり、「変更点などが目に見えやすい部分」ということで自分が何をしているのかなどがわかりやすくなったため「訳もわからず四苦八苦している」という状況から脱し、楽しみつつ進めてもらえました。 3日間を経て、少し慣れた 当初は何もかも初めてだらけで戸惑いが大きかったようですが、2日目、3日目と進めていくうちにどことなく開発に慣れてきたことも好転した要因かもしれません。 自分で調べてみる、同期内での助け合い 少し慣れたこともあってか、「自分で調べてみる」「同期の中で教えあう」ということが自然に行えるようになっていました。 最終日:やり切った! 最終日の5日目は、午前中まで開発を進めて午後から成果発表会です。4日目終了の時点で全員ほぼ完成していたので、午前中は最終調整に充ててもらいました。各々の個性やコンセプトが色濃く出たアプリケーションばかりで、発表会を見た先輩社員からも称賛の声が上がりました。 苦労したからこその達成感 前半はかなり苦労している様子でしたが、後半に入ると達成感を持ちつつ実装を進められたようで、最終的には新卒社員から「楽しかった」という感想をもらえました。 より良い研修を目指して 「終わりよければすべてよし」と言いたいところですが、やはりつまずいたところや課題点もあったので、次回の研修時には、以下のようなことを意識すればより良い研修にできると思います。 用語集を用意する 最初のつまずきが用語の壁だったので、例えばツールの場合は「これはどういったツールで、何のために使うのか」を説明する用語集を用意するなどして、まずはその壁を可能な限り取り除きたいです。 やっていること、やろうとしていることを説明する 前半は特に「やっていること、やろうとしていることをイメージできない」というところが双方にとって辛いところだったと思うので、そこを少しでも解消できれば、と感じました。口頭説明が難しければ何か図を用意して説明しようと思います。 まとめ 今回研修を担当して、知識ゼロの新卒社員に上手く伝えられなかったり、そもそも自分も深く理解できていなかったりと「自分がいかに慣れに頼って仕事をしているか」ということを思い知りました。 慣れや身についた先入観などはどう頑張っても介入してくるものですが、「そこを超えてどう歩み寄れるか」がとても大事であることを実感したとともに、とても難しいことであると学べた5日間だったと感じました。 新卒社員からすると至らない点の多い先輩だったのでは……という気がしていますが、頑張ってついてきてくれたので非常にありがたかったなぁ、と思います。 最終的には「楽しかった」とも感じてもらえたので、業務の全てではないですが、「技術部門ではどのような業務をしているのか」を知ってもらえただけでなく、開発業務のやりがいや魅力についても伝えられたのではないかと思います。

シナリオ機能をリリースしました

TECHSCORE
2020-08-06 11:00:00
2020年7月、Synergy!の新機能としてシナリオ機能をリリースしました。 本記事ではシナリオ機能の開発者の一人として、開発において行った工夫や個人的な反省点をご紹介します。 原 草平(ハラ ソウヘイ) ミステリとSFが好きです。 森博嗣の『すべてがFになる』を読んだのがきっかけでIT業界に興味を持ちました。 小説以外にも哲学関連の本や技術書を読むのが好きです。 シナリオ機能概要 シナリオ機能とは、事前に定義したシナリオに沿って、顧客の行動に応じて適切な対応を自動で行う機能です。 例えば、あるフォームに登録してくれた人にメールを送ったり、そのメールを開封してくれた人には追加でお礼のメールを送ったり、そういった一連の顧客対応を顧客一人ひとりの行動に応じて自動で行う機能です。 これらのことは、既存のメール配信機能を組み合わせればできることもありますが、シナリオ機能には次のようなメリットがあります。 メール配信や開封による分岐などを画面上で直感的に設計できる レポート画面で顧客の行動履歴を視覚的に確認できる これにより、顧客の行動に合わせたコミュニケーションをより簡単に行うことができます。 2020年9月30日(水)までの期間限定で、シナリオ機能を活用した無料のゲーミングコンテンツ「LOVE×CRM ~シナリオをあなたが紡ぐ恋愛シミュレーション~」を公開しています。 気軽にシナリオ機能を体験できますので、ぜひご参加ください。 プレスリリースはこちら。 開発で工夫したところ ここからは、シナリオ機能の開発に携わった一人の開発者として、工夫した点やもっと工夫できたんじゃないかと反省している点を紹介します。 OpenAPI Specification の導入 シナリオ機能の開発とそれまでの開発とで大きく異なる点は、フロントエンド開発チームとバックエンド開発チームのコミュニケーション方法です。 コロナによる強制リモートワークの開始に伴い、フロントエンドとバックエンドのインタフェースの調整に OpenAPI Specification を使うようになりました。 シナリオ機能の開発が本格的にスタートしたのは今年の 2, 3 月あたりからです。 当社では、その頃にはすでにコロナ対策としてリモートワークへの移行が始まっていました。 働く環境の変化に合わせて、コミュニケーション手段もこれまでと異なる方法を用いるようになりました。 その一つとして新しく導入したコミュニケーション手段が、OpenAPI Specification に基づく API 仕様の文書化です。 これまで当社では、担当者同士が口頭で決めた仕様を相談し、API のリクエストとレスポンスを具体的な curl のリクエストや JSON ファイルなどで決め、必要に応じてチーム内で共有していくスタイルでフロントエンドとバックエンドの開発者がコミュニケーションを取っていました。 開発途中で仕様変更があったため一部のリクエスト内容が変更されていたり、レスポンスは最初に決めた形と同じ形だが想定とは違うデータが入っていたりなど、実際にフロントエンドとバックエンドを結合させたときに想定外の事態が発生することが多々ありました。 これまでのように、お互いの顔が見える状態で働いている場合であれば、細かい仕様の確認や調整など即座に行える環境だったので大きな問題はなかったのですが、リモートワークが始まってからはそうもいきません。 そこで、フロントエンドとバックエンドの認識齟齬をなくし、リクエストやレスポンスの詳細を都度確認し合う必要をなくすため OpenAPI Specification を使って仕様を共有することにしました。 OpenAPI Specification を使えば、レスポンスの項目ごとにそれぞれの説明を書くことができますし、ツールを使ってコードを自動生成することでリクエストとレスポンスの形を確実に仕様に合わせることができます。 それにより、不必要なコミュニケーションを減らしつつ、正確に仕様を共有できるようになりました。 シナリオツリーのデータ構造 シナリオを表現するツリー構造の実装については、今回採用した実装方法以外にも選択可能な実装方法があったのではないと思っています。 現状、お客様に使っていただくには支障はない部分ですが、個人的に反省している点を書いておきたいと思います。 シナリオはステップ(「メールを配信するステップ」や「開封 / 未開封の分岐ステップ」など)をツリー状につなぎ合わせて作成します。 シナリオのツリー構造を DB に保存するのですが、各ステップにその親ステップの ID を持つという表現方法を採用しました。 この手法は隣接リストというデータ構造で、構造がシンプルなためわかりやすい、というメリットがあります。 過去に似たような設計でツリー構造を表現して問題なく実装できていた経験から、今回もこの設計を採用しました。 しかし、その時に扱っていたデータは最大階層数に制限があり、また、データは参照用途でのみ使用されツリーの構造を更新することはありませんでした。 今回のシナリオ機能ではユーザが GUI で直感的にシナリオを構成できることがウリのひとつです。 階層の最大値は設けられていませんし、シナリオツリーのどこからでもステップの追加・削除が行えます。 頻繁にツリーのデータが修正される今回のケースでは、隣接リストを使うとツリー構造の操作に関するコードが多く複雑になってしまいます。 別のデータ構造を採用していればすっきりしたコードにできたのでは、と思っています。 youtu.be シナリオの分岐設定をする際のSynergy!管理画面 まとめ 本記事では、7月にリリースしたシナリオ機能について、開発者の立場から振り返り工夫できたと思うところや反省点を紹介しました。 OpenAPI Specification の導入は、口頭での仕様共有に限界を感じ始めていたタイミングだったこともあり、このタイミングで導入できて良かったんじゃないかと思っています。 今後の開発でも、継続して使っていきたいです。 一方、ツリー構造のデータ設計については、改善の余地があると思っています。 シナリオ機能の開発が終盤になるについて、今回採用した実装方法以外の方法を採用したほうが良かったんじゃないかと考えるようになりました。 そんなことを考えるようになりながらリリースまであと1ヶ月ほどとなった頃に、技術的負債に関する翻訳記事が公開されました。 t-wada のブログ:【翻訳】技術的負債という概念の生みの親 Ward Cunningham 自身による説明 リンクの記事では技術的負債という言葉について、言葉の生みの親である Ward Cunningham が、一般に理解されている意味と本人が表現したかった意味との違いについて述べています。 ブログの著者である t-wada さんがうまくまとめている箇所があるので引用します。 Ward の言う負債の悪影響とは開発と共に得られていく知識、理解と目の前のシステムとの乖離が引き起こす生産性低下のことであり、(中略)Ward にとって負債の返済手段はリファクタリングであり、リファクタリングの目的は自分たちのドメイン理解と現時点のプログラムの乖離の解消です。 今回のツリー構造のデータ操作が煩雑になってしまった原因のひとつに、私のシナリオ機能への理解の不完全さがあったと思っています。 この記事を読んだとき、まさに現在のコードこそが技術的負債となっている状態なのだということがよくわかりました。 それと同時に、今後シナリオ機能を強化していく際にリファクタリングをしていく中で、そのときの自分のシナリオ機能への理解を最大限コードに反映させるよう努力すればよいのだと、今回の反省を今後に活かせる確信のようなものを得られました。 なかなか盛りだくさんでリリース直前まで忙しかった思い出が残るシナリオ機能の開発ですが、私にとっては多くを学ばせてもらった貴重なリリースでした。