openclaw 比较火,我分析了它的源代码,写一篇技术博客介绍它的架构原理。 - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
simplejian

openclaw 比较火,我分析了它的源代码,写一篇技术博客介绍它的架构原理。

  •  2
     
  •   simplejian 2 月 6 日 4676 次点击
    这是一个创建于 76 天前的主题,其中的信息可能已经有所发展或是发生改变。

    OpenClaw 是一款专为 AI 代理打造的自托管网关,旨在打破聊天应用与智能助手之间的隔阂。它不仅仅是一个连接器,更是一个强大的中枢,能将 WhatsApp 、Telegram 、Discord 、iMessage 等主流通讯平台无缝接入像 Pi 这样具备编码能力的 AI 代理。

    通过在自己的设备或服务器上运行 OpenClaw ,我们获得了一个完全属于自己的“AI 大脑中枢”。它不仅是一个多渠道的聚合器,更是一个代理原生的操作系统专为处理复杂的工具调用、会话记忆管理和多代理路由而设计。这意味着,无论我们身在何处,通过哪个平台,都能随时唤起我们的私人 AI 助手,而无需担忧数据隐私或依赖不稳定的第三方托管服务。OpenClaw 让我们的 AI 助手真正驻留在自己的硬件上,听从我们的规则,为我们构建一个安全、统一且高度可扩展的智能交互网络。

    虽然关于 OpenClaw 的部署文章已经随处可见,但是当你安装并实际使用时,如果你不了解 OpenClaw 设计架构的精妙之处,你很难真正知道 OpenClaw 能干什么、怎么干,以及它的边界和限制在哪里。本篇文章,我将深入 OpenClaw 的工作原理,让你全面了解这个系统。

    工作原理

    OpenClaw 的原理可以参考下图。

    OpenClaw Architecture

    1) 左侧输入:Chat apps + plugins -> Gateway

    • 各聊天渠道( Telegram/WhatsApp/Discord/Slack 等)通过 channel plugin 接入,统一成标准事件。
    • 消息归一化:每条入站消息在 Gateway 内被归一化为:channel + account + 会话键(sessionKey) + 消息体
    • 插件能力:插件还能扩展工具、hooks 、额外 RPC 方法,它不仅仅是“多一个渠道”。

    2) 中枢:Gateway 做什么

    • 核心职责:负责长驻连接、鉴权、会话状态、方法路由、事件广播。
    • 统一管理:把“谁发来的、发到哪、当前会话上下文”统一管理,然后分发到 agent/chat/send 等。
    • 协议一致:所有前端/客户端几乎都通过同一套 Gateway 协议交互,所以能力一致性很高。

    3) 右侧能力面:Gateway -> Pi agent / CLI / Web UI / macOS / iOS&Android nodes

    • Pi agent:推理执行核心(生成回复、调用工具、读写会话记忆)。
    • CLI:既可直接跑命令,也可作为 Gateway 的运维与调用入口。
    • Web Control UI / macOS app:本质是 Gateway 的可视化控制台(配置、状、日志、会话)。
    • iOS/Android nodes:移动端节点,向 Gateway 注册、收发事件、执行被下发任务。

    Chat apps + plugins

    这块可以理解成:Gateway 左侧的“外部世界接入层”。

    它主要做两件事:

    1. Chat apps:真实消息来源/去向( Telegram 、WhatsApp 、Discord 、iMessage 等)。 负责“把用户消息带进来、把回复发出去”。
    2. Plugins:协议适配器 + 扩展能力。 把每个平台各自不同的 API/事件格式,转换成 Gateway 能统一处理的格式;也能附加新能力(新渠道、工具、hooks 、provider 、自定义命令等)。

    所以这块的作用不是“处理 AI”,而是:把杂乱的外部渠道世界,整理成 Gateway 能懂的统一输入输出。 没有这层,Gateway 就没法稳定接那么多不同平台。

    图里把 plugins 画在左边,是从“概念层”强调它在入口侧扩展渠道能力,但在“实现层”上,插件系统确实是 Gateway 启动时加载、注册到 Gateway 内部 的(不是独立外部服务)。所以它不只是“前置动作”,而是 Gateway 运行时的一部分:

    • 启动时:发现并加载插件;
    • 运行时:插件参与消息接入、路由、工具调用、RPC 扩展、渠道发送。

    Gateway

    Gateway 就是 OpenClaw 的“大脑中枢 + 交通枢纽 + 安全门禁”。

    它的定位不是某个聊天渠道,也不是单纯的 API 服务,而是把所有能力组织起来的核心层:

    • 统一入口:Telegram 、WhatsApp 、Discord 、iMessage 、WebChat 、移动端 node 、CLI 、macOS/iOS/Android 客户端,最后都汇到 Gateway 。
    • 统一协议:不管前端来自哪里,Gateway 都用同一套方法( RPC/事件)处理,避免每个端自己发明一套逻辑。
    • 统一会话:它维护 sessionKey、上下文、最后路由目标、线程信息,让“这次对话是谁、在哪、怎么回”始终可追踪。
    • 统一路由:消息进来后决定交给谁( agent 、chat handler 、工具、channel adapter ),回复再按来源和策略发回去。
    • 统一安全:鉴权、角色、scope 、配对审批、节点命令白名单都在 Gateway 层收口,不让客户端直接越权。
    • 统一扩展:插件( channels/tools/hooks/providers/http/gateway methods )都挂在 Gateway 生态上,扩展时不用改核心主干。
    • 统一可观测:状态、日志、健康检查、事件广播都以 Gateway 为中心,Web 控制台和 CLI 看的是同一份事实。

    Gateway 的价值是把“多端、多渠道、多能力”变成一个一致、可控、可扩展的系统。没有它,OpenClaw 就会退化成一堆彼此割裂的小工具。

    统一安全

    • Gateway 在连接握手就做认证和角色判定( operator / node )并下发 scopes ,后续每个方法再次校验,避免越权调用。
    • 方法级权限是白名单式的:读写、审批、配对、管理员能力分别受控,不是“连上就全能”。
    • 节点( iOS/Android/macOS node )还有二次约束:配对审批 + 命令白名单 + 节点声明能力,三层都通过才执行。
    • 会话层还有发送策略( allow/deny )控制,防止某些 session 被误发消息。

    统一扩展

    • 插件可注册多种能力:渠道、工具、hooks 、provider 、CLI 子命令、Gateway 方法、HTTP 路由。
    • Gateway 启动时统一发现并加载插件,注册到同一个 registry ,核心不需要为每个新渠道写 if-else 。
    • 这让“加一个新渠道”变成“实现插件契约”,不是重构整个系统。
    • 同时支持内置渠道和 extensions 目录下的外部插件,扩展边界清晰。

    统一观测

    • Gateway 集中维护健康状态、在线节点、会话状态、事件流,并广播给 CLI/Web/macOS/mobile 。
    • 日志、心跳、状态快照、运行事件( agent/chat/node )都从同一中枢输出,所以排障时事实源一致。
    • status/health/logs 看到的是同一套运行时,不会出现“CLI 说正常,Web 说异常”的多套口径问题。
    • 对你这种多端场景最关键:任何端的问题都能回溯到 Gateway 这一条主链路。

    用户身份( Telegram/Discord/飞书里的“谁发的消息”)

    • 每个渠道先用自己的原生 ID ( Telegram user id 、Discord user id 、飞书 open_id 等)接入。
    • OpenClaw 不会把它们直接当成同一个人,而是会先带上渠道命名空间(可理解为 telegram:123discord:abcfeishu:xxx)。
    • 然后路由层根据 channel + account + peer (chat/group/thread) 生成 sessionKey,决定这条消息落到哪个会话。

    所以在 OpenClaw 视角,默认是:同一个“人类用户”在不同渠道,先被当成不同身份流量处理。

    如何把同一个人的不同渠道身份认成同为一个人呢?

    会不会“合并”取决于配置策略,不是自动魔法识别。如果你配置了 identityLinks,可以把跨平台 ID 映射到同一 canonical identity,实现“跨渠道同人合并”。不配置的话,通常按渠道隔离或按会话策略合并,不会无脑认同一个人。

    消息入站流程

    消息的入站流程需要先了解 OpenClaw 里的 Agent 、Session 、Context 设计。

    OpenClaw Concepts

    • Agent:可以理解为一个可配置的人格/岗位。每一个 Agent 都可以单独配置一个自己的默认模型、可用工具列表、工作的目录,可以通过 Prompt 预设行为风格。在 OpenClaw 可以通过 CLI 命令创建一个 Agent 。当消息入站,OpenClaw 会根据配置的规则,给请求分配对应的 Agent 。我们可以把 Agent 当成 Java 中的 .class 文件。
    • Session:某个 Agent 的一个持续对话状态容器,可以理解为 Java 中通过 new 创建出来的实例。Session 是“和谁聊、在哪条线聊”的记忆边界。
      • 不同 Session 默认隔离,互不共享历史;这就是多人同时使用同一个 OpenClaw 时不串话的关键。每一次用户的请求,OpenClaw 都会根据配置,分配或者绑定 Session 会话。
    • Context (上下文):Context 是每次调用模型时“喂给 LLM 的输入包”,是临时拼出来的,不是长期对象。它通常由这些部分组成:系统设定 + 当前消息 + 从 Session 里抽取的历史片段 + 工具结果 + 运行时元信息。一次回答结束后,Context 会消失;但对话结果会写回 Session (持久化)。
    • LLMs (模型层):在 OpenClaw 中的 LLM 是“无状态推理器”。OpenClaw 每次请求都会开启一个新的 LLM 实例然后拼接本次会话需要的 Context 。当一次会话结束以后,OpenClaw 会根据对话结果更新 Session ,同时关闭 LLM 的会话。LLM 端是无状态调用:对模型 API 来说每次请求都是新请求;不会天然记住上次。所谓“连续对话”是 OpenClaw 把历史重新带上去实现的。这一点跟 Codex 、OpenCode 、ClaudeCode 等有本质的区别。
    • **技能 (Skills)**:OpenClaw 支持全局共享 Skill 、每个 Agent 独享 Skill ; Session 侧更像是有一个 Skills 可见性快照(用于当次/该会话阶段运行一致性),不是给每个 Session 单独安装一份 Skill 。Skill 的来源按全局/Agent 管; Session 只管当下可见与调用状态。

    消息入站的具体流程为:

    1. 入站先读 Session

      • sessionKey 找会话条目( sessionId 、thinking/model override 、lastChannel/lastTo 等)。
      • 如果不存在或触发 reset ,就新建 sessionId
    2. 临时生成 Context

      • 用当前消息 + 会话历史 + agent/system prompt + 渠道元数据 + 媒体/链接增强拼装本轮输入。
      • 这个 Context 只在本轮推理内存在,不直接持久化。
    3. 模型执行后,写 Transcript

      • 本轮 user/assistant/tool 事件追加到 sessionId 对应 JSONL (物理历史)。
    4. 写回 Session 元数据

      • 更新 updatedAtlastChannel/lastTodeliveryContext、思考级别/模型覆盖、token 统计等。
      • 这一步是“把本轮结果沉淀成下轮可用状态”。

    路由规则

    1) Agent ID 的路由规则:具体哪个身份来处理当前的用户消息

    可以按渠道、群/团队、账号、甚至具体会话目标去分流到不同 Agent 。可以把它看成“分单规则引擎”,输入一条消息后按优先级匹配:

    • peer 精确匹配(某个人/某个群/某个频道)
    • parent peer(线程场景继承父会话)
    • guild/server(如 Discord 服务器级)
    • team/workspace(如 Slack 团队级)
    • account(某渠道下的某账号)
    • channel( Telegram/Discord/Slack…整渠道)
    • 最后回退到 default agent

    配置维度(可控项):

    • Agent 列表(哪些 Agent 存在,哪个是默认)
    • 绑定规则( match.* -> agentId )
      • 可按:channel 、accountId 、peer(kind+id)、guildId 、teamId
    • 运行时可显式指定 Agent ,会覆盖默认路由;但会做一致性校验,防止乱绑。

    2) SessionKey 的路由规则(落哪条记忆线)

    会话类型分三大类:

    • DM (私聊)

    • Group (群聊)

    • Channel (频道/公开通道)

    • DM (私聊):重点是“私聊是否合并/拆分会话” → dmScope

    • Group (群聊):重点是“群是否允许进入、是否必须 @ 、谁可触发” → groupPolicy / groupAllowFrom / groups.<id>.requireMention

    • Channel (公开频道):重点是“频道级 allowlist 与提及规则、按频道绑定到哪个 Agent”(例如 Discord/Slack 常是 guild/channel 级配置 + bindings )

    我们展开讲一下私聊场景,DM 的关键是 dmScope

    它是“私聊会话切分策略”。也就是:当不同人、不同渠道来私聊时,OpenClaw 要不要把他们放到同一条记忆线上。你可以把它理解成“秘书的档案柜分隔规则”。

    四种常见策略:

    1. main:所有私聊共用一个主会话
      • 优点:连续性最强,像同一个人一直在聊。
      • 风险:多人场景容易串上下文( A 的内容被 B 继承)。
    2. per-peer:按“人”分会话(跨渠道可合并同一人)
      • 适合你能稳定识别“同一个人”的场景。
      • 比 main 安全很多。
    3. per-channel-peer:按“渠道 + 人”分会话
      • Telegram 的你和 Discord 的你是两条线。
      • 多人系统里常用,隔离更稳。
    4. per-account-channel-peer:按“账号 + 渠道 + 人”分会话
      • 适合一个系统挂多账号(比如多个 Telegram bot 或多工作区)。
      • 隔离最细,最不容易串。

    额外维度:

    • identityLinks:把跨渠道“同一个人”映射到同一 canonical 身份(只在你配置时生效)。
    • thread/topic:在线程型渠道再细分子会话。
    • mainKey:主会话别名(默认 main )。
    • session scope:有的部署会用全局/按发送者模式做更粗粒度控制。

    先有 Agent ID ,再生成 SessionKey 。 它的输入维度是:AgentId + 会话类型 + 渠道/账号/对象 ID + 线程信息 + DM 切分策略。 根据你的配置,会生成对应的 SessionKey ,然后再绑定到具体的 Session 上面去。

    AgentId + SessionKey 的组合意义:

    • agentId:谁处理(人格/策略)。
    • sessionKey:在哪条记忆线上处理(上下文边界)。
    • 所以同一个人可以:
      • 进同一个 Agent 但不同 Session (隔离)。
      • 或进不同 Agent (不同角色)且各自独立 Session 。

    整个会话的交互时序图如下。

    image.png

    Pi agent

    Pi agent 可以理解成 OpenClaw 的“推理执行内核”。

    它不是渠道,也不是网关,而是负责“真正思考和产出”的那层。

    核心作用:

    • 接收任务:从 Gateway 拿到已经整理好的上下文(用户消息、会话历史、系统设定等)。
    • 调用模型:用配置的 LLM 运行一次 Agent 回合。
    • 做工具编排:需要时触发 tools/skills (查资料、发消息、执行动作等)。
    • 生成结果:输出回复文本、工具结果、状态事件,再回交给 Gateway 分发。
    • 维护回合状态:配合 Session 信息处理 thinking/model override 、中断、等待等流程。

    Agent / Session / Context 是 OpenClaw 的整体架构概念(主要由 Gateway + 运行时共同管理)。 Pi agent 主要负责“执行推理回合”(吃 Context 、跑模型、调用工具、产出结果)。

    消息出站的流程

    1. 产出回复结果
      • Pi agent 返回文本/工具结果/结构化输出给 Gateway 。
    2. 决定“发往哪里”
      • 优先按本次消息的来源路由回去(原渠道、原会话目标)。
      • 如果没有明确来源,再用 Session 里的最后路由信息兜底。
    3. 应用发送策略
      • 检查会话发送策略、频道能力、权限约束(是否允许发、发到哪个目标)。
    4. 渠道适配与投递
      • Gateway 调对应 channel 插件,把统一回复格式转成 Telegram/Discord/WhatsApp 等各自 API 格式并发送。
    5. 写回会话状态
      • 更新 Session 元数据(更新时间、lastChannel/lastTo 、usage 等)并追加 transcript 。
    6. 广播运行事件
      • 把结果/状态同步给 Web 控制台、CLI 、macOS/iOS/Android 客户端。

    Web 与 OpenClaw CLI

    Web 偏在线运营控制台(可视化 + 实时),CLI:偏全量运维与自动化入口(可脚本、可批处理、覆盖更全)。

    Web ( Control UI )能力

    • 实时聊天:发送、流式回复、停止当前运行
    • 会话管理:查看会话列表、改会话参数(如思考/verbose )
    • 渠道运营:看渠道状态、扫码登录、调渠道配置
    • 节点管理:查看已配对节点、能力状态
    • 定时任务:cron 的增删改查、手动触发、查看运行记录
    • 技能管理:查看技能状态、启用/禁用、安装与更新
    • 配置中心:可视化配置编辑(含 schema 表单 + raw JSON )
    • 日志与诊断:health/status/models 快照、实时日志 tail
    • 更新入口:触发更新并查看重启报告

    OpenClaw CLI 能力

    • 安装与初始化:setup 、onboard 、configure
    • 服务生命周期:gateway install/start/stop/restart/run
    • 渠道与插件:channels add/login/status 、plugins install/enable/disable
    • Agent 管理:agent 、agents list/add/delete 等
    • 会话与消息:sessions 、message send/poll/react/broadcast
    • 定时与自动化:cron add/edit/run/runs (脚本化最强)
    • 安全与审批:security audit 、approvals 、devices 、pairing
    • 节点与浏览器控制:nodes 、node 、browser 全套命令
    • 系统运维:logs 、status 、health 、system 、models 、hooks 等

    OpenClaw 定时任务 (Scheduler)

    Gateway 里跑着一个一直在线的定时器( scheduler ),负责管理所有定时任务。这些定时任务都会被保存到磁盘上,所以就算服务重启,任务也不会丢失。到了设定的时间点,系统就会触发一次 Agent 的执行。执行完的结果可以选择:

    • 只在内部记录下来
    • 或者把结果发送到指定的聊天渠道

    每个 cron 任务主要包含以下几个关键信息:

    • agentId:指定由哪个 Agent 来执行这个任务(不填就用默认的 Agent )
    • sessionTarget:决定这次执行是在「主会话」里跑,还是用一个独立的会话
    • payload:到了时间点后,到底要让 Agent 做什么(可以是 system event ,也可以是完整的 agent turn )
    • wakeMode:是立刻唤醒 Agent 处理,还是等到下一次心跳再处理
    • delivery:执行结果要不要往外发送?如果要发,发到哪个聊天渠道或目标

    最核心的两种执行方式对比

    1. 用主会话( sessiOnTarget= main )
      • 系统会往这个 Agent 的主对话里插入一条 system event
      • 然后根据 wakeMode 设置,立即唤醒或等到下次心跳再让 Agent 响应
      • 适合用来做「定时提醒」「日程事项」「重要通知」这类希望融入日常对话、保留上下文的任务
    2. 用独立会话( sessiOnTarget= isolated )
      • 每次执行都会创建一个全新的、临时的会话(内部标记为 cron:<任务 ID>)
      • 不会带入上一次运行的任何对话历史,避免上下文互相干扰
      • 但会继承一些会话级别的配置(比如用哪个模型、思考深度等设置)
      • 特别适合做「日报生成」「数据巡检」「批量处理」「后台统计」这种不需要跟用户主聊天混在一起的任务

    iOS/Android nodes

    iOS/Android nodes 即“移动端节点”,把手机变成 OpenClaw 网络里的一个可控设备角色。

    它的作用主要有三件事:

    1. 当执行端:PC 端的 Gateway 可以给手机下发“受限动作命令”(比如拍照、录屏、定位、发短信等,具体看白名单和权限)。
    2. 当交互端:手机自己也能主动跟 Gateway 说话(比如发 chat/agent 请求),不只是被动等命令。
    3. 当统一会话的一部分:手机、Web 、macOS 、CLI 都连到同一个 Gateway ,会话和状态能同步,形成一个多端协同的“同一个 OpenClaw”。

    现在 iOS/Android node 就是 OpenClaw 的“移动端能力节点 + 控制入口”,让手机成为整个系统里的第一类成员,而不是外挂设备。

    openclaw 与 tailscale

    Tailscale 是一个非常好用的现代虚拟组网 / Mesh VPN 工具,简单来说就是:

    它能让你把分散在世界各地的设备(手机、电脑、NAS 、服务器、树莓派、云服务器等)像处在同一个局域网里一样互相访问,而且整个过程非常简单、安全、几乎零配置。

    openclaw 里默认集成里 tailscale ,默认是关闭的状态。tailscale 模块本质上是 给 Gateway 做“安全远程入口” 。通过 tailscale 你可以在任何地方都能够访问你的 web 管理入口。

    不过 openclaw 在中国大陆的网络环境下有点水土不服,你可以使用星空组网进行平替。

    openclaw 的记忆架构

    openclaw 牛的点在于永久性的记忆,它的记忆机制是让它感觉“像真人一样记住东西”的关键核心:不同于大多数 AI 靠短暂的上下文窗口硬撑,OpenClaw 把记忆彻底外化到磁盘上的纯 Markdown 文件里,文件本身就是真相来源,模型每次只加载需要的内容,就像人类翻笔记而不是把所有人生经历塞进大脑。

    具体来说,它采用非常简洁的两层设计:短期/临时记忆靠每天一个追加式文件(通常在 memory/YYYY-MM-DD.md 里),记录当天的决策、运行日志和上下文,启动会话时自动把今天 + 昨天的内容加载进来,提供最近的连续感却不会把 token 撑爆;长期/精选记忆则集中在单个核心文件 MEMORY.md (也有人叫它“灵魂文件”),里面放用户偏好、重要结论、项目约定、不能忘的关键事实,只有在私密个人会话中才会加载(群聊或共享场景故意不读,保护隐私)。此外还有可选的会话记录( sessions/ 目录下),完整对话历史可以被搜索或定期摘要归档。

    为了“想起来”东西,OpenClaw 不依赖黑盒向量数据库,而是用混合检索( BM25 关键词 + 向量相似度)在这些 Markdown 文件上建小索引,Agent 需要时自己调用工具去搜(比如“memory_search”),真正需要的内容才 page in 到上下文里。整个过程透明到极致:你随时用任意文本编辑器打开、修改、删除 AI 的“记忆”,没有隐藏状态;当上下文太长时,Agent 还能主动把关键点 flush 到 MEMORY.md 再压缩历史,避免遗忘重要信息。这种“磁盘是硬盘、上下文是缓存”的哲学,让 OpenClaw 在本地 Agent 里拥有了罕见的持久性和可控性它不会每次重启就失忆,但也完全由你掌控,不会偷偷积累你不想留的东西。简单、开放、却意外强大,这就是很多人觉得它“像活的”原因。

    openclaw 的自我进化

    技能的存在,还可以让他自己完善自己的能力。比如你可以让它创建一个邮件收发的技能,你只需第一次详细告诉它你的 SMTP/IMAP 配置(服务器地址、端口、用户名、密码或 app-specific password 、加密方式等),并描述期望的行为(如“用我的 Gmail 发带附件的日报”“自动回复特定关键词的邮件”),OpenClaw 就会自己生成一个专属的“邮件收发技能”它会写出 SKILL.md 文件(包含工具描述、调用参数、错误处理逻辑),并关联必要的 Python/Node 脚本或内置工具调用(如 smtplib 或 imaplib )。一旦保存进 skills 目录,这个技能就永久可用。

    这些自我进化的能力源于 OpenClaw 的核心插件系统和内存机制,允许 Agent 不只是执行指令,而是像活的实体一样,通过代码生成、测试和持久存储来扩展自身边界,最终从一个通用助手变成高度个性化的生产力伙伴。

    要是学累了,就来打打游戏吧

    8 条回复    2026-03-02 13:56:08 +08:00
    zz177060
        1
    zz177060  
       2 月 6 日 via iPhone
    我理解,就是个 ai 融合通信调度系统。
    287854442
        2
    287854442  
       2 月 6 日
    写的挺好的。这年头能耐心写这么多的太少了,能看完这么长的都不多。。我要发个感谢
    kenshinhu
        3
    kenshinhu  
       2 月 7 日
    agent loop 这里也可以补充一下
    simplejian
        4
    simplejian  
    OP
       2 月 8 日
    @287854442 哈哈夸得我都不好意思了。我在用 openclaw 搭建一个个人助手的时候,发现多各渠道接入的时候,消息收发和记忆总是调不出我想要的效果,所以就拉来了源代码看了一下。
    tangzhiyong
        5
    tangzhiyong  
       2 月 9 日
    说不定这边文章都是叫 openclaw 做的
    simplejian
        6
    simplejian  
    OP
       2 月 10 日
    @tangzhiyong 我把源代码拉下来,然后我带着问题一步一步让 codex 给我解释的。解释完了以后整理的。我发现带着问题让 ai 来教你,效率很高,印象也比较深刻。
    wingbeat
        7
    wingbeat  
       2 月 11 日
    马克,学习下
    jufushan
        8
    jufushan  
       3 月 2 日
    写的太多了 先收藏一下 后面再看吧
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     5257 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 199ms UTC 09:05 PVG 17:05 LAX 02:05 JFK 05:05
    Do have faith in what you're doing.
    ubao msn snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86