<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	xmlns:media="http://search.yahoo.com/mrss/"
>

<channel>
	<title>技术 归档 - Tinyfool的个人网站</title>
	<atom:link href="https://codechina.org/category/tech/feed/" rel="self" type="application/rss+xml" />
	<link>https://codechina.org/category/tech/</link>
	<description></description>
	<lastBuildDate>Thu, 27 Jun 2024 02:09:50 +0000</lastBuildDate>
	<language>zh-Hans</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	<generator>https://wordpress.org/?v=6.9.4</generator>
	<item>
		<title>用 Xcode cloud 解决 Xcode-beta 无法提交 App 的问题</title>
		<link>https://codechina.org/2024/06/30876/</link>
					<comments>https://codechina.org/2024/06/30876/#respond</comments>
		
		<dc:creator><![CDATA[tinyfool]]></dc:creator>
		<pubDate>Wed, 26 Jun 2024 03:55:17 +0000</pubDate>
				<category><![CDATA[iOS开发]]></category>
		<category><![CDATA[MacOS]]></category>
		<category><![CDATA[技术]]></category>
		<guid isPermaLink="false">https://codechina.org/?p=30876</guid>

					<description><![CDATA[<p>前两天苹果的 WWDC 2024结束，每次苹果召开 WWDC 都是苹果平台开发者的节日。听完 Keynote， [&#8230;]</p>
<p><a href="https://codechina.org/2024/06/30876/">用 Xcode cloud 解决 Xcode-beta 无法提交 App 的问题</a>最先出现在<a href="https://codechina.org">Tinyfool的个人网站</a>。</p>
]]></description>
										<content:encoded><![CDATA[
<p>前两天苹果的 WWDC 2024结束，每次苹果召开 WWDC 都是苹果平台开发者的节日。听完 Keynote，大家往往就想最先下载测试版本的操作系统和 Xcode 来尝鲜。</p>



<p>但是这里也有一个矛盾，一般来说从测试版到正式版要1个多月的时间。而测试版的 Xcode-beta 是无法提交 App。也就是尝鲜的话，你就有一个多月没办法提交你的 App。</p>



<p>解决的方法，一般是如果自己有多台 mac，其中一台不升级，专门留着用来提交 App。还有一种就是安装多系统。</p>



<p>但是前几年，苹果推出了 Xcode cloud，我就想是不是可以利用 Xcode cloud来解决这个问题呢？果然解决了。</p>



<span id="more-30876"></span>



<p>大概做法如下：</p>



<p>首先，打开 Xcode 打开你的代码工程文件。然后按键盘&nbsp;⌘+9 。这会打开侧边栏的 report 页面，如下图，选择 Cloud。即可看到常见 Xcode cloud的向导。</p>


<div class="wp-block-image">
<figure class="aligncenter size-full"><img fetchpriority="high" decoding="async" width="468" height="892" src="https://codechina.org/wp-content/uploads/2024/06/截屏2024-06-26-10.52.26.png" alt="" class="wp-image-30877" srcset="https://codechina.org/wp-content/uploads/2024/06/截屏2024-06-26-10.52.26.png 468w, https://codechina.org/wp-content/uploads/2024/06/截屏2024-06-26-10.52.26-157x300.png 157w" sizes="(max-width: 468px) 100vw, 468px" /></figure>
</div>


<p>点击 Get Started&#8230; 按钮，然后按照向导一步步执行即可。</p>



<p>过程包括选择 product，授权 Xcode 访问你的 Github 代码库等步骤。</p>



<p>完成后，Cloud 页面如图：</p>


<div class="wp-block-image">
<figure class="aligncenter size-full"><img decoding="async" width="484" height="494" src="https://codechina.org/wp-content/uploads/2024/06/截屏2024-06-26-10.55.48.png" alt="" class="wp-image-30878" srcset="https://codechina.org/wp-content/uploads/2024/06/截屏2024-06-26-10.55.48.png 484w, https://codechina.org/wp-content/uploads/2024/06/截屏2024-06-26-10.55.48-294x300.png 294w" sizes="(max-width: 484px) 100vw, 484px" /></figure>
</div>


<p>主要显示的是，Build的历史记录，对勾和叉，代表了成功的构建和失败的构建，这很一目了然。</p>



<p>默认的设置是每次代码提交到 Github 就会自动 build 一次。熟悉其他 CI 系统的人应该很好上手。也可以在 Xcode 当前界面右侧的详情页，右上角点击 Start Build 手动 Build。</p>



<p>在 App Store Connect 网站的 App 页面也可以找到 Xcode cloud 的页面，也可以用页面右上角的 “启动构建版本” 按钮来手动构建。</p>



<figure class="wp-block-image size-large"><img decoding="async" width="1024" height="523" src="https://codechina.org/wp-content/uploads/2024/06/截屏2024-06-26-10.59.43-1024x523.png" alt="" class="wp-image-30879" srcset="https://codechina.org/wp-content/uploads/2024/06/截屏2024-06-26-10.59.43-1024x523.png 1024w, https://codechina.org/wp-content/uploads/2024/06/截屏2024-06-26-10.59.43-300x153.png 300w, https://codechina.org/wp-content/uploads/2024/06/截屏2024-06-26-10.59.43-768x392.png 768w, https://codechina.org/wp-content/uploads/2024/06/截屏2024-06-26-10.59.43-1536x785.png 1536w, https://codechina.org/wp-content/uploads/2024/06/截屏2024-06-26-10.59.43-1200x613.png 1200w, https://codechina.org/wp-content/uploads/2024/06/截屏2024-06-26-10.59.43.png 1852w" sizes="(max-width: 1024px) 100vw, 1024px" /></figure>



<ol class="wp-block-list">
<li>这样直接设置的 Xcode cloud 工作流，直接 build 往往会失败。因为我们往往会用 CocoaPods 或者&nbsp;Carthage 来管理我们依赖的第三方库。直接从 Github 拉出来的代码不包含这些库的代码，就无法正常编译。我自己用的是 CocoaPods 下面就介绍一下。</li>
</ol>



<p>这需要自定义的 build 脚本，不过不用担心，非常简单，如果你熟悉其他的 CI 系统就更容易理解。</p>



<p>Xcode Cloud 的构建过程如下图：</p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="165" src="https://codechina.org/wp-content/uploads/2024/06/Custom-Build-Scripts-1024x165.png" alt="" class="wp-image-30880" srcset="https://codechina.org/wp-content/uploads/2024/06/Custom-Build-Scripts-1024x165.png 1024w, https://codechina.org/wp-content/uploads/2024/06/Custom-Build-Scripts-300x48.png 300w, https://codechina.org/wp-content/uploads/2024/06/Custom-Build-Scripts-768x123.png 768w, https://codechina.org/wp-content/uploads/2024/06/Custom-Build-Scripts-1200x193.png 1200w, https://codechina.org/wp-content/uploads/2024/06/Custom-Build-Scripts.png 1406w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>



<ol class="wp-block-list">
<li>创建临时环境</li>



<li>Clone 代码</li>



<li>执行 Post-Clone 脚本（自定义的在 Clone后做处理的脚本）</li>



<li>解决依赖关系</li>



<li>执行&nbsp;Xcodebuild 之前的前置脚本</li>



<li>执行 xcodebuild 命令</li>



<li>执行&nbsp;Xcodebuild&nbsp;之前的后置脚本</li>



<li>保存结果<br></li>
</ol>



<p>图中蓝色部分，都是系统自动执行的。而3，5，6部分分别对应三个自定义脚本。</p>



<p><code>ci<wbr>_post<wbr>_clone<wbr>.sh 文件</code>处理 clone 代码后续的处理。ci_pre_xcodebuild.sh&nbsp;文件处理执行 Xcodebuild 之前的前置工作。ci_post_xcodebuild.sh 文件处理执行&nbsp;Xcodebuild 之后的后续操作。</p>



<p>在你的代码目录下创建一个&nbsp;ci_scripts 目录，在里面创建这三个文件就可以。加入 CocoaPods 的第三方依赖处理代码，我觉得可以放在&nbsp;ci_post_clone.sh 里，也可以放在&nbsp;ci_pre_xcodebuild.sh。区别不大，我做的时候，放在&nbsp;ci_pre_xcodebuild.sh 里了。</p>



<p>我找到的一个建议&nbsp;CocoaPods 处理代码为：</p>



<pre class="wp-block-code"><code lang="bash" class="language-bash"><code>#!/bin/sh</code>
<code>gem install cocoapods</code>
<code>pod&nbsp;install</code></code></pre>



<p><br>经测试失败，因为 xcode build 环境是 gem 2.6 而且不可直接安装新的库。</p>



<p>我经过测试，自己写的处理代码为：</p>



<pre class="wp-block-code"><code lang="bash" class="language-bash">#!/bin/bash
\curl -sSL https://get.rvm.io | bash -s stable
source /Users/local/.rvm/scripts/rvm
rvm install 2.7.2
rvm use 2.7.2 --default
gem install cocoapods
pod install
</code></pre>



<p><br>经测试，完全没问题。</p>



<p>手动给脚本加上执行权限&nbsp;chmod +x&nbsp;ci_pre_xcodebuild.sh，然后提交到 Git 以后，就OK了。</p>



<p>最后一个操作是在 App Store Connect 的你的 App 的 Xcode Cloud 页面选择“管理工作流程”：</p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="506" src="https://codechina.org/wp-content/uploads/2024/06/截屏2024-06-26-11.28.28-1024x506.png" alt="" class="wp-image-30881" srcset="https://codechina.org/wp-content/uploads/2024/06/截屏2024-06-26-11.28.28-1024x506.png 1024w, https://codechina.org/wp-content/uploads/2024/06/截屏2024-06-26-11.28.28-300x148.png 300w, https://codechina.org/wp-content/uploads/2024/06/截屏2024-06-26-11.28.28-768x379.png 768w, https://codechina.org/wp-content/uploads/2024/06/截屏2024-06-26-11.28.28.png 1130w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>



<p>然后点击你的工作流程，我这里是Default（默认的名称）。</p>



<p>在详情页面里，找到操作：</p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="298" src="https://codechina.org/wp-content/uploads/2024/06/截屏2024-06-26-11.30.00-1024x298.png" alt="" class="wp-image-30882" srcset="https://codechina.org/wp-content/uploads/2024/06/截屏2024-06-26-11.30.00-1024x298.png 1024w, https://codechina.org/wp-content/uploads/2024/06/截屏2024-06-26-11.30.00-300x87.png 300w, https://codechina.org/wp-content/uploads/2024/06/截屏2024-06-26-11.30.00-768x224.png 768w, https://codechina.org/wp-content/uploads/2024/06/截屏2024-06-26-11.30.00-1536x448.png 1536w, https://codechina.org/wp-content/uploads/2024/06/截屏2024-06-26-11.30.00-1200x350.png 1200w, https://codechina.org/wp-content/uploads/2024/06/截屏2024-06-26-11.30.00.png 1860w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>



<p>分发准备里面，选择 App Store Connect。</p>



<p>默认是无，就是只做 build 不提交到 App Store，把这个改好后，每次 build 成功，就会自动把 build 好的 App 提交到 App Store，然后你选择是 TestFlight，还是正式提交了。</p>



<p>昨天我的<a href="https://apps.apple.com/us/app/%E8%8B%B1%E8%AF%AD%E8%BD%BB%E6%9D%BE%E8%AF%BB/id1471605122">英语轻松读</a>的最新版本 1.21，使用 Xcode-beta 开发，使用 Xcode cloud build 的版本已经提交到了 App Store，也过审了。</p>



<p>这个版本，加入了调整文章行间距的功能。</p>


<div class="wp-block-image">
<figure class="aligncenter size-large"><img loading="lazy" decoding="async" width="850" height="1024" src="https://codechina.org/wp-content/uploads/2024/06/Simulator-Screenshot-iPhone-15-Pro-Max-2024-06-26-at-09.58.14-850x1024.png" alt="" class="wp-image-30883" srcset="https://codechina.org/wp-content/uploads/2024/06/Simulator-Screenshot-iPhone-15-Pro-Max-2024-06-26-at-09.58.14-850x1024.png 850w, https://codechina.org/wp-content/uploads/2024/06/Simulator-Screenshot-iPhone-15-Pro-Max-2024-06-26-at-09.58.14-249x300.png 249w, https://codechina.org/wp-content/uploads/2024/06/Simulator-Screenshot-iPhone-15-Pro-Max-2024-06-26-at-09.58.14-768x925.png 768w, https://codechina.org/wp-content/uploads/2024/06/Simulator-Screenshot-iPhone-15-Pro-Max-2024-06-26-at-09.58.14-1275x1536.png 1275w, https://codechina.org/wp-content/uploads/2024/06/Simulator-Screenshot-iPhone-15-Pro-Max-2024-06-26-at-09.58.14-1200x1446.png 1200w, https://codechina.org/wp-content/uploads/2024/06/Simulator-Screenshot-iPhone-15-Pro-Max-2024-06-26-at-09.58.14.png 1290w" sizes="auto, (max-width: 850px) 100vw, 850px" /></figure>
</div>


<p>最后，如果 build 失败，该怎么调试呢？</p>



<p>你可以在 Xcode 侧栏的 report 页面，选择失败的 Build，然后在右边详情页面，选择 log。然后查看具体的 log，根据 log 的提示去修改你的 build 脚本即可。</p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="723" src="https://codechina.org/wp-content/uploads/2024/06/Xcode-Cloud-Solution-2-1024x723.webp" alt="" class="wp-image-30884" srcset="https://codechina.org/wp-content/uploads/2024/06/Xcode-Cloud-Solution-2-1024x723.webp 1024w, https://codechina.org/wp-content/uploads/2024/06/Xcode-Cloud-Solution-2-300x212.webp 300w, https://codechina.org/wp-content/uploads/2024/06/Xcode-Cloud-Solution-2-768x543.webp 768w, https://codechina.org/wp-content/uploads/2024/06/Xcode-Cloud-Solution-2.webp 1080w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>



<p>参考文献：</p>



<ul class="wp-block-list">
<li><strong><a href="https://developer.apple.com/documentation/xcode/writing-custom-build-scripts">Writing custom build scripts</a></strong></li>



<li><strong><a href="https://developer.apple.com/documentation/xcode/making-dependencies-available-to-xcode-cloud#Make-Carthage-dependencies-available-to-Xcode-Cloud">Making dependencies available to Xcode Cloud</a></strong></li>
</ul>
<p><a href="https://codechina.org/2024/06/30876/">用 Xcode cloud 解决 Xcode-beta 无法提交 App 的问题</a>最先出现在<a href="https://codechina.org">Tinyfool的个人网站</a>。</p>
]]></content:encoded>
					
					<wfw:commentRss>https://codechina.org/2024/06/30876/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			<media:content url="https://codechina.org/wp-content/uploads/2024/06/DALL·E-Xcode-Cloud-1024x585.webp" medium="image" />
	</item>
		<item>
		<title>WWDC 2024将近，苹果的AI革命会给基于AI的独立开发者带来灭顶之灾么？</title>
		<link>https://codechina.org/2024/06/30798/</link>
					<comments>https://codechina.org/2024/06/30798/#respond</comments>
		
		<dc:creator><![CDATA[tinyfool]]></dc:creator>
		<pubDate>Thu, 06 Jun 2024 01:20:00 +0000</pubDate>
				<category><![CDATA[iOS开发]]></category>
		<category><![CDATA[IT行业]]></category>
		<category><![CDATA[技术]]></category>
		<guid isPermaLink="false">https://codechina.org/?p=30798</guid>

					<description><![CDATA[<p>6月11日，WWDC 2024 就要召开了。每年 WWDC 召开以后，随着苹果发布一堆新的内嵌功能，就会在推特 [&#8230;]</p>
<p><a href="https://codechina.org/2024/06/30798/">WWDC 2024将近，苹果的AI革命会给基于AI的独立开发者带来灭顶之灾么？</a>最先出现在<a href="https://codechina.org">Tinyfool的个人网站</a>。</p>
]]></description>
										<content:encoded><![CDATA[
<p>6月11日，WWDC 2024 就要召开了。每年 WWDC 召开以后，随着苹果发布一堆新的内嵌功能，就会在推特和各种 blog 网站引发很多讨论。很多独立开发者就会哭着喊着说，苹果在搞垄断，苹果新内嵌的某某功能会影响他们的生意，甚至毁掉他们的营生。</p>



<span id="more-30798"></span>



<p>最早的一个例子可能是手电筒功能，在这个功能被内嵌之前，类似的小工具类应用是 AppStore 上的现金奶牛。很多小厂商和独立开发者都喜欢做这类的小工具。然而，苹果内置这个功能了，一边哀鸿遍野。现在你在 AppStore 搜索还可以找到很多手电筒应用，但是显然他们已经不是当下最热门的应用了。</p>



<p>后来的例子也很多，比如在苹果把 Podcast 功能独立成一个 App 以后，很多做 Podcast 应用的作者都倍感压力。当然也存在反例，Reddit 上一篇非常火热的文章标题是“<a href="https://www.reddit.com/r/apple/comments/o1fvq0/apple_podcasts_is_made_by_a_2_trillion_dollar/">Apple Podcasts is made by a 2 trillion dollar company and yet one developer bests it with Overcast; why?</a>”，即使是苹果推出了自己的独立 Podcast App，还是有很多人更喜欢 Overcast。在中国也是，有很多人更喜欢小宇宙、或者是喜马拉雅之类的类似应用。</p>



<p>苹果推出的 Shortcuts、睡眠跟踪、屏幕时间、甚至是 Safari 内置的广告拦截，等等，各种功能的推出都曾经被一些收到伤害的独立开发者批评。</p>



<p>那么据说最近苹果会在 WWDC 2024 全面拥抱大语言模型，会不会给很多独立开发者带来伤害呢？</p>



<p>我们最直接可以想到的就是语音备忘录类的 App， 比如 <a href="https://apps.apple.com/us/app/rev-record-transcribe/id598332111">Rev</a> 或者我朋友的团队做的 <a href="https://apps.apple.com/cn/app/slaxnote/id6480166286">SlaxNote</a> 都是基于 AI 的语音备忘录 App，它们不仅可以录制语音备忘录，而且可以利用大语言模型把这些录音转换为文本，甚至可以润色、翻译，等等。</p>



<p>然而，现在传言这次 WWDC 苹果会把这些能力都在其内置的语音备忘录 App 里面实现了。</p>



<p>还有就是那些做文章摘要的 App，这次据说 Safari 也会内嵌文章摘要能力。</p>



<p>还有就是轻松可以想到的是在苹果自己的备忘录App里面也会嵌入 AI 能力，这样的话，前些日子因为集成了 AI 能力而吸引了眼球的 <a href="https://www.craft.do/">Craft</a> 和 <a href="https://www.notion.so/">Notion</a> 又何去何从呢？</p>



<p>显而易见的是，邮件、消息 AI 回复建议之类的 App，照片 AI 编辑类的 App，都有可能在这次 WWDC 的发布后，受到波及。</p>



<h2 class="wp-block-heading">那么该怎么办呢？</h2>



<p>以下几点，应该是比较好的应对：</p>



<h3 class="wp-block-heading">1、深挖用户群体需求，构建自己的用户群体</h3>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="585" src="https://codechina.org/wp-content/uploads/2024/06/DALL·E-2024-06-05-16.57.44-Developers-interacting-1024x585.webp" alt="" class="wp-image-30804" srcset="https://codechina.org/wp-content/uploads/2024/06/DALL·E-2024-06-05-16.57.44-Developers-interacting-1024x585.webp 1024w, https://codechina.org/wp-content/uploads/2024/06/DALL·E-2024-06-05-16.57.44-Developers-interacting-300x171.webp 300w, https://codechina.org/wp-content/uploads/2024/06/DALL·E-2024-06-05-16.57.44-Developers-interacting-768x439.webp 768w, https://codechina.org/wp-content/uploads/2024/06/DALL·E-2024-06-05-16.57.44-Developers-interacting-1536x878.webp 1536w, https://codechina.org/wp-content/uploads/2024/06/DALL·E-2024-06-05-16.57.44-Developers-interacting-1200x686.webp 1200w, https://codechina.org/wp-content/uploads/2024/06/DALL·E-2024-06-05-16.57.44-Developers-interacting.webp 1792w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>



<p>苹果内置的功能，集成度高，用户体验好。但是往往是针对最广泛的手机、平板用户去设计的。对特别用户群体的思考比较少。也不会做太深入的探索和用户体验的打磨。</p>



<p>拿刚才提到的 Overcast 为例，Marco Arment 设计了非常独特的 Podcast 加速播放技术，他可以压缩一些语音文件里面的空白部分，从而得到了一个既加速播放，但是又听起来很自然的感觉。这些独特的思路和研究，不太可能出现在苹果设计的内置 App 里面。</p>



<p>再比如，苹果做的睡眠跟踪功能利用了 Apple Watch 的强大能力，甚至可以监控你睡眠的时候的体温。但是有两个问题，如果你不买 Apple Watch，单用 iPhone 是无法跟踪睡眠的，另外，它没有鼾声录制功能。我以前用过的一款<a href="https://apps.apple.com/cn/app/%E8%9C%97%E7%89%9B%E7%9D%A1%E7%9C%A0-%E6%A2%A6%E8%AF%9D%E9%BC%BE%E5%A3%B0%E7%9D%A1%E7%9C%A0%E7%9B%91%E6%B5%8B%E8%AE%B0%E5%BD%95%E5%8F%8A%E5%A4%B1%E7%9C%A0%E6%89%93%E9%BC%BE%E8%A7%A3%E5%86%B3%E6%96%B9%E6%A1%88/id1025313530">蜗牛睡眠</a>，就可以录制鼾声，让自己知道自己打鼾到底多么严重，也可以知道自己说了什么梦话。这些独特的功能，让 Apple Watch 大行其道的时候，这些睡眠监控 App，也仍旧有自己的生存空间。</p>



<h3 class="wp-block-heading">2、长期战略坚持战斗</h3>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="585" src="https://codechina.org/wp-content/uploads/2024/06/DALL·E-Inspiring-Scene-2024-06-05-1024x585.webp" alt="" class="wp-image-30805" srcset="https://codechina.org/wp-content/uploads/2024/06/DALL·E-Inspiring-Scene-2024-06-05-1024x585.webp 1024w, https://codechina.org/wp-content/uploads/2024/06/DALL·E-Inspiring-Scene-2024-06-05-300x171.webp 300w, https://codechina.org/wp-content/uploads/2024/06/DALL·E-Inspiring-Scene-2024-06-05-768x439.webp 768w, https://codechina.org/wp-content/uploads/2024/06/DALL·E-Inspiring-Scene-2024-06-05-1536x878.webp 1536w, https://codechina.org/wp-content/uploads/2024/06/DALL·E-Inspiring-Scene-2024-06-05-1200x686.webp 1200w, https://codechina.org/wp-content/uploads/2024/06/DALL·E-Inspiring-Scene-2024-06-05.webp 1792w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>



<p>从一般的角度来说，很多人会认为苹果的产品是无坚不摧的，是非常强大的。但是，其实长期使用苹果的软件和服务以后，我相信很多人会发现。苹果更擅长做硬件，或者说做硬件和软件结合的产品。对长期稳定的更新软件和进行服务的能力其实不如微软、Google等竞争对手。</p>



<p>例如 Siri 最早推出的时候，是独步天下的。但是在竞争对手 Google 和亚马逊下场后，Siri 的进步缓慢就逐渐被大家认识到了。</p>



<p>我们会发现，苹果的硬件一年更新一次，很多软件也是按照这个频率去更新的。除了在 WWDC 每年发布操作系统的大更新，其实平常 MacOS、iPhone 的软件更新往往局限于安全和细节上的小修改。很少出现功能的提升和用户体验的显著改进。当然苹果的操作系统和软件部门的程序员也是每天工作的，但是按照苹果的习惯，这些工作成果是每年一次性的发布的。</p>



<p>也就是今天苹果推出了某个功能，超越了你的产品，或者说涵盖了你的产品的功能。你有一年的时间，加入一些新的能力和用户体验细节。在这个同时，苹果会安静的等待一年，才有可能用心的体验来跟你竞争。很多时候，苹果的软件产品一旦发布，几年都不会做大的修改。这其实在现在的互联网时代是非常少见的。</p>



<h3 class="wp-block-heading">3、多平台战略</h3>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="585" src="https://codechina.org/wp-content/uploads/2024/06/DALL·E-dynamic-scene-2024-06-05-1024x585.webp" alt="" class="wp-image-30806" srcset="https://codechina.org/wp-content/uploads/2024/06/DALL·E-dynamic-scene-2024-06-05-1024x585.webp 1024w, https://codechina.org/wp-content/uploads/2024/06/DALL·E-dynamic-scene-2024-06-05-300x171.webp 300w, https://codechina.org/wp-content/uploads/2024/06/DALL·E-dynamic-scene-2024-06-05-768x439.webp 768w, https://codechina.org/wp-content/uploads/2024/06/DALL·E-dynamic-scene-2024-06-05-1536x878.webp 1536w, https://codechina.org/wp-content/uploads/2024/06/DALL·E-dynamic-scene-2024-06-05-1200x686.webp 1200w, https://codechina.org/wp-content/uploads/2024/06/DALL·E-dynamic-scene-2024-06-05.webp 1792w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>



<p>苹果绝大多数应用是肯定不会做其他平台版本的。有一些需求上，多平台应用第三方开发者天生有优势。举个例子，苹果有自己的密码仓库功能，但是并不影响 1password 之类的应用。</p>



<p>从安卓到 Mac 传输文件，从 iPhone 传输文件到 Windows PC 之类的需求，都是天生不用担心苹果会去涉足的领域。</p>



<h3 class="wp-block-heading">4、以其人之道，还治其人之身</h3>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="585" src="https://codechina.org/wp-content/uploads/2024/06/DALL·E-Independent-Developer-Scene-1024x585.webp" alt="" class="wp-image-30807" srcset="https://codechina.org/wp-content/uploads/2024/06/DALL·E-Independent-Developer-Scene-1024x585.webp 1024w, https://codechina.org/wp-content/uploads/2024/06/DALL·E-Independent-Developer-Scene-300x171.webp 300w, https://codechina.org/wp-content/uploads/2024/06/DALL·E-Independent-Developer-Scene-768x439.webp 768w, https://codechina.org/wp-content/uploads/2024/06/DALL·E-Independent-Developer-Scene-1536x878.webp 1536w, https://codechina.org/wp-content/uploads/2024/06/DALL·E-Independent-Developer-Scene-1200x686.webp 1200w, https://codechina.org/wp-content/uploads/2024/06/DALL·E-Independent-Developer-Scene.webp 1792w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>



<p>很多开发者没有特别注意到的是，每次苹果开发一些内置功能和 App，都会更新自己的 API，比如屏幕时间就是有 API 的，苹果的健康应用也有 API。有时候你可以站在苹果的肩膀上去跟苹果竞争，苹果把一个需求的基础已经做好了。你可以调用苹果的 API 去完成更深入细分的需求，去跟苹果竞争。</p>



<p>总之，苹果发布基于 AI 的各种功能更新，肯定是对很多现在正在做基于 AI 的产品的独立开发者带来了一些挑战，但是也可能是新的机会。</p>



<p>本文英文版：<a href="https://iapp4me.com/news/83/is-apples-ai-revolution-at-wwdc-2024-a-doomsday-for-ai-based-independent-developers/">Is Apple’s AI Revolution at WWDC 2024 a Doomsday for AI-Based Independent Developers?</a></p>
<p><a href="https://codechina.org/2024/06/30798/">WWDC 2024将近，苹果的AI革命会给基于AI的独立开发者带来灭顶之灾么？</a>最先出现在<a href="https://codechina.org">Tinyfool的个人网站</a>。</p>
]]></content:encoded>
					
					<wfw:commentRss>https://codechina.org/2024/06/30798/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			<media:content url="https://codechina.org/wp-content/uploads/2024/06/DALL·E-dramatic-conference-1024x585.webp" medium="image" />
	</item>
		<item>
		<title>Swift编程中应用@available和deprecated在自己的编程中提供便利</title>
		<link>https://codechina.org/2024/04/30772/</link>
					<comments>https://codechina.org/2024/04/30772/#comments</comments>
		
		<dc:creator><![CDATA[tinyfool]]></dc:creator>
		<pubDate>Thu, 25 Apr 2024 02:52:49 +0000</pubDate>
				<category><![CDATA[iOS开发]]></category>
		<category><![CDATA[iOS]]></category>
		<category><![CDATA[iPhone]]></category>
		<category><![CDATA[swift]]></category>
		<category><![CDATA[swiftui]]></category>
		<guid isPermaLink="false">https://codechina.org/?p=30772</guid>

					<description><![CDATA[<p>在 Swift 中，@available 是一个属性标注（Attribute），它用来表示一个类、结构体、枚举 [&#8230;]</p>
<p><a href="https://codechina.org/2024/04/30772/">Swift编程中应用@available和deprecated在自己的编程中提供便利</a>最先出现在<a href="https://codechina.org">Tinyfool的个人网站</a>。</p>
]]></description>
										<content:encoded><![CDATA[
<p>在 Swift 中，@available 是一个属性标注（Attribute），它用来表示一个类、结构体、枚举、函数或者方法等的可用性信息，指示特定的平台和版本。通过这个属性标注，开发者可以对代码中的各个部分设定适用的操作系统平台及最低支持的版本，也可以指定在某个版本中它们已经过期或不推荐使用，甚至是未来某个版本中会被添加的特性。</p>



<p>我们使用苹果的标准 Swift 库的时候，经常遇到 @available ，一个老代码的某个函数调用，系统升级后，可能会发现一个警告，</p>



<pre class="wp-block-code"><code class="">'oldMethod(text:messages:key:)' is deprecated: Use newMethod() instead</code></pre>



<p>意思就是这个方法或者函数，现在已经被废弃了，最好不要再使用。在这个情况下，往往你其实还可以编译还可以执行。但是这些被废弃的老方法，要么也许有 bug ，或者系统的代码风格，习惯变了，已经被推荐使用了。有的人觉的既然可以编译和执行，何必理会呢？其实不然，有些方法会在某一个操作系统版本废弃，然后在后续的某个大操作系统版本就彻底消失，无法编译和运行。也就是说，废弃声明就是提醒你可以修改代码了，未来这个方法或者类有可能完全不能用了。最好尊重这些声明来写代码。</p>



<p>我们去看系统代码和头文件的时候，会看到很多类似的例子：</p>



<pre class="wp-block-code"><code class="">1. 指定功能在平台上的最小可用版本：<br>@available(iOS 10, *)<br>func newiOS10Method() {<br>    // 这个方法只会在 iOS 10 及以上版本可用<br>}<br><br>2. 标示一个功能在新版本中被弃用：<br>@available(iOS, deprecated: 11.0, message: "Use newMethod instead")<br>func oldMethod() {<br>    // 这个方法在 iOS 11 中被标记为弃用<br>}<br><br>3. 标示一个功能在新版本中被废弃或移除：<br>@available(iOS, obsoleted: 11.0, message: "Use anotherMethod instead")<br>func obsoleteMethod() {<br>    // 这个方法从 iOS 11 开始就废弃了，调用它会出错<br>}<br><br>4. 标示功能未来新增：<br>@available(iOS 15, *)<br>func futureMethod() {<br>    // 这个方法在未来的 iOS 15 版本中会被添加<br>}<br><br>5. 跨多平台设置可用性：<br>@available(iOS 10, macOS 10.12, *)<br>func crossPlatformMethod() {<br>    // 这个方法在 iOS 10 和 macOS 10.12 及以上版本都可用<br>}<br><br>6. 为不同的平台指定不同的最小版本：<br>@available(iOS 14, watchOS 7, *)<br>func multiPlatformMethod() {<br>    // 对于 iOS 平台，这个方法要求版本 14.0 及以上<br>    // 对于 watchOS 平台，这个方法要求版本 7.0 及以上<br>}</code></pre>



<p>但是，这是一般情况下我们接触的 @available 和 deprecated。其实我们自己的代码里面也可以用这些用法。比如我最近在给 <a href="https://tinystudio.ai/">TinyStudio（最好的Mac字幕软件之一）</a>增加新的功能，代码里面涉及到如何调用 ChatGPT，以及用 ChatGPT 来进行一些复杂的字幕后续处理操作。</p>



<p>在此之前我不知道 Swift 的 await 和 actor 语法，所以涉及到 ChatGPT 的代码非常复杂，比如一个巨长的文本发给 ChatGPT 需要实现分段，然后一段一段的去调用 ChatGPT 来进行处理。代码就非常复杂，我用递归调用和回调函数的方法来做，非常麻烦。虽然我可以轻松的写出这样的代码，但是这样的代码在调试、调优和异常处理方面简直是噩梦。</p>



<p>我知道了 Swift 的 await 和 actor 语法后，发现这个场景用这些并发语法来写，代码可以变得非常简洁，而且在调试、调优和异常处理方面非常方便。于是我就着手写 ChatGPT 和文本处理库的异步版本（await/actor）。写的时候，原有的函数叫 send ，新版本就叫做 asyncSend，原有的函数叫 format，新的就叫做 asyncFormat。</p>



<p>初步实现以后，我发现原有的 send 和 format 在很多地方都有调用，直接用文字搜索也会遇到一些类似的函数名。于是我就想起了 @available 和 deprecated 语法。</p>



<p>首先，我先把 ChatGPTKit 类和 TextKit 类的新老版本函数，放在不同的 extension 里（不影响执行，但是从代码来看，就可以把不同类型的方法条理清晰的分明白了）：</p>



<pre class="wp-block-code"><code class="">// 遗留版本函数<br>extension TextKit {<br><br>    func format(textString)  {<br>...<br><br>// 遗留版本函数<br>extension TextKit {<br><br>    func asyncFormat(textString)  {<br>...</code></pre>



<p>然后，在遗留版本函数的 extension 声明前，标注 @available 即可：</p>



<pre class="wp-block-code"><code class="">// 遗留版本函数<br><strong>@available</strong>(*, deprecated, message: "老版本已废弃，请使用异步版本")<br>extension TextKit {<br><br>    func format(textString)  {<br>...<br></code></pre>



<p>这时候编译程序，就会发现还在用老版本函数的代码就会被编译器发出警告，然后我们根据警告信息，一一替换为新版本就好了。如下：</p>



<figure class="wp-block-image size-full"><img loading="lazy" decoding="async" width="682" height="122" src="https://codechina.org/wp-content/uploads/2024/04/截屏2024-04-25-10.41.43-1.png" alt="" class="wp-image-30781" srcset="https://codechina.org/wp-content/uploads/2024/04/截屏2024-04-25-10.41.43-1.png 682w, https://codechina.org/wp-content/uploads/2024/04/截屏2024-04-25-10.41.43-1-300x54.png 300w" sizes="auto, (max-width: 682px) 100vw, 682px" /></figure>
<p><a href="https://codechina.org/2024/04/30772/">Swift编程中应用@available和deprecated在自己的编程中提供便利</a>最先出现在<a href="https://codechina.org">Tinyfool的个人网站</a>。</p>
]]></content:encoded>
					
					<wfw:commentRss>https://codechina.org/2024/04/30772/feed/</wfw:commentRss>
			<slash:comments>2</slash:comments>
		
		
			<media:content url="https://codechina.org/wp-content/uploads/2024/04/截屏2024-04-25-10.51.11-1.png" medium="image" />
	</item>
		<item>
		<title>PHP如何解析Youtube的RSS【ChatGPT】</title>
		<link>https://codechina.org/2024/01/30634/</link>
					<comments>https://codechina.org/2024/01/30634/#respond</comments>
		
		<dc:creator><![CDATA[tinyfool]]></dc:creator>
		<pubDate>Mon, 29 Jan 2024 15:44:29 +0000</pubDate>
				<category><![CDATA[技术]]></category>
		<category><![CDATA[ChatGPT]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[rss]]></category>
		<category><![CDATA[youtube]]></category>
		<guid isPermaLink="false">https://codechina.org/?p=30634</guid>

					<description><![CDATA[<p>最近我想把我的油管视频的RSS引入到我的其他网站，比如OurCoders里。这本来应该不难。本来OurCode [&#8230;]</p>
<p><a href="https://codechina.org/2024/01/30634/">PHP如何解析Youtube的RSS【ChatGPT】</a>最先出现在<a href="https://codechina.org">Tinyfool的个人网站</a>。</p>
]]></description>
										<content:encoded><![CDATA[
<p>最近我想把我的油管视频的RSS引入到我的其他网站，比如<a href="https://ourcoders.com/">OurCoders</a>里。这本来应该不难。本来OurCoders的代码里面就包含了<a href="https://magpierss.sourceforge.net/">magpierss</a>，这是一个古老的PHP RSS解析库，但是一直都可以用。</p>



<span id="more-30634"></span>



<p>但是今天发现，magpirerss解析不出来，这是因为Youtube的RSS其实跟规范不完全统一，不够合法。之前即使magpirerss可以解析的时候，有些部分的解析也是不完全对的，我还需要写代码来调整解析后的结果。</p>



<p>今天又解析不出来了，于是我干脆想换一个新的RSS解析器吧，毕竟这个都10多年没更新的，有些Bug也没人解决。于是我找到了<a href="https://github.com/dg/rss-php">rss-php</a>。安装rss-php，很容易，它支持composer。安装方法是：</p>



<pre class="wp-block-code"><code lang="bash" class="language-bash">composer require dg/rss-php</code></pre>



<p>使用方法也很简单：</p>



<pre class="wp-block-code"><code lang="php" class="language-php">$rss = Feed::loadRss($url);

echo 'Title: ', $rss-&gt;title;
echo 'Description: ', $rss-&gt;description;
echo 'Link: ', $rss-&gt;url;

foreach ($rss-&gt;item as $item) {
	echo 'Title: ', $item-&gt;title;
	echo 'Link: ', $item-&gt;url;
	echo 'Timestamp: ', $item-&gt;timestamp;
	echo 'Description ', $item-&gt;description;
	echo 'HTML encoded content: ', $item-&gt;{'content:encoded'};
}</code></pre>



<p>但是可怕的是换了rss-php还是无法解析。我就想干脆单独自己写解析Youtube RSS的代码吧。</p>



<p>下面是YoutubeRSS的例子：</p>



<pre class="wp-block-code"><code lang="xml" class="language-xml">&lt;?xml version="1.0" encoding="UTF-8"?&gt;
&lt;feed xmlns:yt="http://www.youtube.com/xml/schemas/2015" xmlns:media="http://search.yahoo.com/mrss/" xmlns="http://www.w3.org/2005/Atom"&gt;
 &lt;link rel="self" href="http://www.youtube.com/feeds/videos.xml?channel_id=UCdhngtoCb1xRmJQqkS5DpfA"/&gt;
 &lt;id&gt;yt:channel:dhngtoCb1xRmJQqkS5DpfA&lt;/id&gt;
 &lt;yt:channelId&gt;dhngtoCb1xRmJQqkS5DpfA&lt;/yt:channelId&gt;
 &lt;title&gt;Tinyfool的胡说八道&lt;/title&gt;
 &lt;link rel="alternate" href="https://www.youtube.com/channel/UCdhngtoCb1xRmJQqkS5DpfA"/&gt;
 &lt;author&gt;
  &lt;name&gt;Tinyfool的胡说八道&lt;/name&gt;
  &lt;uri&gt;https://www.youtube.com/channel/UCdhngtoCb1xRmJQqkS5DpfA&lt;/uri&gt;
 &lt;/author&gt;
 &lt;published&gt;2019-03-26T02:06:01+00:00&lt;/published&gt;
 &lt;entry&gt;
  &lt;id&gt;yt:video:0u_rS0CfhFc&lt;/id&gt;
  &lt;yt:videoId&gt;0u_rS0CfhFc&lt;/yt:videoId&gt;
  &lt;yt:channelId&gt;UCdhngtoCb1xRmJQqkS5DpfA&lt;/yt:channelId&gt;
  &lt;title&gt;军事是不是科技大发展的原动力？老范、徐凯和Tinyfool三人谈&lt;/title&gt;
  &lt;link rel="alternate" href="https://www.youtube.com/watch?v=0u_rS0CfhFc"/&gt;
  &lt;author&gt;
   &lt;name&gt;Tinyfool的胡说八道&lt;/name&gt;
   &lt;uri&gt;https://www.youtube.com/channel/UCdhngtoCb1xRmJQqkS5DpfA&lt;/uri&gt;
  &lt;/author&gt;
  &lt;published&gt;2024-01-23T00:40:00+00:00&lt;/published&gt;
  &lt;updated&gt;2024-01-23T00:40:00+00:00&lt;/updated&gt;
  &lt;media:group&gt;
   &lt;media:title&gt;军事是不是科技大发展的原动力？老范、徐凯和Tinyfool三人谈&lt;/media:title&gt;
   &lt;media:content url="https://www.youtube.com/v/0u_rS0CfhFc?version=3" type="application/x-shockwave-flash" width="640" height="390"/&gt;
   &lt;media:thumbnail url="https://i1.ytimg.com/vi/0u_rS0CfhFc/hqdefault.jpg" width="480" height="360"/&gt;
   &lt;media:description&gt;成为此频道的会员即可获享以下福利：
https://www.youtube.com/channel/UCdhngtoCb1xRmJQqkS5DpfA/join


本视频字幕使用TinyStudio生成 https://tinystudio.ai/&lt;/media:description&gt;
   &lt;media:community&gt;
    &lt;media:starRating count="54" average="5.00" min="1" max="5"/&gt;
    &lt;media:statistics views="2065"/&gt;
   &lt;/media:community&gt;
  &lt;/media:group&gt;
 &lt;/entry&gt;
 &lt;entry&gt;
  &lt;id&gt;yt:video:kj8b3sJ_gJE&lt;/id&gt;
  &lt;yt:videoId&gt;kj8b3sJ_gJE&lt;/yt:videoId&gt;
  &lt;yt:channelId&gt;UCdhngtoCb1xRmJQqkS5DpfA&lt;/yt:channelId&gt;
  &lt;title&gt;老范采访我，问我为啥要做游戏&lt;/title&gt;
  &lt;link rel="alternate" href="https://www.youtube.com/watch?v=kj8b3sJ_gJE"/&gt;
  &lt;author&gt;
   &lt;name&gt;Tinyfool的胡说八道&lt;/name&gt;
   &lt;uri&gt;https://www.youtube.com/channel/UCdhngtoCb1xRmJQqkS5DpfA&lt;/uri&gt;
  &lt;/author&gt;
  &lt;published&gt;2024-01-21T01:00:20+00:00&lt;/published&gt;
  &lt;updated&gt;2024-01-21T01:00:20+00:00&lt;/updated&gt;
  &lt;media:group&gt;
   &lt;media:title&gt;老范采访我，问我为啥要做游戏&lt;/media:title&gt;
   &lt;media:content url="https://www.youtube.com/v/kj8b3sJ_gJE?version=3" type="application/x-shockwave-flash" width="640" height="390"/&gt;
   &lt;media:thumbnail url="https://i4.ytimg.com/vi/kj8b3sJ_gJE/hqdefault.jpg" width="480" height="360"/&gt;
   &lt;media:description&gt;成为此频道的会员即可获享以下福利：
https://www.youtube.com/channel/UCdhngtoCb1xRmJQqkS5DpfA/join


本视频字幕使用TinyStudio生成 https://tinystudio.ai/&lt;/media:description&gt;
   &lt;media:community&gt;
    &lt;media:starRating count="54" average="5.00" min="1" max="5"/&gt;
    &lt;media:statistics views="2452"/&gt;
   &lt;/media:community&gt;
  &lt;/media:group&gt;
 &lt;/entry&gt;

&lt;/feed&gt;</code></pre>



<p>但是写起来好麻烦啊。对啊，我们有 ChatGPT，万事不决问ChatGPT，于是我写下了如下的Prompt：</p>



<pre class="wp-block-preformatted">如下的xml，我希望读取每个<code>entry</code>的id，title，link，published，updated，media:thumbnail，media:description等信息，用PHP如何获得 </pre>



<p>ChatGPT回复道：</p>



<pre class="wp-block-preformatted">使用SimpleXML扩展可以轻松地解析这样的XML。但请注意，由于XML具有命名空间，因此需要在处理元素和属性时指定它们。以下是如何用SimpleXML读取每个&lt;entry>的id，title，link，published，updated，media:thumbnail，media:description等信息： </pre>



<pre class="wp-block-code"><code lang="php" class="language-php">&lt;?php
$xmlString = '...'; // 这里放你的原始XML字符串
$xml = simplexml_load_string($xmlString);
$xml->registerXPathNamespace('media', 'http://search.yahoo.com/mrss/');
$xml->registerXPathNamespace('yt', 'http://www.youtube.com/xml/schemas/2015');

foreach ($xml->entry as $entry) {
    $id = (string)$entry->id; // 或者使用 $entry->children('yt', true)->videoId
    $title = (string)$entry->title;
    $link = (string)$entry->link->attributes()->href;
    $published = (string)$entry->published;
    $updated = (string)$entry->updated;
    
    // 获取媒体信息
    $mediaGroup = $entry->children('media', true)->group;
    $mediaThumbnail = (string)$mediaGroup->thumbnail->attributes()->url;
    $mediaDescription = (string)$mediaGroup->description;
    
    // 输出信息
    echo "ID: $id\n";
    echo "Title: $title\n";
    echo "Link: $link\n";
    echo "Published on: $published\n";
    echo "Updated on: $updated\n";
    echo "Thumbnail: $mediaThumbnail\n";
    echo "Description: $mediaDescription\n";
    echo "----------------------\n";
}
?></code></pre>



<pre class="wp-block-preformatted">这段代码首先加载了XML字符串到$xml变量。然后，我们使用registerXPathNamespace()函数来注册XML中使用的命名空间。这对于正确解析media:和yt:前缀的元素至关重要。接着，代码遍历了&lt;entry>标签中的每一个条目，提取和打印了所需的信息。 请注意，由于含有冒号（:）的XML元素属于名称空间，我们需要使用children()方法来访问它们。SimpleXML中的attributes()方法被用于获取元素的属性。 这段代码提供了一个基本的框架，可能需要根据实际XML结构或者特定需求进行适当的调整。同时，确保输入的XML字符串是完整和有效的，这里出于示例缩短了字符串内容。</pre>



<p>问题解决了</p>
<p><a href="https://codechina.org/2024/01/30634/">PHP如何解析Youtube的RSS【ChatGPT】</a>最先出现在<a href="https://codechina.org">Tinyfool的个人网站</a>。</p>
]]></content:encoded>
					
					<wfw:commentRss>https://codechina.org/2024/01/30634/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			<media:content url="https://codechina.org/wp-content/uploads/2024/01/截屏2024-01-29-23.38.21.png" medium="image" />
	</item>
		<item>
		<title>在Mac上用FFMpeg做youtube上传视频的预处理</title>
		<link>https://codechina.org/2024/01/30609/</link>
					<comments>https://codechina.org/2024/01/30609/#comments</comments>
		
		<dc:creator><![CDATA[tinyfool]]></dc:creator>
		<pubDate>Mon, 01 Jan 2024 06:41:33 +0000</pubDate>
				<category><![CDATA[技术]]></category>
		<category><![CDATA[ffmpeg]]></category>
		<category><![CDATA[youtube]]></category>
		<guid isPermaLink="false">https://codechina.org/?p=30609</guid>

					<description><![CDATA[<p>大家知道我有好几个 Youtube 频道，目前主频道是Tinyfool的胡说八道。 我现在有几种视频拍摄方式， [&#8230;]</p>
<p><a href="https://codechina.org/2024/01/30609/">在Mac上用FFMpeg做youtube上传视频的预处理</a>最先出现在<a href="https://codechina.org">Tinyfool的个人网站</a>。</p>
]]></description>
										<content:encoded><![CDATA[
<p>大家知道我有好几个 Youtube 频道，目前主频道是<a href="http://youtube.com/channel/ucdhngtocb1xrmjqqks5dpfa/">Tinyfool的胡说八道。</a></p>



<p>我现在有几种视频拍摄方式，其中一种主要的是用 Mac 的 QuickTime player 来录制，录制高品质的版本生成的 .mov 文件，文件非常大。</p>



<p>我最近录制的一个视频有48分钟，1080p的，文件尺寸足有51G。直接上传到 Youtube 也可以，但是实际上 Youtube 也会把你上传的视频进行压缩，所以，事先先压缩可以节约大量的翻墙流量。</p>



<p>于是我研究了一下 <a href="https://codechina.org/2020/02/ffmpeg-usage/">FFMpeg</a> 的命令，用下面的命令来做压缩：</p>



<pre class="wp-block-code"><code lang="bash" class="language-bash"><code>ffmpeg -i input.mov -vcodec h264 -acodec mp2 -vf scale=-1:1080 output.mp4</code></code></pre>



<ul class="wp-block-list">
<li><code>-vcodec h264</code> 是因为 Youtube 内置的视频格式是 .h264</li>



<li><code>-acodec mp2</code> 是因为 Youtube 内置的音频格式是 mp2</li>



<li>原视频是 1080p 的，用 <code>-vf scale=-1:1080</code> 是为了保护分辨率不被篡改。这些参数的结果是上传到 FFMpeg 以后不会有更近一步的压缩，节省了上传后的处理时间。</li>
</ul>



<p>用了一些日子，效果非常不错。</p>



<p>但是这个转换速度很慢，耗时很长，我今天又研究了一下。在压缩的时候，CPU 可以跑满，这说明这完全是一个软压缩。于是我寻找了一下， FFMpeg 如何在Mac下加速，原来加入 <code>-c:v h264_videotoolbox</code> 就可以了。于是命令变为：</p>



<pre class="wp-block-code"><code class="">ffmpeg -i input.mov -vcodec h264 -acodec mp2 -vf scale=-1:1080 -c:v h264_videotoolbox output.mp4</code></pre>



<p>在我的 Mac M1Max 笔记本上用新命令之前压缩 48 分钟的 51 G Mov文件需要 22分15秒，用了新命令，只需要12分钟1秒，省了大概一半的时间。</p>



<p>但是我发现用新命令的结果非常模糊，用 FFMpeg 检查文件发现，原来的 bitrate 是 2868 kb/s，新命令的结果 bitrate 是 716 kb/s。默认的压缩率太高了，所以看起来很模糊，于是我加入了一个新的参数，-b:v 2800k 限制 bitrate，然后压缩的结果就看起来没有任何问题了。而压缩速度几乎没变。所以，最后的命令如下：</p>



<pre class="wp-block-code"><code class="">ffmpeg -i input.mov -vcodec h264 -acodec mp2 -vf scale=-1:1080 -c:v h264_videotoolbox -b:v 2800k output.mp4</code></pre>



<p></p>
<p><a href="https://codechina.org/2024/01/30609/">在Mac上用FFMpeg做youtube上传视频的预处理</a>最先出现在<a href="https://codechina.org">Tinyfool的个人网站</a>。</p>
]]></content:encoded>
					
					<wfw:commentRss>https://codechina.org/2024/01/30609/feed/</wfw:commentRss>
			<slash:comments>3</slash:comments>
		
		
			<media:content url="https://codechina.org/wp-content/uploads/2024/01/FFmpeg-Ahmad-1024x576.jpg" medium="image" />
	</item>
		<item>
		<title>Mac自带音箱音量过低的解决方法一例</title>
		<link>https://codechina.org/2023/01/27285/</link>
					<comments>https://codechina.org/2023/01/27285/#respond</comments>
		
		<dc:creator><![CDATA[tinyfool]]></dc:creator>
		<pubDate>Wed, 18 Jan 2023 15:41:16 +0000</pubDate>
				<category><![CDATA[Mac Bugs]]></category>
		<category><![CDATA[MacOS]]></category>
		<category><![CDATA[activity monitor]]></category>
		<category><![CDATA[coreaudiod]]></category>
		<category><![CDATA[cpu]]></category>
		<category><![CDATA[headphone]]></category>
		<category><![CDATA[M1Max]]></category>
		<category><![CDATA[MacBook]]></category>
		<category><![CDATA[process]]></category>
		<category><![CDATA[volume]]></category>
		<guid isPermaLink="false">https://codechina.org/?p=27285</guid>

					<description><![CDATA[<p>我的 Mac 是 MacBook M1Max，最近几个月频繁遇到耳机音量正常，自带音箱音量很低，完全无法听清的 [&#8230;]</p>
<p><a href="https://codechina.org/2023/01/27285/">Mac自带音箱音量过低的解决方法一例</a>最先出现在<a href="https://codechina.org">Tinyfool的个人网站</a>。</p>
]]></description>
										<content:encoded><![CDATA[
<p>我的 Mac 是 MacBook M1Max，最近几个月频繁遇到耳机音量正常，自带音箱音量很低，完全无法听清的偶发问题。重启 Mac 后就会完全恢复正常。</p>



<span id="more-27285"></span>



<p>后来，我发现有时候遇到这种问题，可以在活动监视器 activity monitor 的 CPU 任务列表里面找到 coreaudiod 进程，然后双击得到<strong>详情页面</strong>，选择<strong>退出</strong>，然后选择<strong>强制退出</strong>即可。</p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="528" src="https://codechina.org/wp-content/uploads/2023/01/截屏2023-01-18-23.37.35-1024x528.png" alt="" class="wp-image-27287" srcset="https://codechina.org/wp-content/uploads/2023/01/截屏2023-01-18-23.37.35-1024x528.png 1024w, https://codechina.org/wp-content/uploads/2023/01/截屏2023-01-18-23.37.35-300x155.png 300w, https://codechina.org/wp-content/uploads/2023/01/截屏2023-01-18-23.37.35-768x396.png 768w, https://codechina.org/wp-content/uploads/2023/01/截屏2023-01-18-23.37.35-1536x791.png 1536w, https://codechina.org/wp-content/uploads/2023/01/截屏2023-01-18-23.37.35-1200x618.png 1200w, https://codechina.org/wp-content/uploads/2023/01/截屏2023-01-18-23.37.35.png 1700w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /><figcaption class="wp-element-caption">详情页面</figcaption></figure>



<figure class="wp-block-image size-full"><img loading="lazy" decoding="async" width="544" height="652" src="https://codechina.org/wp-content/uploads/2023/01/截屏2023-01-18-23.37.49.png" alt="" class="wp-image-27288" srcset="https://codechina.org/wp-content/uploads/2023/01/截屏2023-01-18-23.37.49.png 544w, https://codechina.org/wp-content/uploads/2023/01/截屏2023-01-18-23.37.49-250x300.png 250w" sizes="auto, (max-width: 544px) 100vw, 544px" /><figcaption class="wp-element-caption">退出选项</figcaption></figure>



<p>一般这样操作后，音箱的音量就正常了。</p>
<p><a href="https://codechina.org/2023/01/27285/">Mac自带音箱音量过低的解决方法一例</a>最先出现在<a href="https://codechina.org">Tinyfool的个人网站</a>。</p>
]]></content:encoded>
					
					<wfw:commentRss>https://codechina.org/2023/01/27285/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			<media:content url="https://codechina.org/wp-content/uploads/2023/01/christina-wocintechchat-com-CmvA0xCDfC8-unsplash.jpg" medium="image" />
	</item>
		<item>
		<title>使用StoreKit2不再需要恢复购买按钮，但是为了审核你还需要放一个【AppStore审核手记】</title>
		<link>https://codechina.org/2023/01/26850/</link>
					<comments>https://codechina.org/2023/01/26850/#respond</comments>
		
		<dc:creator><![CDATA[tinyfool]]></dc:creator>
		<pubDate>Wed, 04 Jan 2023 04:31:14 +0000</pubDate>
				<category><![CDATA[iOS开发]]></category>
		<guid isPermaLink="false">https://codechina.org/?p=26850</guid>

					<description><![CDATA[<p>昨天我提交了一个新App，2023年我的计划就是开发一系列的小App试图在独立开发领域有一份收入。但是今天一早 [&#8230;]</p>
<p><a href="https://codechina.org/2023/01/26850/">使用StoreKit2不再需要恢复购买按钮，但是为了审核你还需要放一个【AppStore审核手记】</a>最先出现在<a href="https://codechina.org">Tinyfool的个人网站</a>。</p>
]]></description>
										<content:encoded><![CDATA[
<p>昨天我提交了一个新App，2023年我的计划就是开发一系列的小App试图在独立开发领域有一份收入。但是今天一早就发现被拒绝了。</p>



<p>理由是：</p>



<span id="more-26850"></span>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow">
<p><strong>Guideline 3.1.1 &#8211; Business &#8211; Payments &#8211; In-App Purchase</strong></p>



<p>We found that your app offers in-app purchases that can be restored but does not include a &#8220;Restore Purchases&#8221; feature to allow users to restore the previously purchased in-app purchases, as specified in the &#8220;Restoring Purchase Products&#8221; section of the <a href="https://developer.apple.com/library/archive/documentation/NetworkingInternet/Conceptual/StoreKitGuide/Introduction.html">In-App Purchase Programming Guide</a>:</p>



<p>&#8220;Users restore transactions to maintain access to content they&#8217;ve already purchased. For example, when they upgrade to a new phone, they don&#8217;t lose all of the items they purchased on the old phone. Include some mechanism in your app to let the user restore their purchases, such as a Restore Purchases button.&#8221;</p>



<p><strong>Next Steps</strong></p>



<p>To restore previously purchased in-app purchase products, it would be appropriate to provide a &#8220;Restore&#8221; button and initiate the restore process when the &#8220;Restore&#8221; button is tapped by the user. Note that automatically restoring purchases on launch will not resolve this issue.</p>
</blockquote>



<p>这段大概可以翻译为：</p>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow">
<p>准则3.1.1 &#8211; 业务 &#8211; 支付 &#8211; 应用内购买</p>



<p>我们发现你的应用程序提供了可以恢复的应用内购买，但不包括 &#8220;恢复购买 &#8220;功能，以允许用户恢复之前购买的应用内购买，如应用内购买程序指南的 &#8220;恢复购买产品 &#8220;部分所规定的。</p>



<p>&#8220;用户恢复交易以保持对他们已经购买的内容的访问。例如，当他们升级到一个新的手机时，他们不会失去他们在旧手机上购买的所有物品。在你的应用程序中包括一些机制，让用户恢复他们的购买，如恢复购买按钮。&#8221;</p>



<p>接下来的步骤</p>



<p>为了恢复以前购买的应用内产品，应该提供一个 &#8220;恢复 &#8220;按钮，并在用户点击 &#8220;恢复 &#8220;按钮时启动恢复程序。请注意，启动时自动恢复购买的产品不会解决这个问题。</p>
</blockquote>



<p>意思就是，我提供了一个应用内购买功能（付费用户），但是没有提供恢复购买按钮。</p>



<p>我当时就很奇怪，因为我用的是StoreKit2，我记得学习这套新API的原因有两个大点，第一个就是这套新API更简洁，更好用。第二就是，不需要恢复购买的流程了，自动会保持与AppStore购买记录的同步。</p>



<p>我找来当时让我选择了Storekit2的WWDC官方视频“<a href="https://www.youtube.com/watch?v=E5Vz11NyR2g">Meet StoreKit 2 | 10114 | WWDC2021”</a>，里面明确的说了，</p>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow">
<p>So, all of this means&nbsp;that users won&#8217;t need to restore completed transactions&nbsp;when your app is reinstalled or downloaded on a new device.&nbsp;Everything should automatically be fetched by StoreKit&nbsp;and stay up to date.&nbsp;</p>



<p>因此，所有这些都意味着，当你的应用程序被重新安装或下载到新设备上时，用户将不需要恢复已完成的交易。&nbsp;一切都应该由StoreKit自动获取，并保持最新状态。&nbsp;</p>
</blockquote>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="516" src="https://codechina.org/wp-content/uploads/2023/01/截屏2023-01-04-12.20.26-1024x516.png" alt="" class="wp-image-26852" srcset="https://codechina.org/wp-content/uploads/2023/01/截屏2023-01-04-12.20.26-1024x516.png 1024w, https://codechina.org/wp-content/uploads/2023/01/截屏2023-01-04-12.20.26-300x151.png 300w, https://codechina.org/wp-content/uploads/2023/01/截屏2023-01-04-12.20.26-768x387.png 768w, https://codechina.org/wp-content/uploads/2023/01/截屏2023-01-04-12.20.26-1536x773.png 1536w, https://codechina.org/wp-content/uploads/2023/01/截屏2023-01-04-12.20.26-1200x604.png 1200w, https://codechina.org/wp-content/uploads/2023/01/截屏2023-01-04-12.20.26.png 1748w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>



<p>结果，我没注意的是，这句以后，他还说了一句，</p>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow">
<p>But people use their Apple devices in millions of ways in millions of places.&nbsp;In the rare case that a user thinks&nbsp;they should have a transaction but you don&#8217;t see it,&nbsp;you can use the App Store sync API.&nbsp;This immediately resynchronizes all StoreKit 2 transactions.&nbsp;This is a replacement for the&nbsp;restoreCompletedTransactions API,and you should provide UI in your app that allows users to initiate the sync.&nbsp;However, thanks to StoreKit 2&#8217;s automatic synchronization,&nbsp;it should be very rare&nbsp;that a user needs to initiate a sync manually.&nbsp;</p>



<p>但人们在数百万个地方以数百万种方式使用他们的苹果设备。&nbsp;在罕见的情况下，如果用户认为他们应该有一个交易，但你没有看到它，你可以使用App Store的sync API。&nbsp;这将立即重新同步所有StoreKit 2交易。&nbsp;这是对 restoreCompletedTransactions API 的替代，你应该在你的应用程序中提供允许用户启动同步的用户界面。&nbsp;然而，由于StoreKit 2的自动同步功能，用户需要手动启动同步的情况应该非常少。&nbsp;</p>
</blockquote>



<p>也就是说，虽然，基本上用不上恢复购买按钮，但是我们还是需要提供一个恢复购买按钮，来同步Appstore的购买记录。</p>



<p>而且，审核Guideline也没变，还是要求提供恢复购买按钮。</p>



<p>那能怎么办呢？那就加吧。</p>



<p>在UI的底部加上一段代码，倒是不复杂：</p>



<pre class="wp-block-code"><code lang="swift" class="language-swift">Button {
    Task {
        do {
            try await AppStore.sync()
        } catch {
            print(error)
        }
    }
} label: {
    Text("Restore Purchases")
}
</code></pre>



<p>我本来觉得这个按钮就是蠢的要死。你在别的网络服务买个账号，需要有个按钮明确的恢复购买么？不都是网络化的，有信号就自动更新的东西么。唉，本以为StoreKit2以后就不用放这个愚蠢的按钮，看来还是需要，放就放吧。</p>



<p>我也能理解苹果遇到的问题，总有网络问题，或者用户觉得自己买过，也许是糊涂了，给他一个按钮，让他可以手动恢复，可能会让用户更安心吧。唉。</p>
<p><a href="https://codechina.org/2023/01/26850/">使用StoreKit2不再需要恢复购买按钮，但是为了审核你还需要放一个【AppStore审核手记】</a>最先出现在<a href="https://codechina.org">Tinyfool的个人网站</a>。</p>
]]></content:encoded>
					
					<wfw:commentRss>https://codechina.org/2023/01/26850/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			<media:content url="https://codechina.org/wp-content/uploads/2023/01/截屏2023-01-04-12.20.26-1024x516.png" medium="image" />
	</item>
		<item>
		<title>从零开始，使用SwiftUI和PDFKit快速构建完全可定制的PDF阅读器</title>
		<link>https://codechina.org/2023/01/26809/</link>
					<comments>https://codechina.org/2023/01/26809/#respond</comments>
		
		<dc:creator><![CDATA[tinyfool]]></dc:creator>
		<pubDate>Tue, 03 Jan 2023 13:39:05 +0000</pubDate>
				<category><![CDATA[iOS开发]]></category>
		<category><![CDATA[技术]]></category>
		<category><![CDATA[pdf]]></category>
		<category><![CDATA[pdfkit]]></category>
		<category><![CDATA[swift]]></category>
		<category><![CDATA[swiftui]]></category>
		<guid isPermaLink="false">https://codechina.org/?p=26809</guid>

					<description><![CDATA[<p>SwiftUI快速创建UI的能力非常强大，苹果还提供了PDFKit框架，所以，用SwiftUI和PDFKit可 [&#8230;]</p>
<p><a href="https://codechina.org/2023/01/26809/">从零开始，使用SwiftUI和PDFKit快速构建完全可定制的PDF阅读器</a>最先出现在<a href="https://codechina.org">Tinyfool的个人网站</a>。</p>
]]></description>
										<content:encoded><![CDATA[
<p>SwiftUI快速创建UI的能力非常强大，苹果还提供了PDFKit框架，所以，用SwiftUI和PDFKit可以用非常少的代码，非常快速的创建一个完全可定制的PDF阅读器。</p>



<p>我们来从零开始，做一个PDF阅读器。</p>



<span id="more-26809"></span>



<h2 class="wp-block-heading">创建项目</h2>



<p>首先，打开Xcode，创建一个新的iOS App。项目名字可以就叫做PdfReader。Interface选择Swift UI，language选择Swift。</p>



<p>因为PDFKit是一个UIKit库，不是原生的SwiftUI对象，所以，我们先需要做一个UIViewRepresentable类，来作为两者之间的桥梁。我已经帮你准备好了一个。你只需要创建一个SwiftPDFView.swift，把如下代码复制进去即可。</p>



<pre class="wp-block-code"><code lang="swift" class="language-swift">//
//  SwiftPDFView.swift
//  PdfReader
//
//  Created by HaoPeiqiang on 2023/1/3.
//

import SwiftUI
import PDFKit

struct SwiftPDFView: UIViewRepresentable {

    
    let url:URL

    func makeUIView(context: Context) -&gt; PDFView {
        
        let pdfView = PDFView()
        pdfView.document = PDFDocument(url: url)
        pdfView.displayMode = .singlePage
        pdfView.autoScales = true
        pdfView.usePageViewController(true, withViewOptions: nil)
        return pdfView
    }
    
    
    func updateUIView(_ pdfView: PDFView, context: Context) {
        
    }

}

struct SwiftPDFView_Previews: PreviewProvider {
    static var previews: some View {
        
        SwiftPDFView(url:Bundle.main.url(forResource: "sample_pdf", withExtension: "pdf")!)
    }
}
</code></pre>



<p>然后，你可以找到自动生成的ContentView.swift文件，把在body内部自动生成的代码删除，加上<code>SwiftPDFView(url: Bundle.main.url(forResource: "sample_pdf", withExtension: "pdf")!)</code>。好，三分钟不到，你已经成功创建了一个PDF阅读器了。</p>



<p>如果你打开了Xcode代码区域右侧的预览区域，都不用执行App，你已经可以看到你的PDF浏览器已经可以工作了，也可以在PDF页面之间翻页。</p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="662" src="https://codechina.org/wp-content/uploads/2023/01/截屏2023-01-03-20.49.53-1024x662.png" alt="" class="wp-image-26819" srcset="https://codechina.org/wp-content/uploads/2023/01/截屏2023-01-03-20.49.53-1024x662.png 1024w, https://codechina.org/wp-content/uploads/2023/01/截屏2023-01-03-20.49.53-300x194.png 300w, https://codechina.org/wp-content/uploads/2023/01/截屏2023-01-03-20.49.53-768x496.png 768w, https://codechina.org/wp-content/uploads/2023/01/截屏2023-01-03-20.49.53-1536x993.png 1536w, https://codechina.org/wp-content/uploads/2023/01/截屏2023-01-03-20.49.53-2048x1324.png 2048w, https://codechina.org/wp-content/uploads/2023/01/截屏2023-01-03-20.49.53-1200x776.png 1200w, https://codechina.org/wp-content/uploads/2023/01/截屏2023-01-03-20.49.53-1980x1280.png 1980w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>



<h2 class="wp-block-heading">加入缩略图导航栏</h2>



<p>你可能见过有的PDF App，在PDF页面下方有一排缩略图，可以导航也可以预览PDF的文件内容，这个叫做<code>PDFThumbnailView</code>。加入<code>PDFThumbnailView</code>可以让我们的PDF阅读器，看起来更专业。</p>



<p>我们可以回到<code>SwiftPDFView.swift</code>文件，在SwiftPDFView类的代码里面加入如下代码：</p>



<pre class="wp-block-code"><code lang="swift" class="language-swift">    func setThumbnailView(_ pdfView:PDFView) {
        let thumbnailView = PDFThumbnailView()
        thumbnailView.translatesAutoresizingMaskIntoConstraints = false
        pdfView.addSubview(thumbnailView)
        
        thumbnailView.leadingAnchor.constraint(equalTo: pdfView.safeAreaLayoutGuide.leadingAnchor).isActive = true
        thumbnailView.trailingAnchor.constraint(equalTo: pdfView.safeAreaLayoutGuide.trailingAnchor).isActive = true
        thumbnailView.bottomAnchor.constraint(equalTo: pdfView.safeAreaLayoutGuide.bottomAnchor).isActive = true
        thumbnailView.bottomAnchor.constraint(equalTo: pdfView.safeAreaLayoutGuide.bottomAnchor).isActive = true
        
        thumbnailView.heightAnchor.constraint(equalToConstant: 40).isActive = true

        thumbnailView.thumbnailSize = CGSize(width: 20, height: 30)
        thumbnailView.layoutMode = .horizontal
        thumbnailView.pdfView = pdfView
    }
</code></pre>



<p>然后在刚才的<code>makeUIView</code>方法，<code>return pdfView</code>之前加入一句<code><strong>self</strong>.setThumbnailView(pdfView)</code>即可。</p>



<p>然后，查看预览区域，就会发现PDF显示区域下面出现了缩略图导航栏。</p>



<figure class="wp-block-image size-full"><img loading="lazy" decoding="async" width="964" height="610" src="https://codechina.org/wp-content/uploads/2023/01/截屏2023-01-03-21.33.40.png" alt="" class="wp-image-26825" srcset="https://codechina.org/wp-content/uploads/2023/01/截屏2023-01-03-21.33.40.png 964w, https://codechina.org/wp-content/uploads/2023/01/截屏2023-01-03-21.33.40-300x190.png 300w, https://codechina.org/wp-content/uploads/2023/01/截屏2023-01-03-21.33.40-768x486.png 768w" sizes="auto, (max-width: 964px) 100vw, 964px" /></figure>



<p>项目代码可从Github下载 <a href="https://github.com/Swift-Cast/PdfReader">https://github.com/Swift-Cast/PdfReader</a></p>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<p><a href="https://iapp4me.com/pdf-extractor">PDF Extractor &#8211; Extract text/images from PDF</a></p>
<p><a href="https://codechina.org/2023/01/26809/">从零开始，使用SwiftUI和PDFKit快速构建完全可定制的PDF阅读器</a>最先出现在<a href="https://codechina.org">Tinyfool的个人网站</a>。</p>
]]></content:encoded>
					
					<wfw:commentRss>https://codechina.org/2023/01/26809/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			<media:content url="https://codechina.org/wp-content/uploads/2023/01/截屏2023-01-03-20.49.53-1024x662.png" medium="image" />
	</item>
		<item>
		<title>万能的ChatGPT真有智能了么？一篇文章让你彻底搞懂ChatGPT-人类是怎么训练出了一只聪明的莎士比亚的猴子</title>
		<link>https://codechina.org/2023/01/25998/</link>
					<comments>https://codechina.org/2023/01/25998/#comments</comments>
		
		<dc:creator><![CDATA[tinyfool]]></dc:creator>
		<pubDate>Mon, 02 Jan 2023 04:18:48 +0000</pubDate>
				<category><![CDATA[AI]]></category>
		<category><![CDATA[技术]]></category>
		<category><![CDATA[ChatGPT]]></category>
		<category><![CDATA[GPT3]]></category>
		<guid isPermaLink="false">https://codechina.org/?p=25998</guid>

					<description><![CDATA[<p>很多人说ChatGPT这样的人工智能已经拥有真正的人类智慧了。他们提到了许多例子，比如ChatGPT能够和人类 [&#8230;]</p>
<p><a href="https://codechina.org/2023/01/25998/">万能的ChatGPT真有智能了么？一篇文章让你彻底搞懂ChatGPT-人类是怎么训练出了一只聪明的莎士比亚的猴子</a>最先出现在<a href="https://codechina.org">Tinyfool的个人网站</a>。</p>
]]></description>
										<content:encoded><![CDATA[				<div class="wp-block-uagb-table-of-contents uagb-toc__align-left uagb-toc__columns-1  uagb-block-50f2e9f5      "
					data-scroll= "1"
					data-offset= "30"
					style=""
				>
				<div class="uagb-toc__wrap">
						<div class="uagb-toc__title">
							Table Of Contents						</div>
																						<div class="uagb-toc__list-wrap ">
						<ol class="uagb-toc__list"><li class="uagb-toc__list"><a href="#无限猴子定理" class="uagb-toc-link__trigger">无限猴子定理</a><li class="uagb-toc__list"><a href="#什么是语言模型" class="uagb-toc-link__trigger">什么是语言模型</a><ul class="uagb-toc__list"><li class="uagb-toc__list"><a href="#语言模型的发展历史" class="uagb-toc-link__trigger">语言模型的发展历史</a><li class="uagb-toc__list"><li class="uagb-toc__list"><a href="#gpt各个版本之前的差别和发展历史" class="uagb-toc-link__trigger">GPT各个版本之前的差别和发展历史</a><li class="uagb-toc__list"><li class="uagb-toc__list"><a href="#gpt-3的语料包含哪些内容" class="uagb-toc-link__trigger">GPT-3的语料包含哪些内容</a></li></ul></li><li class="uagb-toc__list"><a href="#这么厉害的chatgpt到底是不是真的达到了人类的智慧" class="uagb-toc-link__trigger">这么厉害的ChatGPT到底是不是真的达到了人类的智慧？</a><li class="uagb-toc__list"><a href="#webgpt和google" class="uagb-toc-link__trigger">WebGPT和Google</a><ul class="uagb-toc__list"><li class="uagb-toc__list"><a href="#时效性" class="uagb-toc-link__trigger">时效性</a><li class="uagb-toc__list"><li class="uagb-toc__list"><a href="#那什么是webgpt呢" class="uagb-toc-link__trigger">那什么是WebGPT呢？</a></li></ul></li></ul></li><li class="uagb-toc__list"><a href="#chatgpt是怎么炼成的呢" class="uagb-toc-link__trigger">ChatGPT是怎么炼成的呢？</a><ul class="uagb-toc__list"><li class="uagb-toc__list"><a href="#1收集示例数据训练一个有监督的模型" class="uagb-toc-link__trigger">1、收集示例数据，训练一个有监督的模型</a><li class="uagb-toc__list"><li class="uagb-toc__list"><a href="#2收集比较数据训练一个奖励模型" class="uagb-toc-link__trigger">2、收集比较数据，训练一个奖励模型</a><li class="uagb-toc__list"><li class="uagb-toc__list"><a href="#3根据奖励模型对有监督模型进行持续的强化学习" class="uagb-toc-link__trigger">3、根据奖励模型，对有监督模型进行持续的强化学习</a><li class="uagb-toc__list"><li class="uagb-toc__list"><a href="#参见" class="uagb-toc-link__trigger">参见：</a></li></ul></li></ul></li></ul></li><li class="uagb-toc__list"><a href="#参考" class="uagb-toc-link__trigger">参考</a></ul></ul></ul></ol>					</div>
									</div>
				</div>
			


<p>很多人说ChatGPT这样的人工智能已经拥有真正的人类智慧了。他们提到了许多例子，比如ChatGPT能够和人类进行对话，甚至可以进行智能聊天，可以<a href="https://codechina.org/2022/12/chatgpt-function-1-writting/" data-type="post" data-id="25946">帮助你润色文章，提取摘要，甚至直接帮你扩写内容</a>。但是事实并非如此，今天我们就好好聊聊这个问题。</p>



<span id="more-25998"></span>



<figure class="wp-block-embed is-type-video is-provider-youtube wp-block-embed-youtube wp-embed-aspect-16-9 wp-has-aspect-ratio"><div class="wp-block-embed__wrapper">
<iframe loading="lazy"  id="_ytid_35051"  width="580" height="326"  data-origwidth="580" data-origheight="326" src="https://www.youtube.com/embed/v7sJnErxIgc?enablejsapi=1&#038;autoplay=0&#038;cc_load_policy=0&#038;cc_lang_pref=&#038;iv_load_policy=1&#038;loop=0&#038;rel=1&#038;fs=1&#038;playsinline=0&#038;autohide=2&#038;theme=dark&#038;color=red&#038;controls=1&#038;disablekb=0&#038;" class="__youtube_prefs__  epyt-is-override  no-lazyload" title="YouTube player"  allow="fullscreen; accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen data-no-lazy="1" data-skipgform_ajax_framebjll=""></iframe>
</div></figure>



<p>首先，我们必须明确，人工智能并不是真正的智能。它是一种人造智能，是由人类通过研究和开发而创造出来的。因此，它不具备真正的人类智慧，而只是一种模仿人类智慧的技术。</p>



<p>其次，虽然ChatGPT可以进行聊天，但这并不能证明它拥有真正的人类智慧。聊天只是一种表面现象，它并不能证明ChatGPT拥有人类的思考能力。只有当ChatGPT能够理解人类的思想，并能够思考、判断和决策时，我们才能说它拥有真正的人类智慧。</p>



<p>最后，我们要知道，人工智能是一个极具挑战性的领域。尽管科学家和工程师们已经取得了巨大的进步，但人工智能还有很长的路要走。我们不能因为当前的技术水平而把人工智能误认为是真正的智慧，我们应该保持理性的态度。</p>



<p>但是也不能因为ChatGPT不是完全跟人脑一样的智慧体就小瞧它，它可以在很多方面辅助我们。比如说，它可以帮助我们解决一些复杂的数学问题，甚至可以帮助我们预测未来的发展趋势。此外，它还可以用于智能客服、智能问答、智能聊天等多种应用场景。我最近就写了一系列文章介绍我们如何用ChatGPT来帮助我们的生产生活，如下：</p>



<ul class="wp-block-list">
<li><a href="https://codechina.org/2022/12/chatgpt-function-1-writting/" data-type="post" data-id="25946">【ChatGPT实用指南用】帮助你快速高效地完成你的写作任务</a></li>
</ul>



<p>今天，我们就好好聊聊ChatGPT的原理和细节，局限性以及应用场景。</p>



<p>我们尽量不用任何公式，数学模型来把问题搞复杂，对大众来说，了解ChatGPT的原理可以满足他们的好奇心，也利于他们用好ChatGPT，在合适的地方去用，该怎么用。</p>



<p>首先，我简单的引入一个莎士比亚的猴子的概念。</p>



<h2 class="wp-block-heading">无限猴子定理</h2>



<p>让一只猴子在打字机上随机地按键，当按键时间达到无穷时，几乎必然能够打出任何给定的文字，比如莎士比亚的全套著作。（1）</p>



<p>这个定理有各种表述，也可以说，只要有足够多的时间，足够多的猴子，可以打印出来整个大英图书馆，或者法国图书馆的全部藏书，等等。</p>



<p>这是在揭示在随机的信息里面可能蕴含了无尽的信息。也有一个说法是，在圆周率π里面包含了人类全部的信息，因为π是无限不循环小数。</p>



<p>但是，随机信息和有信息量的信息的区别在于，即使我们知道猴子最终可以打印出莎士比亚的全套著作，我们也不知道什么时候才能完成。如何找到猴子打印出来的结果在哪里。</p>



<p>刘慈欣有一本小说，叫做诗云。大概逻辑是一个高于人类文明无数倍的外星生物，了解到人类有诗，看了无数的人类的文学作品。它想超越人类的诗作者，它想到了一个办法，去随机生成无数的文字，在这些文字里面必然包含了无数的优秀的诗。但是最后，它发现生成这些随机的文字，存储他们需要耗费无数的资源。但是都生成了也没用，因为无法找到。</p>



<p>我引入这个隐喻就是想介绍虽然GPT已经包含了智能，但是也包含很多问题，语言模型的先天问题。如何从一个貌似包含了人类全部文字信息的语言模型，引出一个可以稳定执行各种命令，回答人类各种问题的实用产品。这就是有了GPT-3这样的超级无敌AI机器，然后需要解决的问题，也就是我们今天为什么能看到ChatGPT的原因。</p>



<p>首先我们需要了解GPT和语言模型。</p>



<h2 class="wp-block-heading">什么是语言模型</h2>



<p>ChatGPT的本质是GPT3，而GPT3是一种语言模型，要理解Chat GPT和GTP3，我们需要先理解什么是语言模型。</p>



<p>语言模型是一种人工智能模型，它可以对给定的语言文本进行分析和建模，并预测下一个可能出现的词语(2)。例如下图：</p>



<figure class="wp-block-image size-full"><img loading="lazy" decoding="async" width="954" height="506" src="https://codechina.org/wp-content/uploads/2022/12/截屏2022-12-09-14.45.59.png" alt="" class="wp-image-26016" srcset="https://codechina.org/wp-content/uploads/2022/12/截屏2022-12-09-14.45.59.png 954w, https://codechina.org/wp-content/uploads/2022/12/截屏2022-12-09-14.45.59-300x159.png 300w, https://codechina.org/wp-content/uploads/2022/12/截屏2022-12-09-14.45.59-768x407.png 768w" sizes="auto, (max-width: 954px) 100vw, 954px" /></figure>



<p>最简单的也是最早期的语言模型叫做n元模型，很简单也很好理解。就是把句子里面连续n个单词（汉语的话连续n个汉字，或连续n个词）当作一个单元，拆解以后，统计他们相邻出现的概率。</p>



<p>比如，一个英文例句为， the students opened their books。 用n元模型来分析的话，</p>



<ul class="wp-block-list">
<li>1元： &#8220;the&#8221;, &#8220;students&#8221;, &#8220;opened&#8221;, &#8220;their&#8221;, &#8220;books&#8221;</li>



<li>2元： &#8220;the students&#8221;, &#8220;students opened&#8221;, &#8220;opened their&#8221;, &#8220;their books&#8221;</li>



<li>3元： &#8220;the students opened&#8221;, &#8220;students opened their&#8221;, &#8220;opened their books&#8221;</li>



<li>4元：&#8221;the students opened their&#8221;, &#8220;students opened their books&#8221;</li>
</ul>



<p>如果是一段中文例子为“学生们打开来了他们的书。”用n元模型来切分（已分词）则是，</p>



<ul class="wp-block-list">
<li>1元：&#8221;学生们&#8221;, &#8220;打开&#8221;, &#8220;来了&#8221;, &#8220;他们&#8221;, &#8220;的&#8221;, &#8220;书&#8221;</li>



<li>2元：&#8221;学生们打开&#8221;, &#8220;打开来了&#8221;, &#8220;来了他们&#8221;, &#8220;他们的&#8221;, &#8220;的书&#8221;</li>



<li>3元：&#8221;学生们打开来了&#8221;, &#8220;打开来了他们&#8221;, &#8220;来了他们的&#8221;, &#8220;他们的书&#8221;</li>



<li>4元：&#8221;学生们打开来了他们&#8221;, &#8220;打开来了他们的&#8221;, &#8220;来了他们的书&#8221;</li>
</ul>



<p>那么当问题是，“学生打开来了他们的______”的时候，我们到底应该选择，书本、笔记本、试题、还是思路呢？这就要看出现的概率了。</p>



<p>也就是，在给定的语料库下，“学生打开来了他们的书本”，“学生打开来了他们的笔记本”，“学生打开来了他们的试题”和“学生打开来了他们的思路”跟“学生打开来了他们的”出现次数的比值关系了。</p>



<p>n元语言模型可以算作最简单的语言模型，后面会介绍一步步语言模型的发展，但是它们的实现细节差异很大，但是基本上要完成的任务是一样的。</p>



<p>语言模型本身就可以应用在很多地方，比如输入法的联想，</p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="967" src="https://codechina.org/wp-content/uploads/2022/12/IMG_7293-1024x967.jpg" alt="" class="wp-image-26021" srcset="https://codechina.org/wp-content/uploads/2022/12/IMG_7293-1024x967.jpg 1024w, https://codechina.org/wp-content/uploads/2022/12/IMG_7293-300x283.jpg 300w, https://codechina.org/wp-content/uploads/2022/12/IMG_7293-768x726.jpg 768w, https://codechina.org/wp-content/uploads/2022/12/IMG_7293-1200x1134.jpg 1200w, https://codechina.org/wp-content/uploads/2022/12/IMG_7293.jpg 1284w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /><figcaption class="wp-element-caption">输入法的联想</figcaption></figure>



<p>聊天和信息软件的自动推荐</p>



<figure class="wp-block-image size-full"><img loading="lazy" decoding="async" width="968" height="696" src="https://codechina.org/wp-content/uploads/2022/12/截屏2022-12-09-15.10.50.png" alt="" class="wp-image-26022" srcset="https://codechina.org/wp-content/uploads/2022/12/截屏2022-12-09-15.10.50.png 968w, https://codechina.org/wp-content/uploads/2022/12/截屏2022-12-09-15.10.50-300x216.png 300w, https://codechina.org/wp-content/uploads/2022/12/截屏2022-12-09-15.10.50-768x552.png 768w" sizes="auto, (max-width: 968px) 100vw, 968px" /><figcaption class="wp-element-caption">聊天和信息软件的自动推荐</figcaption></figure>



<p>Google搜索的自动推荐</p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="817" src="https://codechina.org/wp-content/uploads/2022/12/截屏2022-12-09-15.11.15-1024x817.png" alt="" class="wp-image-26023" srcset="https://codechina.org/wp-content/uploads/2022/12/截屏2022-12-09-15.11.15-1024x817.png 1024w, https://codechina.org/wp-content/uploads/2022/12/截屏2022-12-09-15.11.15-300x239.png 300w, https://codechina.org/wp-content/uploads/2022/12/截屏2022-12-09-15.11.15-768x613.png 768w, https://codechina.org/wp-content/uploads/2022/12/截屏2022-12-09-15.11.15.png 1038w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /><figcaption class="wp-element-caption">Google搜索的自动推荐</figcaption></figure>



<p>但是更重要的是，语言模型通常用于帮助构建其他的自然语言处理任务，如语音识别、机器翻译、文本分类等，它可以帮助计算机理解和处理人类语言。语言模型可以通过预训练和微调来实现模型的提升，并且在不断推进的研究过程中也取得了巨大的进步。</p>



<h3 class="wp-block-heading">语言模型的发展历史</h3>



<p>语言模型的发展可以追溯到20世纪50年代末，当时科学家们开始探索如何让计算机处理人类语言。在随后的几十年里，随着计算机硬件和软件技术的发展，语言模型也不断演进。20世纪90年代，神经网络模型开始被广泛应用于语言模型的研究，并取得了显著的进步。随后，深度学习模型也开始在语言模型领域得到广泛应用，并取得了更多的成果。</p>



<p>在历史上，有许多重要的语言模型，其中包括：</p>



<ul class="wp-block-list">
<li>基于n元语法的语言模型：这是最早的语言模型之一，它基于n元语法的概率分布来建模语言文本，并预测下一个词语的可能性。它的优点是简单易行，但缺点是无法处理长距离依赖关系。</li>



<li>神经网络语言模型：这是一种基于神经网络的语言模型，它通过多层感知器来建模语言文本，并使用语言模型的损失函数来训练模型。它的优点是可以处理长距离依赖关系，但缺点是计算复杂度高，难以训练大规模的模型。</li>



<li>基于RNN的语言模型：这是一种基于循环神经网络的语言模型，它通过对时序数据进行处理，来捕捉语言文本中的长距离依赖关系。它的优点是能够处理长距离依赖关系，但缺点是计算复杂度高，难以处理长文本。</li>



<li>基于Transformer的语言模型：这是一种基于Transformer模型的语言模型，它通过结合注意力机制和多头注意力机制，来实现对语言文本的建模。它的优点是计算效率高，能够处理长文本，并且可以通过预训练来提高模型的泛化能力。它的缺点是训练时需要大量的训练数据，并且需要高性能的计算机硬件支持。</li>



<li>基于BERT的语言模型：这是一种基于双向注意力机制的语言模型，它通过对语言文本的上下文进行建模，来提高模型的表示能力。它的优点是能够有效地捕捉语言文本中的上下文信息，并且可以通过预训练来提高模型的泛化能力。它的缺点是训练时需要大量的训练数据，并且需要高性能的计算机硬件支持。</li>



<li>总的来说，语言模型的发展历史可以分为三个阶段：早期的基于n元语法的语言模型，中期的神经网络语言模型和基于RNN的语言模型，以及近年来出现的基于Transformer和BERT的语言模型。这些模型在不同时期都取得了重要的突破，为人工智能领域的发展做出了巨大贡献。</li>
</ul>



<h3 class="wp-block-heading">GPT各个版本之前的差别和发展历史</h3>



<ul class="wp-block-list">
<li>GPT：这是最早的GPT模型，它采用了单层的Transformer模型，并通过对大量语言文本进行预训练来提高模型的泛化能力。它可以用于各种自然语言处理任务，如文本生成、语言模型预测。通过对40亿个语言文本词语进行预训练来提高模型的泛化能力。</li>



<li>GPT2：这是GPT模型的下一个版本，它采用了多层的Transformer模型，并通过对更大量的语言文本进行预训练来提高模型的泛化能力。它具有更高的计算能力和更丰富的语言表示能力，可以用于更复杂的自然语言处理任务。通过对7000亿个语言文本词语进行预训练来提高模型的泛化能力。</li>



<li>GPT-3：这是GPT模型的最新版本，它采用了更多层的Transformer模型，并通过对更大规模的语言文本进行预训练来提高模型的泛化能力。它具有更高的计算能力和更丰富的语言表示能力，可以用于更多种类的自然语言处理任务，如文本生成、语言模型预测、机器翻译、问答系统等。通过对175000亿个语言文本词语进行预训练来提高模型的泛化能力。</li>



<li>ChatGPT：ChatGPT是一种专门用于实现对话系统的自然语言处理模型，它采用了多层的Transformer模型，并通过对大量对话文本进行预训练来提高模型的泛化能力。可以说ChatGPT是GPT-3的一个特殊应用，它专注于对话系统领域，而GPT-3则是一个更加通用的自然语言处理模型，可以应用于更多种类的自然语言处理任务。</li>
</ul>



<h3 class="wp-block-heading">GPT-3的语料包含哪些内容</h3>



<p>具体来说，GPT-3的语料包含了以下内容：</p>



<ul class="wp-block-list">
<li>丰富的语言文本：GPT-3的语料包含了大量的语言文本，包括小说、新闻、网页、博客、社交媒体等各种类型的文本。这些文本来自于不同的语言、文化背景，并且涵盖了广泛的话题。</li>



<li>多样化的语言表示：GPT-3的语料涵盖了多种语言表示方法，包括文本、图像、音频、视频等多种形式。这使得GPT-3模型能够捕捉到不同类型的语言信息，并实现更为丰富的语言表示能力。</li>



<li>深度的语言理解：GPT-3的语料还包含了大量的语言理解信息，如语义、句法、语用等。这使得GPT-3模型能够更深入地理解语言文本的含义，并能够更准确地完成各种自然语言处理任务。</li>
</ul>



<p>总的来说，GPT-3的语料包含了丰富、多样化和深度的语言信息</p>



<h2 class="wp-block-heading">这么厉害的ChatGPT到底是不是真的达到了人类的智慧？</h2>



<p>我已经写了文章说明<a href="https://codechina.org/2022/12/chatgpt-function-1-writting/" data-type="post" data-id="25946">用ChatGPT，可以帮你写文章</a>，可以帮你起标题，润色文章，扩写文章，提取摘要，校对文字，还可以翻译。</p>



<p>而且还可以帮我们写程序，查询函数的参数，帮你进行的代码审核，可以帮你写unit test，等等。</p>



<p>它还可以帮我们学英语，找例句，翻译，帮我们润色英文作文，等等。</p>



<p>这些工作它做的甚至比一些专门设计去做这些工作的软件做的还好，甚至可以达到人类比较厉害的人的水平，那么它就真的拥有智能了么？</p>



<p>其实并不能。</p>



<p>举一个例子，我们问ChatGPT，<strong>1+1等于多少？</strong></p>



<p>它会回答：</p>



<pre class="wp-block-code"><code class="">1 + 1 等于 2。

这是一个很简单的数学题，许多人都能很快地回答出来。在做这道题时，我们只需要把 1 和 1 相加，就能得到答案 2。

值得注意的是，我们并不需要特别复杂的数学知识来解决这道题。只要我们熟悉基本的数学运算，就能很容易地回答出来。因此，1 + 1 等于 2 这道题是一道入门难度的数学题。</code></pre>



<p>很多人做过很多这样的加法测试，都得到了正确的结果，例如，如下，<strong>34+56等于多少？</strong></p>



<p>它回答，</p>



<pre class="wp-block-code"><code class="">34 + 56 等于 90。

这道题和上一道题相似，也是一道很简单的数学题。我们只需要将 34 和 56 相加，就能得到答案 90。

值得注意的是，在做这道题时，我们需要注意十进制数字的运算规则。例如，我们在计算 34 + 56 时，需要先将个位数字相加，再将十位数字相加。

为了更好地理解这道题，我们可以使用如下的运算方式来计算 34 + 56：

将个位数字相加得到 4 + 6 = 10

将十位数字相加得到 3 + 5 = 8

将结果相加得到 10 + 8 = 18

由于 18 是两位数字，因此我们需要进一步将这两位数字分别计算。于是，我们得到答案 90。

总之，34 + 56 等于 90。</code></pre>



<p>答案是对的，看起来也头头是道，但是等着“<mark style="background-color:rgba(0, 0, 0, 0)" class="has-inline-color has-accent-color">将结果相加得到 10 + 8 = 18 </mark>”这句话是什么意思？不符合我们的数学基本原理啊？</p>



<p>虽然最后的结果是对的。我们再随便把数字加大，比如问它，<strong>70654+89034等于多少？</strong></p>



<p>它回答道：</p>



<pre class="wp-block-code"><code class="">70654 + 89034 等于 159680。

这道题和前面两道题相似，都是一道很简单的数学题。我们只需要将 70654 和 89034 相加，就能得到答案 159680。

值得注意的是，在做这道题时，我们需要注意十进制数字的运算规则。例如，我们在计算 70654 + 89034 时，需要先将个位数字相加，再将十位数字相加，最后将百位数字相加。

为了更好地理解这道题，我们可以使用如下的运算方式来计算 70654 + 89034：

将个位数字相加得到 4 + 4 = 8
将十位数字相加得到 6 + 3 = 9
将百位数字相加得到 5 + 9 = 14
将千位数字相加得到 0 + 0 = 0
将万位数字相加得到 6 + 9 = 15
将十万位数字相加得到 7 + 8 = 15
由于 15 和 15 是两个两位数字，因此我们需要进一步将这两个数字分别计算。于是，我们得到答案 159680。

总之，70654 + 89034 等于 159680。</code></pre>



<p>我们一眼就发现结果也是错了，论述也是错误的，但是为啥听上去，还是头头是道呢。</p>



<p>首先，它的语料库里面包罗万有，所以一些数学题，一些简单的加减乘除的教材可能也有，所以，当一个题目的答案在他的语料库里面的时候，它多半是回答正确的。这个过程就类似于它去自己的数据库里面查了一次一样（实际上是因为整理过的语料里面，正确的结果存在的概率一定高于错误的结果）。</p>



<p>但是当数字很大，很怪，大概率语料库中不存在的时候，它所输出的加法的结果就是基于语言学逻辑概率的结果，而不是数学逻辑下的结果，自然就有可能打错特错了。但是它仍旧可以给你讲的头头是道。</p>



<p><mark style="background-color:rgba(0, 0, 0, 0)" class="has-inline-color has-accent-color">你可以理解为它是一个自然语言学问的博士，对语言无比精通，对其他的知识一无所知</mark>，天天跟各种数学家交谈（在数学语料下训练），它听过的东西，一般不会答错，虽然它并不明白它回答的意思是什么。它的泛化能力很强大，让你以为它可以举一反三，但是这种泛化是基于语言结构和语料的，并不能无中生有，不能进行严密的逻辑推理。<mark style="background-color:rgba(0, 0, 0, 0)" class="has-inline-color has-accent-color">所以，它没听过的东西，它回答的时候，近似于胡猜。但是听起来很有道理，因为它很会说话，所以，有很多时候可以蒙对。</mark></p>



<p>所以，因为它的语料库，知识库保罗万有，所以你问一些包含在知识库，语料库内的内容，它几乎都不会答错。它似乎是一个全能全知的神。但是它其实并不理解这些内容。</p>



<p>当然，我们现在说的是ChatGPT，它可以做无数的事情，但是不是每件事情。它不是真的学会了数学。但是ChatGPT比GPT-3的效果要好得多。所以，在GPT3推出来的时候引发了无数业界的关注，但是其实普通人并不了解。只有ChatGPT出现以后，GPT家族才成了彻底的显学。</p>



<p>其实，我前面讲了GPT只是一个语言模型，它确实可以补全很多话，很多时候它会表现的非常有智能。但是有很多时候，它会输出车轱辘话，它会输出毫无意义的话，有时候结果有很好。它在真正使用前，往往需要使用他的公司对他进行finetune。所谓finetune就是使用针对性的语料对GPT-3进行针对性的训练，在finetune的过程中，GPT-3 原有包含的语料信息和知识信息不会消失，但是会形成对特定问题的特定领域知识。</p>



<p>比如你Notion AI和Craft AI都是把GPT-3用在笔记应用里，他们就对GPT-3在文本润色，标题处理，摘要，等具体的应用方向上，准备大量的语言，去finetune，从而让GPT-3的输出效果在笔记应用这个层面更好用。</p>



<p>这就有点像我们的莎士比亚猴子，本来空读了无数的书，但是不知道人们喜欢它怎么说话，所以说话完全由着性子，虽然饱读诗书，但是看起来还是不够聪明。经过了finetune，它知道了在某个地方大家喜欢怎么说话，它就学着这么说话，就让大家觉得聪明了。</p>



<p>或者用一个金庸小说里面的桥段，GPT-3学了全部的武林秘籍，又用吸星大法吸收了各种内力，但是不能融会贯通。有时候打出一拳来威力无穷，有时候又软绵绵的无力，不能收放自如。然而这时候，如果学了一门剑法，剑术加内力就成了剑术高手。</p>



<p>但是，ChatGPT不是简单的在任何方向上单独finetune的结果，后面我们会详细介绍，为什么chatGPT在无数的领域都可以做出很好的效果。</p>



<p>ChatGPT就像是找到了一个方法，彻底把全部内力打通，各种无数都学会，再有内力加持就变成了无敌高手。</p>



<h2 class="wp-block-heading">WebGPT和Google</h2>



<p>首先我们介绍一个OpenAI没有正式发布的产品WebGPT。</p>



<p>我们知道Google的原理，Google的本质就是抓遍全网的数据，然后建立索引。所谓一个关键词的索引，其实就是一个关键词的全部结果的列表。如果你搜一个复杂的问题，就等于是既是的把多个关键词的索引组合起来给你得到一个结果。</p>



<p>你不管问什么问题，Google本质上，就回答有xxx个答案，然而按照相关性排序，最靠谱的排在前面。</p>



<p></p>



<p><strong>Google的基本原理</strong></p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="536" src="https://codechina.org/wp-content/uploads/2022/12/截屏2022-12-09-20.01.38-1024x536.png" alt="" class="wp-image-26043" srcset="https://codechina.org/wp-content/uploads/2022/12/截屏2022-12-09-20.01.38-1024x536.png 1024w, https://codechina.org/wp-content/uploads/2022/12/截屏2022-12-09-20.01.38-300x157.png 300w, https://codechina.org/wp-content/uploads/2022/12/截屏2022-12-09-20.01.38-768x402.png 768w, https://codechina.org/wp-content/uploads/2022/12/截屏2022-12-09-20.01.38-1536x804.png 1536w, https://codechina.org/wp-content/uploads/2022/12/截屏2022-12-09-20.01.38-1200x628.png 1200w, https://codechina.org/wp-content/uploads/2022/12/截屏2022-12-09-20.01.38.png 1892w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /><figcaption class="wp-element-caption"><strong>Google的基本原理</strong></figcaption></figure>



<p><strong>我们再看ChatGPT的基本原理</strong></p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="553" src="https://codechina.org/wp-content/uploads/2022/12/截屏2022-12-09-20.17.59-1024x553.png" alt="" class="wp-image-26048" srcset="https://codechina.org/wp-content/uploads/2022/12/截屏2022-12-09-20.17.59-1024x553.png 1024w, https://codechina.org/wp-content/uploads/2022/12/截屏2022-12-09-20.17.59-300x162.png 300w, https://codechina.org/wp-content/uploads/2022/12/截屏2022-12-09-20.17.59-768x415.png 768w, https://codechina.org/wp-content/uploads/2022/12/截屏2022-12-09-20.17.59-1536x830.png 1536w, https://codechina.org/wp-content/uploads/2022/12/截屏2022-12-09-20.17.59-1200x648.png 1200w, https://codechina.org/wp-content/uploads/2022/12/截屏2022-12-09-20.17.59.png 1866w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /><figcaption class="wp-element-caption"><strong>ChatGPT的基本原理</strong></figcaption></figure>



<h3 class="wp-block-heading">时效性</h3>



<p>从时效性来看Google更好，任何信息发布后几天，甚至几分钟内，在Google里就可以搜索到。这是因为Google的爬虫每时每刻都在爬取新的内容，而Google的索引服务也每时每刻都在更新索引。</p>



<p>而从GPT来看，ChatGPT是最近推出的，包含了很多新的内容，但是也只是截止到2021年而已，比如我问它，<strong>2022年8月发生了什么大事儿</strong>，它回答</p>



<pre class="wp-block-code"><code class="">很抱歉，我无法确定 2022 年 8 月发生了什么大事。由于我的知识截止日期是 2021 年，我无法提供有关 2022 年的信息。</code></pre>



<p>但是，我问它，<strong>2021年12月发生了什么大事儿</strong>，它回答</p>



<pre class="wp-block-code"><code class="">由于我的知识截止日期是 2021 年，我无法提供有关 2022 年的信息。但是，我可以告诉您 2021 年 12 月发生的一些重要事件：

2021 年 12 月 10 日，第二届“一带一路”国际合作高峰论坛在北京举行。
2021 年 12 月 11 日，英国与欧盟达成贸易协议。
2021 年 12 月 14 日，美国总统特朗普签署国防授权法案。
2021 年 12 月 21 日，世界气象组织宣布，2021 年将成为有史以来第三热年。

这些事件仅供参考，具体信息以相关媒体报道为准。</code></pre>



<p>抓取数据后，编入语料库，需要进行大量的处理，包含数据清洗，对齐和一些语义挖掘，所以需要大量的时间。而海量的语料库的训练也需要海量的计算资源和时间，目前还无法像Google那么随时更新。</p>



<p>所以，GPT发布于2018年，GPT-2发布于2019年，而GTP-3发布于2020年。ChatGPT最近发布，但是数据可能截止到2021年底左右。</p>



<h3 class="wp-block-heading">那什么是WebGPT呢？</h3>



<figure class="wp-block-image size-full"><img loading="lazy" decoding="async" width="720" height="310" src="https://codechina.org/wp-content/uploads/2023/01/幻灯片20.png" alt="" class="wp-image-26753" srcset="https://codechina.org/wp-content/uploads/2023/01/幻灯片20.png 720w, https://codechina.org/wp-content/uploads/2023/01/幻灯片20-300x129.png 300w" sizes="auto, (max-width: 720px) 100vw, 720px" /></figure>



<p>所谓WebGPT是OpenAI没有正式发布的一个产品，仅仅是一个Demo。它的思路是从Google的搜索结果里面找到最好的内容，然后整合成一篇短文。你可以理解为，比如它可以把Google搜索一个关键词的前十名文章，凑成一篇长文章，然后用它自己的摘要功能把这篇超长的文章，写成一个比较短的摘要。</p>



<h2 class="wp-block-heading">ChatGPT是怎么炼成的呢？</h2>



<p>我们前面介绍了语言模型，GPT-3，甚至WebGPT，是希望大家建立一个概念。在ChatGPT前，GPT-3已经表现出了智能，但是结果不稳定，具体用之前需要针对应用领域去finetune。但是ChatGPT几乎什么都能干，它是怎么炼成的呢？</p>



<p>简单的说，三个步骤：</p>



<ul class="wp-block-list">
<li>收集示例数据，训练一个有监督的模型</li>



<li>收集比较数据，训练一个奖励模型</li>



<li>根据奖励模型，对有监督模型进行持续的强化学习</li>
</ul>



<h3 class="wp-block-heading">1、收集示例数据，训练一个有监督的模型</h3>



<figure class="wp-block-image size-full"><img loading="lazy" decoding="async" width="720" height="405" src="https://codechina.org/wp-content/uploads/2023/01/幻灯片22.png" alt="" class="wp-image-26762" srcset="https://codechina.org/wp-content/uploads/2023/01/幻灯片22.png 720w, https://codechina.org/wp-content/uploads/2023/01/幻灯片22-300x169.png 300w" sizes="auto, (max-width: 720px) 100vw, 720px" /></figure>



<p>如上图，第一步，系统从之前收集的提示数据库，也就是一堆形形色色的问题，可能有几万到几十万的有意义的问题，中间选一个。</p>



<p>比如这个问题是，<strong>如何向一个六岁小孩儿解释什么是登陆月球。</strong></p>



<p>然后，由一个标注人员，就是一个人，来写一个期待AI能回答出来的比较好的答案的一个范本。</p>



<p>这些问题和人写好的回答，就形成了训练数据。</p>



<p>用这些数据去fine-tune现有的GPT-3或者是GPT-3.5模型，得到一个监督学习的模型。这个模型的精神内核还是GPT，但是它更会回答问题了，它参考了这些数据库里面抽取的问题和标注人员写好的答案。它具有了一定的好好回答问题的能力。</p>



<h3 class="wp-block-heading"><strong>2、收集比较数据，训练一个奖励模型</strong></h3>



<figure class="wp-block-image size-full"><img loading="lazy" decoding="async" width="720" height="405" src="https://codechina.org/wp-content/uploads/2023/01/幻灯片23.png" alt="" class="wp-image-26764" srcset="https://codechina.org/wp-content/uploads/2023/01/幻灯片23.png 720w, https://codechina.org/wp-content/uploads/2023/01/幻灯片23-300x169.png 300w" sizes="auto, (max-width: 720px) 100vw, 720px" /></figure>



<p>如上图，有了刚才第一个有监督的模型以后，我们就可以让那个模型多次输出不同的答案。然后让标注人员，来对多个结果进行质量评估。比如得到D&gt;C&gt;A=B的结果。也就是A和B答案质量差不多。C更好，D最好的这么一个评估结果。这样我们就可以给答案排序。</p>



<p>有了问题、一组答案和排序，我们就可以训练一个奖励模型。这个奖励模型就是给它任何一个问题和一组答案，它都能自动得判断哪一个答案更好。</p>



<h3 class="wp-block-heading">3、根据奖励模型，对有监督模型进行持续的强化学习</h3>



<figure class="wp-block-image size-full"><img loading="lazy" decoding="async" width="720" height="405" src="https://codechina.org/wp-content/uploads/2023/01/幻灯片24.png" alt="" class="wp-image-26765" srcset="https://codechina.org/wp-content/uploads/2023/01/幻灯片24.png 720w, https://codechina.org/wp-content/uploads/2023/01/幻灯片24-300x169.png 300w" sizes="auto, (max-width: 720px) 100vw, 720px" /></figure>



<p>有了第一个回答问题的监督模型，评估答案的奖励模型。我们就可以开始强化学习的循环。</p>



<p>所谓的强化学习就有点像我们在《射雕英雄传》里面看到的周伯通的左右互搏，我们让AI不断的生成答案，然后根据奖励模型，我们可以告诉AI哪一次生成的答案更好。如果结果好，我们就鼓励模型继续这么做，如果不好，我们就惩罚模型让它改进。</p>



<p>为什么会有这三个步骤呢。其实前面两步都是监督学习。需要人工参与，需要准备大量的标注数据。这样呢，训练的规模很难上去，经济成本和时间成本都很高。第三步，有了前两步的准备，就全部是机器左右互搏，就不再需要人工的参与，就可以进行海量的运算去不断的优化结果了。</p>



<p>我们估计在前两步的数据量估计是在几万到几十万的量级，成本高昂，旷日持久。但是到了第三步，几乎不需要人的参与，主要耗费的就是计算力和电力。这个时候，训练的规模就可以几乎无限的大，尽力去追求最好的结果。</p>



<p>如果你了解下围棋天下第一的AlphaGo，其实它最早期的版本就是通过标注信息进行监督学习。在这个时期，它相当于接受了人类所有历史上已知的棋局，它就已经达到了秒杀全部人类高手的能力。但是这时候，相对于围棋全部的知识来说，AlphaGo和人类还没掌握到全部的精髓。</p>



<figure class="wp-block-image size-full"><img loading="lazy" decoding="async" width="1000" height="562" src="https://codechina.org/wp-content/uploads/2023/01/gettyimages-688097364_wide-449445f9a096aa86764e907b6711373d15f6c723.jpg" alt="" class="wp-image-26770" srcset="https://codechina.org/wp-content/uploads/2023/01/gettyimages-688097364_wide-449445f9a096aa86764e907b6711373d15f6c723.jpg 1000w, https://codechina.org/wp-content/uploads/2023/01/gettyimages-688097364_wide-449445f9a096aa86764e907b6711373d15f6c723-300x169.jpg 300w, https://codechina.org/wp-content/uploads/2023/01/gettyimages-688097364_wide-449445f9a096aa86764e907b6711373d15f6c723-768x432.jpg 768w" sizes="auto, (max-width: 1000px) 100vw, 1000px" /><figcaption class="wp-element-caption">Ke Jie, the world&#8217;s No. 1 Go player, stares at the board during his second match against AlphaGo in Wuzhen, China, on Thursday. The 19-year-old grandmaster dropped the match in the best-of-three series against Google&#8217;s artificial intelligence program.</figcaption></figure>



<p>后面的AlphaGo也是用强化学习去训练的，这个时候，全世界的人类都无法跟AlphaGo比肩，人类的历史棋谱也不如AlphaGo的水平高了。怎么继续提高，就是左右互搏，两个原始的AlphaGo互相下，没有限制的各种下，探索人类从来没有达到过的高度。用机器来判定每一步哪个AlphaGo下得更好，逐渐相互学习，得到了目前人类和机器都无法企及的高度。</p>



<p>ChatGPT的第三步也是如此。这也说明为什么目前Chat GPT虽然看起来万能，但是它会主动说2021年12月以后的信息它并不掌握。因为训练GPT-3和GPT3.5已经是旷日持久的工作，需要几个月的时间，用大量最好的AI服务器不停的训练。而在GPT-3和3.5的基础上，得到了前两步的监督模型和奖励模型后，进行强化学习还需要大量的训练时间去精益求精。</p>



<p>好。我们尽全力不用任何公式，用普通人应该能听得懂的原理解释的方式去讲清楚了ChatGPT是怎么炼成的，它当然还有它的局限性。但是它也仍旧在继续进化中。</p>



<p>据说，GPT-4很快要发布，后续GPT家族，还有Google、Meta，其他硅谷巨头的类似模型也都在研发，我们继续关注，AI如何改变我们的生活，我们怎么去理解AI的发展，从而了解原理更好的了解它的局限性和功能，从来用好AI。</p>



<h3 class="wp-block-heading">参见：</h3>



<ul class="wp-block-list">
<li><a href="https://codechina.org/2022/12/seo-chatgpt-search/">SEO：用ChatGPT来做搜索关键词聚类分析，方法和实例</a></li>



<li><a href="https://codechina.org/2022/12/chatgpt-faq/">ChatGPT常见问题解答【官方/非官方版】</a></li>



<li><a href="https://codechina.org/2022/12/chatgpt-function-1-writting/">ChatGPT帮助你快速高效地完成你的写作任务</a></li>
</ul>



<h2 class="wp-block-heading">参考</h2>



<p>（1）无限猴子定理<a href="https://zh.wikipedia.org/wiki/%E7%84%A1%E9%99%90%E7%8C%B4%E5%AD%90%E5%AE%9A%E7%90%86">https://zh.wikipedia.org/wiki/%E7%84%A1%E9%99%90%E7%8C%B4%E5%AD%90%E5%AE%9A%E7%90%86</a></p>



<p>（2）Stanford CS224N: NLP with Deep Learning | Winter 2019 | Lecture 6 – Language Models and RNNs <a href="https://youtu.be/iWea12EAu6U">https://youtu.be/iWea12EAu6U</a></p>
<p><a href="https://codechina.org/2023/01/25998/">万能的ChatGPT真有智能了么？一篇文章让你彻底搞懂ChatGPT-人类是怎么训练出了一只聪明的莎士比亚的猴子</a>最先出现在<a href="https://codechina.org">Tinyfool的个人网站</a>。</p>
]]></content:encoded>
					
					<wfw:commentRss>https://codechina.org/2023/01/25998/feed/</wfw:commentRss>
			<slash:comments>2</slash:comments>
		
		
			<media:content url="https://codechina.org/wp-content/uploads/2022/12/Monkey-typing.jpg" medium="image" />
	</item>
		<item>
		<title>ChatGPT常见问题解答【官方/非官方版】</title>
		<link>https://codechina.org/2022/12/26143/</link>
					<comments>https://codechina.org/2022/12/26143/#respond</comments>
		
		<dc:creator><![CDATA[tinyfool]]></dc:creator>
		<pubDate>Sun, 11 Dec 2022 01:13:37 +0000</pubDate>
				<category><![CDATA[AI]]></category>
		<category><![CDATA[技术]]></category>
		<category><![CDATA[ChatGPT]]></category>
		<category><![CDATA[GPT3]]></category>
		<guid isPermaLink="false">https://codechina.org/?p=26143</guid>

					<description><![CDATA[<p>ChatGPT官方常见问题解答 翻译自官方的FAQ页面，翻译由ChatGPT完成。 1、ChatGPT 的使用 [&#8230;]</p>
<p><a href="https://codechina.org/2022/12/26143/">ChatGPT常见问题解答【官方/非官方版】</a>最先出现在<a href="https://codechina.org">Tinyfool的个人网站</a>。</p>
]]></description>
										<content:encoded><![CDATA[
<h2 class="wp-block-heading">ChatGPT官方常见问题解答</h2>



<p>翻译自<a href="https://help.openai.com/en/articles/6783457-chatgpt-faq">官方的FAQ页面</a>，翻译由ChatGPT完成。</p>



<span id="more-26143"></span>



<h3 class="wp-block-heading">1、ChatGPT 的使用成本是多少？</h3>



<p>在最初的研究预览期间，ChatGPT 免费使用。</p>



<h3 class="wp-block-heading">2、ChatGPT 是如何运作的？</h3>



<p>ChatGPT 是从 GPT-3.5 进行微调的，GPT-3.5 是一个被训练用来生成文本的语言模型。ChatGPT 通过使用人类反馈的强化学习 (RLHF) 进行优化，以便适用于对话 &#8211; 这是一种利用人类演示来指导模型朝着期望行为的方法。</p>



<h3 class="wp-block-heading">3、为什么 AI 看起来如此真实而逼真？</h3>



<p>这些模型是在由人类编写的大量互联网数据上进行训练的，包括对话，因此它提供的响应可能听起来像人类。重要的是要记住，这是该系统设计 (即最大化输出与模型训练数据集之间的相似性) 的直接结果，并且这些输出有时可能是不准确的，不真实的，其他方面也可能会误导。</p>



<h3 class="wp-block-heading">4、我能相信 AI 告诉我的是真相吗？</h3>



<p>ChatGPT 未连接互联网，并且它偶尔会产生不正确的答案。它对 2021 年后的世界和事件的知识有限，并且也可能偶尔会产生有害指令或有偏见的内容。</p>



<p>我们建议检查模型的答案是否准确。如果您发现答案不正确，请通过使用“踩”按钮提供反馈。</p>



<h3 class="wp-block-heading">5、谁可以查看我的对话？</h3>



<p>作为我们致力于安全和负责任 AI 的承诺，我们会审查对话，以改进我们的系统，并确保内容符合我们的政策和安全要求。</p>



<h3 class="wp-block-heading">6、您会使用我的对话来进行训练吗？</h3>



<p>是的。您的对话可能会被我们的 AI 训练师审查，以改进我们的系统。</p>



<h3 class="wp-block-heading">7、您能删除我的数据吗？</h3>



<p>是的，请按照这里的数据删除流程：<a href="https://help.openai.com/en/articles/6378407-how-can-i-delete-my-account">https://help.openai.com/en/articles/6378407-how-can-i-delete-my-account</a></p>



<h3 class="wp-block-heading">8、您能删除特定的提示吗？</h3>



<p>不，我们无法删除您的历史记录中的特定提示。请不要在对话中分享任何敏感信息。</p>



<h3 class="wp-block-heading">9、我能看到我的主题历史记录吗？我怎样才能保存我已经进行过的对话？</h3>



<p>不，此时无法查看您的对话历史记录，但这是我们正在研究的功能。</p>



<h3 class="wp-block-heading">10、您在哪里保存我的个人和对话数据？</h3>



<p>有关我们如何处理数据的更多信息，请参阅我们的隐私政策和使用条款。</p>



<h3 class="wp-block-heading">11、我如何实现此功能？这个有实现指南吗？</h3>



<p>ChatGPT 正在作为研究预览提供，因此我们可以了解它的优点和弱点。它不可用于 API。</p>



<h3 class="wp-block-heading">12、如果我已经有了 Labs 或 Playground 账户，那么我需要新账户吗？</h3>



<p>如果您在 labs.openai.com 或 beta.openai.com 上已经有账户，那么您可以使用相同的登录信息在 chat.openai.com 直接登录。如果您没有账户，您需要在 chat.openai.com 上注册一个新账户。</p>



<h2 class="wp-block-heading">非官方常见问题解答</h2>



<p>由Tinyfool根据对这个系统的理解、分析和使用体验得出。不保证完全正确，尽量帮助大家解答，也欢迎有问题留言，我会回复留言来解答。</p>



<h2 class="wp-block-heading">1、为什么ChatGPT会出现一些明显的事实错误？是语料库的问题么？</h2>



<p>ChatGPT的本质还是GPT，还是语言模型，它的内核的目标是说的像人说的话，而不是真的对语料的内容有理解。所以，它可能会张冠李戴的说《活着》是莫言写的。从语言上这么说没错，事实上是错误的。这是模型本质决定的。</p>



<p>但是这不影响ChatGPT的应用，因为实际应用的时候，可以让ChatGPT作为前端，知识库作为后端结合使用，就可以保证事实错误不会出现了。</p>



<h2 class="wp-block-heading">ChatGPT实用指南系列</h2>



<ul class="wp-block-list">
<li><a href="https://codechina.org/2022/12/chatgpt-function-1-writting/">ChatGPT帮助你快速高效地完成你的写作任务</a></li>
</ul>
<p><a href="https://codechina.org/2022/12/26143/">ChatGPT常见问题解答【官方/非官方版】</a>最先出现在<a href="https://codechina.org">Tinyfool的个人网站</a>。</p>
]]></content:encoded>
					
					<wfw:commentRss>https://codechina.org/2022/12/26143/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			<media:content url="https://codechina.org/wp-content/uploads/2022/12/DALL·E-2022-12-10-23.38.10-random-blue-color-Rectangle-as-background-white-big-question-mark-block-on-top-it-a-robot-sit-on-it-1024_768-1.png" medium="image" />
	</item>
	</channel>
</rss>
