<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0" xmlns:cc="http://cyber.law.harvard.edu/rss/creativeCommonsRssModule.html">
    <channel>
        <title><![CDATA[Stories by Steven Shen on Medium]]></title>
        <description><![CDATA[Stories by Steven Shen on Medium]]></description>
        <link>https://medium.com/@syshen?source=rss-13cbc18d6975------2</link>
        <image>
            <url>https://cdn-images-1.medium.com/fit/c/150/150/1*1gPuI8nbZLm4GQNtrwK6UQ.jpeg</url>
            <title>Stories by Steven Shen on Medium</title>
            <link>https://medium.com/@syshen?source=rss-13cbc18d6975------2</link>
        </image>
        <generator>Medium</generator>
        <lastBuildDate>Sat, 14 Nov 2026 16:44:17 GMT</lastBuildDate>
        <atom:link href="https://medium.com/@syshen/feed" rel="self" type="application/rss+xml"/>
        <webMaster><![CDATA[yourfriends@medium.com]]></webMaster>
        <atom:link href="http://medium.superfeedr.com/" rel="hub"/>
        <item>
            <title><![CDATA[用 n8n 做 Status Page 監控]]></title>
            <link>https://syshen.medium.com/%E7%94%A8-n8n-%E5%81%9A-status-page-%E7%9B%A3%E6%8E%A7-d33e4dd37606?source=rss-13cbc18d6975------2</link>
            <guid isPermaLink="false">https://medium.com/p/d33e4dd37606</guid>
            <dc:creator><![CDATA[Steven Shen]]></dc:creator>
            <pubDate>Fri, 09 Aug 2024 02:50:40 GMT</pubDate>
            <atom:updated>2024-08-09T02:50:40.404Z</atom:updated>
            <content:encoded><![CDATA[<p>大部分的 SaaS 服務都有 Status Page，也都長得差不多，我用 n8n 搭配 GPT 來做 Status Page 的監控，當有發現 Outage 時，通知到 Slack，這篇簡單講述一下做法。</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*EVRM3SSLJfaTRwldh14gXw.png" /></figure><p>概念很簡單</p><ol><li>設定一個 Schedule trigger node，固定每幾分鐘跑一次</li><li>加上一個 HTTP Node，去抓 Status Page，例如我這裡想抓 Anthropic 的 <a href="https://status.anthropic.com/">Status Page</a></li><li>然後將結果丟給一個 HTML node 去剪出我需要的部分內容就好。因為後面會用 ChatGPT 去分析這個網頁目前是否有 Outage，如果我將整個 HTML source 丟進去，可能會花掉不少 token 費用，所以我先剪出部分內容就好。以這個例子，我用 CSS selector 來做篩選</li></ol><figure><img alt="" src="https://cdn-images-1.medium.com/max/703/1*yrEuHXnenpmRxvsTkq9slA.png" /><figcaption>使用 .unresolved-incidents 這個 css class 來篩選部分內容</figcaption></figure><p>4. 接下來是將篩選出來的結果丟給 ChatGPT 去判斷</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/563/1*8WkLDWMXCIFU9HNfD1IdYQ.png" /></figure><p>我使用 4o，並強制要求 JSON 格式輸出，底下是我使用的 Prompt</p><pre>底下是某個 API 服務的 status page HTML 程式碼，請幫我分析一下目前這個服務是否有 outage<br> {{ $json[&#39;&#39;] || &#39;&#39; }}<br><br>請以底下 JSON 格式回傳:<br><br>{<br>  outage: true,<br>  status: &#39;status text&#39;<br>}<br><br>如果沒有提供 HTML ，則代表沒有 Outage，回傳:<br><br>{<br>  outage: false,<br>  status: &#39;&#39;<br>}</pre><p>5. 最後，用一個 IF node 去判斷 outage 欄位是否為 true ，如果是 true 就串到 Slack node 去通知 Slack channel</p><p>此外，我想做個改良，當從有 Outage 到 Outage 結束時，我也想做個通知，這樣才能確定 Outage 是否已經結束了，所以我必須把狀態儲存下來。</p><p>但，n8n 是 stateless 的，如果要儲存狀態，需要安裝一個額外的套件。</p><p>如果你是自己架設的 n8n server，你可以安裝一個 community node: <a href="https://github.com/telepilotco/n8n-nodes-kv-storage"><strong>@telepilotco/n8n-nodes-kv-storage</strong></a></p><p>這是一個在記憶體的 Key Value Storage，所以 n8n 重跑後就沒有了，但沒關係，夠我們使用了。我們將 outage 的狀態儲存在一個 Key anthropic_status 當中。</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/566/1*8GiNITmWssm1P6DNQUn58A.png" /></figure><p>在第四步驟的同時，讀出 anthropic_status 目前的值，然後將 ChatGPT 的結果結合，並加上一個 Code Node，來做判斷:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/711/1*lNTGbNXgQBe_eN_4w3y0Xg.png" /></figure><p>程式碼:</p><pre>let notify = false;<br>let color = &#39;:large_green_circle:&#39;;<br>let outage = false;<br>let status = &#39;&#39;;<br>for (const item of $input.all()) {<br>  if (item.json.message.content.outage) {<br>    notify = true;<br>    color = &#39;:red_circle:&#39;;<br>    outage = true;<br>    status = item.json.message.content.status;<br>  } else if (item.json.val &amp;&amp; item.json.val[0]) {<br>    notify = true;<br>    color = &#39;:large_green_circle:&#39;;<br>    outage = false;<br>    status = &#39;No more outage&#39;;<br>  }<br>}<br><br>return {<br>  json: {<br>    notify,<br>    color,<br>    outage,<br>    status<br>  }<br>}</pre><p>然後我們就在接下來的 IF node 去判斷 notify 的結果是否為 true，如果是 true 就通知到 Slack:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/562/1*8N5gEMLvs9khndrS8MOe8g.png" /></figure><p>Slack 的 block code:</p><pre>{<br> &quot;blocks&quot;: [<br>  {<br>   &quot;type&quot;: &quot;section&quot;,<br>   &quot;text&quot;: {<br>    &quot;type&quot;: &quot;mrkdwn&quot;,<br>    &quot;text&quot;: &quot;{{ $json.color }} {{ $json.status }}&quot;<br>   }<br>  }<br> ]<br>}</pre><p>最後的結果就像這樣:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/488/1*mQhKteZKii_AEOoLQiHw5Q.png" /></figure><p>結語，n8n 很好用! 我逢人都會推 n8n，尤其在加入眾多 AI 串接功能後，很多自動化變得很容易，很容易就可以達到 no-code 自動化境界。</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=d33e4dd37606" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[WWDC Apple Intelligence]]></title>
            <link>https://syshen.medium.com/wwdc-apple-intelligence-9681de606dcd?source=rss-13cbc18d6975------2</link>
            <guid isPermaLink="false">https://medium.com/p/9681de606dcd</guid>
            <category><![CDATA[wwdc]]></category>
            <category><![CDATA[ai]]></category>
            <category><![CDATA[apple]]></category>
            <dc:creator><![CDATA[Steven Shen]]></dc:creator>
            <pubDate>Wed, 12 Jun 2024 16:15:56 GMT</pubDate>
            <atom:updated>2024-06-12T16:52:58.490Z</atom:updated>
            <content:encoded><![CDATA[<p>Apple 的 AI 雖然慢了，但不會差</p><p>Keynote 出來後果然引起了廣泛討論，正反觀點都有，但看了幾篇網路文章，目前主流觀點都是逐漸往「Apple 更重視用戶隱私與 AI 落地應用，不直接硬幹大模型火力比拼」 這個方向走。</p><p>我自己也看了幾篇 Apple blog 跟 video，目前的了解是</p><ol><li>Apple 有自己的語言模型，他稱之為<a href="https://machinelearning.apple.com/research/introducing-apple-foundation-models"> Foundation Model</a>，參數數量約不到 30 億。要用小模型主要是因為他要放到裝置裡頭去。</li><li>在手機內有內建一個壓縮過的 on-device foundation model，這個模型採用 adapter 的技術來適配到不同的功能上，讓不同的功能如文字摘要、生成等可以達到最好的效果。</li><li>不管是 On-device model 還是 server model ，評測下來都比同等級的模型來得好，不過是不是自吹自捧還是要等公開評測才知道。</li><li>裝置 (包含 iPhone 跟 mac) 上有個 orchestration 模組，會根據用戶的指令，判斷該用 on-device model 還是送到 server 端去使用較大的模型</li><li>另外，Apple 為了獲得更多 User 的 context 資料，來讓 AI 更聰明，能做的事情更多。內部有個模組 Semantic Index ，系統會透過 App Entities 來取得 App 內的資料，Semantic Index 則是適當的調用不同 App 間的資料來讓不同的 model 使用。另外 App 可以透過 App Intent 來定義 Action 讓 Siri 可以知道怎麼操作該 App</li><li>Apple 為了確保隱私問題，重新設計了他的伺服器架構 Private Cloud Compute</li></ol><p><a href="https://machinelearning.apple.com/research/introducing-apple-foundation-models">Introducing Apple&#39;s On-Device and Server Foundation Models</a></p><h3>Private Cloud Compute</h3><p><a href="https://security.apple.com/blog/private-cloud-compute/">Private Cloud Compute: A new frontier for AI privacy in the cloud - Apple Security Research</a></p><ol><li>OS 採用簡化過的 iOS 系統</li><li>沒有 persistent storage，沒有資料被 log 下來的疑慮</li><li>沒有 remote shell，無法遠端登入</li><li>Secure enclave 保護 encryption key 安全</li><li>Secure boot 只允許 verified / signed 過的 OS image 可以被啟動</li><li>Trusted Execution Monitor 只允許 signed / verified 過的程式可以被執行</li><li>Attestation: 裝置在送 request 到 server cluster 前會先驗證 cluster 的 identity 跟 configuration，每個 request 都是端到端加密，只有被選定的 Cluster 可以解密，其他 Cluster 無法解密，確保連 Apple 自己都無法看到用戶內容</li><li>OS Image 都是公開可被檢視，如果有被發現漏洞或者有任何 Apple 宣稱沒做到的隱私保護，都會發獎金</li></ol><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*vroaFE1UtTeqSe_jOdMP4Q.png" /></figure><p>至於 Elon 出來嗆 Apple 要是跟 OpenAI 合作，揚言不會在自家公司內允許員工使用 Apple devices (這將包含 Mac，大概一堆 Elon 員工在哀嚎了)，我覺得是放入了太多對 OpenAI 的個人感情在裡頭。</p><h3>Elon Musk on X (formerly Twitter): &quot;If Apple integrates OpenAI at the OS level, then Apple devices will be banned at my companies. That is an unacceptable security violation. / X&quot;</h3><p>If Apple integrates OpenAI at the OS level, then Apple devices will be banned at my companies. That is an unacceptable security violation.</p><h3>Elon Musk on X (formerly Twitter): &quot;Apple using the words &quot;protect your privacy&quot; while handing your data over to a third-party AI that they don&#39;t understand and can&#39;t themselves create is *not* protecting privacy at all! / X&quot;</h3><p>Apple using the words &quot;protect your privacy&quot; while handing your data over to a third-party AI that they don&#39;t understand and can&#39;t themselves create is *not* protecting privacy at all!</p><p>以目前的資訊了解，ChatGPT 在 iOS 內有點像是預設搜尋引擎的感覺，例如 Safari 的預設搜尋引擎是 Google，使用者用 Safari 狀態列搜尋會先跑到 Google 去，但用戶是可以改掉預設搜尋引擎的。</p><p>iOS 18 應該是直接內建 ChatGPT 支援，用戶不需要再為 ChatGPT 付費，Apple 幫你付了。但在調用前，Apple 也會尋求你的同意，使用時他也會透過 UI 讓你很清楚目前是在使用 ChatGPT。所以不存在隱私問題，這就像即便 Apple 沒有整合，你還是會用 ChatGPT 一樣。我不認為是 OS level 的整合。</p><p>iOS 18 還是以自家的模型為主。且看目前Apple自家模型的效能評測，其實不差了，所以 ChatGPT 很可能是個過渡型整合，等自家模型更成熟了，可能就會放棄 ChatGPT ，畢竟每年的權利金也是不少錢。 (有沒有既視感? Apple 過去曾放棄 Google Map 自己跑去開發地圖服務，只是一路走得跌跌撞撞就是)</p><p>另外，就算 Elon 對員工使用 ChatGPT 有 Security 疑慮，其實是可以透過 MDM 去關掉這個功能的，老馬可能不知道，或者純粹在抒發對 OpenAI 的不爽罷了。</p><p>我個人認為 Apple 揭示了未來 AI 落地應用可能的走向：</p><ol><li>不需要一個特大、超聰明的模型</li><li>不同小模型、不同模態模型協同運作，有些是 on-device ，有些放 cloud</li><li>由一個 orchestration 來協同這些模型的運作</li><li>OS level 可以調用不同 app 內的資料，透過 intent 去操作 app 動作，但都已達到最好的 User experience 以及確保 User privacy 為考量。</li></ol><p><a href="https://twitter.com/karpathy">Andrej Karpathy</a> 也有類似的看法</p><h3>Andrej Karpathy on X (formerly Twitter): &quot;Actually, really liked the Apple Intelligence announcement. It must be a very exciting time at Apple as they layer AI on top of the entire OS. A few of the major themes.Step 1 Multimodal I/O. Enable text/audio/image/video capability, both read and write. These are the native... / X&quot;</h3><p>Actually, really liked the Apple Intelligence announcement. It must be a very exciting time at Apple as they layer AI on top of the entire OS. A few of the major themes.Step 1 Multimodal I/O. Enable text/audio/image/video capability, both read and write. These are the native...</p><p>另外，這真的只有 Apple / Google 能做，這是 OpenAI 的夢想，但如果他沒自家硬體、作業系統，很難達成這個願景。</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=9681de606dcd" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Sam Altman 談如何培養新創想法]]></title>
            <link>https://syshen.medium.com/sam-altman-%E8%AB%87%E5%A6%82%E4%BD%95%E5%9F%B9%E9%A4%8A%E6%96%B0%E5%89%B5%E6%83%B3%E6%B3%95-36c43217f55f?source=rss-13cbc18d6975------2</link>
            <guid isPermaLink="false">https://medium.com/p/36c43217f55f</guid>
            <category><![CDATA[idea-generation]]></category>
            <category><![CDATA[ideas]]></category>
            <dc:creator><![CDATA[Steven Shen]]></dc:creator>
            <pubDate>Wed, 15 Mar 2023 00:45:42 GMT</pubDate>
            <atom:updated>2023-03-15T00:56:05.130Z</atom:updated>
            <content:encoded><![CDATA[<p>Sam Altman 過去曾經是 Y-Combinator CEO ，目前是 OpenAI CEO。他跟 PG 很像，會寫文章，即便數量少很多，但每篇文章質量很高。以下是他在 2020 年寫的一篇文章，談論該如何正確培養新創的創意想法，我覺得很有幫助，轉發於此。另外這篇文章是用人工智慧翻譯，工人智慧編修，有錯誤可以跟我說一下。</p><p>原文連結: <a href="https://blog.samaltman.com/idea-generation">https://blog.samaltman.com/idea-generation</a></p><p>翻譯開始:</p><p>新創創辦人最常問的問題是如何獲得新創公司的想法。第二個最常見的問題是你是否對他們的創業公司有任何想法。</p><p>但由別人給創辦人一個想法這樣的做法是行不通的。能夠擁有想法是新創公司創始人最重要的素質之一 — 你需要在經營新創公司的過程中產生大量的新想法。</p><p>YC曾經嘗試過一個實驗，即資助沒有想法但看似優秀的創辦人。但在這個軌道上的每一家公司都失敗了。事實證明，優秀的創辦人對任何事情都有很多想法，因此，如果你想成為一名創辦人，卻無法為公司獲得一個想法，你也許應該先在產生好想法上下功夫。</p><p>你如何做到這一點？</p><p>重要的是要在正確的環境中，和正確的人在一起。你要和那些對未來有良好感覺的人在一起，他們會接受看似不可能的計劃，很樂觀，在創造性方面很聰明，並且有很高的想法產出量。這類人往往在思考時沒有多數人的約束，沒有很多過濾器，也不太在乎別人的看法。</p><p>最好的想法是脆弱的；大多數人甚至根本不開始談論它們，因為它們聽起來很傻。也許最重要的是，你想和那些不會因為提到一個壞主意而讓你感到愚蠢的人在一起，當然他們自己也不會因為這樣做而感到愚蠢。</p><p>遠離那些厭世和貶低你的野心的人。不幸的是，這就是世界上的大多數人。但他們堅守著過去，而你想生活在未來。</p><p>你希望能夠把自己的目光投向未來20年，然後從那裡向後思考。相信你自己 — 20年是一個很長的時間；如果你對它的想法看起來很激進也沒關系。</p><p>另一種方法是思考現在正在發生的最重要的構造性轉變。世界是如何從根本上發生變化的？你能確定一個變化的前沿和它所釋放的機會嗎？2008–2012年的移動裝置爆炸發展是這方面最近的重要例子 — 我們早就該再來一次了!</p><p>在這樣的構造性轉變中，世界變化如此之快，以至於大的在位者通常會被快速移動和專注的新創企業擊敗。(順便說一下，善於區分真正的趨勢和虛假的趨勢是很有用的。一個關鍵的區分因素是，新平台是被少數人大量使用，還是被很多人少量使用）。</p><p>任何時候，只要你能想到今年有可能，而去年不可能的事情，你都應該注意。你可能有一個偉大的創業想法的種子。如果明年就太晚了，那就更是如此。</p><p>當你可以說 “我確信這將會發生，我只是不確定我們是否會是做這件事的人”，這是一個好兆頭。Uber對我來說就是這樣 — 在我第一次使用它之後，很明顯我們不會再叫出租車了，但我不確定Uber是否會贏得這個空間。</p><p>在思考一個想法的早期，要問自己一個好問題，那就是 “如果它成功了，這能成為巨大的財富嗎？” 世界上有許多好的想法，但很少有能使新創公司獲得巨大成功的內在優勢。大多數企業在擴大規模時不會產生有價值的積累性優勢。盡早思考為什麽一個想法可能具有這種屬性。對於 Facebook 或 Airbnb 來說，它是顯而易見的，但它往往以更微妙的方式存在。</p><p>思考你適合做什麽也很重要。這一點很難用純粹的內省來做；理想情況下，你可以問問導師或一些與你合作過的人，你特別擅長什麽。我逐漸相信，創辦人/公司的適合性 (founder/company fit) 與產品/市場 (product/market fit) 的適合性一樣重要。</p><p>最後，對一個想法的良好測試是，如果你能闡明為什麽大多數人認為這是一個壞主意，但你明白它好在哪里。</p><p><em>這是我在2018年中國的一個YC活動中的演講筆記。感謝 Eric Migicovsky 鼓勵我把它貼出來!</em></p><p><em>我寫這篇文章時，我主要考慮的是新創公司；現在我主要考慮的是人工智慧發展。我對其中很多內容的適用性感到震驚，特別是第5–9段。</em></p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=36c43217f55f" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[快速打造一個 OpenAI 工具]]></title>
            <link>https://syshen.medium.com/%E5%BF%AB%E9%80%9F%E6%89%93%E9%80%A0%E4%B8%80%E5%80%8B-openai-%E5%B7%A5%E5%85%B7-f497b154fff3?source=rss-13cbc18d6975------2</link>
            <guid isPermaLink="false">https://medium.com/p/f497b154fff3</guid>
            <dc:creator><![CDATA[Steven Shen]]></dc:creator>
            <pubDate>Sat, 25 Feb 2023 03:23:10 GMT</pubDate>
            <atom:updated>2023-02-25T03:23:10.241Z</atom:updated>
            <content:encoded><![CDATA[<p>生成式 AI 幾個月快速席捲世界，但不是每個人每個公司都有能力訓練自己的 LLM，目前最快的方式就是直接串接 OpenAI 的 API。</p><p>本文講解一下如何用 OpenAI API 快速打造自己的工具，本文以網路文章的摘要與翻譯產生器為例。原本這個是用來解決我自己的問題，但我想透過同樣的方式，你也快速打造自己的 OpenAI 工具。</p><p>先來看看最後成果長什麼樣子:</p><p><a href="https://syshen-summarization-summarization-tgfl9g.streamlit.app/">summarization · Streamlit</a></p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*Lc0j39H5hIo3H6bxiXjEdw.png" /></figure><p>一開始先讓使用者輸入自己的 OpenAI API Key，再來是輸入文章網址，程式會自動抓取網頁的內文，透過 OpenAI 產生摘要。</p><p>整個 app 是透過 <a href="https://streamlit.io/">Streamlit</a> 打造，Streamlit 原本是打造給深度學習AI 的一個工具，很類似 JupiterNotebook。透過它，你不需要了解前後端技術，只要會寫 Python，就可以寫出類似的 App，並且在 Streamlit 上執行完全不需要費用。</p><p>程式本身也不複雜，可以參考原始程式碼:</p><p><a href="https://github.com/syshen/summarization">GitHub - syshen/summarization</a></p><p>只有約一百行程式左右。不過有點要注意的是，由於 GPT3 有 Token的上限，最高只允許 4096 個 Token，但是我們在分析一些長文時，很容易就超過這個上限，目前 OpenAI <a href="https://openai.com/blog/summarizing-books/">建議的做法</a>也是將文章拆成數個片段，依序去執行。</p><p>所以要拆文章時，可以用 pretrained 的 GPT2 切 Token 的方式來做估算，以兩千個 Token 為單位拆開，再個別丟給 OpenAI 就好。</p><pre>from transformers import AutoTokenizer<br><br>tokenizer = AutoTokenizer.from_pretrained(&quot;gpt2&quot;)<br><br>def text_to_chunks(text, chunk_size=2000, overlap=100):<br>  tokens = tokenizer.encode(text)<br>  num_tokens = len(tokens)<br>    <br>  chunks = []<br>  for i in range(0, num_tokens, chunk_size - overlap):<br>    chunk = tokens[i:i + chunk_size]<br>    chunks.append(chunk)<br>    <br>  return chunks</pre><p>因為是切出多個 Chunk，所以每個 Chunk 之間也保留 100 個 Token 的 overlap ，來避免有些資訊不見了。</p><p>OpenAI API 呼叫方式可以參考官方文件，但它是 Restful API，透過 SDK 使用很簡單:</p><pre>def callOpenAI(prompt_request, max_tokens=500):<br>  response = openai.Completion.create(<br>            model=&quot;text-davinci-003&quot;,<br>            prompt=prompt_request,<br>            temperature=.5,<br>            max_tokens=max_tokens,<br>            top_p=1,<br>            frequency_penalty=0,<br>            presence_penalty=0<br>  )<br>  return response.choices[0].text</pre><p>GPT 模型都是用 Prompt 去控制你要的結果，所以只要在文字前給予正確的指令就好，例如: Summarize text: &lt;your article text&gt;</p><p>兜在一起要做文章摘要程式會像這樣:</p><pre>def summarize_text(full_text):<br>  chunks = text_to_chunks(full_text)<br>  summaries = []<br><br>  for i, chunk in enumerate(chunks):<br>    text = tokenizer.decode(chunks[i])<br>    summary = callOpenAI(f&quot;Summarize: {text}&quot;)<br>    summaries.append(summary)    <br><br>  if len(summaries) &gt; 0:<br>    final_summary = callOpenAI(f&quot;Consolidate the summaries with paragraphs: {str(summaries)}&quot;, max_tokens=2000)<br>  return final_summary</pre><p>每個 Chunk 個摘要組合起來，再請 OpenAI 做個最後總結就好了。</p><p>最後用 Streamlit 來控制程式執行流程，至於 Streamlit 怎麼用，可以參考一些網路上的中文說明，例如<a href="https://medium.com/@yt.chen/%E6%A9%9F%E5%99%A8%E5%AD%B8%E7%BF%92-%E8%B3%87%E6%96%99%E7%A7%91%E5%AD%B8%E6%A1%86%E6%9E%B6%E6%87%89%E7%94%A8-streamlit%E5%85%A5%E9%96%80-1-d07478cd4d8">這篇</a>。</p><p>你可以先在本機端跑 Streamlit 測試，測試好了，註冊 Streamlit 帳號，連結 Github ，然後就可以部署到 Streamlit 上去給別人用了。</p><p>記得不要隨便把 OpenAI API 直接放在程式裡讓別人使用，要不然你的 Quota 很快就爆了。</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=f497b154fff3" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[區塊鏈儲備證明 Proof of reserve]]></title>
            <link>https://syshen.medium.com/%E5%8D%80%E5%A1%8A%E9%8F%88%E5%84%B2%E5%82%99%E8%AD%89%E6%98%8E-proof-of-reserve-235375de3278?source=rss-13cbc18d6975------2</link>
            <guid isPermaLink="false">https://medium.com/p/235375de3278</guid>
            <dc:creator><![CDATA[Steven Shen]]></dc:creator>
            <pubDate>Sun, 13 Nov 2022 12:52:33 GMT</pubDate>
            <atom:updated>2022-11-13T12:52:33.833Z</atom:updated>
            <content:encoded><![CDATA[<p>上禮拜虛擬幣市場發生大事，世界第二大交易所 FTX 資不抵債宣告破產，有人說這是雷曼兄弟事件翻版，很多人的錢都被卡在裡面，影響的不只是個人還包含各種投資公司，未來能把錢拿回來的機會渺茫，FTX 創辦人 SBF 從神壇跌落人間，這件事也嚴重影響大眾對於虛擬幣的信心，也出現各種檢討的聲音。</p><p>不過這篇文章不是要講什麼「我早就知道」「早說會這樣」的文章，但我比較想要聊這件事會怎麼影響未來技術的發展。</p><p>這幾天，包含 CZ 在內都拋出了 <a href="https://twitter.com/cz_binance/status/1590055819416330240">Proof of reserve (儲備證明 PoR) 的概念</a>，基本上概念就是交易所要做自清，把資產攤出來給大家看，目前幾間交易所為了自清公佈自家金庫地址，並透過 Nansen porfolio 公佈出來以昭公信，其中包含</p><p>Bitfinex <a href="https://portfolio.nansen.ai/dashboard/bitfinex">https://portfolio.nansen.ai/dashboard/bitfinex</a><br><a href="http://cyrpto.com/">Cyrpto.com</a> <a href="https://portfolio.nansen.ai/dashboard/crypto.com">https://portfolio.nansen.ai/dashboard/crypto.com</a><br>KuCoins <a href="https://portfolio.nansen.ai/dashboard/kucoin">https://portfolio.nansen.ai/dashboard/kucoin</a><br>Binance <a href="https://portfolio.nansen.ai/dashboard/binance">https://portfolio.nansen.ai/dashboard/binance</a><br>OKX <a href="https://portfolio.nansen.ai/dashboard/okx">https://portfolio.nansen.ai/dashboard/okx</a></p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*KTGKzShPaWtBXMF-9uMKAQ.png" /><figcaption>Binance profolio (2022/11/13)</figcaption></figure><p>大家可以看一下這些交易所內部的資產分佈，但他們事實上不能證明什麼，因為你不知道目前交易所是否有沒公佈的地址。另外根據 <a href="https://niccarter.info/proof-of-reserves/">Nic Carter</a> 的講法，你要符合底下公式:</p><pre>Proof of Reserves + Proof of Liability = Proof of Solvency</pre><p>Proof of Liability (PoL) 是指債務證明，兩者相加代表該交易所的償還能力，這要是正的才行，概念很簡單，就是資要能抵債。</p><p>所以最近幾天包含 CZ 在內紛紛出來鼓吹儲備證明，Chainlink 更是趕在這波新聞下推出了 <a href="https://chain.link/proof-of-reserve">Proof of reserve 服務</a>。其實這個概念並不是最近才出來的，一兩年前就有人在提，<a href="https://www.kraken.com/proof-of-reserves">交易所 Kraken 在今年年初就率先提供了相關服務給他的用戶</a>，他的用戶可以看到自己的資產什麼時候被稽核過，以及被哪個單位稽核。</p><p>Nic Carter 推出了一個<a href="https://niccarter.info/proof-of-reserves/">網站</a>，條列了目前 PoR 的發展狀況，以及有哪些交易所或者 Fund 答應要支援或者已經支援 PoR。</p><p>目前被提出來的執行方式是透過 Merkle Tree 的方式來實作。Merkle Tree 經常被用在區塊鏈相關技術中，概念是將資料分段去做雜湊運算，再將個別雜湊組合起來再繼續算雜湊，就像一個樹倒過來，好處是可以個別資料做驗證，如果其中一部分有資料被變動過，也可以立刻知道是哪段資料有問題，也能節省整體的運算量。運用在 PoR 上，交易所會定期做 snapshot，計算 Merkle Tree，每個用戶可以在自己的帳戶資料下，知道屬於自己帳戶 balance 的雜湊，然後整個 Merkle Tree 會被保存下來，並交給稽核公司查核。每個用戶當然不能知道其他用戶的 balance，但是可以藉由知道自己的 balance 以及自己的雜湊來判斷整個 Root 雜湊是否有被串改過，或者交易所有沒有把你的 balance 算在他 Merkle Tree 內。</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/870/0*EfXNWxh9NqkSiwh_.jpg" /></figure><p>不過光只有 PoR 是不夠的，你還需要 PoL (Proof of Liability)，你的債務到哪去了？但我覺得未來很可能會走向不管交易所或者 Fund 都會需要整合 PoR，並公告金庫地址，由於區塊鏈特性，他們的資金流向會變得更透明。再進一步延伸，我認為未來 PoR 資料都會上鏈，可以被任何人檢驗，然後會有更多第三方的信評機構會出現，透過這些公開資訊給予信用評鑑，這些信評機構需要公開他們評鑑的方式，不同機構評鑑的方式不同，給予的信用分數也會不同，但交易所或投資公司可以將這些信用分數放在官網讓用戶參考。此外，信評機構透過區塊鏈 DID 技術 (Decentralized Identity)，為評鑑結果背書並上鏈。</p><p>透過透明的資金流向，這些交易所或者基金也必須要跟同樣標準有提供 PoR 的投資公司合作，如果資金流動到相對不透明的錢包，會進而影響到自己的信用分數，透過這樣的方式做到 Chain of trust。</p><p>所以說，並不是說交易所或者 Fund 不能拿用戶的錢轉投資，因為傳統金融也都會做類似的事情，只是你的投資方式要比以往更透明，投資人透過信用分數來評斷風險，風險與報酬能夠被更透明的機制評斷，如果風險承受度低，可以選擇信用評鑑分數高的投資公司，但相對地獲取報酬會比較低。但如果想要獲取較高的報酬，可以承受較高的風險，可以找尋報酬高但信用評鑑較沒那麼高的投資公司，但風險自負。</p><p>此外，由於資金流向會有可能影響到信用評鑑，所以未來像是 Binance 這樣什麼都做的交易所可能會開始拆分成不同的實體，有點像是傳統金融，銀行是銀行，投資公司是投資公司，兩者不能混在一起。Binance 這樣的龐然大物需要拆分「純交易所」跟「投資公司」，用戶存在交易所內的資金不能隨意被拿來做其他用途，如此一來用戶權益才能受到保障。</p><p>人類有個特性，會從犯的錯誤中學習，然後再忘記再犯錯，在一個又一個不斷犯錯學習改正的循環中前進。所以前面才會提到，FTX 事件像是另外一個雷曼兄弟翻版，人們可能早已忘了過去金融風暴中所犯的錯誤，又再痛了一次。類似的事情未來還是會繼續發生，人們畢竟是健忘的，但每次犯錯就會再往前一點點，逐步的改善讓環境越來越好。</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=235375de3278" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[App 測試自動化: RobotFramework + Appium (3)]]></title>
            <link>https://medium.com/cubo-ai/app-%E6%B8%AC%E8%A9%A6%E8%87%AA%E5%8B%95%E5%8C%96-robotframework-appium-3-2c25d423dcec?source=rss-13cbc18d6975------2</link>
            <guid isPermaLink="false">https://medium.com/p/2c25d423dcec</guid>
            <category><![CDATA[appium]]></category>
            <category><![CDATA[software-test-automation]]></category>
            <category><![CDATA[qa]]></category>
            <category><![CDATA[test]]></category>
            <dc:creator><![CDATA[Steven Shen]]></dc:creator>
            <pubDate>Fri, 02 Jul 2021 12:35:44 GMT</pubDate>
            <atom:updated>2021-07-02T12:35:44.323Z</atom:updated>
            <content:encoded><![CDATA[<p>這篇要提該如何串接 CI 與 TCMS 系統，基本上想要實踐的想法就是，當開發者將程式碼推上 git 時，觸發 CI pipeline 流程，流程包含 build -&gt; test -&gt; deploy，所以只要有新的版本，都會經過自動化測試的驗證，並且將執行結果更新回到 TCMS 系統上，對 QA 來說，只要關注失敗的 Test Run 就好。</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/721/1*wur3vQYSyYWjui9Xc9d9rQ.png" /></figure><p>這裡用的 CI 是 gitlab CI，TCMS 是 Kiwi 雲端版。Kiwi 因為有支援 RobotFramework 以及自動化測試，然後又便宜，所以我們公司目前採用 Kiwi 作為 Test Case Management System。</p><p>概念其實很簡單，分作兩部分，第一部份怎麼將 RobotFramework 的執行結果更新到 TCMS 系統中，第二部分則是怎麼讓 CI build 同時去觸發 RobotFramework 對新 build 執行自動化測試。</p><p>先講第一部分，怎麼將 RF 的執行結果更新到 TCMS 中。</p><ol><li>先安裝 RF 的 kiwitcms 套件 pip install --upgrade kiwitcms-robotframework-plugin</li><li>在 Home directory 中，建立 ~/.tcms.conf 檔案，並輸入你的 Kiwi 網址與帳號密碼</li></ol><pre>[tcms]<br>url = https://&lt;your_tenant_name&gt;.tenant.kiwitcms.org/xml-rpc/<br>username = &lt;login_account&gt;<br>password = &lt;your_password&gt;</pre><p>3. 將底下程式 (儲存為 <a href="http://tcmstools.py/">tcmsTools.py</a>)跟你的 RF 腳本放在一起</p><pre>import os<br>from zealand.listener import KiwiTCMS<br>from zealand.listener import RFBackend</pre><pre>class PrivateTenantBackend(RFBackend):<br>    def default_tester_id(self):<br>        user_id = self.built_in.get_variable_value(&#39;${build_user_id}&#39;)<br>        return user_id</pre><pre>    def finish_test_run(self):<br>        self.rpc.TestRun.add_tag(self.run_id, &#39;automation&#39;)</pre><pre>class PrivateTenantKiwi(KiwiTCMS):<br>    backend_class = CuboBackend</pre><p>為什麼要加這個程式，因為我們的 Kiwi 環境是直接跟 Kiwi 租用的，所以呼叫 tcms_api 的 User api 都會得到 403 Forbidden 的錯誤，為了避開這個錯誤，我在這段程式中多加個 build_user_id 來讓你可以直接輸入 tester 的 user id，而繞開 User API 的呼叫(如果你是自己架設 Kiwi 系統，應該是可以不用多加這段程式碼)。另外，這段程式也會在結束測試時，在該 Test Run 多加個 automation 的 tag，如此一來在 Kiwi 中搜尋 automated test runs 時會比較容易。</p><p>接下來在你的 RF 腳本中，要多帶幾個參數</p><pre>*** Variables ***<br>${plan_id}                          11<br>${product}                          Cubo Ai Baby Camera<br>${build_user_id}                    9062</pre><pre>*** Test Cases ****<br>成功登入<br>    [Tags]              TC-1110     login<br>    #.....</pre><ul><li>plan_id: 這個 Test suite 是要測試哪個 Test plan。我的習慣是會建立一個 Automation 的 Test plan，然後在這裡指定該 Test plan 的 ID</li><li>product: 輸入你 Kiwi 中的產品名稱</li><li>build_user_id: 輸入 tester 的 user id (如果你不是用我附加的程式碼，請在這裡換成 tester 以及該測試者的 email)</li></ul><p>另外在每個 Test case 中，會多帶 [Tags] TC-1110 login ，其中 TC-1110 是某個 test case 的 ID，這裡是用 Tags 的指令來表示該 test case 對應到 Kiwi 中是哪個測試項目。</p><p>執行 RobotFramework 的方式改為:</p><pre>export TCMS_PRODUCT_VERSION=2.0<br>export TCMS_BUILD=2377<br>robot  --listener tcmsTools.PrivateTenantKiwi  tcms_test.robot</pre><p>執行完畢後，檢查 Kiwi，就會有筆 Test run 被建立出來:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*RABLkgV5Dz96d0lK" /></figure><p>如此一來，RobotFramework 與 Kiwi的串連就完成了。</p><p>但是你可能有注意到，上面在執行 RobotFramework 腳本時，有多帶個 TCMS_PRODUCT_VERSION 與 TCMS_BUILD ，這兩個參數從哪裡來，其實就是要從 CI build 而來。</p><p>什麼？你們公司還沒有 CI Build? 那要先檢討一下了</p><p>我們用 gitlab CI 來做範例，我們的做法是在公司放一台 Mac mini 執行 gitlab-runner 來跑 CI。所以當工程師把 Code commit 並 push 到 gitlab 時就會觸發 CI 流程。</p><pre>.ios-build-task:<br>  stage: build<br>  tags:<br>    - ios-build<br>  only:<br>    - dev</pre><pre>.ios-test-task:<br>  stage: test<br>  variables:<br>    GIT_SUBMODULE_STRATEGY: recursive<br>  tags:<br>    - ios-build<br>  only:<br>    - dev</pre><pre>stages:<br>  - build<br>  - test<br>  - deploy</pre><pre>variables:<br>  LC_ALL: &quot;en_US.UTF-8&quot;</pre><pre>before_script:<br>  - pod repo update<br>  - pod install</pre><pre>build_project:<br>  extends: .ios-build-task<br>  script:<br>    - xcodebuild clean -workspace &quot;Cubo.xcworkspace&quot; -scheme &quot;Cubo&quot; | xcpretty<br>    - bundle exec fastlane beta_build<br>artifacts:<br>    paths:<br>      - build.xcarchive<br>      - build</pre><pre>automation-test:<br>  extends: .ios-test-task<br>  script:<br>    - export TCMS_PRODUCT_VERSION=$(bundle exec fastlane run get_version_number target:Cubo | grep Result | grep -oE &#39;[0-9]+\\.[0-9]+\\.?[0-9]*&#39;)<br>    - export TCMS_BUILD=$(bundle exec fastlane run get_build_number | grep Result | grep -oE &#39;\\s[0-9]+&#39; | grep -oE &#39;[0-9]+&#39;)<br>    - cd automation; robot --listener cubo_tools.CuboKiwi ios_test_cases.robot</pre><pre>deploy:<br>  stage: deploy<br>  script:<br>    - bundle exec fastlane beta_deploy</pre><p>我們是用 <a href="https://fastlane.tools/">fastlane</a> 來 build app，fastlane 設定如下:</p><pre>default_platform(:ios)</pre><pre>platform :ios do<br>  def install_pods<br>    cocoapods(<br>      clean: true,<br>      podfile: &quot;Podfile&quot;,<br>      try_repo_update_on_error: false<br>    )<br>  end</pre><pre>	desc &quot;Build app, and archive in ./build.xcarchive path&quot;<br>  lane :beta_build do<br>    install_pods()<br>    xcode_select(&quot;/Applications/Xcode.app&quot;)<br>    increment_build_number({<br>      build_number: latest_testflight_build_number + 1<br>    })<br>    build_app(workspace: &quot;Cubo.xcworkspace&quot;, scheme: &quot;Cubo&quot;, archive_path: &quot;./build&quot;, output_directory: &quot;./build&quot;)<br>  end</pre><pre>  desc &quot;Push a new beta build to TestFlight&quot;<br>  lane :beta_deploy do<br>    upload_to_testflight(<br>        skip_waiting_for_build_processing: true<br>    )<br>  end<br>end</pre><p>所以可以在 test stage 可以透過 fastlane 取得 app 版本與 build number (build number 是每次會自動遞增)。不過 fastlane 的輸出比較 fancy 會用控制碼帶上顏色，所以在設定給環境變數時，控制碼會造成跟 Kiwi server 溝通上的問題，這問題苦惱了我很久，最後還是寫出這樣很奇怪的處理方式，如果你有更好的解法請務必跟我說：</p><pre>bundle exec fastlane run get_version_number target:Cubo | grep Result | grep -oE &#39;[0-9]+\\.[0-9]+\\.?[0-9]*&#39;</pre><p>在 RF 腳本中，你會想要安裝這個剛 build 出來的 app ，你可以指定 app 或者 ipa 的檔案位置，例如在我的 Fastlane 腳本中，我將 app 的 archive 儲存在 build.xcarchive 下，所以在 RF 腳本中 app 可以直接寫死該檔案的絕對路徑，當 RF 腳本執行時，就會安裝這個新 build 出來的版本。</p><p>另外這裡有個小 trick，我們的自動化測試腳本是放在另外一個 gitlab repo 中，所以在 iOS repo 裡透過 submodule 的方式，讓 gitlab CI 也自動將另外一個 repo 也 checkout 下來 (automation 目錄下)。</p><p>所以當程式碼 push 上 gitlab 時，啟動 gitlab pipeline 會自動完成三個 stage: build, test 以及 deploy</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*jIBlscbpoR9OCnE1" /></figure><p>執行完畢後，檢查 Kiwi，一樣會有筆 Test run 被建立出來:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*bqr2Ty-PzbgnudAb" /></figure><p>整個設定過程你大概會面臨到很多 try and error 的機會，要設定好也不容易，但盡量是簡化設定，避免環境變動影響到自動化測試的結果，如果自動化測試三天兩頭損壞，那麼久了沒修理就慢慢失去它的意義了。</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=2c25d423dcec" width="1" height="1" alt=""><hr><p><a href="https://medium.com/cubo-ai/app-%E6%B8%AC%E8%A9%A6%E8%87%AA%E5%8B%95%E5%8C%96-robotframework-appium-3-2c25d423dcec">App 測試自動化: RobotFramework + Appium (3)</a> was originally published in <a href="https://medium.com/cubo-ai">Cubo AI</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[App 測試自動化: RobotFramework + Appium (2)]]></title>
            <link>https://medium.com/cubo-ai/app-%E6%B8%AC%E8%A9%A6%E8%87%AA%E5%8B%95%E5%8C%96-robotframework-appium-2-f63635953369?source=rss-13cbc18d6975------2</link>
            <guid isPermaLink="false">https://medium.com/p/f63635953369</guid>
            <category><![CDATA[appium]]></category>
            <category><![CDATA[test]]></category>
            <category><![CDATA[apps]]></category>
            <category><![CDATA[software-test-automation]]></category>
            <category><![CDATA[qa]]></category>
            <dc:creator><![CDATA[Steven Shen]]></dc:creator>
            <pubDate>Fri, 02 Jul 2021 12:35:00 GMT</pubDate>
            <atom:updated>2021-07-02T12:35:00.784Z</atom:updated>
            <content:encoded><![CDATA[<p>上一篇介紹 Appium 與 AppiumDesktop，這一篇介紹一下如何編寫 RobotFramework 腳本。</p><p>先看底下範例</p><pre>*** Settings ***<br>Documentation       A test suite with app tests<br>Library             AppiumLibrary<br>Test Teardown       Close All Applications</pre><pre>*** Variables ***<br>${APPIUM_URL}                       &lt;http://127.0.0.1:4723/wd/hub&gt;<br>${IOS_AUTOMATION_NAME}              XCUITest<br>${PLATFORM_NAME}                    iOS<br>${PHOTOS_APP_NAME}                  com.apple.mobileslideshow<br>${PLATFORM_VERSION}                 14.6<br>${DEVICE_NAME}                      your_iphone_name<br>${UDID}                             your_iphone_device_identifier<br>${XCODE_ORG_ID}                     your_team_id</pre><pre>*** Test Cases ***<br>Test another app<br>    開啟 iOS app    ${PHOTOS_APP_NAME}<br>    略過app介紹說明<br>    Sleep   2s<br>    Click Element    xpath=//XCUIElementTypeImage[@name=&quot;照片, 6月11日, 下午2:31&quot;]<br>    Run Keyword And Ignore Error     Click Button       Got It  # 這邊會彈出一個視窗也是只有第一次使用 App 才會有，<br>                                                                    # 所以如果是第二次以後使用，Click Button 失敗，所以我們就 Ignore 這個錯誤<br>    Sleep                       1s<br>    Swipe    346    441    83    449<br>    Sleep                       1s<br>    Swipe    181    256    188    536        <br>    Sleep                       3s</pre><pre>*** Keywords ***<br>開啟 iOS app<br>    [Arguments]     ${app_name}<br>    Open Application    ${APPIUM_URL}       iOSApp<br>    ...  automationName=${IOS_AUTOMATION_NAME}<br>    ...  platformName=${PLATFORM_NAME}<br>    ...  deviceName=${DEVICE_NAME}<br>    ...  platformVersion=${PLATFORM_VERSION}<br>    ...  udid=${UDID}<br>    ...  xcodeSigningId=iPhone Developer<br>    ...  xcodeOrgId=${XCODE_ORG_ID}<br>    ...  clearSystemFiles=true<br>    ...  app=${app_name}</pre><pre>略過app介紹說明<br>    # App 介紹頁只有第一次使用該 App 時才會出現<br>    # 而且這個不是 Test case 要關注的點<br>    # 所以這邊會使用 RUN Keyword 來執行 Click Button，<br>    # 如果 Click Continue Button 有成功，就會 Sleep 2 兩，等待動畫結束<br>    # 如果這頁沒出現，Click Continue Button 就會失敗，所以我們就不用做 Sleep，直接到下個步驟<br>    Sleep               2s<br>    ${status}   Run Keyword And Return Status     Click Button    Continue<br>    IF  ${status}<br>        Sleep           2s<br>    END</pre><p>RF 腳本跟其他程式語言比較不一樣的是由 Keyword 所組成，你可以自訂 Keyword 去擴充他，所以也有別人會寫 Keyword 來擴充原有功能，像是 Appium 的支援就是透過 AppiumLibrary 來引入。</p><p>Keyword 的用法是</p><pre>&lt;Keyword&gt;    &lt;param1&gt;...</pre><p>像是上面範例中的 Library 或者 Test Teardown 或者 Click Element 都是 Keyword，Keyword 與參數之間至少要間隔一個空白以上，如果只有一個空白就會被視為同一個 Keyword。你也可以自訂義 Keyword，像是上述範例中的 開啟 iOS app 就是我自行定義的 Keyword，你可以把它視為一個可以被重複利用的函示。</p><p>至於到底有哪些 Keyword 可以用，可以參考底下幾個常用的文件</p><ul><li>內建的 Keyword: <a href="https://robotframework.org/robotframework/latest/libraries/BuiltIn.html">https://robotframework.org/robotframework/latest/libraries/BuiltIn.html</a></li><li>Operating System: <a href="https://robotframework.org/robotframework/latest/libraries/OperatingSystem.html">https://robotframework.org/robotframework/latest/libraries/OperatingSystem.html</a></li><li>Appium: <a href="https://serhatbolsu.github.io/robotframework-appiumlibrary/AppiumLibrary.html">https://serhatbolsu.github.io/robotframework-appiumlibrary/AppiumLibrary.html</a></li><li>Selenium: <a href="https://robotframework.org/SeleniumLibrary/SeleniumLibrary.html">https://robotframework.org/SeleniumLibrary/SeleniumLibrary.html</a></li></ul><p>如果要使用 AppiumLibrary，要先做安裝</p><pre>pip install --upgrade robotframework-appiumlibrary</pre><p>執行 App 是透過 Open Application 這組 Keyword，在執行前需要先把 Appium server 跑起來 (透過 Appium Desktop 或者 appium 命令都可以)，這個 Keyword 的參數包含 appium server url，以及上一篇提到的 Capabilities。</p><p>上面這個範例就是執行 Photos app (com.apple.mobileslideshow) ，並進行一些操作。</p><p>你也可以透過一些其他 Keyword 如 Element Should Be Visible &lt;name&gt; 來驗證符合 &lt;name&gt; 名稱的元件應該有出現，來作為 Test case 的驗證項目。</p><p>只要腳本執行有錯，這個 test case 就會被視為失敗。</p><p>下一篇我會介紹一下如何整合到 CI 環境中，讓他真的自動化被執行。</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=f63635953369" width="1" height="1" alt=""><hr><p><a href="https://medium.com/cubo-ai/app-%E6%B8%AC%E8%A9%A6%E8%87%AA%E5%8B%95%E5%8C%96-robotframework-appium-2-f63635953369">App 測試自動化: RobotFramework + Appium (2)</a> was originally published in <a href="https://medium.com/cubo-ai">Cubo AI</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[App 測試自動化: RobotFramework + Appium (1)]]></title>
            <link>https://medium.com/cubo-ai/app-%E6%B8%AC%E8%A9%A6%E8%87%AA%E5%8B%95%E5%8C%96-robotframework-appium-1-3b917087729b?source=rss-13cbc18d6975------2</link>
            <guid isPermaLink="false">https://medium.com/p/3b917087729b</guid>
            <category><![CDATA[automation]]></category>
            <category><![CDATA[appium]]></category>
            <category><![CDATA[test]]></category>
            <category><![CDATA[software-test-automation]]></category>
            <category><![CDATA[qa]]></category>
            <dc:creator><![CDATA[Steven Shen]]></dc:creator>
            <pubDate>Fri, 02 Jul 2021 12:34:14 GMT</pubDate>
            <atom:updated>2021-07-02T12:34:14.243Z</atom:updated>
            <content:encoded><![CDATA[<p>這是一篇簡單的教學文，紀錄如何透過 RobotFramework 與 Appium 來達到軟體測試自動化的目的。至於為什麼要做自動化測試，我相信已經有很多人有文章介紹，我自己的看法，一是減少人為錯誤，提升軟體 QA 的工作效率，再來是提升產品發布時的信心。</p><p>第一篇會先介紹，什麼是 Appium，以及如何安裝與設定，第二篇會介紹，如何透過 RobotFramework 編寫 Test cases，第三篇則會進一步談到如何串聯 CI 與 TCMS 系統。</p><p>對了，我不是 QA，所以對於專業的 QA 經驗，我真的沒辦法提供太多見解。</p><p>先從 Appium 談起好了</p><p>要做網頁自動化，大家應該都會先想到 Selenium，但是如果是 App 呢？ Appium 提供一個相當優秀的框架，他是一個 Client/Server 的框架，提供一套完整的 Protocol 讓你可以去操控 iOS/Android/Windows app，不管是模擬器或者實體機器都可以運作，功能十分強大。</p><p>RobotFramework 則是一套自動化腳本程式框架，可以透過 Library 的引用擴充功能，所以可以串接 Selenium，當然也可以介接 Appium。我覺得 RobotFramework 最棒的是他的語法，他是 Keyword based 的邏輯，你可以透過引入 Library 擴充更多 Keyword，也可以自訂 Keyword，Keyword 可以是任何語言，像是中文。透過 Keyword 的設計，可以讓你寫 Test cases 像是在寫自然語言文章一樣。RobotFramework + Appium 是完美的組合。</p><p>我們先從 Appium 來安裝好了。</p><p>Appium 是由 Node.js 寫成，所以你要先安裝 Node.js，而且版本要新，安裝很簡單:</p><pre>npm install -g appium</pre><p>另外要裝 <a href="https://appium.io/downloads.html">Appium Desktop</a>，而且是非常強烈建議要裝，很重要，會省超多時間。Appium Desktop 就上它的 github 下載安裝就好。</p><p>接下來，我們先從 iOS Simulator 開始玩起，但想要有 iOS Simulator，得先裝 Xcode。Xcode 在 Mac App Store 上就可以下載了，但你還必須要有開發者帳號。</p><p>接下來，先開啟 Appium Desktop，按下 Start Server，這個意思跟你直接在命令列執行 appium 是一樣的，就是跑 appium server。</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*tNGi52rGJ_M6_rnZ" /></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*KxyUI_iV_SdiRCtV" /></figure><p>Appium server 跑在 4723 Port 上。接下來按右上角的 Start Inspector Section 按鈕(放大鏡那個)。</p><p>並在 Desired Capabilities 中輸入：</p><ul><li>platformName: iOS</li><li>automationName: XCUITest</li><li>platformVersion: 14.5 (要看你 Simulator 的 iOS 版本而定)</li><li>deviceName: iPhone 12 Pro (看你想跑在哪個 Simulator 上，你也可以用 iPhone simulator 這個名稱)</li><li>app: com.apple.mobileslideshow (這個內建 Photos app 的 bundle ID，你也可以指定你自己 app 的 bundle ID，或者 app/ipa/apk 檔案路徑)</li></ul><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*U_VIc8uDjdCMstjQ" /></figure><p>將這組 Capabilities Save As 成你想儲存的名稱，未來可以重複使用。然後按下 Start Session。</p><p>記住 Appium 只是一個 Client，你是先透過它把 Appium Server 執行起來，然後在連上 Server，並提供你一個好用的介面，將命令送給 Server，再由 Server 透過底層的 Driver 去控制模擬器跟 App。</p><p>在 Start Session 後，你就會看到 Simulator 被叫起來，Photos app 被打開。</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*Rp-Yz91Jelb5kwpu" /></figure><p>簡單介紹一下 Inspector UI。左邊是 App 畫面截圖，你把滑鼠游標移過去，會發現有些元件會被 Highlight 顯示，效果就像瀏覽器的 Inspector 一樣，這是讓你可以很容易鎖定某個特定 UI 元件。中間的部分是 UI 的樹狀階層關係，如果你從左邊的截圖還是很難鎖定你要的元件的話，你也可以從樹狀階層一層一層下去找，總是會找到的。最右邊是你選定元件的內容。基本上 Inspector 可以查看每個 app ，即便是 iPhone 內建的 app 也是。</p><p>然後上面有一排按鈕</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/778/0*auDRZNyGY3EBrPVW" /></figure><p>這排按鈕提供一些功能像是重新載入、搜尋 UI 元件、錄製動作等等，也可以模擬 Swipe 或者 Click Element At Coordinates 動作。</p><p>最右邊視窗是 Selected Element，在這裡你可以取得元件的一些相關資訊，尤其是 Locator，這很重要，讓你之後在測試項目時，才有辦法在你的腳本中去定位元件的位置。</p><p>如果只能在模擬器上跑不太過癮，那麼 Appium 也能在真的 iPhone 上執行嗎?</p><p>不過相比於模擬器，要在 iPhone 上執行會稍微比較複雜一點。</p><ol><li>你必須要有個開發者帳號，在 Xcode 中登入你的開發者帳號，並取得 Team ID。</li><li>在 Xcode 的 Devices and Simulators 中登錄你的手機，允許作為開發用機子，並取得手機的 identifier。</li></ol><figure><img alt="" src="https://cdn-images-1.medium.com/max/902/0*Vbguk7Bp-HfZ3-oA" /></figure><ol><li>用 Xcode 開啟 /usr/local/lib/node_modules/appium/node_modules/appium-webdriveragent/WebDriverAgent.xcodeproj (如果你找不到的話，代表你尚未用 npm 安裝 appium。此外，如果你是使用 nvm 安裝 node.js 的話，appium 安裝路徑應該會是在 ~/.nvm/versions/node/v14.17.0/lib/node_modules/appium/node_modules/appium-webdriveragent/WebDriverAgent.xcodeproj/ )</li><li>WebDriverAgent 的 xcode 專案被開啟後，修改 target WebDriversAgentLib、 WebDriverAgentRunner 的 Signing &amp; Capabilities 設定，將 Team 切換為你的開發者帳號。</li><li>將 WebDriverAgentRunner build 到你的手機中。</li><li>Build 成功後，你手機桌面會多出個 WebDriverAgentRunner app，不要刪除這個 app，接下來我們同樣用 Appium Desktop 來測試一下。</li></ol><p>與模擬器連線不同，Capabilities 的參數有些改變。</p><p>多了幾個:</p><ul><li>udid: 在這裡輸入你手機的 identifier</li><li>xcodeOrgId: 輸入你的 team ID</li><li>xcodeSigningId: 輸入 iPhone Developer</li><li>deviceName: 輸入你 iPhone 手機名稱</li><li>clearSystemFiles: 型態設為 boolean，並設為 true</li></ul><p>手機記得解鎖，Start Session 後就會看到你的 app 被執行起來了。</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=3b917087729b" width="1" height="1" alt=""><hr><p><a href="https://medium.com/cubo-ai/app-%E6%B8%AC%E8%A9%A6%E8%87%AA%E5%8B%95%E5%8C%96-robotframework-appium-1-3b917087729b">App 測試自動化: RobotFramework + Appium (1)</a> was originally published in <a href="https://medium.com/cubo-ai">Cubo AI</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[[讀書筆記] 你的行為決定你是誰]]></title>
            <link>https://syshen.medium.com/%E8%AE%80%E6%9B%B8%E7%AD%86%E8%A8%98-%E4%BD%A0%E7%9A%84%E8%A1%8C%E7%82%BA%E6%B1%BA%E5%AE%9A%E4%BD%A0%E6%98%AF%E8%AA%B0-85009472dab8?source=rss-13cbc18d6975------2</link>
            <guid isPermaLink="false">https://medium.com/p/85009472dab8</guid>
            <dc:creator><![CDATA[Steven Shen]]></dc:creator>
            <pubDate>Sun, 03 Jan 2021 14:47:16 GMT</pubDate>
            <atom:updated>2021-02-02T14:07:53.280Z</atom:updated>
            <content:encoded><![CDATA[<p>有些書在不對的時間讀，就沒什麼感覺。Ben Horowitz 的「什麼才是最難的事？」就是這樣的書，讀的時候我還是在 0–1 階段，但是那本書講的是 1–100 階段。</p><p>Ben 的新書「你的行為決定你是誰」也是差不多，都不太適合在 0–1 階段去讀，不過如果說，我能夠在早期就先知道，對於日後成長為 1–100 時會更有幫助。</p><p>我相信「文化」對於一間公司的重要程度，現在應該沒有人會反對吧。我以前在趨勢科技服務，趨勢科技就是一間極端重視企業文化的公司，不過離開接近十年後回頭看，我反而認為當年趨勢所設計的文化比較像是領導人想要員工遵從的價值，而非從上到下的推行。</p><blockquote>企業文化就是當你不在時，公司如何做出各式各樣的決定，就是員工每天用來解決問題的那套無形概念，以及他們私底下的行為</blockquote><p>Ben 這本書通篇就在講一個想法，那個想法就是書名本身: What you do is who you are — 你的行為決定你是誰。</p><p>我相信很多企業領導人在導入公司文化、某種價值時，都喜歡引用他們所推崇(或喜歡)的其他領導人(或公司)的文化跟價值，例如有些人喜歡賈伯斯，喜歡蘋果的產品，但不是某間公司都能夠像蘋果一樣，甚至更少人真的能像賈伯斯一樣出色; 有些人推崇 Simon Sinek，將同理心引入到企業價值當中，但結果往往是</p><blockquote>有些部屬會把同理心的價值觀當作武器，反擊說：「你給我這種回饋！表示你缺乏同理心！」</blockquote><p>我還真的聽過這樣的例子。</p><p>企業文化應該來自於領導人本身的特質、信念、所相信的價值，當你每天遇到困難的問題時，下決定所依據的原則，就會是你公司的文化。</p><blockquote>要讓文化穩固，文化必須與領導人真正信想的價值一致，而不是與他自以為激勵人心的價值一致。因為，領導人主要是透過行動與他親自設下的範例朔造文化。</blockquote><p>文化沒有好或不好的分別，只有適不適合自己公司的差異。一個領導人在朔造公司文化的時候，要先誠實檢視自己，了解自己。自己有什麼優缺點，都會成為公司的文化一環。領導人過度膨漲自己並不會為公司帶來什麼好的文化。</p><blockquote>企業領導人也得面臨同樣的挑戰，但是他們往往自認為「好人」，常常忽略自己的缺點，這會導致文化上的危險後果。</blockquote><p>我想，在找尋一個適合自己公司文化的過程中，這個做法可能不錯，給大家參考：</p><ol><li>列出自己特質、相信的信念、價值，想要改進什麼缺點</li><li>跟其他共同創辦人一起列出來，最大公約數便有可能會是你企業的文化精髓</li><li>言行一至</li></ol><blockquote>要設計成功的文化，第一步就是做自己，但是這可不容易。</blockquote><p>做自己很重要</p><blockquote>如果你嘗試要當另外一個人，不只會無法領導眾人，面對跟你看齊、想要迎頭趕上你的人，你還會感到相當羞愧。</blockquote><blockquote>如果你沒有做自己，就連你都不會追隨身為執行長的你。</blockquote><p>人無法每天活在面具下，在壓力下，你的言行會反映你的思緒，如果你的文化不是代表你自己，其他人都看得出來，領導人要了解，既然做為領導人，站在光環下，其他人都在看著你，言行要一致，文化才能經得起檢視。</p><blockquote>請記住，你的員工會用你的文化美德測試你，不管他們是有意還是無意的，所以，在你把美德放進企業文化前，先問自己：「我願意通過這項測試嗎？」</blockquote><p>文化也必須是你所相信的價值，如此一來你才會重視它，並不斷地砥礪它，要求自己也要求別人做到。</p><blockquote>如果你看到某些事情低於標準切毫無反應，那你已經設下了新的標準。</blockquote><blockquote>如果你看到某些不符合文化的事情卻選擇忽略，那麼你已經創造了新文化。</blockquote><p>另外，外在環境會改變，企業文化也要隨時做出修正。</p><blockquote>文化就像創造文化的組織一樣，必須隨時演進以因應新挑戰。</blockquote><blockquote>在任何一家有規模的公司中，總是會出現違反文化的案例。但是，重點不在於完美，而是在於比昨天更好。</blockquote><blockquote>策略會演進，環境會改變，你會學到新的事物，所以當這些狀況發生時，你就必須改變企業文化，不然會被舊規矩牢牢的箝制住。</blockquote><p>信任是雙向的，信任建構於坦誠，不管對員工、對其他共同創辦人皆然。</p><blockquote>信任來自於坦誠，如果員工無法相信你，公司就會分崩離析。這裡的技巧在於，要有技巧地說實話但不摧毀公司。</blockquote><blockquote>事實是什麼就是什麼，最重要的是，公司裡的每一個人都知道事實跟你所知道的事實如出一徹</blockquote><blockquote>如果是你的領導造成公司受挫，不得不裁員，那就承認吧。</blockquote><p>Strip CEO 神童 Patrick Collison 曾說過： (這段話很好，不過我找不到原文)</p><blockquote>『我們顯然無法提供終生聘僱的保障，但是我希望我們能夠做到的是，當人們在十五年後回頭看的時候，他們會認為在這公司做的是生涯中最有意義的工作。我期待員工做好兩件事作為交換條件：一、道德的一致性; 二、為公司而不是為自己追求卓越。如果他們能夠達成這兩項期待，我們會珍惜、尊重員工，並且對他們忠誠。』</blockquote><p>最後</p><blockquote>文化始於你決定什麼是最重要的事，然後你必須協助組織裡每一個人，讓他們實踐能夠反映這些重要價值的行為</blockquote><blockquote>你得注意自己的行為，你的行為對企業文化有什麼影響？你是你想要成為的那個人嗎？</blockquote><p>另外，一般來說我不太看引言，但是中文譯本引言來自於 Dcard CEO，我覺得他寫得蠻好的</p><blockquote>把一個問題往上丟，得到的回應就是文化</blockquote><p>創業過程，每個階段都是新的學習</p><blockquote>You must unlearn what you learnt. Periodically.</blockquote><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=85009472dab8" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Amazon Prime Video 美劇片單]]></title>
            <link>https://syshen.medium.com/amazon-prime-video-%E7%BE%8E%E5%8A%87%E7%89%87%E5%96%AE-19a5e0025c5c?source=rss-13cbc18d6975------2</link>
            <guid isPermaLink="false">https://medium.com/p/19a5e0025c5c</guid>
            <dc:creator><![CDATA[Steven Shen]]></dc:creator>
            <pubDate>Tue, 10 Mar 2020 00:59:43 GMT</pubDate>
            <atom:updated>2020-03-10T05:49:06.793Z</atom:updated>
            <content:encoded><![CDATA[<p>其實台灣目前就可以看 Prime Video 了，不過好像不普遍，我周遭的人都還是在看 Netflix。</p><p>今年開始我看了兩個多月的 Prime Video，這邊推幾部我喜歡的美劇，並附上 IMDb 的分數以及我自己給他的評分</p><h3>Terror 極地惡靈</h3><p>目前有兩季，第一季根據傳奇小說 Dan Simmons 的 Terror 改編，而小說則根據真實故事改編。在 1845 年，英國派出兩艘船 Terror 跟 Erebus 前往北極探勘新航道，但是卻受困在北極冰層中，後來從此音訊全無，兩艘船總共有129名船員卻無人生還，並且直到 2014 年跟 2016 年時才被加拿大政府發現。這件事最後因為無人生還，所以這之間到底發生什麼事情，沒人知道，但是在處於絕望，冰封且糧食短缺的高度壓力下，人類到底會做出什麼樣的事情，就是整部片最高度張力之處。</p><p>IMDb 8 分<br>爛番茄: 87% (真的不能再高了)<br>我給的評分: 4 顆半</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/900/1*nfxPhkZZ2VKRgm2ZSYebmg.jpeg" /></figure><p>歷史是最吸引我的部分了，在看得過程我會不斷去翻這兩艘船的歷史，他們都曾經歷過戰爭與南北極的探險之旅，充滿色彩，最後的下場也充滿神秘感。</p><h3>The Expanse 太空無垠</h3><p>這部由 SyFy 高成本拍攝的影集之前曾在 Netflix 上過，但後來 SyFy 一度要取消第三季，但是影迷實在太喜歡了，紛紛發起拯救活動，後來是 Amazon 出手相救，才會有現在的 1 ~ 4 季，而且從 Netflix 下架。</p><p>這部是我最喜歡的 sci-fi 影集，比 Star Trek 好，我喜歡他的故事背景設計，故事時間發生在第 23 世紀，人類的足跡已經廣佈到太陽系幾個主要行星與小行星上，並且分裂成火星、小行星帶、與地球三個不同的陣營; 因為根據地不同，人類長時間在太空中生活，也造就一些生理上的差異，以及民族性認知上的不同。像是小行星帶上的居民，經常物質短缺，且生活在低重力環境，身體構造異於其他星球上的居民，無法適應重力生活，也比較憤世忌俗，經常打游擊四處劫掠。而火星上的居民生活也不易，好不容易在火星上建立殖民地，一心想要將火星改造成另外一個地球，所以科技發展最為先進，擁有高科技武器。而地球則仰仗著豐富的資源，舒適的生活環境，人口多，武力強盛，有著大地球思維。所以簡單看，這是太空版的三國演義，影集的發展也從一個尋人事件發展，跨過四季逐漸變成一個跨越宇宙的事件，相當好看。</p><p>IMDb: 8.5<br>爛番茄: 93%<br>我的評分: 5 顆星</p><p>另外 The Expanse 中也相當考究一些物理現象，很多特效不是亂演的，非常精確也不浮誇，是劇中值得注意的亮點。</p><h3>Star Trek: Picard 畢凱艦長</h3><p>Star Trek 的全盛時期就是在 The Next Generation 的畢凱艦長，後來還可以看的就只有 Voyager。如果要拯救這系列，最終還是要靠畢凱艦長自己了。</p><p>這部雖然沒有企業號，也沒有漂亮的星艦，Starfleet 也從內部開始腐爛，但是 Patrick Steward 回鍋演 Picard 就很值得看了，更何況回鍋的還有 7 of 9、Data 上尉、永遠的副艦長Rick。</p><p>不過 Picard 就像 Professor X 一樣，真的老了， 不再像以往意氣風發的站在鑑橋喊出 Engage。</p><iframe src="https://cdn.embedly.com/widgets/media.html?src=https%3A%2F%2Fwww.youtube.com%2Fembed%2FIQN2B0mFAaw%3Ffeature%3Doembed&amp;display_name=YouTube&amp;url=https%3A%2F%2Fwww.youtube.com%2Fwatch%3Fv%3DIQN2B0mFAaw&amp;image=https%3A%2F%2Fi.ytimg.com%2Fvi%2FIQN2B0mFAaw%2Fhqdefault.jpg&amp;key=a19fcc184b9711e1b4764040d3dc5c07&amp;type=text%2Fhtml&amp;schema=youtube" width="854" height="480" frameborder="0" scrolling="no"><a href="https://medium.com/media/7846ce51bf57c049aea6e3ff184bb451/href">https://medium.com/media/7846ce51bf57c049aea6e3ff184bb451/href</a></iframe><p>另外 Star Trek: Picard 的劇情結構有些鬆散，常常跳來跳去的，如果對 Star Trek 過往不熟悉的人，可能看得會有些辛苦，像我大概都快忘光羅慕倫人到底之前是發生了什麼事情。另外有些角色沒有好好花揮也有些可惜，像是全像投影醫生，以前在 Voyager，Hologram Doctor 可說是佔盡風頭。</p><p>IMDb: 8<br>爛番茄: 90<br>我的評價: 4 顆星</p><h3>Tom Clancy’s Jack Ryan</h3><p>Jack Ryan 改編自湯姆可蘭西的小說，以前福伯拍過(愛國者遊戲)，後來是另外一位 Enterprise 艦長 Chris Pine 也拍過，這次是噤界的 John Krasinski。</p><p>Jack Ryan 的故事情節多半都差不多，主角一開始是中情局中的小小分析師，後來立大功變成間諜的故事。</p><p>目前有兩季，第一季講中東，第二季則是前陣子蠻紅的委內瑞拉。這部美劇劇情緊湊，不小心一沒注意兩季就看完了，我自己是給他蠻高的評價。非常適合用來打發無聊的時間。</p><p>IMDb: 8.1<br>爛番茄: 71%<br>我的評價: 4.5 顆星</p><h3>一些我還沒看完的</h3><h4>High Castle</h4><p>評價很高，但我沒那麼愛。講的是虛構的歷史，假設當年不是聯軍贏得二次大戰，而是德日兩國聯軍贏了二戰，並瓜分美國領土，到底會是怎麼樣的光景。</p><h4>Treadstone</h4><p>Tredstone 同樣是改編自很有名的電影 Jason Bourne 系列，講的是一種強化人類的神秘藥物被用在一些特務上，並被拿來執行一些暗殺任務。是 Jason Bourne 的影子在裡面，但是劇情也是有些跳來跳去，有時候就比較難繼續發落下去。</p><h3>一些在待看名單中的</h3><ul><li>The Purge</li><li>Homecoming</li><li>Taken</li></ul><p>看來 Amazon Prime Video 很愛把一些熱門的電影再改拍為影集，我猜是怕出錯，票房保證搞砸機率比較低，這部份跟 Netflix 有很大的不同。所以在影集的多樣化上，比 Netflix 差。但是當 Netflix 鬧劇荒時，倒是偶爾可以轉到 Prmie Video 這來找一些好片來看。</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=19a5e0025c5c" width="1" height="1" alt="">]]></content:encoded>
        </item>
    </channel>
</rss>