鬱になったSEの憂鬱

仕事関係、プライベート、技術情報とかを書いていきます。(たぶん)

【Dialog Flow】 Access Tokenの作り方。

DialogFlowの調教は簡単なので他にまかせる。

 

DialogFlowはWebインターフェースが「Web Demo」しかない。
Demoって書いてある。ようはDemo用なのだ。


しかもスマホからだと送信ボタンがないとちょっと使い勝手が悪い。
なのでオリジナルUIからAPI経由でリクエストし、得たレスポンスをそこに描画する形にしたい。


今回はそのAPIを実行するためのAccess Tokenの作り方でちょっと迷ったので書いてく。


[本家のマニュアル]
https://dialogflow.com/docs/reference/v2-auth-setup

 

マニュアルにあるように、Google Cloud Platform上でDialogFlow用のユーザを登録しないといけない。

実はAWSユーザで、AWSにも似たようなものがあるんだが従量課金がいきなり始まるので
あえてDialogFlowを使いたい要求がある。

 

DialogFlowはFreeプランのままであれば請求がないはず。
さらに支払情報を入れてなくてもGCPのDialogFlow用アカウント作成は行うことができるので
請求が発生することはないだろう。


まず、[本家のマニュアル]->「Getting the Service Account key」に従って、ロールを作成し、json形式の鍵を入手する。

鍵が入手出来たら、[本家のマニュアル]->「Using the key」にあるように、Cloud SDKを使ってAccess Tokenを生成する。

どこかサーバーか、自分のマシンにCloud SDKを入れて発行することになる。
私はAWSで使いたいのでEC2に入れることになる。


もっというと、このAccess Tokenは一定の時間毎に無効化される。
なので、DialogFlowのAPIへリクエストするサーバーにインストールをしておいて、リクエストごとにAccess TokenをSDKから取得してAPIを実行することになる。

 

Linux(Cent OS)だとYumで入れられる。
https://cloud.google.com/sdk/docs/quickstart-redhat-centos
[SDK の初期化]の最後までやり終えること。

 

その後、一旦SDKを終了(Ctrl +C)
次に、
export GOOGLE_APPLICATION_CREDENTIALS=/path/to/json/key.json
GCPのロール作成からダウンロードしたjson形式の鍵へのパスを設定)

をする。

 

その後、

gcloud auth application-default print-access-token

と実行すればAccess Tokenが画面に表示される。
パスが合っていればエラーなく表示されるだろう。

 

実は、yumでのCloud SDKのインストールに戸惑った。
何故かPython2.7を入れているのにPython 2.6を参照してしまい、依存性エラーとなりインストールができない。

調べていると同じ事に迷っている人がいた。
http://jhurani.com/linux/2018/07/30/GCSDK-on-centos6.html

英語だが、言われたようにやっていくとインストールできそう。


[追記] Python2.7の追加
 

sudo yum install python27

1)
/etc/alternatives/python
の向き先を
/usr/bin/python2.7
に変更

2)
/usr/bin/python2
の向き先を
/usr/bin/python2.7
に変更

 が必要

 

 

次はDialogFlow用のSDKを使わないでPHPでリクエストする方法を書こうと思う。

 

 

【DialogFlow】ウェブチャットボット作成

調べていたら、Googleが買収したAIチャットボットDialogFlowと言うのを見つけた。
2016、17年くらいからあるらしい。


私めっちゃ遅れてるやん....in2019

DeepLearningの中身の勉強はしているんだけど実際にこんなサービスがもうあるんだってことを知らなかった。
木を見て森を見ずと言うか、なんつーか。。。

気を取り直して、DialogFlowでチャットボットを作ろうと思う。


[まず感想]

  • DialogFlowは、DeepLearningを用いて質問文の表記・表現ゆれを吸収してくれたダイヤログチャートみたいな感じ。オリジナルな概念は教えてあげないといけない。
    (”色”という概念は一般的だけど、例えば”社員”という概念ならば会社により概念が違うので、社員全員の名前を教えてあげないといけない。)
  • 「こう聞かれたらこう返す」という単調な仕組みが大枠。回答内容を自動生成してくれる、とかはなく、全パターン自分で用意する。
  • じゃあどこがDeepLearningなのかというと、たぶんだけど、「今日」とか「東京」をちゃんと「date:2019-01-25」「place:東京」といった感じに概念を拾ってくれるところかと思ってる。
  • 音声にも対応している。
  • Webインターフェースはデモしかない。(APIが使えるからそっちで作るよ!)
  • DialogFlowは無料で使えるけど利用制限があるよ。(ぐぐってみてね)


ということで、作って遊ぼう。

  1. DialogFlowのAgentを作成
  2. Intentってなに
  3. Entityってなに
  4. Contextってなに
  5. Fullfilmentってなに
  6. 会話して情報の入力を促す方法(Parameter)


1.DialogFlowのAgentを作成
ここはぐぐってもらっていいですか。

 

2.Intentってなに
Intent:英語で意図、目的という意味。


感覚的には、「こう聞かれたときにこう返す」の1パターンがIntent。
「Training Phrase」に例えば「ハンバーグ食べたい」、「Response」に「そうだね」と入れて学習させたら、「ハンバーグ食べたい」と言われた時には「そうだね」と返答するようになる。(さくっとできる)


他にも「こう言われたときに「そうだね」」と返したい入力がある場合は、さらに「Training Phrase」にパターンを入れていく。
これが1Intentだと解釈している。

 

こんなIntentには「食べ物に相槌を打つ」とかタイトルを付けとく。

 

3.Entityってなに
最初からEntityを触る/理解する必要はない。


例えばさっきの「そうだね」と返答させたい入力を「"<私が好きな食べ物全般>食べたい"」にまで拡張したい場合、Training Phraseに食べたいものを思いつくだけ
文章を作成して設定すればいい。

  • 「ハンバーグ食べたい」「焼き魚食べたい」「ラーメン食べたい」


とすると、私が食べたいものを言えば「そうだね」と言ってくれるようになる。登録していない嫌いな食べ物を言っても反応しない。

 

ただ、食べたいものがどんどん増えていくと、入力がめんどうくさい。
ここで、「"<私が好きな食べ物全般>食べたい"」という<私が好きな食べ物全般>の概念(単語の一覧みたいなもの)を作っておいてそちらを参照してくれた方が楽である。


それがEntityである。

<私が好きな食べ物全般>として「ハンバーグ」「焼き魚」「ラーメン」とEntityに作成、Training Phraseに設定すれば、「焼き魚食べたい」と入れると「そうだね」と返してくれるようになる。
好きな食べ物が増えた場合、Entityの編集を行えばいい。

 

Training PhraseからEntityを紐づけるには、なんでもいいので1つTraining Phraseを入れて(例えば:「ラーメン食べたい」)、"ラーメン"の部分を文字列選択するとEntityの一覧が出てくるからさっき作ったEntity<私が好きな食べ物全般>を選択してあげる。
そうすると、「XXXX食べたい」のXXXX部分には<私が好きな食べ物全般>が入ってくるんだな、とDialogFlowは解釈してくれる。
「スズメ食べたい」と言っても、スズメは<私が好きな食べ物全般>に無いので「そうだね」とは言ってくれない。

 

4.Contextってなに
DialogFlowのContextは、フローチャートのいわゆる線の部分に”名前”を付けたようなものである。

 

例えば友達に「ラーメン食べたい」と言ったら「そうだね」と言われ、「君はそうだねとしか言わないね」と言ったら「本当にラーメン食べたいと思ってるよ」と言われたとする。


この返答は「ラーメン食べたい」、「そうだね」という会話を先にしないといけない。していない場合はこの会話の「フロー」に入ってはいけない。
なんの食べ物の話をしたかわからないからね。
この「フロー」がいわゆる文脈でありContextである。

 

「「<私が好きな食べ物全般>食べたい」と言ったら「そうだね」」というContextを”Food-Talk”としよう。
Output Contextに”Food-Talk”と入れると、このIntentが発生した時点で裏で「”Food-Talk”っていう会話をした」という状態フラグが立つようになる。

 

さらに、「「君はそうだねとしか言わないね」と言ったら「本当にラーメン食べたいと思ってるよ」」と返すIntentのInput Contextに”Food-Talk”と入れると、
「”Food-Talk”っていう会話をした時だけこのIntentが発生するよ」と設定ができるのである。

 

これがContextであり、名前は自由につけてよい。


5.Fullfilmentってなに
ここは他のシステムとの連携のための設定になる。


とある会話が終わった時点での会話の流れをログとしてどこかにPOSTしたいとか、別サービスにリクエストすることで動的な返答を実現したい場合など、
そういう場合に動作を設定するところである。

なんか場合によっては金払わないといけないらしいので割愛。

 

6.会話して情報の入力を促す方法(Parameter)
この「そうだね」ボットは食べたいものに対して「そうだね」と同意してあげることを生きがいとしている。
何か話しかけられる時があれば、相手の「食べたい」に「そうだね」と言ってあげたいのだ。

 

だから何か話しかけられたら「何が食べたい?」って聞きだしてほしい。

 

それがParameterセクションで設定できる。

最初の会話に<私が好きな食べ物全般>が入っていなかったら、言ってくれるまで「何が食べたい?」とぶっきらぼうに質問しまくらせよう。

  • ParameterのREQUIREDにチェックを入れる。
  • nameは良くわかってないんだごめん。
  • Entityには<私が好きな食べ物全般>を入れる。
  • Valueはその<私が好きな食べ物全般>をResponseの文章内に引き継ぐときの参照名をいれる。
    例えばfavoriteFoodとすれば「本当に$favoriteFood食べたいと思ってるよ」と動的に返答できる。
  • Promptsがまさに、<私が好きな食べ物全般>を聞き出すための文章をいれるところである。
    「ところで君は何が食べたい?」と入れよう。

 

これがDialogFlowの個人的な解釈/メモである。
画面が無くてごめん。

 

 

次はV2のAccess Tokenの作り方を書こうと思う

 

使えない問い合わせのBBAをAIで置き換える。


問い合わせ業務というのは、開発者でもできると私は思っています。
でも、開発者がやらないほうが良いとも思います。
何故なら開発者はプログラムを書いたり、システムを構築してこそ企業に対する成果を最大限にすることができるからです。
(そりゃそうだそうやって雇われてそうやって査定されるんだから)

さて、問合せ担当というのが私の会社に居るんですが、その窓口さんにはシステムの問い合わせ・不具合の報告、たまにはクレームが
届くことがあります。
問合せ担当たるもの、その場で解決できることは解決するし、さらにその場で解決できそうなことがあればそれをノウハウとして蓄積して行って欲しい。
一言でいうとシステムへの問い合わせをできる限り少なくしてほしいわけです。

問い合わせ担当というのは、居るのであれば開発者が開発に集中できる環境を整えるために居るのだと私は考えています。
それに、問合せ担当がいなくても対応してくれと言われれば対応できます。究極居なくてもなんとかなると思います。

弊社にも問合せ担当としてお給料を貰っているBBAが入らっしゃいます。
入らっしゃいますが、まるで学習しない。

同じ問い合わせを何回もこちらに聞いてくる。
不具合があれば環境情報を聞いてくれと言っていて、環境情報と言っても例えばスマホの種類・バージョン・ブラウザの種類。
決まり切っていることであるにもかかわらず添えられてこない。
挙句の果てにはお客さんが何を言おうとしているのかわからないと聞きに来る。(そこを詰めるのがお前の仕事だバ〇)

結局、聞きなおしてくれとお願いするか、直接私が客とやりとりする。
そんで要件を聞いてみるとお問合せ担当が過去に対応”できている”問い合わせと一緒だったりする。

お前は何のためにそこにいるんだBBA。
金の無駄なんだよ。


挙句の果てにお問合せの一部を、これは私の仕事じゃないとかほざいて丸投げしてくる。


お前がプログラム実装手伝ってくれたことあるか?
なんで俺がお前の仕事を手伝うだけで、お前は俺の実装を手伝ってくれないんだ?
俺の仕事はプログラム書くことなんだけど?
そろそろ滅びてくれない?


まじでこいつと仕事したくない。
お前の仕事俺できるから、辞めて欲しい。
心の底からそう思っている。

 


しかし、攻めあぐねていた。

 


実際に彼女の仕事を私が行うと、少ないプログラマー(弊社1名のみ)がいなくなってしまうので社長は許さないだろう。
ビジネスがインテグレーションをストップしてしまう()

仕方なく悶々とした日々を過ごしていた。


しかし今日私は気づいた。

 


「そうだ、AIで置き換えよう。」

 

今まではシェルスクリプトでメールを全部俺に転送して俺がやり切ってやろうと考えていたが、
今はもうAIの時代!

何故気づかなかったんだ。。。(勉強中なのに

 

ということで、これからは「使えない問い合わせのBBAをAIで置き換える。」と称してチャットボットの作成・育成をつづろうと思います。

頑張ります!!!

 

 

ld: library not found for -lPods clang: error: linker command failed with exit code 1 (use -v to see invocation)

ld: library not found for -lPods
clang: error: linker command failed with exit code 1 (use -v to see invocation)

環境:MacOS
Xcode:たぶん Xcode10

Debugのビルドは成功するが、Archiveがうまくいかない。


一通り試した。

・複数のプロジェクトを使っている場合はxcodeprojじゃなくてxcworkspaceの方を開かないといけない

とか

・General -> Signing を Automatically にせずに個別に指定しろ

とか

・プロジェクトごとのiOS Targetの数値がバラバラになっている

とか。


直んねぇ。


出てくるもの全部やったような気がするが、

直んねぇ。

 

途方に暮れて、ふと考えた。

 

「Debugなら動くんだから、ArchiveとDebugの設定に違いがあるのではないか??」


ここで、メニュー「Product -> Edit Scheme」の「Build Configuration」のところのプルダウンに「Debug」が選択できるのに気づく。
Debugを選択してArchiveすると、Archiveできた。なるほどそうか。
(ちなみに、変更する前はArchiveのBuild ConfigurationはDistributionになっていた。)


しかし、リリース版をDebug設定でコンパイルしてリリースするのはちょっと気持ちが悪い。
なのでひたすらDebug と Archiveで設定の違いがあるところを見つけてはDebugの設定に寄せてArchiveの項目の設定を変え、Archiveができる設定を探すことにした。


...

...


直んねぇ。
ふざけんな。

 

かれこれ3日悩んだ。

 

・Debugだとうまくいく。
・Archiveだとうまくいかない。


libPods.aがちゃんとコンパイルされているのも何度も確認している。


しかし、「library not found for -lPods」....


Archiveエラーのログを見てるとコマンドが出るから、それを実行してみると確かに同じエラーがでる。


とコマンドを見て気づく。

 

... -L/Users/***(PCのユーザ名)***/Library/Developer/Xcode/DerivedData/Build/Intermediates.noindex/ArchiveIntermediates/WordPress/BuildProductsPath/Distribution-iphoneos/ ...

⇒フォルダ:「Distrubution-iphoneos」というところが、debugとarchiveで違いそう。
なるほど、このフォルダにlibPods.aが来てないのか????

 

試しにArchiveのBuild Settingsを「Debug」にして Archive。成功する。

その場合、

... -L/Users/***(PCのユーザ名)***/Library/Developer/Xcode/DerivedData/Build/Intermediates.noindex/ArchiveIntermediates/WordPress/BuildProductsPath/Debug-iphoneos/ ...

ディレクトリ名が変わった。

`ls /Users/***(PCのユーザ名)***/Library/Developer/Xcode/DerivedData/Build/Intermediates.noindex/ArchiveIntermediates/WordPress/BuildProductsPath/Debug-iphoneos/`
とすると、
・libPods.a
がいらっしゃる。

 

次に、ArchiveのBuild Settingsを「Distribution」にして Archive。失敗する。

その場合、

... -L/Users/***(PCのユーザ名)***/Library/Developer/Xcode/DerivedData/Build/Intermediates.noindex/ArchiveIntermediates/WordPress/BuildProductsPath/Distribution-iphoneos/ ...

ディレクトリ名が変わった。

`ls /Users/***(PCのユーザ名)***/Library/Developer/Xcode/DerivedData/Build/Intermediates.noindex/ArchiveIntermediates/WordPress/BuildProductsPath/Distribution-iphoneos/`
とすると、
・libPods.a
ない


そして、なぜか、同一階層に
/Users/***(PCのユーザ名)***/Library/Developer/Xcode/DerivedData/Build/Intermediates.noindex/ArchiveIntermediates/WordPress/BuildProductsPath/Release-iphoneos/

というのがいて、そちらに
・libPods.a
いらっしゃる


んんん??
Podの設定がおかしいのか!

 

ということでDistributionの場合に出力するディレクトリの設定がどうなっているか確かめようとしたら

・Debug
・Release

の行しかない。
メインのプロジェクトにはいた「Distribution」と「Beta」がいない。


ははーーーーーん。

 

PodプロジェクトにはDistribution用の設定がないからRelease用のBuild Settingsで動いていて、メインプロジェクトとPodのコンパイル先が一致しないから「Not Found」なんだ!

 

と、ここで、

「え、じゃあ、ArchiveのBuild SettingsをReleaseにしたら動くとか???」

結果、動いた。

FXXK!!

 

Git管理しててそのままのはずなんだけどなーー

おしまい。

会社辞めようか(50回は考えている)

単体テストを描く時間が工数に入っていないクソ案件で300時間×4ヶ月という致死量の案件を、社長も見てくれているはず!と思い弱音も吐きつつ頑張った結果鬱になり社長は「知らなかった」とかほざき、二週間会社を休み三ヶ月は定時強制帰り、メンタルは弱りまくりでこんなにいろんなものを犠牲にしたにもかかわらず年2万アップとかいう去年よりも低いというクソな昇級を受けた話を意識にしないようにしていたにもかかわらずまた意識してしまった。

 

まだ心の中では終わっていない。

 

そりゃあ外部案件慣れてないから人より時間がかかるのは仕方ないしそこは納得してるけど単体テストコードが無ければ時間も余裕があって無事にこなせたんだよ。

 

この会社じゃあ外部案件はもうやりたくない。いつの間にか命かけさせられて2万かよ。

 

かといってSEとして一丁前になるのがキャリアとして正解かも知れないと思う。

自社案件に戻って、考えないですむ状態になってしまっている。先延ばしだよね。

 

やめよーかな。

11月の分裂は8月の分裂と違うぞ!

いつもソースがなくて申し訳ないと思ってる。

めんどくさい笑

 

https://twitter.com/rbitcoincash/status/915784368290967552

 

これを見る限り、あなたのBTCは、

・3bitなんとかっていうアドレスに送金するとSegwitコインとして扱われる

・逆に送信しない(何もしない)ならばSegwit2xとして扱われる

 

ということだ。

BCHや、今度のBTGのような分裂とは違うぞ!

 

取引所にいる人はどうしたらいいんだろうね(・_・;

八月に、「自分のウォレットに移したほうがいい」って言ってたのはそういうことかな。

きっと取引所などにあると、取引所がどうするかに引きづられそうな気がする。

 

 

そして、Segwit2xが自分は勝つと思う。

Segwit2xはライトニングやサイドチェーンができないと言ってる人がいるけど、2MBならそもそもサイドチェーンに外出しする必要ないでしょ。容量足りるっしょ!

 

一番はBCHに勝ってほしいですが笑

バランスシートはBCH100%です!!

 

2MBより8MB!!