Living Computer Museum

f:id:takoratta:20181022073809j:plain

シアトルのセーフコ・フィールド近くにLiving Computer Museumという博物館がある。1960年代から今に至るまでのコンピューター技術をハンズオンで体験できる施設で、つい先日亡くなったPaul Allenが設立したものだ。

コンピューターの歴史を知ることができると言えば、シリコンバレーにあるComputer History Museumが良く知られているが、このLiving Computer Museum(正式名称は、Living Computer Museum + Labsで略して、LCM+Lと呼ばれるようだ)もその内容は引けを取らなかった。

takoratta.hatenablog.com

1階は今日の技術を中心に、2階はメインフレーム時代から今に至るまでを展示。Computer Hisotory Museumとの大きな違いは、こちらは実際に触れるものが多数あること。

例えば、パンチカードを自分で作ってみることもできる。

f:id:takoratta:20181022072612p:plain

(動画はこちら

で、出来上がったのが、これ。

f:id:takoratta:20181022072750j:plain

サンノゼThe Techという体験しながら技術を学べる施設があるが、LCM+LはComputer History MuseumとThe Techのコンピューター技術の部分を融合した感じだ。

1階で体験できるものには、VR、AI、自動運転*1、そしてちょうど70年代後半から80年代にかけて、高校のコンピュータークラブがあったらこんな感じだろうなというのを再現した教室など。

2階には、ミニコンからパソコン、そしてPDAまで展示*2され、そして別室にメインフレームが鎮座。ちょうど80年代や90年代の「電算室」がそうであったように、エアコンが効いた部屋に集約されている*3

シアトルには、AmazonMicrosoft訪問で訪れる人も多いと思うが、その途中にでも是非寄って見て欲しい。

RIP Paul Allen

f:id:takoratta:20181019155633j:plain

*1:シミュレーターがあるのだが、酔ってしまい、最後まで体験はできなかった

*2:触れるものも多い。パンチカードもその1つ

*3:昔はデータセンターという別の建物よりも同じ建物内に部屋が確保されていたことがほとんど

エンジニアのためのマネジメントキャリアパス ―テックリードからCTOまでマネジメントスキル向上ガイド

オライリーから本日出版された「エンジニアのためのマネジメントキャリアパス ―テックリードからCTOまでマネジメントスキル向上ガイド」はエンジニアリングマネジメントを考える人には必読の書だ。

 

エンジニアリングマネジメントを考える人とは、今すでにエンジニアの上司である人やエンジニアリング組織の長である人はもとより、人事上の上司ではないが、後輩などの面倒を見る立場の人や開発において技術的にリードするような人、そして漠然と将来のキャリアパスとしてマネジメントを考えている人までを含む。さらに言うならば、技術系でなくても、自社の技術組織の戦略を考える立場である人も読むべきであろう。

目次を見るとわかるが、本書はマネジメントされる立場のエンジニアから話は始まる。そしてメンタリングする立場になったとき、次にテックリードになったときと、まさにキャリアパスを1つずつ登っていくのに際しての心構えと具体的なスキルについて解説されている。ここまで網羅された本は米国であっても多くない。だからこそ、米国でも高く評価されている。

さて、日本だけでなく、世界的にエンジニアはマネジメントロールを嫌う。日本だけでないとは言え、日本ではその傾向が特に強いように私は思う。その理由はいくつかあるが、1) 過去の上司がろくでもない人だった(ので、そんな人に自分はなりたくない)、2) マネジメントについた先輩が幸せそうに見えない(ので、そんな立場には自分はなりたくない)、3) マネジメントとは具体的に何をすればわからない というのが主なところだろう。

1) は問題外で、組織としてはそのようなろくでもない上司は排除せねばならない。これは技術系に限らない。

2) はマネジメントとしての仕事の多くが技術に直接関係ない仕事であり、多くは事業(ビジネス)サイドとの折衝などが中心であり、そこには板挟みとしての苦悩がある。これでは楽しいわけがない。企業としては、本当に技術的に優れた人にその仕事をやらせる必要があるかを考えねばならない。

3) は武器もなしにいきなり戦場に出ろと言われているのに等しいのだから、武器、すなわちマネジメントスキルを与えなければいけない。

見ればわかるが、1) は問題外として、2) と 3) は企業(組織)が自らの努力により改善可能なものだ。エンジニアリング強化に組織力強化が必要と認識し、そこに投資をするつもりであるならば、エンジニアリングマネージャーという職種を魅力あるものにしなければいけない。実際、本書でも書かれているが、エンジニアリングマネージャーは醍醐味のある魅力ある職種である*1。だが、そこに地図もコンパスも無ければ、その道程は険しいものとなろう。本書はエンジニアリングマネジメントを志す人のサバイバルガイドと言っても過言ではない。例えば、マネージャーになると、当たり前のように、1on1をするように言われるが、1on1で何を話せば良いかわからない人も多いだろう。実は、1on1というのは1つしか形式が無いわけではない。本書では複数の形式を提示し、読者が状況に応じて選べるようにしている。かように、極めて実践的な内容が含まれている。

実は、本書のまえがきを書くという名誉ある仕事を任された。そこにも書いたが、ここで書かれているエンジニアリングマネージャーはスーパーマンかと思うような人である*2。大変な仕事だが、だからこそ今までマネジメントを毛嫌いしていた人であっても、マネジメントに魅力を感じるであろう。技術を通じて製品やサービスを作り、人や社会に変革をもたらすというのがエンジニアの夢ならば、それに加えて、そのようなエンジニアが成長し、高い意欲で開発を続ける組織を作るというのが加わったのが、エンジニアマネージャーなのだ。人嫌いの人には向かないが、組織作りもエンジニアリングと共通点は多い。創意工夫次第で1人では出来なかったことが実現されていく様子を見るのは純粋な開発にも負けないくらい魅力的だ。スーパーマンと言ったのは、どのように地位が高くなろうと、自ら手を動かし技術に触る機会を持つべきであると一環して言われているように、高い技術力と組織作りの両方が要求されるからであるが、技術をやり続けられるならばと魅力を感じる人も多いであろう。

日本では、未だにある程度まで昇進すると、強制的にマネジメントロールにつかなければならないという旧態依然とした人事制度にとらわれている企業も多い。これは明らかに改めるべきものであるが、一方で、スペシャリスト(英語ではIndividual Contributorと呼ぶことが多い)としてのキャリアパスが用意されている場合であっても、もしくはそのようはキャリアパスを企業に要求する場合にしても、スペシャリストとしての実績がマネジメントのキャリアパスに進んだ人間と比するものにするには何をしなければならないかは考えなければならない。マネジメントの能力や評価は、そこまで単純ではないにしろ、組織の規模に比例するところは大きい。10人より50人、そして100人とモチベーション高く働くエンジニアを束ねていたならば、その規模だけでも功績は認められよう。スペシャリストは、100人の組織の長となっている人間に匹敵するには、どのような功績を残すことがふさわしいのか、自らも考えてみるべきである。マネジメントに進むもの、マネジメント以外での貢献を選ぶもの、多様なキャリアパスを用意することが組織や企業を強くしていくが、そのどちらも自らの役割を見つめ直すことが必要であろう。

本書がエンジニアリングマネジメントはもとより、スペシャリストの道を進むものにとっても、自分の役割を改めて考えるきっかけになればと思う。

 

*1:もちろん向き不向きはある

*2:だからこそ、私はまえがきの中で、「自分のことは棚にあげるが」と書かせて貰った

Watson Conversation APIでBotを作るための記事

Node.jsベースのBotkitでBotを開発、IBM Cloudで運用しているのだが、Nodeのブロックング/ノンブロッキングとBotkitの非同期処理の扱いが良くわからず、細かい所の制御が出来ずにいる。bot.replyとか非同期で動くのだが、強制的に順序を合わせることが出来ずにいたり… 自分の理解不足を感じる。

ただ、簡単なことをやるには簡単だし、見た目(返信の順序とか)を気にしなければ良いと言えば良いので、自分や小さいコミュニティ向けのBot開発には悪くない選択ではないか。HubotやRubotyも昔使ってみたことがあるが、CoffeeScriptRubyじゃなく、JavaScriptでやりたいという強い意志がある場合には特に良い。

これに味をしめて、もう少しちゃんとした会話が出来るBotを作ってみようと考えているが、同じIBM Cloudということで、Watson Conversation APIが気になっている。

www.ibm.com

これは

  • Intents: 会話の中身
  • Entities: 会話構成要素となる単語など
  • Dialog: 会話のフロー

を定義することで、ノンプログラミングでチャットのコア部分が出来るという優れもの。しかも、Watsonなので、Entitiesなどは勝手に学習して賢くなっていってくれる。GoogleのDialogflow(旧api.ai)もそうだが、こんな簡単にChat Botが出来るなんて、なんて良い世の中になったもんだ。

ということで、次はWatson Conversation APIを使ってみようと考えているのだが、そんな時に秀逸な紹介記事が出ていることに気づいた。

ThinkWatsonというIBMのオウンドメディアでの記事だが、次の4記事が公開されている。

www.ibm.com

www.ibm.com

www.ibm.com

www.ibm.com

この4記事で、Conversation APIを用いたチャットの設計・開発、Node-REDを使って、これまたノンプログラミングでSlackと連携、API化してWordPressに組み込むことまで出来る。素晴らしい。

5年くらい前に、もう無くなってしまったYahoo! PipesTwitterBotを作ったことがあったが、その時はなんだかんだで結構たいへんだった。良い世の中になったもんだ。

Botにリマインドしてもらう

takoratta.hatenablog.com

昨日書いたBotkitを使ったBotIBM Cloudライトアカウントを使って動かしているが、このIBM Cloudライトアカウントは

  • 10日間 開発なしでアプリを自動停止
  • 30日間 活動なしでサービスの自動削除

という制限がある。Botなので、ずっと動かし続けているから、後者は良いとして前者については、開発をし続けるしかない

忘れないようにリマインダーとして、Slackにメッセージを送って貰うようにした。Botkitとnode-cronを用いた。

const = require('cron'); して、startRTM()のところを次のように変えた。

controller.spawn({
    token: process.env.token
}).startRTM((err, bot, payload) => {
    if (err) {
        throw new Error(err);
    }
    new cron.CronJob({
        cronTime: '0 0 9 17 0 *', // 1/17の9時に起動
        onTick: () => {
            bot.say({
                channel: 'takoratta_test', // チャンネル名
                text: 'IBM Cloudライトアカウントを使っているので開発し続けないとサービスが停止します'
            });
        },
        start: true,
        timeZone: 'Asia/Tokyo'
    });
});

cronTimeのところはサービスが停止する数日前にしておけば良い。本当は更新期限をIBM Cloud側から取得したかったが、どうすれば良いかわからないので、ハードコードとしてある。ソースコードを変更後に、cf pushするときに、ここも更新しておけば良い。ここだけ更新するだけで開発したことになるだろうとも思うし、こんなリマインダー送るようなことしなくても、cf pushをローカルマシンでCronしておけば良いではないかというチートも考えつくがやっちゃいけない。

ところで、Cronの時間設定のフォーマットはいつも間違える。今回も月が0から始まることを忘れていた。ここは、cronTime: 'sec min hour day month(0~11) week'となっている。

BotにSlackのプライベートチャンネルリストを教えてもらう(Node.jsのBotkitとIBM Cloudを用いた対応)

課題

自分が属している団体のSlackで運営スタッフだけのプライベートチャンネルがいくつかあるが、プライベートチャンネルのため、どのような運営用チャンネルが存在しているかわからなくなるという問題がある。一度誤って抜けてしまうと、誰かに頼まないと戻れなくなるのだが、誰に頼んで良いのかもわからなくなることもある。

この問題を解決するためにBotを開発した。ただし、プライベートチャンネルのため、Botもそのプライベートチャンネルに所属していないとならない。

運用イメージ

  • 運営用プライベートチャンネルはBotをメンバーとして登録する
  • 運営スタッフはそのBotにメンションかDMかで話しかけることにより、Botが属しているプライベートチャンネルの全リストをその作成者名とともに取得できる
  • 自分が入るべきプライベートチャンネルがあったならば、その作成者にコンタクトし、招待してもらう。ここにはBotは介在しない

Botの開発

BotはNode.jsで開発し、IBM Cloudで運用することにした。

Botkit

Node.jsで作られたBotkitを利用した。Slackとの連携も極めて簡単。

使ったものは、

ソースコードは以下。

const Botkit = require('botkit');
const async = require('async');

if (!process.env.token) {
  console.log('Error: Missing API Token');
  process.exit(1);
}

const controller = Botkit.slackbot({
    debug: false,
    retry: Infinity // 常駐させるため
});

controller.spawn({
    token: process.env.token
}).startRTM((err, bot, payload) => {
    if (err) {
        throw new Error(err);
    }
});

// pubchlistと聞かれたら
controller.hears('pubchlist',['direct_message','direct_mention','mention'],(bot,message) => {
    bot.api.channels.list({}, (err, res) => {
        async.each(res.channels, (channel, callback) => {
            if(!channel.is_archived){
                bot.api.users.info({user:channel.creator}, (err,res) => {
                bot.reply(message, channel.name + ' created by ' + res['user']['name']);
                })
            }
        })
    })
});

// prchlistと聞かれたら
controller.hears('prchlist',['direct_message','direct_mention','mention'], (bot,message) => {
    bot.api.groups.list({}, (err, res) => {
        async.each(res.groups, (groups, callback) => {
            if(!groups.is_archived){
                bot.api.users.info({user:groups.creator}, (err,res) => {
                bot.reply(message, groups.name + ' created by ' + res['user']['name']);
                })
            }
        })
    })
});

// それ以外を聞かれたら
controller.hears(['(.*)'], ['direct_message','direct_mention','mention'], (bot,message) => {
    bot.reply(message, 'Usage: type prchlist to get private channels list OR publist to get public channels');
});

Botに話しかけられるコマンドは2つだけ。

  • pubchlist: パブリックチャンネルの一覧をその作成者とともに表示
  • prchlist: Botが所属しているプライベートチャンネルの一覧をその作成者とともに表示

【追記】Admin権限を持つ人だけがプライベートチャンネルリストを見れるようにする

プライベートチャンネルリストが見れる人をAdmin権限を持つ人だけに絞るには、prchlisthearsしている部分を以下のように変更する。

// prchlistと聞かれたら
controller.hears('test',['direct_message','direct_mention','mention'], (bot,message) => {
    var currentUser; 
    bot.api.users.info({user:message.user},function(err,response) {
        if (err) {
            throw new Error(err);
        }
        currentUser = response['user'];
        if (!currentUser['is_admin']) {
            bot.reply(message, 'Only Admin can see the list of private channels');
        }
        bot.api.groups.list({}, (err, res) => {
            async.each(res.groups, (groups, callback) => {
                if(!groups.is_archived){
                    bot.api.users.info({user:groups.creator}, (err,res) => {
                    bot.reply(message, groups.name + ' created by ' + res['user']['name']);
                    })
                }
            })
        })        
    })
});

Slack APIusers.infoでBotkitから代えるmessage.user情報を取得し、Admin権限があるかどうかを確認している。

Slack側の準備

プログラムの中でSlackのBot用のAPI Tokenを利用している。これは環境変数で引き渡すことになる。

Sign in | Slack にアクセスし、API Tokenを発行する。

f:id:takoratta:20180109155043p:plain

ローカル環境での動作

$ token=<API Token> node app.js

これでSlack側でBotにDMするか、Inviteしたチャンネルでメンションし、話しかけてテストできる。

Botの運用

BotはNode.jsが動かせる環境ならなんでも良かったのだが、IBM Cloudライトアカウントの無料枠の範囲で十分そうだったので、それを使った。

$ cf api https://api.ng.bluemix.net/
$ cf login
$ cf push itdartbot --no-route -u none -m 256M
$ cf cf set-env itdartbot token <api token>
$ cf restage itdartbot

cf pushでの--no-route-u noneはワーカーとして動作させ、Health Check不要のため。また、-m 256MIBM Cloudライトアカウントではメモリが256MBに制限されているため。

参考にしたもの