让 Agent 面向用户:AG-UI 协议构建 Agent 前端

导读:Agent 后端与用户界面之间长期缺一套标准通信协议,每个团队都在重复发明轮子。MCP 标准化了 Agent 调用工具的方式,A2A 标准化了 Agent 之间的通信,AG-UI 则在 Agent 与前端的交互维度补上了关键一环。


假设你正在做一个 AI 编程助手。LangGraph 编排好了后端逻辑链,React 前端搭好了聊天界面,一切看起来都很顺。然后你开始处理 Agent 的输出,问题才真正浮出水面:LLM 吐出的一串串 Token 得解析成可渲染的片段,工具调用的中间结果要实时更新到界面,用户点击"确认执行"后得通知后端放行,Agent 的推理过程想展示给用户但又不想阻塞主线程。

很快你会发现,自己写了一堆自制的 SSE 解析器、一个自定义的 JSON 状态机,外加若干套前后端各自维护的"约定"。

这些代码与你的业务逻辑毫无关系,但每做一个新项目就要重写一遍。

这就是 AG-UI 协议诞生的背景。它不是某天突然冒出来的抽象概念,而是从大量 Agent 应用的实际开发中提炼出的共同需求。


协议做了什么

AG-UI 的全称是 Agent-User Interaction Protocol,由 CopilotKit 团队主导开发,2025 年 5 月开源,采用 MIT 许可。截至 2026 年 7 月,GitHub 上 ag-ui-protocol/ag-ui 仓库已有约 15.1k 星标、1.4k Fork。这个数字反映了这个痛点的普遍性。

它的核心定义很简洁 :一个标准化的、事件驱动的、传输无关的协议层,专门用于 Agent 后端与用户界面之间的通信。事件驱动意味着所有通信天然是异步的,适配流式输出。传输无关意味着它不绑定 SSE、WebSocket 或任何具体传输层------当前主流实现基于 SSE,但 WebSocket 和 webhook 同样受支持。

一个典型的 AG-UI 事件流长这样:

css 复制代码
data: {"type":"RUN_STARTED","runId":"run_abc123","timestamp":1720000000000}

data: {"type":"TEXT_MESSAGE_START","messageId":"msg_1"}

data: {"type":"TEXT_MESSAGE_CONTENT","messageId":"msg_1","delta":"我正在分析你的代码,请稍等..."}

data: {"type":"TOOL_CALL_START","toolCallId":"tc_1","toolName":"read_file","args":{}}

data: {"type":"TOOL_CALL_ARGS","toolCallId":"tc_1","args":{"path":"/src/main.py"}}

data: {"type":"TOOL_CALL_END","toolCallId":"tc_1"}

data: {"type":"TOOL_CALL_RESULT","toolCallId":"tc_1","content":"..."}

data: {"type":"TEXT_MESSAGE_END","messageId":"msg_1"}

data: {"type":"RUN_FINISHED","runId":"run_abc123"}

每一条 data: 行就是一个事件,事件类型在 JSON 的 type 字段里。这与官方 SDK 的编码方式一致------AG-UI 规范不依赖 SSE 的 event: 命名字段,前端只需监听默认的 message 事件即可收到全部事件。

这个模式本身不复杂。在它出现之前,每个团队都在各自发明同一个模式。


事件模型

AG-UI 定义了约 27 种事件类型,分布在 7 个类别中。理解这些事件类型,是使用协议的第一步。

生命周期事件

RUN_STARTEDRUN_FINISHEDRUN_ERROR 三个事件构成了 Agent 执行的完整生命周期。它们定义了一次 Agent 运行的边界,从开始到结束,中间可能包含任意数量的文本消息、工具调用与状态变更。这个模型与 HTTP 请求响应的生命周期不同:一个 Run 可以持续数秒到数十分钟,其内部包含多个异步子过程。

文本消息事件

这是最直观的类别。TEXT_MESSAGE_STARTTEXT_MESSAGE_CONTENTTEXT_MESSAGE_END 三个事件构成了流式文本输出的完整通道。TEXT_MESSAGE_CONTENT 可以多次发送,每次携带一段 delta 增量文本。前端收到后直接追加到消息缓冲区即可。这个模式与 LLM 的流式 Token 输出天然匹配,甚至不需要额外的缓冲或拼接逻辑。

工具调用事件

TOOL_CALL_STARTTOOL_CALL_ARGSTOOL_CALL_ENDTOOL_CALL_RESULT 四个事件跟踪了工具调用的完整过程。TOOL_CALL_ARGS 独立于 TOOL_CALL_START 发出,因为参数可能是在 Agent 运行过程中逐步收集的,比如从用户那里获取缺失的输入。

TOOL_CALL_RESULT 单独发出,让前端可以在工具返回结果后立即更新 UI,而不必等待 Agent 的完整输出收齐。

状态管理事件

STATE_SNAPSHOTSTATE_DELTA 是 AG-UI 中两个最强大的事件类型。STATE_SNAPSHOT 发送 Agent 的完整状态快照,通常用于初始化或恢复会话。STATE_DELTA 使用 RFC 6902 JSON Patch 格式发送增量更新,只传递状态变化的部分。对于包含完整对话历史、工具调用上下文的大型状态对象,这种增量机制能显著降低传输开销。

推理事件

REASONING_STARTREASONING_MESSAGE_CONTENTREASONING_END 三个事件取代了早期版本中的 THINKING_* 事件。这个命名变化反映了设计思路的演进:Agent 展示给用户的不是"思考过程",而是"推理路径"。推理事件让前端可以独立于文本输出流展示 Agent 的推理步骤,例如在聊天界面旁边显示一个思维链面板。

活动事件

ACTIVITY_SNAPSHOTACTIVITY_DELTA 管理 Agent 的"活动日志"------那些不必出现在聊天消息里、但对用户了解 Agent 行为至关重要的信息流,比如 Agent 正在访问哪些文件、尝试了哪些 API、遇到了什么错误。如果这些全部塞进聊天窗口,对话会变得难以阅读。

特殊事件

CUSTOMINTERRUPTRUN_ERROR 提供了扩展、中断和错误处理通道。CUSTOM 允许开发者定义命名空间隔离的自定义事件类型;INTERRUPT 用于在执行中暂停 Agent 以请求人工输入或审批(携带 reason 字段区分中断原因,如 tool_callconfirmation);RUN_ERROR 提供了标准化的错误报告机制,包含错误码、错误信息和可选的堆栈跟踪字段。


在 Agent 协议体系中的定位

把 AG-UI 放到更大的图景里看,2026 年的 AI Agent 生态已经形成了三组核心通信协议。它们分别解决 Agent 系统中不同维度的通信问题,合在一起构成了当前 Agent 协议体系的主干。

MCP(Model Context Protocol)解决 Agent ↔ 工具的通信。由 Anthropic 于 2024 年 11 月发布,基于 JSON-RPC,定义了 Agent 如何发现工具、调用工具、接收工具返回结果。MCP 是三组协议中最成熟的一组,月均 SDK 下载量超过 9700 万次(Anthropic 官方博客,2025 年 12 月)。

A2A(Agent-to-Agent Protocol)解决 Agent ↔ Agent 的通信。由 Google 于 2025 年 4 月发布,定义了 Agent 之间的任务生命周期管理,一个 Agent 可以向另一个 Agent 委派任务、跟踪执行进度、接收完成通知。2025 年 6 月,Google 将 A2A 捐赠给 Linux 基金会。

AG-UI 解决 Agent ↔ 用户界面的通信。它不替代 MCP 或 A2A,而是与它们互补。一个典型的 Agent 应用往往三组协议同时使用:MCP 让 Agent 调工具,A2A 让 Agent 协调其他 Agent,AG-UI 将结果流式呈现给用户。

这三组协议不是竞争关系,也不是严格的上下层依赖------它们覆盖的是 Agent 系统中三个正交的通信维度。

Oracle 在 2026 年 3 月宣布在 Agent Spec 中集成 AG-UI,微软 Agent Framework v1.0 在 2026 年 4 月原生集成了 AG-UI,AWS Bedrock AgentCore 在 2026 年 3 月增加了 AG-UI 支持(各厂商官方公告)。这些信号表明 AG-UI 正在成为 Agent 与用户界面之间通信的主流候选标准。


代码:流式交互的最小实现

以一个前端 React 组件加 Python FastAPI 后端为例,展示 AG-UI 是如何在真实代码中运行的。

消费 AG-UI 事件流

python 复制代码
import { useState, useEffect, useRef } from 'react'

type AGUIEvent = {
  type: string
  runId?: string
  messageId?: string
  delta?: string
  toolCallId?: string
  toolName?: string
  args?: any
  content?: string
  message?: string
  code?: string
  [key: string]: any
}

function useAgentStream(url: string) {
  const [messages, setMessages] = useState<any[]>([])
  const [isRunning, setIsRunning] = useState(false)
  const [error, setError] = useState<string | null>(null)
  const eventSourceRef = useRef<EventSource | null>(null)

  const run = (input: string) => {
    // 先关闭上一次的连接,避免连接泄漏
    eventSourceRef.current?.close()
    setIsRunning(true)
    setError(null)
    eventSourceRef.current = new EventSource(
      `${url}?input=${encodeURIComponent(input)}`
    )

    eventSourceRef.current.onmessage = (event) => {
      const data: AGUIEvent = JSON.parse(event.data)

      switch (data.type) {
        case 'TEXT_MESSAGE_CONTENT':
          setMessages(prev => {
            // 在整个列表中查找同 messageId 的文本消息(中间可能穿插工具调用事件)
            const idx = [...prev].reverse().findIndex(
              m => m.type === 'text' && m.messageId === data.messageId
            )
            if (idx !== -1) {
              const i = prev.length - 1 - idx
              return [
                ...prev.slice(0, i),
                { ...prev[i], content: prev[i].content + data.delta },
                ...prev.slice(i + 1)
              ]
            }
            return [
              ...prev,
              { type: 'text', messageId: data.messageId, content: data.delta }
            ]
          })
          break
        case 'TOOL_CALL_START':
          setMessages(prev => [...prev, {
            type: 'tool_call',
            toolCallId: data.toolCallId,
            toolName: data.toolName,
            status: 'running'
          }])
          break
        case 'TOOL_CALL_END':
          setMessages(prev => prev.map(m =>
            m.toolCallId === data.toolCallId
              ? { ...m, status: 'completed' }
              : m
          ))
          break
        case 'TOOL_CALL_RESULT':
          setMessages(prev => prev.map(m =>
            m.toolCallId === data.toolCallId
              ? { ...m, result: data.content }
              : m
          ))
          break
        case 'RUN_FINISHED':
          setIsRunning(false)
          eventSourceRef.current?.close()
          break
        case 'RUN_ERROR':
          setError(data.message || data.code || 'Unknown error')
          setIsRunning(false)
          eventSourceRef.current?.close()
          break
      }
    }
  }

  useEffect(() => {
    return () => eventSourceRef.current?.close()
  }, [])

  return { messages, isRunning, error, run }
}

这个 Hook 处理了三种核心事件:文本增量的流式追加、工具调用的状态跟踪、运行生命周期的管理。注意 TEXT_MESSAGE_CONTENT 的处理方式------它不是简单地把每条消息推入列表,而是在整个消息列表中按 messageId 查找同一条文本消息,找到就追加而非新建。这样保证了一段 LLM 的流式输出被正确拼接成一条完整消息,即使中间穿插了工具调用等事件,也不会被拆成碎片。

发送 AG-UI 事件

python 复制代码
from fastapi import FastAPI
from fastapi.responses import StreamingResponse
import asyncio
import json

app = FastAPI()

async def agent_stream(input: str):
    run_id = "run_abc123"
    msg_id = "msg_1"
    tc_id = "tc_1"

    # 生命周期开始
    yield f"data: " \
          f"{json.dumps({'type': 'RUN_STARTED', 'runId': run_id})}\n\n"

    # 文本消息开始
    yield f"data: " \
          f"{json.dumps({'type': 'TEXT_MESSAGE_START', 'messageId': msg_id})}\n\n"

    # 流式输出
    for chunk in ["我", "正在", "分析", "你的", "代码"]:
        await asyncio.sleep(0.1)
        yield f"data: " \
              f"{json.dumps({'type': 'TEXT_MESSAGE_CONTENT',
                            'messageId': msg_id, 'delta': chunk})}\n\n"

    # 工具调用
    yield f"data: " \
          f"{json.dumps({'type': 'TOOL_CALL_START',
                         'toolCallId': tc_id,
                         'toolName': 'read_file'})}\n\n"
    await asyncio.sleep(0.3)
    yield f"data: " \
          f"{json.dumps({'type': 'TOOL_CALL_END',
                         'toolCallId': tc_id})}\n\n"
    yield f"data: " \
          f"{json.dumps({'type': 'TOOL_CALL_RESULT',
                         'toolCallId': tc_id,
                         'content': 'file content'})}\n\n"

    # 文本消息结束
    yield f"data: " \
          f"{json.dumps({'type': 'TEXT_MESSAGE_END', 'messageId': msg_id})}\n\n"

    # 生命周期结束
    yield f"data: " \
          f"{json.dumps({'type': 'RUN_FINISHED', 'runId': run_id})}\n\n"

@app.get("/agent")
async def agent(input: str):
    return StreamingResponse(
        agent_stream(input), media_type="text/event-stream"
    )

后端代码的核心是 StreamingResponse 返回的一个 SSE 流。每个事件按 data: JSON 的格式发送,事件类型在 JSON 的 type 字段里,事件之间用空行分隔。

前端 EventSource 自动解析这个格式,所有事件都作为默认的 message 事件触发 onmessage 回调,开发者只需要在回调中按 data.type 分发即可。这也是官方 SDK 的编码方式------AG-UI 规范不依赖 SSE 的 event: 命名字段。


设计模式

以下五个模式来自社区实践和 Zylos Research 的 Agentic UX 研究,是实际项目中反复出现的交互方案。

1. 流式增量模式

这是最基本也最容易被忽视的模式。文本消息使用增量 delta 更新,状态使用 JSON Patch 增量更新。两个层面的增量组合在一起,前端可以只渲染变化的部分,而不必每次收到新事件就重新渲染整个界面。STATE_DELTA 的事件结构如下:

json 复制代码
{
  "type": "STATE_DELTA",
  "stateId": "state_1",
  "patch": [
    { "op": "replace", "path": "/agentStatus", "value": "thinking" },
    { "op": "add", "path": "/steps/-", "value": { "id": "step_3", "name": "分析代码" } }
  ]
}

2. 工具审批模式

人类在环(Human-in-the-loop)是 Agent 应用中最重要的安全机制之一。AG-UI 的 INTERRUPT 事件天然支持这个模式:Agent 遇到需要人工确认的操作时,发送 INTERRUPT 事件(reason 字段为 "tool_call",附带待执行的工具调用详情),前端展示审批界面。

用户点击"确认"或"拒绝"后,前端通过 WebSocket 或 HTTP POST 将决策发送回后端,Agent 继续执行或终止该工具调用。

这个模式的关键在于审批不是"全有或全无"的。你可以让 Agent 自由执行"读"操作,但"写"操作需要审批;或者让 Agent 在低风险环境中自动执行,在高风险环境中暂停等待审批。

3. 前端工具调用模式

AG-UI 支持一个反向模式------Agent 调用前端注册的函数。比如 Agent 说"在浏览器中高亮第 3 行代码",传统做法是 Agent 输出某种命令格式,前端解析后执行。AG-UI 的做法是:前端注册一个 highlightCode 工具,Agent 通过标准的 TOOL_CALL_* 事件调用它,TOOL_CALL_RESULT 携带执行结果返回给 Agent。

这个模式模糊了"后端工具"与"前端功能"的边界,让 Agent 可以操作浏览器 DOM、控制前端动画、触发文件下载等原本需要硬编码的交互。

4. 活动面板分离模式

Zylos Research 在 2026 年发布的 Agentic UX 研究中指出,活动面板分离是 Agent 界面设计中反复被强调的关键决策。大多数第一版 Agent 应用把各类信息塞进聊天窗口,导致用户翻完冗长对话也找不到关键信息。

活动面板分离把 Agent 的行为日志(ACTIVITY_* 事件)与聊天消息(TEXT_MESSAGE_* 事件)分开显示。

Augment Code 团队的研究数据显示,没有运行中可见性的 Agent 会话,用户放弃率是有实时进度面板的 3 倍(Zylos Research 引述,2026 年 5 月)。

5. 快照加增量状态同步

状态同步是 Agent 应用中最棘手的问题之一。STATE_SNAPSHOT 提供完整状态快照,适合会话恢复和初始化;STATE_DELTA 提供增量更新,适合持续运行中的状态同步。前端在收到 STATE_SNAPSHOT 时替换整个状态树,收到 STATE_DELTA 时应用 JSON Patch。这个模式配合 Immutable 数据结构,可以实现高性能的不可变状态管理。


生成式 UI:从文本到组件

AG-UI 事件流不只承载文本和工具调用状态,它同样可以传输更复杂的 UI 描述。这就是生成式 UI(Generative UI)的方向------Agent 不再只输出文字,而是输出完整的界面组件。

Google A2UI 提供了声明式的 UI 组件规范,运行在 AG-UI 传输层之上。Agent 将组件描述(按钮、表单、图表等)以 JSON 结构发出,前端收到后直接渲染为交互组件,而不是纯文本。CopilotKit 也已经在用 AG-UI 事件流传输动态 UI 组件。

当 Agent 能动态生成 UI 时,静态的聊天界面和固定的工具栏布局可能变得不再够用。这也是 AG-UI 的价值延伸:它不仅是文本流的标准,也在成为 Agent 驱动前端界面的通用通道。


框架实现对比

截止 2026 年 7 月,主流框架对 Agent 与 UI 通信的支持情况如下:

框架 协议方式 流式事件 生成式 UI 状态同步 典型场景
CopilotKit + AG-UI 原生 AG-UI 完整 支持 JSON Patch 通用 AI 应用
Vercel AI SDK 自定义流格式 完整 支持(json-render) 内置 hooks 文本生成、聊天
LangGraph + LangServe 自定义 SSE 支持 不支持 自定义状态 复杂 Agent 工作流
Microsoft Agent Framework 原生 AG-UI 完整 有限 JSON Patch 企业 Agent 应用
Google ADK + A2UI A2A + AG-UI 传输 完整 声明式 UI JSON Patch 多 Agent 协作
Anthropic Claude Artifacts 私有协议 有限 支持(沙箱) 私有 代码生成、文档

CopilotKit 是 AG-UI 的原生实现者,也是目前功能最完整的原生实现之一。Vercel AI SDK 的流式事件处理相当成熟,状态管理通过 useChatuseCompletion 等内置 hooks 提供,但不遵循 AG-UI 协议规范。

LangGraph 的 Agent 编排能力突出,前端通信层通过 LangServe 提供 SSE 流式输出,事件格式为自定义格式,不少 LangGraph 项目会在前端侧补充 AG-UI 适配层以统一交互体验。


常见陷阱

协议本身不复杂,但把它做成产品时,有几个反复出现的坑。

聊天界面是唯一界面

这是最普遍的错误。Agent 不只是"会回答问题的聊天机器人",它还执行任务、调用工具、操作文件、运行代码。把这些活动全都塞进一个聊天窗口,用户在长对话中会完全迷失。解决方案很简单:把 ACTIVITY_* 事件渲染到独立面板,让用户同时看到"Agent 说了什么"和"Agent 做了什么"。

全有或全无的自主性

很多 Agent 应用二元地选择了"要么全自动、要么全手动"。前者让用户失去安全感,后者让用户交互成本过高。AG-UI 的 TOOL_CALL_* 事件序列天然支持分级审批,可以按工具类型、操作对象、风险等级灵活配置审批策略------读操作自动放行,写操作请求确认,高危操作需要双重验证。

把 LLM 当内存用

Atlan 引述的 MemU 研究显示,65% 的企业 AI Agent 失败案例与上下文漂移有关(Atlan《AI Agent Harness Failures: 13 Anti-Patterns》,2026 年 6 月)。AG-UI 的 STATE_* 事件提供了标准化的状态管理方案,把 Agent 状态从前后端各自的"约定"中解放出来,交给协议层统一管理。

通用错误状态

Agent 应用容易出错:LLM 输出不稳定、工具调用超时、权限不足。大多数应用用一个笼统的"出错了"来应付。AG-UI 的 RUN_ERROR 事件结构要求携带错误码和错误信息,前端据此渲染不同的错误界面:

•网络错误显示重试按钮•权限错误显示联系管理员按钮•LLM 输出错误显示重新生成按钮

这个"什么、为什么、怎么办"的结构,在 Zylos 的研究中能提升任务完成率。


局限性与风险

在看到 AG-UI 价值的同时,有必要坦诚地讨论它目前的局限和潜在风险。这些问题不是为了否定协议的意义,而是让开发者在做技术选型时对代价有清晰预期。

协议仍在快速演进

AG-UI 2025 年 5 月才开源,到 2026 年中不过一年多时间。规范版本仍在迭代中,事件类型的增删、字段的调整时有发生。对于需要长期稳定 API 的企业级应用,这意味着升级成本需要纳入评估------不像 HTTP 或 WebSocket 那样有几十年的稳定历史,AG-UI 还处于快速成长期。

真实生产采用率不透明

GitHub 的 15k stars 反映了开发者关注度,但关注度不等于生产使用率。目前缺乏权威的生产环境采用率数据------有多少团队只是在 side project 里试了试,又有多少是核心业务线上跑着 AG-UI?各大云厂商的集成公告更多是战略布局信号,不是实际使用量的证明。做技术选型时,不能把"明星项目"等同于"成熟基础设施"。

治理结构单一

AG-UI 由 CopilotKit 团队主导开发和维护,这既是优势(决策效率高)也是风险(单点依赖)。相比之下,MCP 已由 Anthropic 捐赠给 Agentic AI 基金会,A2A 已由 Google 捐赠给 Linux 基金会,两者都有中立的治理实体。AG-UI 目前还没有类似的中立治理安排,如果 CopilotKit 团队的方向发生变化,协议的演进路线可能受到影响。

对简单场景可能过度设计

对于一个只需要文本流式输出的简单聊天机器人,AG-UI 的 20 多种事件类型、状态管理、活动日志等能力可能超出了实际需要。协议的通用性越强,简单场景下的接入成本就越高。团队需要评估:你的应用真的需要完整的事件模型吗?还是说一个自定义的 SSE 流就足够了?

传输无关性的实践边界

协议声称"传输无关",但目前主流实现几乎都基于 SSE。WebSocket 和 webhook 支持在理论上存在,但生态工具链、调试工具、最佳实践大多围绕 SSE 展开。如果你的应用架构需要 WebSocket 双向通信,可能会发现可用的参考实现和社区资源少很多。


趋势与展望

AG-UI 的采纳速度很快。2025 年 5 月它还只是 CopilotKit 团队的一个开源项目,到 2026 年中,Oracle、Microsoft、AWS、Google 四大云厂商都以不同方式集成了它。OpenAI 已宣布将于 2026 年 8 月 26 日关闭 Assistants API(2025 年 8 月公告),这进一步推动了社区向标准化协议迁移。

协议标准化的趋势正在明确。MCP 标准化了工具调用,A2A 标准化了 Agent 间通信,AG-UI 标准化了人机界面交互------三套协议覆盖了 Agent 系统的三个核心通信维度。对于正在构建 AI 应用的前端开发者来说,如果你的项目涉及 Agent 后端与前端的流式交互,了解 AG-UI 的设计思路是值得的------它不一定是最终答案,但代表了当前社区对这个问题最成熟的思考方向。


参考来源

  • AG-UI Protocol Documentation: docs.ag-ui.com
  • AG-UI GitHub Repository: github.com/ag-ui-proto...
  • "Software as Content": arXiv:2603.21334v1 (March 2026)
  • "A Survey of Agent Interoperability Protocols": arXiv:2505.02279v1 (May 2025)
  • Google: "Developer's Guide to AI Agent Protocols": developers.googleblog.com (March 18, 2026)
  • MindStudio: "MCP vs A2A vs AGUI": mindstudio.ai (May 20, 2026)
  • Codecademy: "AG-UI: How the Agent-User Interaction Protocol Works" (2026)
  • Zylos: "Agentic UX: Frontend Design Patterns for AI Agents in 2026" (May 28, 2026)
  • Atlan: "AI Agent Harness Failures: 13 Anti-Patterns" (June 10, 2026)
  • 掘金: "AI Agent 进入协议时代:MCP、A2A、AG-UI 三大协议全景解析"
相关推荐
文心快码BaiduComate1 小时前
不限额度!「文心快码测试版」限免体验来了
agent·ai编程·文心快码
人生百态,人生如梦1 小时前
每日论文解读 (8.3) 1——DeepResearch Agent System:稀疏激活架构驱动的自主深度研究Agent
架构·llm·agent·deepresearch
小白学大数据1 小时前
把 Modbus 轮询塞进 Trio 的异步循环:内存映射与定时采集实战
网络·python·搜索引擎
程序员黑豆2 小时前
鸿蒙应用开发 @Extend 装饰器使用教程
前端·harmonyos
FriendshipT2 小时前
Ubuntu 20.04 下使用 Ollama 本地部署 AI 大模型
linux·人工智能·python·深度学习·ubuntu
杨先生哦2 小时前
【2026热端攻防系列 10/12】前端凭据安全深度攻防:Cookie/Storage劫持、会话固定、凭据泄露与浏览器最新加固方案
前端·笔记·安全·web安全
莫石2 小时前
坦克打无人机模拟(three-tile 地形)
前端
天天爱吃肉82182 小时前
# 商用车多体动力学实战笔记|第7篇:制动系统与制动热衰退、ABS滞环控制
大数据·人工智能·笔记·python·嵌入式硬件·汽车
牧艺2 小时前
别让 Agent 猜需求:前端用「一页 Spec」把返工砍掉一半
人工智能·agent·vibecoding