Claude Code 深度拆解:Agent 执行内核 2 — Pipeline 与上下文压缩

Hi,大家好,欢迎来到维元码簿。

本文属于 《Claude Code 源码 Deep Dive》 系列,专注于 Agent 执行内核中的 Pipeline 与上下文压缩 板块。如果你想了解整个系列,可以先看系列开篇 | Claude Code 源码架构概览:51万行代码的模块地图

50 轮对话后,消息历史可以轻松膨胀到 10 万+ token------如果不做处理,不仅费钱,而且可能超过模型上下文窗口。 Claude Code 的解决方案不是在 API 层面优化(那是 Prompt Cache 系列的主题),而是在每次 API 调用前,对消息执行四层压缩:Snip(截断)、Microcompact(去重)、ContextCollapse(折叠)、AutoCompact(摘要)。

读完全文,你将能回答这几个问题:

  • Pipeline 是什么?和压缩有什么关系? 答案:Pipeline 是架构模式------数据流、条件跳站、跨站参数传递、错误恢复路径;压缩是每个站承载的功能。Pipeline 不等于压缩,压缩只是 Pipeline 的一种应用。
  • 四层压缩各自解决什么问题?为什么它们的执行顺序不可换? 答案:Snip 截断远的历史 → Microcompact 去重 → Collapse 折叠可恢复 → AutoCompact 摘要不可逆------每一层假设前一层已完成。
  • 什么时候压缩?每一次都需要调用大模型吗? 答案:Snip、Microcompact、ContextCollapse 都是纯本地操作,不调大模型;只有 AutoCompact 和 Reactive Compact 需要调用独立的 compact agent------而且有 circuit breaker 防止无限重试。
  • AutoCompact 失败了怎么办? 答案:circuit breaker------连续失败 3 次就放弃,不再重试。还有 Reactive Compact 作为 413 错误的被动防线。
  • 压缩前后的 token 变化有多大? 答案:一次 AutoCompact 可将 8 万+ token 削减到约 1.2 万 token------削减 85%+。

本篇覆盖的源码范围

模块 核心文件 核心代码行 文件总行 职责
Pipeline 编排 src/query.ts L365-543(snip→microcompact→collapse→autocompact) 1730 行 四层压缩的总调度
Snip src/services/compact/snipCompact.ts(Feature: HISTORY_SNIP) -- -- 历史消息按 token 阈值截断
Microcompact src/services/compact/microCompact.ts L1-600(microcompact 主逻辑) ~600 行 重复工具结果去重 + cache_edits
ContextCollapse src/services/contextCollapse/(Feature: CONTEXT_COLLAPSE) -- -- 可恢复的语境折叠投影
AutoCompact src/services/compact/autoCompact.ts L28-82(阈值计算 + circuit breaker) 352 行 自动摘要压缩主逻辑
Compact 核心 src/services/compact/compact.ts L1-100(入口函数 compactConversation) ~1600 行 调用 compact agent 生成摘要

为什么叫 Pipeline?

你可能会问:为什么用 Pipeline 这个词?有直接的代码依据。

query.ts L396-467 中,消息数组 messagesForQuery 依次流过 4 个压缩函数------每个函数的输出就是下一个函数的输入,形成标准的 Pipeline(流水线)模式。四层压缩顺序串行、层层递进,在代码结构上就是一个典型的 Pipeline。

这个类比也不是本文独创的------消息上下文管理篇 中,同样的 messages 数组在发给 API 之前还要经过另一道"清洗 Pipeline"(normalizeMessagesForAPI()),处理类型映射、Content Part 组装、缓存断点标记。两篇讲的是同一件事的不同阶段:一个对消息做压缩清洗,一个对消息做预发清洗。

用 Pipeline 统一描述,是为了让读者看到消息从用户输入到最终发出 API,全程都处在 Pipeline(流水线)处理中


前情提要:从主循环到第一阶段

在姊妹篇 [主循环与状态机](./04-Claude Code深度拆解-Agent执行内核-主循环与状态机.md) 中,我们建立了全局认知------while(true) 循环的 4 个阶段(准备→调用→执行→转移)。本文聚焦第 1 个阶段------准备阶段中的 Pipeline 与上下文压缩。

query.ts 中,这段代码位于 L365-543------在 API 调用之前,在构建完整 Prompt 之前。每次进入循环,第一步就是对消息历史做"瘦身"。

与 Prompt Cache 机制的区别 :Prompt Cache(缓存工程深度拆解篇)讲的是 Anthropic API 的 KV Cache------服务端如何复用已计算的 KV 向量来跳过前缀处理。那是"让 API 少算"。这里的四层压缩是"让 API 少看"------先砍掉不必要的 token,再发给 API。两者互相独立但又协同工作:压缩后的消息更短 → 前缀更稳定 → KV cache 命中率更高。


Pipeline 机制详解:不等于压缩,而是一套架构模式

你可能会有疑问:标题叫"Pipeline 与上下文压缩",但读下来不就是四层压缩吗?Pipeline 和压缩是什么关系?

它们不是同一件事。

  • 压缩是每个处理站承载的功能------截断、去重、折叠、摘要
  • Pipeline 是把这些功能串起来的架构模式------数据怎么流、哪些站跳过、参数怎么跨站传递、出错时怎么回退

打个比方:压缩是流水线上每台机器做的事(切割、打磨、喷涂、质检),Pipeline 是流水线本身的传动设计------物料怎么从上一台传到下一台、哪台机器可以跳过、质检失败怎么回炉。

理解 Pipeline 的运行机制,才能看懂后面每一层压缩为什么要这样编排。

下面这张图展示了 Pipeline 的架构机制:主数据流、条件跳站、跨站参数传递、短路重置、错误恢复双路径------注意和 Tab 4(四层压缩功能)的区别,这里讲的是"站怎么串"而不是"每站做什么"。

数据流:一个数组,四次变换

Pipeline 的核心数据实体只有一个:messagesForQueryMessage[] 数组)。它从 getMessagesAfterCompactBoundary() 初始化后,依次流过四个处理站------每一站都接收数组、变换后返回:

text 复制代码
原始 messages
    │
    ▼
getMessagesAfterCompactBoundary() ── 提取压缩边界之后的消息
    │
    ▼ messagesForQuery = [...子集]
    │
  ① Snip ──→ messagesForQuery = snipResult.messages
    │
    ▼
  ② Microcompact ──→ messagesForQuery = microcompactResult.messages
    │
    ▼
  ③ ContextCollapse ──→ messagesForQuery = collapseResult.messages
    │
    ▼
  ④ AutoCompact ──→ messagesForQuery = buildPostCompactMessages(result)
    │
    ▼
  最终 messagesForQuery ──→ 送往 API

这是经典的 Pipeline(链式处理)模式------每一站的输出就是下一站的输入。

条件跳站:不是每站都必跑

Pipeline 不是固定四站全跑。它有条件跳站机制------根据运行环境动态决定哪些站执行:

处理站 跳站条件 什么时候跳过
Snip feature('HISTORY_SNIP') 未开启 feature gate 关闭时整站跳过
Microcompact 无(默认执行) 永不跳过
ContextCollapse feature('CONTEXT_COLLAPSE') && contextCollapse feature gate 关闭或无折叠数据时跳过
AutoCompact token 阈值未超 前三层之后 token 仍在窗口内时不触发

这意味着在轻量对话中,Pipeline 可能只跑 Microcompact 一站。执行路径是自适应的------不是机械的四步流程,而是根据当前消息状态决定走哪条路。

跨站参数传递:不止是主数据流

除了主数据流 messagesForQuery,Pipeline 还有侧信道(side channel)传递参数。这些参数不参与数据变换,但影响后续站的决策:

  • Snip → AutoCompactsnipTokensFreed(Snip 释放的 token 数)被传递给 AutoCompact 的阈值计算。因为 AutoCompact 的 token 估算基于"上次 API 返回的使用量",感知不到 Snip 削减了多少------需要手动补偿,否则 AutoCompact 会在不该触发时触发。
  • Compact 结果 → task_budget :压缩后 taskBudgetRemaining 被重新计算,传递给下一轮 API 调用,保证服务端预算追踪在多次压缩后仍准确(详见后文"Token Budget 的跨 Compact 传递"一节)。

这种"主数据流 + 侧信道"的双轨传递,是 Pipeline 区别于简单函数调用链的关键设计。

短路重置:AutoCompact 的"核爆"

前三层是增量修改 ------在原数组上修剪(Snip)、合并(Microcompact)、折叠(Collapse)。AutoCompact 完全不同:它替换整个数组

buildPostCompactMessages() 返回的是一个全新的消息结构(摘要消息 + 保留的最近几轮对话尾巴),完全覆盖之前的 messagesForQuery。这是 Pipeline 中的"短路重置"------一旦触发,前三层的增量修改被归零,消息结构从零重建。

这也是为什么 AutoCompact 排在最后:只有增量操作都无能为力时,才值得付出一次 API 调用的代价做彻底替换。

错误恢复路径:Pipeline 的第二条命

Pipeline 不是一条直线。当 API 返回 413(prompt too long)时,控制流会重新进入 Pipeline 的恢复路径

text 复制代码
正常路径:Snip → Microcompact → Collapse → AutoCompact → API 调用
                                                      │
                                                      │ 413 错误
                                                      ▼
恢复路径:Collapse Drain → Reactive Compact → 重试 API
                                                      │
                                                      │ 仍然 413
                                                      ▼
                                               return prompt_too_long

ContextCollapse 的 recoverFromOverflow() 是第一个恢复手段------排空已折叠内容释放空间。如果失败,Reactive Compact 作为被动防线。两者都失败,才真正放弃------返回 prompt_too_long 错误。

这种"正常 Pipeline + 恢复 Pipeline"的双路径设计,是 Agent 能长时间运行不崩溃的关键。后面讲 ContextCollapse 和 Reactive Compact 时,我们还会回到这张图。


四层压缩全景:为什么需要四层?

一层压缩不够。 不同的"冗余"需要不同的手术刀。

压缩层 解决的问题 操作方式 执行者 性能 可逆性 Feature Gate
Snip 远离当前的旧对话无用 按 token 阈值截断 本地剪裁 messages 数组 微秒级,0 API 调用 不可逆 HISTORY_SNIP
Microcompact 同一 tool_use_id 的重复结果 合并保留最新 本地遍历比对 毫秒级,0 API 调用 不可逆 (默认开启)
ContextCollapse 大段完整对话占位 折叠为摘要投影 本地语义折叠 毫秒级,0 API 调用 可恢复 CONTEXT_COLLAPSE
AutoCompact 总 token 超过模型窗口 调用 compact agent 生成摘要 compact agent(fork query()) 秒级,1 次 API 调用/触发 不可逆 (默认开启)

下面这张图展示了四层压缩的执行顺序和各自的效果------从上到下依次执行,每一层的输出是下一层的输入。

执行顺序为什么不能换? 因为每层假设前一层已完成。举个例子:如果先做 AutoCompact(1 次 API 调用),再做 Microcompact(0 次 API),那摘要里可能还包含重复的工具结果------去重白做了,API 也白调了。正确顺序是:先截断远的历史(Snip),再去重(Microcompact),再折叠(Collapse),最后如果还是太长,才调用摘要(AutoCompact)------这是"0 成本 → 0 成本 → 0 成本 → 不得不花 1 次 API"的阶梯。

四层压缩的代码编排也反映了这个顺序。在 query.ts 中:

typescript 复制代码
// query.ts L396-467 --- 四层压缩的执行顺序
let messagesForQuery = [...getMessagesAfterCompactBoundary(messages)]

// 第1层:Snip(Feature gated)
if (feature('HISTORY_SNIP')) {
  const snipResult = snipModule.snipCompactIfNeeded(messagesForQuery)
  messagesForQuery = snipResult.messages
  snipTokensFreed = snipResult.tokensFreed
}

// 第2层:Microcompact
const microcompactResult = await deps.microcompact(messagesForQuery, ...)
messagesForQuery = microcompactResult.messages

// 第3层:ContextCollapse(Feature gated)
if (feature('CONTEXT_COLLAPSE') && contextCollapse) {
  const collapseResult = await contextCollapse.applyCollapsesIfNeeded(...)
  messagesForQuery = collapseResult.messages
}

// 第4层:AutoCompact
const { compactionResult } = await deps.autocompact(messagesForQuery, ...)
if (compactionResult) {
  messagesForQuery = buildPostCompactMessages(compactionResult)
}

注意两点:一是 messagesForQuery 被层层赋值------每层都改变了消息数组;二是 Snip 的 snipTokensFreed 被传递给了 AutoCompact------因为 AutoCompact 的阈值判断需要考虑 Snip 已经削减了多少 token。


Snip:历史消息截断

Snip 是最"暴力"的一层------直接砍掉远离当前对话的旧消息。

它按 token 阈值截断:保留最近的消息直到累计 token 接近某个上限,更早的消息直接丢弃。被丢弃的消息不会以任何形式保留------这就是为什么它是"不可逆"的。

Snip 不是默认开启的------它由 HISTORY_SNIP feature gate 控制。为什么需要 gate?因为截断意味着 Agent "遗忘"了早期的对话------如果早期对话包含关键上下文(比如用户说"请用 TypeScript"),截断后 Agent 可能会"失忆"。所以这是有代价的优化。

它有一个重要输出:snipTokensFreed。这个数字会被传递给后续的 AutoCompact------AutoCompact 的阈值计算依赖 tokenCountWithEstimation(messagesForQuery),但这个估计是基于"上次 API 返回的使用量"的,Snip 削减的 token 它感知不到。所以需要手动减去 snipTokensFreed,否则 AutoCompact 会在不该触发的时候触发。


Microcompact:重复工具结果去重

Microcompact 解决的是"一个工具被多次调用,结果被重复注入"的问题。

在 Agent 的循环中,同一个工具可能被连续调用多次(比如连续 Read 了 5 个文件)。每次调用都会在 messages 中追加一个 tool_result 消息。这些结果可能在后续轮次中不再需要,但它们仍然占据 token。

Microcompact 的做法是:按 tool_use_id 去重------同一个 tool_use_id 只保留最后一次结果。这比简单截断更智能------它是语义级的去重,不是位置级的。

另外,Microcompact 还利用了 Anthropic API 的 cache_edits 机制。这个机制允许客户端标记"哪些 tool_result 可以从缓存中删除",服务端在下次请求时会报告实际删除的 token 数(cache_deleted_input_tokens)。Microcompact 结合这个机制,不仅能减少发送的 token,还能精确追踪"省了多少"。


ContextCollapse:可恢复的上下文折叠

ContextCollapse 是四层压缩中唯一"可恢复"的一层。

它和 AutoCompact 的本质区别是:Collapse 是"折叠"而不是"压缩" 。折叠后的内容仍然以结构化的方式存储,只是读取时被投影为一个摘要。如果后续代码需要访问折叠区的内容,可以通过 projectView() 恢复------AutoCompact 做不到这点。

ContextCollapse 由 CONTEXT_COLLAPSE feature gate 控制。它的核心函数是 applyCollapsesIfNeeded()------检查是否有大段对话可以折叠,如果有就提交折叠日志。折叠后的 messagesForQuery 中,大段对话被替换为一个"折叠标记"。

这层还有一个关键用途:recoverFromOverflow()。当 API 返回 413(prompt too long)时,这是第一个被调用的恢复手段------把已折叠的内容"排空",释放更多空间。如果排水成功,continue 回到循环顶部重试;如果排水失败(没有可折叠的内容了),就交给下一层------Reactive Compact。


AutoCompact:自动摘要压缩

AutoCompact 是四层压缩的"核武器"------调用一个独立的 compact agent 来生成对话摘要。

下面这张图展示了 AutoCompact 的决策流程:什么时候触发、怎么计算阈值、失败了怎么办。

什么时候触发?

AutoCompact 的触发条件是:当前消息的估算 token 数超过了一个阈值。

阈值的计算公式是:

复制代码
threshold = effectiveContextWindow - AUTOCOMPACT_BUFFER_TOKENS

其中 effectiveContextWindow 是模型的上下文窗口大小减去输出预留(20,000 tokens),AUTOCOMPACT_BUFFER_TOKENS = 13,000。这个 buffer 的存在是为了"在真需要压缩之前就压缩"------不是在上下文窗口满了才动手,而是提前 13,000 tokens 就开始准备。

还有一个 CLAUDE_CODE_AUTO_COMPACT_WINDOW 环境变量可以覆盖窗口大小(只减不增),方便测试和调试。

怎么执行?

AutoCompact 不是直接在 query.ts 里写压缩逻辑------它调用一个独立的 compact agent 。这个 compact agent 是另一个 query() 调用(fork agent),接收当前对话历史,输出一个摘要。摘要生成有自己的 token 预算:最多 20,000 个输出 token。

压缩完成后,messagesForQuery 被替换为压缩后的精简版本------摘要消息 + 少量保留消息(最近几个 turn 的对话尾巴)。同时 autoCompactTracking 被重置(turnId = uuid()turnCounter = 0),因为压缩后对话结构变了,需要新的计数周期。

下面这张图展示了压缩前后的消息结构对比------从 10+ 条完整消息变成了"摘要 + 保留尾巴"。

失败了怎么办?------Circuit Breaker

AutoCompact 不是每次都能成功。如果 compact agent 调用失败(比如 API 错误、生成的摘要太大),consecutiveFailures 计数器会递增。当 consecutiveFailures >= MAX_CONSECUTIVE_AUTOCOMPACT_FAILURES (3) 时,circuit breaker 熔断------不再尝试自动压缩。

这个设计来自生产环境的数据:BQ 2026-03-10 报告显示,1,279 个 session 有 50+ 次连续失败(最多 3,272 次),每天浪费约 25 万次 API 调用。Circuit breaker 就是为这个场景设计的------与其无限重试,不如 3 次后放弃。


Reactive Compact:被动的最后防线

当四层压缩都拦不住 413 错误时,Reactive Compact 上场。

下面这张图展示了 Reactive Compact 的触发路径------从 413 错误被 withhold 开始,到恢复成功或放弃。

它的工作方式跟 AutoCompact 类似(也叫 compact agent 生成摘要),但有两个关键区别:

  1. 被动触发 :不是阈值判断,而是 API 返回 413 后才启动。413 错误先被 withhold(不 yield 给用户),然后依次尝试:Collapse Drain → Reactive Compact。
  2. 只尝试一次hasAttemptedReactiveCompact 标志位保证不会死循环。如果 RC 已经尝试过且仍然 413,就直接 return { reason: 'prompt_too_long' }------不再重试。

这是一种"防御性"设计:主动压缩(AutoCompact)尽力而为,被动恢复(Reactive Compact)兜底。如果两者都拦不住,说明是真正的不可恢复错误------比如用户在单轮中塞入了太多图片。


Token Budget 的跨 Compact 传递

AutoCompact 之后,消息结构发生了根本性变化------从完整对话变成了"摘要 + 尾巴"。这会影响一个关键的追踪变量:task_budget.remaining

task_budget 是服务端用来追踪"剩余预算"的机制------如果对话太长,服务端会限制轮次。在压缩之前,服务端能看到完整对话,自己数 token。压缩之后,服务端只看到摘要,需要客户端告诉它"压缩前的最后窗口用了多少 token"。

taskBudgetRemaining 就是这个"传递变量"------每次 compact 时,计算压缩前的 final context tokens,从 remaining 中减去。这保证了服务端的预算追踪在多次压缩后仍然准确。

typescript 复制代码
// query.ts L508-514 --- task_budget 跨 compact 传递
if (params.taskBudget) {
  const preCompactContext = finalContextTokensFromLastResponse(messagesForQuery)
  taskBudgetRemaining = Math.max(
    0,
    (taskBudgetRemaining ?? params.taskBudget.total) - preCompactContext,
  )
}

各压缩层在模型上下文中的位置

四层压缩都在操作 messages 部分,但每一层操作的位置和粒度不同。理解它们在模型上下文中的位置,有助于判断压缩带来的影响。

消息上下文管理篇的上下文全景图可知,发给模型的数据分为三块:

text 复制代码
┌───────────────────────────────────────────────┐
│  system(System Prompt)     ~30%   ← 不压缩   │
├───────────────────────────────────────────────┤
│  messages(对话历史)        ~60%   ← 压缩目标  │
│    ├── 早期对话(远的历史)     ← Snip 截断     │
│    ├── 中间对话(大段内容)     ← Collapse 折叠  │
│    ├── 工具结果(重复内容)     ← Microcompact   │
│    └── 整体(超窗口时)         ← AutoCompact   │
├───────────────────────────────────────────────┤
│  tools(工具 Schema)        ~10%   ← 不压缩   │
└───────────────────────────────────────────────┘

Snip 操作在 messages 尾部------它按 token 阈值从数组末尾往前数,砍掉超过阈值的部分。被砍掉的是"最老的消息",即模型视角中"最不相关"的上下文。代价是 Agent 可能"失忆"------这就是它由 feature gate 控制的原因。

Microcompact 操作在 messages 的 tool_result 区域 ------它遍历所有 tool_result Content Part,按 tool_use_id 合并。被压缩的是"旧的工具执行结果",不是整个对话。因为每个 tool_result 对应一个 tool_use,压缩后模型不会"失忆",只是看不到旧结果了------影响较小。

ContextCollapse 操作在 messages 的大段连续对话区------它把可折叠的段落投影为摘要标记,同时保留恢复能力。模型仍然知道"有过这段对话",但看不到细节------是四层中唯一在"保记忆"和"省 token"之间做平衡的。

AutoCompact 操作在整个 messages 数组------它在三层之后,如果总 token 仍然超过模型窗口,就调用 compact agent 把大部分消息替换为摘要。模型只能看到"压缩前发生过这些事"的简述,细节完全丢失。这也是为什么 AutoCompact 只在前三层都无能为力时才触发------它是"核武器"。

消息上下文管理篇对比:消息上下文管理篇关注的是"发给模型的数据由哪几块组成",本文关注的是"在发给模型之前,对 messages 这块做了哪些预处理"。两块知识合在一起,才是消息从用户输入到 API 调用的完整生命周期。


本章小结

本文从两个维度拆解了 Agent 执行内核的 Pipeline 设计:

Pipeline 架构维度 :消息数组 messagesForQuery 流过四个处理站,每站可选跳过(条件跳站)、通过侧信道传递参数(跨站参数传递)、AutoCompact 触发时整个替换(短路重置)、413 错误时进入恢复路径(双路径设计)。这不是简单的函数调用链,而是一套有自适应能力的架构模式。

压缩功能维度------四个处理站各自做了什么:

  • Snip(截断) 按 token 阈值砍掉旧消息------代价是"失忆",由 feature gate 控制。
  • Microcompact(去重) 合并重复工具结果------语义级去重,不是位置级。
  • ContextCollapse(折叠) 可恢复的语境投影------比直接删除更优雅。
  • AutoCompact(摘要) 调用独立的 compact agent 生成摘要------削减 85%+ token,但有 circuit breaker 防死循环。
  • Reactive Compact(被动) 当四层都拦不住 413 时的最后防线------只尝试一次。

这四层压缩和 Prompt Cache 机制是正交关系:压缩减少"发给 API 的 token 量",Cache 减少"API 处理这些 token 的计算量"。两者叠加,才是 Claude Code 能从 50 轮对话中省下 10 倍成本的原因。

下一姊妹篇 [从 API 调用到安全退出](./04-Claude Code深度拆解-Agent执行内核-从API调用到安全退出.md) 将深入压缩完成后的完整链路------API 调用、流式工具执行、错误恢复、生命周期收尾。


系列导航

本文属于 《Claude Code 源码 Deep Dive》 系列中「Agent 执行内核」命题的子篇章,专注于 Pipeline 与上下文压缩

姊妹篇(可独立阅读):


如果这篇文章对你有帮助,欢迎点赞收藏 支持一下。如果你对 Claude Code 源码感兴趣,欢迎关注本系列 后续更新。有任何想法或疑问,欢迎评论区留言讨论 👋

相关推荐
hrhcode3 小时前
【LangGraph】二.State 和 Node 的设计细节
python·ai·langchain·langgraph·ai框架
也许明天y4 小时前
LangChain4j + Spring Boot 多智能体协调架构原理深度解析
spring boot·后端·agent
Trouvaille ~4 小时前
零基础入门 LangChain 与 LangGraph(八):真正让 Agent“活起来”——持久化、记忆、人机交互与时间旅行
langchain·人机交互·agent·python3.11·持久化机制·langgraph·ai应用开发
0xR3lativ1ty4 小时前
每周AI新工具速览:Kiln与OpenRA-RL登场
人工智能·ai
赵康4 小时前
智人曾经这样灭绝猛犸象:AI入侵与行业灭绝
ai·llm
Agent产品评测局5 小时前
离散制造业生产流程优化,AI落地实操步骤详解:从传统自动化到企业级智能体的技术范式跃迁
运维·人工智能·ai·自动化
还是转转5 小时前
深入认识 Agent —— 实现你自己的 Agent
ai·agent
小羊Yveesss5 小时前
2026年前端开发新趋势:智能协同、工具革新与场景深耕
前端·ai
YXWik65 小时前
Linux内网搭建FastGpt+配置ollama私有化的deepseek-r1:7b模型
ai