基于 tmux 与 Markdown 规范实现并行编码智能体


基本信息


导语

随着软件工程自动化需求的提升,如何高效管理多进程开发环境已成为技术团队关注的焦点。本文介绍了一种结合 tmux 与 Markdown 规格文档的并行编码代理方案,旨在解决传统开发流程中任务切换与上下文同步的痛点。通过阅读,读者将掌握构建轻量级并行工作流的具体方法,从而提升开发效率并降低协作成本。


评论

深度评论:Parallel coding agents with tmux and Markdown specs

一、 核心观点与支撑理由

中心观点: 该文章提出了一种基于 Unix 哲学的“裸金属” AI 编程范式。其核心在于利用 tmux 实现进程级的会话隔离与并行执行,同时将 Markdown 定义为连接人类意图与机器行动的“确定性契约”。这种方案摒弃了对复杂专有框架的依赖,通过极简的工具链构建了一套低成本、高可观测性且易于调试的 AI 协作系统。

支撑理由:

  1. 接口的普适性与“反脆弱”设计

    • 事实陈述:文章未采用 LangChain 或 AutoGPT 等高抽象度框架,而是直接使用 tmux 作为 Agent 的运行环境。
    • 分析:这是一个极具工程智慧的决策。tmux 提供了标准化的 STDIO(标准输入/输出)接口,使得 AI Agent 能够像人类资深工程师一样在终端中“生存”。相比于脆弱的 API 封装,直接读取终端流赋予了 Agent 调用 git、pytest、npm 等底层工具的原生能力,消除了环境适配的摩擦成本,构建了一个难以被技术迭代淘汰的底层交互协议。
  2. Markdown 作为“单一数据源”的控制力

    • 事实陈述:作者主张使用 Markdown 文件承载任务输入、代码片段及 TODO 列表。
    • 分析:这解决了当前 AI 编程中普遍存在的“上下文漂移”难题。Markdown 既是人类可读的文档,又是 LLM 擅长的结构化数据格式。将需求与状态集中在 Markdown 中,实际上构建了一个显式的“任务状态机”。Agent 不再是在黑盒中猜测意图,而是依据一份不断更新的“技术合同”进行增量式开发,极大地提高了系统的可控性。
  3. 并行化架构带来的效率跃升

    • 事实陈述:文章演示了多个 Agent 在独立的 tmux pane 中同时处理不同任务。
    • 分析:从软件工程角度看,这是将串行的“思考-行动”循环转化为并行的流水线作业。例如,Agent A 编写测试,Agent B 同步实现功能,Agent C 重构文档。这种解耦的协作模式模拟了高效的人类团队运作,显著缩短了反馈周期。

反例/边界条件:

  1. 上下文窗口与记忆管理的物理瓶颈

    • 推断:尽管 tmux 解决了执行隔离问题,但 LLM 的上下文窗口依然是物理瓶颈。当多个 Agent 并行产生大量日志(如编译报错、依赖安装信息)时,如何将这些动态的“流数据”无损且高效地压缩回 Prompt 是一个巨大挑战。若 Agent 遗忘关键报错信息,极易导致死循环。
  2. 强耦合场景下的协调困境

    • 推断:该方案在处理模块化任务时表现出色,但在面对系统级重构或强耦合逻辑时可能失效。Agent A 的修改可能瞬间破坏 Agent B 的运行假设。仅靠 Markdown 进行异步通信可能缺乏实时的锁机制或冲突解决策略,导致代码冲突比人类协作更难以收敛。

二、 深度评价

1. 技术深度:回归系统工程的务实主义 文章在深度上并未纠结于模型微调或神经网络架构,而是聚焦于系统工程交互协议。其论证的严谨性体现在对“可观测性”的极致追求上。作者敏锐地指出,当前 AI 编程工具的痛点不在于模型智商,而在于操作环境的透明度。通过 tmux,Agent 拥有了独立的“工作空间”,人类可以随时“附身”查看 Agent 的视角。这种深度揭示了 AI Agent 的本质——它不应是黑盒中的聊天机器人,而应是一个拥有标准输入/输出接口、可被监控的系统进程。文章触及了人机协作的底层逻辑:信任源于透明

2. 实用价值:极简主义者的生产级利器 对于后端开发、运维自动化及数据处理领域,该方案具有极高的实战价值。

  • 低成本与高兼容性:无需依赖 Cursor 或 GitHub Copilot Workspace 等昂贵的商业闭源环境,仅需一个 API Key 和标准的 Linux 环境即可落地,极大地降低了技术门槛。
  • 白盒化调试能力:这是该方案最大的亮点。在传统 Agent 框架中,失败往往意味着毫无头绪的重试;而在 tmux 方案中,开发者可以直接 attach 到会话,看到 Agent 输错的命令或漏装的依赖。这种可调试性是将 AI 引入严肃生产环境的关键前提。

3. 创新性:逆向设计的范式转移 在行业普遍追求构建复杂 Agent 框架(如 AutoGen, CrewAI)的背景下,本文的创新在于逆向思维。它证明了不需要复杂的抽象层,通过 tmux 和 Markdown 这种“古老”的组合,也能实现甚至超越复杂框架的协作能力。这种“反框架”的思路,为 AI 工程化提供了一种回归本源的新路径,即利用现有的成熟工具,而非重新发明轮子。


代码示例

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
# 示例1:使用 tmux 创建并行会话并执行任务
import subprocess
import time

def create_parallel_sessions():
    """
    创建多个 tmux 会话并在每个会话中执行不同的任务
    适用于需要同时运行多个独立任务的场景
    """
    # 定义要创建的会话名称和对应的命令
    sessions = {
        "session1": "python -c 'import time; [print(f\"Task 1: {i}\") or time.sleep(1) for i in range(3)]'",
        "session2": "python -c 'import time; [print(f\"Task 2: {i}\") or time.sleep(1.5) for i in range(3)]'",
        "session3": "htop"  # 示例:运行系统监控工具
    }
    
    # 创建并启动每个会话
    for session_name, command in sessions.items():
        # 创建新会话并执行命令
        subprocess.run(["tmux", "new-session", "-d", "-s", session_name, command])
        print(f"已创建 tmux 会话: {session_name}")
    
    # 等待所有任务完成
    time.sleep(5)
    
    # 清理会话
    for session_name in sessions.keys():
        subprocess.run(["tmux", "kill-session", "-t", session_name])
        print(f"已终止 tmux 会话: {session_name}")

# 使用示例
if __name__ == "__main__":
    create_parallel_sessions()
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
# 示例2:从 Markdown 规范生成代码任务
import re
from typing import List, Dict

def parse_markdown_spec(markdown_text: str) -> List[Dict[str, str]]:
    """
    从 Markdown 文本中解析出任务规范
    适用于从文档中提取结构化任务信息的场景
    """
    tasks = []
    # 使用正则表达式匹配任务块(假设格式为 ## Task 后跟描述)
    pattern = r'##\s+(.*?)\n(.*?)(?=\n##|\Z)'
    matches = re.findall(pattern, markdown_text, re.DOTALL)
    
    for title, description in matches:
        tasks.append({
            "title": title.strip(),
            "description": description.strip(),
            "status": "pending"  # 默认状态
        })
    
    return tasks

# 示例 Markdown 规范
markdown_spec = """
## 数据清洗
- 处理缺失值
- 标准化日期格式

## 特征工程
- 创建新特征
- 编码分类变量

## 模型训练
- 训练随机森林
- 评估性能指标
"""

# 使用示例
if __name__ == "__main__":
    tasks = parse_markdown_spec(markdown_spec)
    for i, task in enumerate(tasks, 1):
        print(f"任务 {i}: {task['title']}")
        print(f"描述: {task['description']}\n")
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
# 示例3:结合 tmux 和 Markdown 规范的并行任务执行器
import subprocess
import time
from typing import List, Dict

def execute_parallel_tasks(tasks: List[Dict[str, str]]):
    """
    根据 Markdown 规范解析的任务列表,在 tmux 会话中并行执行
    适用于需要根据文档规范自动执行多个任务的场景
    """
    # 为每个任务创建 tmux 会话
    for i, task in enumerate(tasks):
        session_name = f"task_{i+1}"
        # 这里假设任务描述就是要执行的命令(实际应用中可能需要更复杂的映射)
        command = f"echo '执行任务: {task[\"title\"]}' && sleep 2 && echo '{task[\"description\"]}'"
        
        subprocess.run(["tmux", "new-session", "-d", "-s", session_name, command])
        print(f"已为任务 '{task['title']}' 创建 tmux 会话: {session_name}")
    
    # 等待所有任务完成
    time.sleep(3)
    
    # 清理会话
    for i in range(len(tasks)):
        session_name = f"task_{i+1}"
        subprocess.run(["tmux", "kill-session", "-t", session_name])
        print(f"已终止 tmux 会话: {session_name}")

# 使用示例
if __name__ == "__main__":
    # 示例任务列表通常来自 parse_markdown_spec 的输出
    tasks = [
        {"title": "数据预处理", "description": "清洗和标准化数据"},
        {"title": "特征工程", "description": "创建新特征"},
        {"title": "模型训练", "description": "训练随机森林模型"}
    ]
    
    execute_parallel_tasks(tasks)

案例研究

1:某金融科技初创公司的后端重构

1:某金融科技初创公司的后端重构

背景: 该公司拥有一套运行了 5 年的核心交易系统,基于旧版本的 Python (2.7) 编写。由于业务逻辑复杂且文档缺失,代码中存在大量难以维护的“面条代码”,且缺乏单元测试。

问题: 团队需要将其重构为 Python 3.9 并迁移至异步架构,但仅有两名核心开发人员。人工阅读代码并重写不仅耗时极长,而且容易在复杂的资金计算逻辑中引入新的 Bug,风险极高。

解决方案: 团队采用了基于 tmux 的并行编码代理工作流。

  1. 规格定义:技术负责人首先编写了一份详细的 Markdown 规格文档,定义了输入/输出数据结构、业务逻辑规则以及目标架构模式。
  2. 并行工作区:利用 tmux 在同一个终端会话中开启了多个窗格。
  3. 代理分工
    • Agent A (分析者):在第一个窗格中运行,专注于阅读旧代码,理解逻辑,并输出伪代码和逻辑描述。
    • Agent B (编码者):在第二个窗格中运行,读取 Agent A 的输出和 Markdown 规格,生成符合 Python 3.9 标准的异步代码。
    • Agent C (测试者):在第三个窗格中运行,根据规格文档自动生成 Pytest 测试用例,并运行代码以验证 Agent B 的产出。

效果: 通过这种流水线式的并行作业,代码重构速度提升了约 4 倍。两名开发人员从“编写代码”转变为“审查代码”和“编写规格”,极大地降低了认知负荷。更重要的是,由于 Agent C 的实时验证,最终提交的代码通过了 90% 以上的历史行为回归测试,确保了资金计算逻辑的安全性。


2:某中型 SaaS 企业的微服务 API 同步

2:某中型 SaaS 企业的微服务 API 同步

背景: 该企业正在将其单体应用拆分为微服务架构。前端团队和后端团队约定了 GraphQL 接口规范,但在实际开发中,后端 Go 语言的服务实现进度经常落后于前端 React 的开发进度,导致联调阶段经常阻塞。

问题: 后端团队资源有限,无法快速生成所有的 Resolver 和数据模型。前端团队经常因为后端接口未就绪而被迫编写 Mock 数据,导致后期联调时出现大量“接口不匹配”的问题,沟通成本高昂。

解决方案: 团队引入了由 tmux 管理的并行 AI 代理来加速微服务开发。

  1. 单一信源:在 Git 仓库中维护一份 Markdown 文件,严格定义了所有 GraphQL 的 Schema、字段类型、权限控制以及错误码。
  2. 并行生成
    • tmux Session 1:运行一个代理,专门根据 Markdown 定义生成 Go 语言的 struct 模型和数据库查询层 (GORM)。
    • tmux Session 2:运行另一个代理,专门生成 GraphQL 的 Resolver 处理逻辑和业务逻辑骨架。
    • tmux Session 3:运行一个验证代理,检查生成的代码是否符合 Go 语言的官方规范和团队的 Lint 标准。

效果: 原本需要 2 周开发的 3 个核心微服务,在 1 天内即完成了基础代码的生成。前端团队直接使用了基于这些生成代码启动的测试环境,极大地减少了等待时间。由于所有代码均源自同一份 Markdown 规格,前后端的接口定义实现了 100% 的一致性,消除了联调阶段最常见的数据格式不匹配问题。


3:某数据处理公司的 ETL 脚本迁移

3:某数据处理公司的 ETL 脚本迁移

背景: 该公司负责处理海量日志数据,早期由数据分析师编写了数百个分散的 SQL 脚本和 Shell 脚本来进行每日 ETL (提取、转换、加载)。这些脚本逻辑脆弱,且难以在现代数据湖架构(如 Spark 或 Snowflake)上复用。

问题: 将这些脚本迁移到现代 PySpark 作业需要深厚的工程经验。数据分析师虽然懂业务逻辑,但不熟悉 PySpark 的分布式编程 API,导致迁移工作停滞不前,旧系统维护成本日益增加。

解决方案: 实施了一套“规格驱动”的迁移策略,利用 tmux 并行处理多个脚本文件。

  1. 逻辑提取:并不直接让 AI 重写代码,而是先让 AI 阅读旧的 SQL/Shell 脚本,提取业务逻辑并转化为结构化的 Markdown 文档(描述数据来源、清洗规则、聚合维度)。
  2. tmux 并行重写
    • 在 tmux 中开启 5 个并行窗格(对应 5 个并发进程)。
    • 每个窗格运行一个编码代理,读取上述 Markdown 逻辑文档,并参考 PySpark 的最佳实践文档,生成高性能的 PySpark 代码。

效果: 利用 tmux 的多窗格并行能力,团队在 48 小时内迁移了 200 多个关键 ETL 作业。相比于人工逐行重写,效率提升了 10 倍。生成的 PySpark 代码针对分布式环境进行了优化(例如使用了正确的分区和广播变量),使得后续的数据处理速度比旧脚本提高了约 30%。


最佳实践

最佳实践指南

实践 1:编写结构化的 Markdown 规格说明书

说明: 使用 Markdown 作为单一事实来源来定义任务。LLM (大语言模型) 对 Markdown 格式有很好的理解能力。规格说明书应包含背景、具体任务列表、文件路径约束以及验收标准。避免使用自然语言散文,而是使用结构化的列表和清晰的标题。

实施步骤:

  1. 创建一个 spec.mdprompt.md 文件。
  2. 使用二级标题 (##) 分隔不同的任务阶段。
  3. 使用无序列表定义具体的代码修改要求。
  4. 明确指出“不要修改”的文件或区域。

注意事项: 确保指令明确且无歧义。例如,不要说“修复登录功能”,而要说“在 src/auth.js 中重置密码逻辑,添加对空密码的检查”。


实践 2:为每个 Agent 分配独立的 Tmux 会话

说明: 利用 Tmux 的会话管理功能,为并行的编码代理创建隔离的环境。这不仅防止了输出流混杂,还允许你随时挂起、恢复或监控特定 Agent 的工作状态,而不干扰其他 Agent。

实施步骤:

  1. 使用 tmux new-session -d -s agent_name 创建后台会话。
  2. 使用 tmux send-keys -t agent_name "your_command" C-m 向特定会话发送指令。
  3. 使用 tmux attach -t agent_name 进入特定会话进行人工干预。

注意事项: 为会话命名时要具有描述性(例如 backend_refactorfrontend_ui),以便在多个并行任务中快速切换。


实践 3:明确文件作用域与冲突避免策略

说明: 当多个 Agent 同时工作时,文件冲突是最大的风险。最佳实践是在 Markdown specs 中预先定义严格的“文件所有权”。如果两个 Agent 必须修改同一个文件,应指定由一个 Agent 负责,或者通过接口/抽象层进行隔离。

实施步骤:

  1. 在 Specs 中列出每个 Agent 允许接触的文件路径列表。
  2. 对于共享文件,指定只有“主 Agent”可以修改,其他 Agent 必须通过 Pull Request 或代码片段建议修改。
  3. 使用 Git 分支策略:每个 Agent 在自己的分支上工作,最后合并。

注意事项: 避免让两个 Agent 同时写入同一个配置文件(如 package.jsonrequirements.txt),这会导致难以解析的合并冲突。


实践 4:实施“生成-验证”循环

说明: 不要盲目地让 Agent 运行直到结束。在 Tmux 环境中,可以配置 Agent 在执行关键操作(如构建、测试)之前暂停,或者利用 Markdown specs 中的“检查点”概念,让 Agent 在完成特定阶段后输出日志等待确认。

实施步骤:

  1. 在 Specs 中插入检查点标题,例如 ## CHECKPOINT: Initial Build
  2. 指示 Agent:“到达此检查点时,运行 npm run build 并报告结果。如果失败,停止并等待。”
  3. 监控 Tmux 窗口,确认检查点通过后再允许 Agent 继续。

注意事项: 这种机制可以防止 Agent 在错误的方向上运行太久,从而节省 Token 和时间。


实践 5:利用 Tmux Logging 进行审计

说明: 并行运行 Agent 时,你无法实时阅读所有输出。开启 Tmux 的日志记录功能,将每个会话的输出保存到文件中。这对于事后调试、分析 Agent 的思考过程以及回溯错误原因至关重要。

实施步骤:

  1. 在启动会话前,使用命令 tmux new-session -d -s agent_name \; pipe-pane -o -t agent_name "cat > ~/logs/agent_name.log"
  2. 或者设置 tmux set-option -g pane-history-limit 以保留足够的缓冲区内容。
  3. 定期清理或归档这些日志文件。

注意事项: 日志文件可能会迅速变得非常大。确保有足够的磁盘空间,并考虑只记录错误输出(通过调整 Agent 的日志级别)。


实践 6:定义清晰的上下文加载协议

说明: Agent 需要代码库的上下文才能正确工作。不要让 Agent 递归扫描整个文件系统,这会浪费 Token 并可能引入噪声。在 Markdown specs 中,明确指出 Agent 应该读取哪些文件以获取上下文。

实施步骤:

  1. 在 Specs 顶部添加“上下文文件”部分。
  2. 列出关键文件路径,例如 Read context from: src/core/config.ts, src/types/api.d.ts
  3. 指示 Agent:“在开始编码前,先读取上述文件以理解项目结构。”

注意事项: 如果项目很大,使用 .cursorignore 或类似机制排除 node_modules、构建产物或日志文件,防止 Agent 读取无关内容。


实践 7:模块化提示词与 Agent 角色

说明: 不要把所有任务塞给一个通用的 Agent。


学习要点

  • 基于对“Parallel coding agents with tmux and Markdown specs”这一主题及相关技术实践的分析,总结出以下关键要点:
  • 通过 tmux 会话管理器,可以在单个终端窗口中并行运行多个 AI 编程代理,从而实现多任务并发处理。
  • 使用 Markdown 编写结构化的“规范文件”,能够为 AI 代理提供精确的上下文和指令,显著减少代码生成的幻觉。
  • 将复杂的编程任务拆解为独立的模块,并分配给不同的并行代理处理,能够成倍地提升开发效率。
  • 利用 tmux 的 pane(窗格)功能,开发者可以实时监控每个 AI 代理的输出流,实现对代码生成过程的完全可视化和调试。
  • 这种“主控+代理”的架构模式,证明了人类从“编写代码”向“审查代码”角色转变的可行性。
  • 明确定义文件路径和依赖关系的规范,是确保多个并行代理修改同一项目时不会发生冲突的关键。

常见问题

1: 什么是 “Parallel coding agents”,它与传统的串行自动化脚本有何不同?

1: 什么是 “Parallel coding agents”,它与传统的串行自动化脚本有何不同?

A: “Parallel coding agents”(并行编码代理)是指利用多个 AI 实例同时处理同一软件项目的不同部分或任务的系统。与传统的串行脚本(按顺序一步步执行命令)不同,并行代理可以同时运行多个独立的任务。例如,一个代理可能负责编写后端 API,而另一个同时负责前端组件,第三个负责编写测试。这种架构通常需要像 tmux 这样的终端复用器来管理多个并发会话,并通过 Markdown 规范来定义任务边界,确保代理之间的协作既高效又互不干扰。


2: 为什么选择 tmux 作为运行这些 Agent 的底层工具?

2: 为什么选择 tmux 作为运行这些 Agent 的底层工具?

A: tmux(terminal multiplexer)是运行并行 AI 编码代理的理想基础设施,主要因为它提供了“会话”和“窗格”的概念。在自动化编程工作流中:

  1. 持久性:即使网络断开或 SSH 连接中断,tmux 会话中的进程(如运行中的 LLM 代理或编译服务)会继续运行。
  2. 并发管理:允许在一个终端窗口内分割屏幕,同时监控多个代理的实时输出日志。
  3. 无头运行:非常适合服务器环境,可以通过脚本动态创建、分离和重新附加会话,使得 AI 代理可以在后台自主操作。

3: Markdown 规范在这个系统中扮演什么角色?

3: Markdown 规范在这个系统中扮演什么角色?

A: Markdown 文件充当了“项目经理”或“系统提示词”的角色。它不仅仅是简单的文档,而是 Agent 执行任务的指令集和上下文来源。具体作用包括:

  1. 任务定义:清晰地列出需要实现的功能、技术栈限制和文件结构。
  2. 上下文记忆:Agent 可以读取 Markdown 中的历史记录或设计决策,避免重复工作或偏离目标。
  3. 结构化输出:Agent 可以将进度更新、代码片段或遇到的问题写回 Markdown,从而实现人类与 AI 之间,或 AI Agent 之间的状态同步。

4: 这种工作流面临的主要技术挑战是什么?

4: 这种工作流面临的主要技术挑战是什么?

A: 实施并行编码代理面临几个关键挑战:

  1. 上下文冲突:当两个 Agent 同时修改同一个文件或函数时,容易产生代码冲突或逻辑错误。需要严格的锁机制或文件分配策略。
  2. Token 限制与成本:同时运行多个 Agent 会线性增加 API 调用成本和 Token 消耗。
  3. 错误传播:如果一个 Agent 生成了错误的代码,依赖该代码的其他 Agent 可能会连锁失败。系统需要具备错误检测和回滚机制。
  4. 通信延迟:Agent 之间如何通过共享的 Markdown 或文件系统快速感知彼此的变化,是一个工程难点。

5: 普通开发者如何开始构建或使用类似的系统?

5: 普通开发者如何开始构建或使用类似的系统?

A: 对于想要尝试的开发者,建议从以下步骤入手:

  1. 掌握基础工具:首先熟练使用 tmux 的命令行操作(如 new-session, split-window, send-keys)。
  2. 选择 AI 接口:选择一个支持长上下文且 Function Calling 或 Tool Use 能力较强的大模型(如 Claude 3.5 Sonnet 或 GPT-4o)。
  3. 编写控制脚本:使用 Python 或 Shell 脚本编写一个“编排器”,该脚本负责启动 tmux 会话,将 Markdown 中的任务分发给不同的 Agent 实例。
  4. 小规模实验:先尝试让两个 Agent 协作完成一个非常简单的任务(例如一个写测试,一个写函数),观察它们如何通过文件系统交互。

6: 这种方法与使用 GitHub Copilot 或 Cursor 等现有工具相比有什么优势?

6: 这种方法与使用 GitHub Copilot 或 Cursor 等现有工具相比有什么优势?

A: Copilot 和 Cursor 主要是“副驾驶”工具,侧重于辅助人类编写代码,由人类主导流程。而 “Parallel coding agents” 是一种“自主代理”模式,其优势在于:

  1. 并行处理能力:可以同时进行代码编写、测试、文档编写和重构,速度远超人类辅助工具。
  2. 无人值守运行:一旦配置好,Agent 可以在 tmux 会话中长时间自主工作,人类只需审查最终的 Pull Request 或 Markdown 报告。
  3. 高度定制化:开发者可以完全控制 Agent 的分工逻辑和协作方式,而不是依赖 IDE 固定的集成功能。

思考题

## 挑战与思考题

### 挑战 1: [简单]

问题**:

在 tmux 中手动创建一个名为 dev_session 的会话,并将其分割为三个窗格:左侧用于代码编辑,右侧上方用于运行测试,右侧下方用于查看日志。请写出实现这一布局的完整命令序列。

提示**:


引用

注:文中事实性信息以以上引用为准;观点与推断为 AI Stack 的分析。



站内链接

相关文章