1"use strict";(self.webpackChunkflyskypie_github_io=self.webpackChunkflyskypie_github_io||[]).push([[7199],{91567:(e,n,i)=>{i.r(n),i.d(n,{assets:()=>a,contentTitle:()=>r,default:()=>p,frontMatter:()=>o,metadata:()=>c,toc:()=>d});var s=i(11527),t=i(88717);const o={slug:"2026-07-12_biomes",authors:["weiji"],tags:["Biomes"]},r="Biomes \u7814\u7a76\u7b46\u8a18 8",c={permalink:"/posts/2026-07-12_biomes",source:"@site/post/2026-07-12_biomes/index.md",title:"Biomes \u7814\u7a76\u7b46\u8a18 8",description:"\u524d\u60c5\u63d0\u8981",date:"2026-07-12T00:00:00.000Z",formattedDate:"July 12, 2026",tags:[{label:"Biomes",permalink:"/posts/tags/biomes"}],hasTruncateMarker:!1,authors:[{name:"Wei Ji",title:"\u9583\u4eae\u75c7\u5019\u7fa4\u5de5\u7a0b\u5c4d",url:"https://github.com/FlySkyPie",imageURL:"https://avatars.githubusercontent.com/u/9475660",key:"weiji"}],frontMatter:{slug:"2026-07-12_biomes",authors:["weiji"],tags:["Biomes"]},unlisted:!1,prevItem:{title:"Agentic \u7db2\u8def\u8a2a\u554f\u96dc\u8a18",permalink:"/posts/2026-08-24_agent-search"},nextItem:{title:"OpenBMC \u7684\u6b77\u53f2",permalink:"/posts/2026-07-11_openbmc-history"}},a={authorsImageUrls:[void 0]},d=[{value:"\u524d\u60c5\u63d0\u8981",id:"\u524d\u60c5\u63d0\u8981",level:2},{value:"Zod Schema",id:"zod-schema",level:2},{value:"\u7531\u4e0a\u800c\u4e0b\u7684\u5617\u8a66",id:"\u7531\u4e0a\u800c\u4e0b\u7684\u5617\u8a66",level:2},{value:"Bob",id:"bob",level:3},{value:"GCP \u91cd\u5ea6\u4ef0\u8cf4",id:"gcp-\u91cd\u5ea6\u4ef0\u8cf4",level:3},{value:"\u904e\u671f\u7684\u9032\u5165\u9ede",id:"\u904e\u671f\u7684\u9032\u5165\u9ede",level:3},{value:"\u5c0f\u7d50",id:"\u5c0f\u7d50",level:2}];function l(e){const n={a:"a",code:"code",h2:"h2",h3:"h3",img:"img",p:"p",pre:"pre",...(0,t.a)(),...e.components},{Head:o}=n;return o||function(e,n){throw new Error("Expected "+(n?"component":"object")+" `"+e+"` to be defined: you likely forgot to import, pass, or provide it.")}("Head",!0),(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(o,{children:(0,s.jsx)("meta",{property:"og:image",content:"https://raw.githubusercontent.com/FlySkyPie/flyskypie.github.io/main/post/2026-07-12_biomes/00_cover.webp"})}),"\n",(0,s.jsx)(n.h2,{id:"\u524d\u60c5\u63d0\u8981",children:"\u524d\u60c5\u63d0\u8981"}),"\n",(0,s.jsxs)(n.p,{children:["\u8acb\u898b\uff1a",(0,s.jsx)(n.a,{href:"https://flyskypie.github.io/posts/2025-12-24_biomes/",children:"Biomes \u7814\u7a76\u7b46\u8a18 7"})]}),"\n",(0,s.jsx)(n.h2,{id:"zod-schema",children:"Zod Schema"}),"\n",(0,s.jsxs)(n.p,{children:["Biomes \u7684 ",(0,s.jsx)(n.code,{children:"shared"})," \u6a21\u7d44\u4e2d\u5b9a\u7fa9\u4e86\u5f88\u591a\u8cc7\u6599\uff0c\u7576\u4e2d\u4e0d\u5c11\u6a94\u6848\u662f\u8d85\u904e 500 \u884c\u7684\uff0c\u4e26\u4e14\u4e0d\u5c11\u6709\u5faa\u74b0\u4ef0\u8cf4\uff1a"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-typescript",children:'export const zBiscuitAttributeAssignment = z.lazy(\n memoize(() =>\n z.discriminatedUnion("kind", [\n zParentTrayAssignment,\n zConstantAssignment,\n zReferenceAssignment,\n zUnassignment,\n zInferenceAssignment,\n ])\n )\n) as ZodType<BiscuitAttributeAssignment>;\n\nexport const zParentTrayAssignment = z.object({\n kind: z.literal("parentTray"),\n to: zBiscuitAttributeAssignment,\n});\n'})}),"\n",(0,s.jsxs)(n.p,{children:["\u70ba\u4e86\u5c0d\u4ef0\u8cf4\u95dc\u4fc2\u6709\u66f4\u7d30\u7684\u7406\u89e3\uff0c\u907f\u514d\u592a\u591a\u6771\u897f\u88ab ",(0,s.jsx)(n.code,{children:"import"}),"\uff0c\u800c\u628a\u5b9a\u7fa9\u8cc7\u6599\u6a94\u6848\u62c6\u6210\u7368\u7acb\u7684\u6a94\u6848\uff0c\u7136\u800c\u5faa\u74b0\u4ef0\u8cf4\u6703\u9020\u6210 runtime error\u3002"]}),"\n",(0,s.jsx)(n.p,{children:"\u52a0\u4e0a\u5f88\u591a\u578b\u5225\u662f\u7528 Zod \u7684 schema \u672c\u8eab\u9032\u884c\u63a8\u8ad6\u7684\uff1a"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-typescript",children:"export const zShotMetadata = z.object({\n coordinates: zVec3f,\n cameraLookAt: zVec3f.optional(),\n shotInMinigameId: zBiomesId.optional(),\n shotInMinigameInstanceId: zBiomesId.optional(),\n shotInMinigameType: zMinigameType.optional(),\n});
1\n\nexport type ShotMetadata = z.infer<typeof zShotMetadata>;\n"})}),"\n",(0,s.jsxs)(n.p,{children:["\u9020\u6210\u4ef0\u8cf4 ",(0,s.jsx)(n.code,{children:"type"})," \u7684\u6642\u5019\u4f9d\u7136\u6703 ",(0,s.jsx)(n.code,{children:"import"})," \u5230\u5be6\u4f5c\uff0c\u52a0\u5287\u4e86\u5faa\u74b0\u4ef0\u8cf4\u7684\u554f\u984c\u3002"]}),"\n",(0,s.jsx)(n.h2,{id:"\u7531\u4e0a\u800c\u4e0b\u7684\u5617\u8a66",children:"\u7531\u4e0a\u800c\u4e0b\u7684\u5617\u8a66"}),"\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.img,{src:i(76160).Z+"",width:"1236",height:"1062"})}),"\n",(0,s.jsx)(n.p,{children:"\u4e94\u6708\u4efd\u7684\u6642\u5019\u6709 Biomes \u7684\u5167\u90e8\u4eba\u54e1\u4fee\u5fa9\u4e86\u7d20\u6750\u5305\u7f3a\u5931\u7684\u554f\u984c\uff0c\u539f\u672c\u8a72\u5c08\u6848\u81ea\u52d5\u5316\u8173\u672c\u6703\u53bb GCP \u4e0b\u8f09\u9810\u5148\u6253\u5305\u7684\u7d20\u6750\u5305\uff0c\u4f46\u662f\u8a72\u8cc7\u6e90\u5df2\u7d93\u7121\u6cd5\u88ab\u8a2a\u554f\uff0c\u4fee\u5fa9\u7684\u5167\u5bb9\u5c31\u662f\u5728 GitHub \u4e0a release \u4e00\u4efd\uff0c\u4e26\u4e14\u66f4\u65b0\u81ea\u52d5\u5316\u8173\u672c\u3002"}),"\n",(0,s.jsx)(n.p,{children:"\u5728\u9019\u4e4b\u524d\u6211\u662f\u4ee5\u7531\u4e0b\u800c\u4e0a\uff0c\u5f9e\u4ef0\u8cf4\u93c8\u672b\u7aef\u7684\u57fa\u672c\u5143\u4ef6\u6162\u6162\u91cd\u69cb\u8207\u7de8\u8b6f\u5f80\u4e0a\u7d44\u5408\u7684\u3002\u65e2\u7136\u539f\u59cb\u5718\u968a\u7684\u4eba\u5df2\u7d93\u505a\u4e86\u4e00\u4e9b\u4fee\u5fa9\u4e26\u4e14\u8072\u7a31\u81ea\u5df1\u6e2c\u8a66\u904e\u53ef\u4ee5\u904b\u884c\uff0c\u6211\u5c31\u8a66\u8457\u7531\u4e0a\u800c\u4e0b\u8dd1\u8dd1\u770b\u5427\u3002"}),"\n",(0,s.jsx)(n.h3,{id:"bob",children:"Bob"}),"\n",(0,s.jsx)(n.p,{children:"Biomes \u7684\u7a0b\u5f0f\u78bc\u53ef\u4ee5\u770b\u5230\u4e0d\u5c11\u540d\u70ba Bob \u7684\u6771\u897f\uff1a"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"\u251c\u2500\u2500 deploy/\n\u2502\xa0\xa0 \u2514\u2500\u2500 k8/\n\u2502\xa0\xa0 \u2514\u2500\u2500 services/\n\u2502\xa0\xa0 \u2514\u2500\u2500 bob.yaml\n\u251c\u2500\u2500 Dockerfile.bob\n\u251c\u2500\u2500 scripts/\n\u2502\xa0\xa0 \u2514\u2500\u2500 deploy_bob.sh\n\u2514\u2500\u2500 src/\n \xa0\xa0 \u2514\u2500\u2500 server/\n \xa0\xa0 \u2514\u2500\u2500 bob/\n"})}),"\n",(0,s.jsx)(n.p,{children:"\u56e0\u70ba\u6700\u5f8c\u662f\u4ee5 Docker \u7684\u5f62\u5f0f\u5b58\u5728\uff0cK8s \u7de8\u6392\u5167\u4e5f\u6709\uff0c\u6211\u4e4b\u524d\u4e00\u76f4\u4ee5\u70ba\u9019\u662f\u904a\u6232\u672c\u9ad4\u7684\u5167\u90e8\u4ee3\u865f\uff0c\u6700\u8fd1\u4ed4\u7d30\u770b\u4e86\u4e00\u4e0b\u5be6\u4f5c\u624d\u77e5\u9053\u5b83\u662f\u624b\u6413\u7684\u81ea\u52d5\u5316\u7a0b\u5f0f\uff0c\u88ab\u64ec\u4eba\u5316\u70ba\u4e00\u500b\u540d\u70ba Bob \u7684 Agent\u3002"}),"\n",(0,s.jsx)(n.p,{children:"\u9019\u500b\u7a0b\u5f0f\u5728\u505a\u7684\u4e8b\u60c5\u5c31\u662f\u8f2a\u8a62 Git\u3001\u904b\u884c Bazel \u8207 Docker (DnD)\u3001\u63a8\u9001\u6620\u50cf\u6a94\u3001\u89f8\u767c Discord \u901a\u77e5...\u7b49\u3002\u7d66\u4eba\u4e00\u7a2e\u300c\u4e0d\u77e5\u9053 CI/CD \u70ba\u4f55\u7269\u7684\u524d\u7aef\u4ed4\u7528 Typescript \u6413\u51fa\u4f86\u7684\u6771\u897f\u300d\u7684\u611f\u89ba\u3002"}),"\n",(0,s.jsx)(n.h3,{id:"gcp-\u91cd\u5ea6\u4ef0\u8cf4",children:"GCP \u91cd\u5ea6\u4ef0\u8cf4"}),"\n",(0,s.jsx)(n.p,{children:"\u7a0b\u5f0f\u904b\u884c\u5f8c\u6703\u88ab GCP/Firebase \u7684\u9451\u6b0a\u64cb\u4f4f\uff0c\u4ed4\u7d30\u67e5\u770b\u7a0b\u5f0f\u78bc\u6703\u767c\u73fe\u5be6\u4f5c\u9ad8\u5ea6\u8026\u5408 BigQuery\u3001Firestore\u3001GCP Storage\u3001App Engine...\u7b49 Google \u7684\u670d\u52d9\u3002"}),"\n",(0,s.jsx)(n.p,{children:"\u5e7e\u4e4e\u53ef\u4ee5\u60f3\u898b\u8a72\u5718\u968a\u88ab\u5fae\u8edf\u9ad4\u7cfb\u7684 OpenAI \u6536\u8cfc\u4e4b\u5f8c\u6703\u6709\u4ec0\u9ebc\u6a23\u7684\u885d\u64ca\u3002"}),"\n",(0,s.jsx)(n.h3,{id:"\u904e\u671f\u7684\u9032\u5165\u9ede",children:"\u904e\u671f\u7684\u9032\u5165\u9ede"}),"\n",(0,s.jsxs)(n.p,{children:["\u8abf\u67e5 ",(0,s.jsx)(n.code,{children:"Dockerfile.bob"})," \u548c ",(0,s.jsx)(n.code,{children:"Dockerfile.biomes"})," \u7684\u5efa\u69cb\u6d41\u7a0b\u6703\u767c\u73fe\u660e\u986f\u6709\u8a2d\u8a08 Next.js \u548c Webpack \u7684\u5efa\u7f6e\u6d41\u7a0b\u3002"]}),"\n",(0,s.jsx)(n.p,{children:"\u4f46\u662f\u8abf\u67e5 K8s \u8a2d\u5b9a\u6703\u770b\u5230\u8af8\u5982\u9019\u6a23\u7684\u5167\u5bb9\uff1a"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-yaml",children:" containers:\n - image: us-central1-docker.pkg.dev/zones-cloud/b/biomes:devin-deploy-2\n name: biomes\n args:\n - '-r'\n - ts-node/register\n - src/server/gaia_v2/main.ts\n - '--bikkieCacheMode'\n - redis\n - '--biscuitMode'\n - redis2\n - '--chatApiMode'\n - redis\n - '--firehoseMode'\n - redis\n - '--serverCacheMode'\n - redis\n - '--storageMode'\n - firestore\n - '--worldApiMode'\n - hfc-hybrid\n - '--simulations'\n - restoration\n - lifetime\n - ore_growth\n"})}),"\n",(0,s.jsx)(n.p,{children:"\u6240\u6709\u5fae\u670d\u52d9\u90fd\u662f\u4e0d\u7d93\u904e\u5efa\u7f6e\uff0c\u76f4\u63a5\u7528 Typescript \u904b\u884c\u7684\u3002\u7531\u6b64\u53ef\u77e5\u7a0b\u5f0f\u78bc\u5167\u90e8\u6709\u56b4\u91cd\u7684\u5272\u88c2\uff0c\u4e0d\u540c\u6642\u671f\u7684\u9032\u5165\u9ede\u540c\u6642\u5b58\u5728\uff0c\u53ef\u80fd\u9084\u6709\u4e0d\u5c11\u985e\u4f3c\u7684\u5ee2\u68c4\u7a0b\u5f0f\u78bc\u5b58\u5728\u3002"}),"\n",(0,s.jsx)(n.h2,{id:"\u5c0f\u7d50",children:"\u5c0f\u7d50"}),"\n",(0,s.jsx)(n.p,{children:"\u7531\u4e0a\u800c\u4e0b\u5927\u6982\u662f\u8d70\u4e0d\u901a\u7684\u8def\u7dda\uff0c\u56e0\u70ba\u5fc5\u9808\u8981\u5efa\u7acb\u5b8c\u6574\u7684 GCP \u5c08\u6848\u4ee5\u53ca\u5b8c\u6574\u7684 K8s \u670d\u52d9\u7c07\u624d\u6709\u53ef\u80fd\u628a\u7a0b\u5f0f\u8dd1\u8d77\u4f86\uff0c\u8ddf GCP \u7684\u4ef0\u8cf4\u53c8\u6709\u56b4\u91cd\u8026\u5408\uff0c\u5f88\u96e3\u900f\u904e\u7c21\u55ae\u7684\u91cd\u69cb\u62bd\u63db\u6210\u5176\u4ed6\u66ff\u4ee3\u5fae\u670d\u52d9\u3002"})]})}function p(e={}){const{wrapper:n}={...(0,t.a)(),...e.components};return n?(0,s.jsx)(n,{...e,children:(0,s.jsx)(l,{...e})}):l(e)}},76160:(e,n,i)=>{i.d(n,{Z:()=>s});const s=i.p+"assets/images/01_asset-package-dd9b7846b56344aea8bb49f6378d97e4.webp"},88717:(e,n,i)=>{i.d(n,{Z:()=>c,a:()=>r});var s=i(50959);const t={},o=s.createContext(t);function r(e){const n=s.useContext(o);return s.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function c(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(t):e.components||t:r(e.components),s.createElement(o.Provider,{value:n},e.children)}}}]);
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.