DeepAgents 学习

前言

Deep Agents 复杂智能体开发框架,langchain公司下现在排名第一的项目。

想象一下,你要做一个 AI 助手,通常需要自己组装很多零件:prompt、工具、上下文管理等等。但 Deep Agents 帮你把这些都准备好了,你只需要少量的步骤,就能得到一个功能强大的 AI Agent。

并非颠覆性的技术创新,而是将业界验证过的最佳实践打包成开箱即用的框架,灵感来源于Claude code/ Deep Search/Manus等应用,这些应用验证了三个关键点:

Agent关键点

1、Agent需要规划能力

不能上来就开干,要先分解任务;

2、Agent需要文件系统

长对话中,中间结果需要有存放的地方;

3、Agent需要子Agent协作

单体Agent会被上下文撑爆;

所以"深度 Agent"可以做更多:

  • 规划 - 使用 write_todos 工具来分解任务、跟踪进度
  • 文件系统访问 - 读取、写入、编辑文件,搜索代码
  • Shell 执行 - 运行命令(带沙箱隔离)
  • 子 Agent - 使用 task 工具委托工作给专门的子 Agent
  • 智能默认 - 内置的 prompt 教模型如何有效使用这些工具
  • 上下文管理 - 自动摘要长对话,大输出保存到文件

DeepAgents项目框架

deepagents/

├── libs/

│ ├── deepagents/ # 核心 SDK(Python)

│ ├── cli/ # 命令行工具

│ ├── acp/ # Agent Context Protocol 支持

│ ├── evals/ # 评估套件

│ └── partners/ # 第三方集成

├── examples/ # 示例项目

└── .github/ # CI/CD 配置

核心组件详解

Deep Agents SDK (libs/deepagents/)这是整个项目的心脏。它是一个 Python 包,提供了创建"深度 Agent"的所有能力。

SDK 的代码结构:

deepagents/

├── graph.py # 创建 Agent 的主入口 (create_deep_agent)

├── _models.py # 模型解析 (resolve_model, get_default_model)

├── base_prompt.md # 基础提示词模板

├── middleware/ # 中间件(核心逻辑)

│ ├── init.py # 导出和中间件工厂函数

│ ├── _utils.py # 工具函数

│ ├── filesystem.py # 文件系统工具 (ls, read, write, edit, glob, grep)

│ ├── memory.py # 记忆系统 (AGENTS.md)

│ ├── skills.py # 技能系统 (SKILL.md)

│ ├── subagents.py # 同步子 Agent 管理

│ ├── async_subagents.py # 异步子 Agent 管理

│ ├── summarization.py # 上下文摘要(长对话压缩)

│ └── patch_tool_calls.py # 工具调用修补

└── backends/ # 后端实现

├── init.py # 导出和后端工厂

├── protocol.py # 协议定义 (BackendProtocol, SandboxBackendProtocol)

├── state.py # 内存状态后端

├── filesystem.py # 真实文件系统后端

├── sandbox.py # 沙箱执行后端 (支持 execute 命令)

├── local_shell.py # 本地 Shell 后端

├── composite.py # 组合后端

├── langsmith.py # LangSmith 后端

├── store.py # 持久化存储后端

└── utils.py # 后端工具函数

核心文件说明

|-----------------------------|--------------------------|
| 文件 | 作用 |
| graph.py | create_deep_agent() 入口函数 |
| middleware/filesystem.py | 提供文件操作和执行命令工具 |
| middleware/subagents.py | 提供 task 工具调用子代理 |
| middleware/summarization.py | 自动压缩长对话 |
| backends/protocol.py | 定义后端接口规范 |
| backends/sandbox.py | 远程沙箱执行环境 |

核心入口:create_deep_agent

所有 Magic 从 create_deep_agent 函数开始。打开 graph.py,我们来看这个核心函数。

python 复制代码
def create_deep_agent(
    model: str | BaseChatModel | None = None,
    tools: Sequence[BaseTool | Callable | dict[str, Any]] | None = None,
    *,
    system_prompt: str | SystemMessage | None = None,
    middleware: Sequence[AgentMiddleware] = (),
    subagents: Sequence[SubAgent | CompiledSubAgent | AsyncSubAgent] | None = None,
    skills: list[str] | None = None,
    memory: list[str] | None = None,
    response_format: ResponseFormat | None = None,
    context_schema: type[Any] | None = None,
    checkpointer: Checkpointer | None = None,
    store: BaseStore | None = None,
    backend: BackendProtocol | BackendFactory | None = None,
    interrupt_on: dict[str, bool | InterruptOnConfig] | None = None,
    debug: bool = False,
    name: str | None = None,
    cache: BaseCache | None = None,
) -> CompiledStateGraph:

这个函数接受很多参数,但不要被吓到------它们都有合理的默认值。

参数详解
backend

决定了智能体如何执行 lsread_filewrite_file等文件操作,以及这些数据的存储位置和生命周期

基础系统提示

Deep Agents 有一个精心设计的基础系统提示,定义了 Agent 的核心行为:

python 复制代码
BASE_AGENT_PROMPT = """你是一个 Deep Agent,一个使用工具帮助用户完成任务的 AI 助手。你通过文本和工具调用来回复。用户可以实时看到你的回复和工具输出。

## 核心行为规范

- 简洁直接。除非被要求,否则不要过度解释。
- 永远不要添加不必要的开场白(如 "好的!"、"好问题!"、"我现在...")。
- 不要说 "我现在来做 X" --- 直接去做。
- 如果请求不明确,在行动前先提问。
- 如果被问及如何处理某事,先解释再行动。

## 专业客观

- 重视准确性而非验证用户的信念
- 当用户错误时礼貌地不同意
- 避免不必要的夸张、赞美或情感认同

## 执行任务

当用户让你做某事时:

1. **先理解** --- 阅读相关文件,检查现有模式。
2. **行动** --- 实现解决方案。
3. **验证** --- 检查你的工作是否符合要求。

持续工作直到任务完全完成。不要中途停止。"""

这个提示定义了 Agent 的行为准则

  • 简洁直接
  • 不说废话
  • 先理解再行动
  • 验证自己的工作
中间件系统

Deep Agents 里最核心的设计;

1. 什么是中间件?

想象一下:你和 LLM 之间有一个"关卡",每次你发送消息给 LLM,或者收到 LLM 的响应时,都会经过这个关卡。

中间件就是这个关卡上的"拦截器"。

它可以在:

  • 消息发送给 LLM 之前拦截并修改
  • LLM 响应回来 之后拦截并处理
  • 工具被调用 之前/之后做额外处理
2. 为什么需要中间件?

普通的工具函数只能在 LLM 调用时被触发。但中间件可以在 LLM 调用之前拦截请求,做很多事情:

  • 动态过滤工具 - 比如 FilesystemMiddleware 根据后端类型决定是否暴露 execute 工具
  • 注入系统提示 - 比如 MemoryMiddleware 和 SkillsMiddleware 在每次调用时注入相关指令
  • 转换消息 - 比如 SummarizationMiddleware 统计 token 数、截断旧内容、用摘要替换历史
  • 维护跨轮状态 - 中间件可以读写跨 Agent 轮次持久化的状态字典
3. Deep Agents 的中间件架构

所有中间件都继承自 AgentMiddleware

python 复制代码
class AgentMiddleware(Generic[ContextT, ModelRequest, ModelResponse, ResponseT]):
    def wrap_model_request(self, request: ModelRequest) -> ModelRequest:
        """在请求发送给 LLM 之前调用"""
        return request

    def wrap_model_response(self, response: ModelResponse) -> ModelResponse:
        """在收到 LLM 响应后调用"""
        return response

    def wrap_tool_calls(self, tool_calls: list[ToolCallRequest]) -> list[ToolCallRequest]:
        """在工具调用执行前调用"""
        return tool_calls

    def wrap_tool_result(self, tool_name: str, result: Any) -> Any:
        """在工具执行后调用"""
        return result

AgentMiddleware 提供了多个钩子:

4. 中间件栈的构建

这是整个函数最复杂的部分。中间件的执行顺序非常关键。

++4.1 主Agent的中间件栈:++

python 复制代码
主 Agent:
1. TodoListMiddleware        # 任务规划
2. SkillsMiddleware          # 技能系统(如果启用)
3. FilesystemMiddleware      # 文件操作
4. SubAgentMiddleware        # 子 Agent
5. SummarizationMiddleware   # 上下文摘要
6. PatchToolCallsMiddleware  # 工具调用修补
7. AnthropicPromptCachingMiddleware # 提示缓存
8. MemoryMiddleware          # 记忆系统(如果启用)
9. HumanInTheLoopMiddleware  # 人在环中(如果启用)
python 复制代码
deepagent_middleware: list[AgentMiddleware[Any, Any, Any]] = [
    TodoListMiddleware(),
]

if skills is not None:
    deepagent_middleware.append(SkillsMiddleware(backend=backend, sources=skills))

deepagent_middleware.extend([
    FilesystemMiddleware(backend=backend),
    SubAgentMiddleware(backend=backend, subagents=inline_subagents),
    create_summarization_middleware(model, backend),
    PatchToolCallsMiddleware(),
])

if async_subagents:
    deepagent_middleware.append(AsyncSubAgentMiddleware(async_subagents=async_subagents))

if middleware:
    deepagent_middleware.extend(middleware)

# 缓存和记忆放在最后
# 原因:记忆更新不应该使 Anthropic 提示缓存前缀失效
deepagent_middleware.append(AnthropicPromptCachingMiddleware(...))
if memory is not None:
    deepagent_middleware.append(MemoryMiddleware(backend=backend, sources=memory))
if interrupt_on is not None:
    deepagent_middleware.append(HumanInTheLoopMiddleware(interrupt_on=interrupt_on))

++4.2 通用子 Agent 的中间件栈++

python 复制代码
gp_middleware: list[AgentMiddleware[Any, Any, Any]] = [
    TodoListMiddleware(),           # 任务规划
    FilesystemMiddleware(backend=backend),  # 文件系统
    create_summarization_middleware(model, backend),  # 摘要
    PatchToolCallsMiddleware(),    # 工具调用修补
]

if skills is not None:
    gp_middleware.append(SkillsMiddleware(backend=backend, sources=skills))

gp_middleware.append(AnthropicPromptCachingMiddleware(...))

if interrupt_on is not None:
    gp_middleware.append(HumanInTheLoopMiddleware(interrupt_on=interrupt_on))

中间件详解

1. TodoListMiddleware

功能:提供任务规划能力

提供的工具

  • write_todos - 创建、更新、删除待办事项

工作原理

  • 维护一个待办事项列表在 Agent 状态中
  • 每次 LLM 调用时,将待办事项注入系统提示
  • 工具调用后更新状态

注入到系统提示词的内容(动态生成):

python 复制代码
## 待办事项

你的当前待办列表:
- [ ] 阅读现有代码库
- [ ] 实现新功能
- [ ] 编写测试

使用 `write_todos` 工具更新你的待办列表.

每次 LLM 调用时,会将当前待办事项列表格式化后注入到系统提示中,让 Agent 随时了解任务进度。

2. FilesystemMiddleware

**功能:**提供文件系统操作能力

提供的工具:

  • ls - 列出目录
  • read_file - 读取文件
  • write_file - 写入文件
  • edit_file - 编辑文件
  • glob - 文件名匹配
  • grep - 文本搜索
  • execute - 执行命令(需要沙箱后端)

工作原理:

  1. 根据后端类型动态决定提供哪些工具
  2. 使用后端协议与实际存储交互
  3. 处理文件路径验证、权限检查

大结果驱逐机制

当工具返回结果过大时(超过 20000 token),自动将结果写入文件系统

注入到系统提示词的内容

python 复制代码
## 遵循惯例

- 编辑前先阅读文件 --- 在做出更改之前了解现有内容
- 模仿现有的风格、命名约定和模式

## 文件系统工具 `ls`, `read_file`, `write_file`, `edit_file`, `glob`, `grep`

你可以使用这些工具与文件系统交互。所有文件路径必须以 / 开头。

- ls: 列出目录中的文件(需要绝对路径)
- read_file: 从文件系统读取文件
- write_file: 向文件系统写入文件
- edit_file: 编辑文件系统中的文件
- glob: 查找匹配模式的文件(如 "**/*.py")
- grep: 在文件中搜索文本

## 大型工具结果

当工具结果太大时,可能会被卸载到文件系统而不是内联返回。在这种情况下,使用 `read_file` 分块检查保存的结果,或在 `/large_tool_results/` 中使用 `grep`。

当后端支持执行时额外注入

python 复制代码
## 执行工具 `execute`

你有一个 `execute` 工具用于在沙箱环境中运行 shell 命令。
使用此工具运行命令、脚本、测试、构建和其他 shell 操作。

3. SubAgentMiddleware

功能:提供子 Agent 委托能力

提供的工具

  • task - 调用子 Agent

工作原理

  • 在系统提示中注入可用子 Agent 的描述
  • 拦截 task 工具调用
  • 创建并运行子 Agent
  • 将结果作为 ToolMessage 返回给主 Agent

注入到系统提示词的内容

python 复制代码
## `task`(子代理生成器)

你有一个 `task` 工具来启动处理独立任务的短生命周期子代理。这些代理是临时的------它们只存在于任务期间并返回单个结果。

何时使用 task 工具:
- 当任务复杂且多步骤,可以完全独立委托时
- 当任务独立于其他任务,可以并行运行时
- 当任务需要集中推理或大量 token/上下文使用时

子代理生命周期:
1. 生成 → 提供清晰的角色、指令和预期输出
2. 运行 → 子代理自主完成任务
3. 返回 → 子代理提供单个结构化结果
4. 调和 → 将结果合并到主线程

可用子代理类型:
- general-purpose: 用于研究复杂问题的通用代理
- researcher: 用于搜索和收集信息的研究代理

4. SummarizationMiddleware

功能:管理长上下文

工作原理

  • 跟踪对话的 token 数量
  • 当接近上下文窗口限制时:
    1. 调用 LLM 生成历史摘要
    2. 用摘要替换原始历史
    3. 继续处理当前请求

触发阈值:默认 80% 上下文使用率

注入到系统提示词的内容

python 复制代码
## 压缩对话工具 `compact_conversation`

你有一个 `compact_conversation` 工具。这个工具刷新你的上下文窗口以减少上下文膨胀和成本。

你应该何时使用这个工具:
- 当用户要求完全转向新任务,且之前的上下文可能无关时
- 当你已完成结果提取或综合,且之前的上下文不再需要时

5. SkillsMiddleware

功能:提供技能系统

工作原理

  • 扫描指定目录查找 SKILL.md 文件
  • 解析 YAML frontmatter 获取技能元数据
  • 在系统提示中注入可用技能列表(渐进式披露)
  • 按需读取完整技能内容

注入到系统提示词的内容

python 复制代码
## 技能系统

你有一个技能库,提供专业能力和领域知识。

**技能位置**:
- **用户技能**: `/skills/user/`
- **项目技能**: `/skills/project/`(更高优先级)

**可用技能**:
- **web-research**: 进行深入网络研究的结构化方法
  -> 可用工具: search, fetch
  -> 阅读 `/skills/user/web-research/SKILL.md` 获取完整说明

**如何使用技能(渐进式披露)**:
1. 识别技能何时适用:检查用户任务是否匹配技能描述
2. 阅读技能的完整说明:使用上面技能列表中的路径
3. 按照技能的说明执行:SKILL.md 包含分步工作流、最佳实践和示例
4. 访问支持文件:技能可能包含辅助脚本、配置或参考文档

技能元数据结构

python 复制代码
class SkillMetadata(TypedDict):
    path: str           # SKILL.md 文件路径
    name: str           # 技能名称(1-64 字符)
    description: str    # 技能描述(1-1024 字符)
    license: str | None
    compatibility: str | None
    metadata: dict[str, str]
    allowed_tools: list[str]

6. MemoryMiddleware

功能:提供持久记忆

工作原理

  • 加载 AGENTS.md 文件
  • 在系统提示中注入记忆内容
  • 每次请求时自动包含

注入到系统提示词的内容

python 复制代码
<agent_memory>
~/.deepagents/AGENTS.md
# 项目指南

- 所有新代码使用 TypeScript
- 遵循 src/ 中的现有代码风格
- 提交前运行测试

./project/AGENTS.md
# Agent 上下文

这是一个使用 Next.js 14 的 React 项目。
API 路由在 src/app/api/ 中
</agent_memory>

<memory_guidelines>
上面的 <agent_memory> 是从文件系统中的文件加载的。当你在与用户的交互中学习时,你可以通过调用 `edit_file` 工具保存新知识。

**从反馈中学习:**
- 你最主要的任务之一是从与用户的交互中学习。
- 当你需要记住某些东西时,更新记忆必须是你的第一个、立即的行动。
- 当用户说某些东西更好/更差时,捕获原因并将其编码为模式。

**何时更新记忆:**
- 当用户明确要求你记住某些东西时
- 当用户描述你的角色或你应该如何行为时
- 当用户对你的工作提供反馈时
- 当用户提供工具使用所需的信息时

**何时不更新记忆:**
- 当信息是临时的或短暂的时
- 当信息是一次性任务请求时
- 永远不要在任何文件或记忆中存储 API 密钥、访问令牌、密码
</memory_guidelines>

7. PatchToolCallsMiddleware

功能:修补工具调用

工作原理

  • 规范化工具参数
  • 处理参数类型转换
  • 添加默认参数值

是否修改系统提示词:否(该中间件只处理工具调用参数,不涉及提示词注入)

8. AnthropicPromptCachingMiddleware

**功能:**优化 Anthropic 模型的提示缓存

工作原理:

  • 检测静态内容(系统提示、工具定义)
  • 使用 Anthropic 的提示缓存 API
  • 减少重复传输的 token

是否修改系统提示词:否(该中间件使用 API 层面的缓存机制,不修改提示词内容)

9. HumanInTheLoopMiddleware

功能:人在环中审批

工作原理:

  • 配置哪些工具需要审批
  • 执行前暂停 Agent
  • 等待人类批准或修改
  • 继续执行或拒绝

是否修改系统提示词:否(该中间件在运行时拦截工具调用,不修改提示词)

10. AsyncSubAgentMiddleware

**功能:**提供异步子 Agent(远程 LangGraph 服务器)

工作原理:

  • 在远程 LangGraph 服务器上启动后台任务
  • 提供异步任务管理工具
  • 支持任务状态检查、更新、取消

提供的工具:

  • start_async_task - 启动后台任务
  • check_async_task - 检查任务状态
  • update_async_task - 更新任务指令
  • cancel_async_task - 取消任务
  • list_async_tasks - 列出所有任务

注入到系统提示词的内容:

python 复制代码
## 异步子代理(远程 LangGraph 服务器)

你有一个异步子代理工具,可以在远程 LangGraph 服务器上启动后台任务。

#### 工具:
- `start_async_task`: 启动新的后台任务。立即返回任务 ID。
- `check_async_task`: 获取任务的当前状态和结果。
- `update_async_task`: 向正在运行的任务发送新指令。
- `cancel_async_task`: 停止正在运行的任务。
- `list_async_tasks`: 列出所有跟踪的任务及其实时状态。

#### 关键规则:
- 启动后,始终立即将控制权返回给用户。启动后永远不要自动检查。
- 永远不要循环轮询 `check_async_task`。
- 对话历史中的任务状态始终是过时的------始终调用工具获取当前状态。

可用异步子代理类型:
- my-agent: 异步子代理的描述

最终系统提示词结构

python 复制代码
[用户自定义 system_prompt]

你是一个 Deep Agent,一个使用工具帮助用户完成任务的 AI 助手。用户可以实时看到你的回复和工具输出...

## 核心行为规范
- 简洁直接。除非被要求,否则不要过度解释。
- 永远不要添加不必要的开场白(如 "好的!"、"好问题!"、"我现在...")。
- 如果请求不明确,在行动前先提问。
- 如果被问及如何处理某事,先解释再行动。

## 专业客观
- 重视准确性而非验证用户的信念
- 当用户错误时礼貌地不同意
- 避免不必要的夸张、赞美或情感认同

## 执行任务
当用户让你做某事时...

## 待办事项
你的当前待办列表:
- [ ] 任务 1
- [ ] 任务 2

使用 `write_todos` 工具更新你的待办列表。

## 技能系统
你有一个技能库,提供专业能力和领域知识。

**技能位置**:
- **用户技能**: `/skills/user/`
- **项目技能**: `/skills/project/`(更高优先级)

**可用技能**:
- **web-research**: 进行深入网络研究的结构化方法
  -> 可用工具: search, fetch
  -> 阅读 `/skills/user/web-research/SKILL.md` 获取完整说明

**如何使用技能(渐进式披露)**:
1. 识别技能何时适用:检查用户任务是否匹配技能描述
2. 阅读技能的完整说明:使用上面技能列表中的路径
3. 按照技能的说明执行:SKILL.md 包含分步工作流、最佳实践和示例
4. 访问支持文件:技能可能包含辅助脚本、配置或参考文档

## 遵循惯例
- 编辑前先阅读文件 --- 在做出更改之前了解现有内容
- 模仿现有的风格、命名约定和模式

## 文件系统工具 `ls`, `read_file`, `write_file`, `edit_file`, `glob`, `grep`
你可以使用这些工具与文件系统交互。所有文件路径必须以 / 开头。
- ls: 列出目录中的文件(需要绝对路径)
- read_file: 从文件系统读取文件
- write_file: 向文件系统写入文件
- edit_file: 编辑文件系统中的文件
- glob: 查找匹配模式的文件(如 "**/*.py")
- grep: 在文件中搜索文本

## 大型工具结果
当工具结果太大时,可能会被卸载到文件系统而不是内联返回。在这种情况下,使用 `read_file` 分块检查保存的结果,或在 `/large_tool_results/` 中使用 `grep`。

## `task`(子代理生成器)
你有一个 `task` 工具来启动处理独立任务的短生命周期子代理。这些代理是临时的------它们只存在于任务期间并返回单个结果。

何时使用 task 工具:
- 当任务复杂且多步骤,可以完全独立委托时
- 当任务独立于其他任务,可以并行运行时
- 当任务需要集中推理或大量 token/上下文使用时

子代理生命周期:
1. 生成 → 提供清晰的角色、指令和预期输出
2. 运行 → 子代理自主完成任务
3. 返回 → 子代理提供单个结构化结果
4. 调和 → 将结果合并到主线程

可用子代理类型:
- general-purpose: 用于研究复杂问题的通用代理

## 压缩对话工具 `compact_conversation`
你有一个 `compact_conversation` 工具。这个工具刷新你的上下文窗口以减少上下文膨胀和成本。

你应该何时使用这个工具:
- 当用户要求完全转向新任务,且之前的上下文可能无关时
- 当你已完成结果提取或综合,且之前的上下文不再需要时

<agent_memory>
[memory 内容]
</agent_memory>

<memory_guidelines>
上面的 <agent_memory> 是从文件系统中的文件加载的。当你在与用户的交互中学习时,你可以通过调用 `edit_file` 工具保存新知识。

**从反馈中学习:**
- 你最主要的任务之一是从与用户的交互中学习。
- 当你需要记住某些东西时,更新记忆必须是你的第一个、立即的行动。
- 当用户说某些东西更好/更差时,捕获原因并将其编码为模式。

**何时更新记忆:**
- 当用户明确要求你记住某些东西时
- 当用户描述你的角色或你应该如何行为时
- 当用户对你的工作提供反馈时
- 当用户提供工具使用所需的信息时

**何时不更新记忆:**
- 当信息是临时的或短暂的时
- 当信息是一次性任务请求时
- 永远不要在任何文件或记忆中存储 API 密钥、访问令牌、密码
</memory_guidelines>

提示词组装顺序

  1. 用户自定义 system_prompt(如有)
  2. BASE_AGENT_PROMPT - Deep Agent 核心行为规范
  3. TodoListMiddleware - 待办事项(动态)
  4. SkillsMiddleware - 技能系统(如果有 skills 配置)
  5. FilesystemMiddleware - 文件系统工具说明
  6. SubAgentMiddleware - 子 Agent 工具说明
  7. SummarizationMiddleware - 上下文压缩工具
  8. AnthropicPromptCachingMiddleware - 缓存标记(API 层面)
  9. MemoryMiddleware - 记忆内容(如果有 memory 配置)

每个中间件通过 modify_requestwrap_model_call 方法将内容追加到系统消息末尾。

默认工具

创建 Deep Agent 时,你不需要手动添加任何工具------以下工具默认可用:

1. 任务规划
  • write_todos - 管理待办事项列表
2. 文件操作

ls - 列出目录内容

read_file - 读取文件

write_file - 写入文件

edit_file - 编辑文件

glob - 文件名模式匹配

grep - 文本搜索

3. Shell 执行

execute - 运行 Shell 命令(需要支持沙箱的后端)

4. 子 Agent

task - 调用子 Agent

参考:

https://blog.csdn.net/qq_44193969/article/details/159503998?sharetype=blog&shareId=159503998&sharerefer=APP&sharesource=weixin_37545216&sharefrom=link

相关推荐
好好研究2 小时前
Java基础学习(十三):IO流基础
java·开发语言·学习·io流
知识分享小能手2 小时前
R语言入门学习教程,从入门到精通,R语言传统绘图系统 - 完整知识点与案例代码(2)
开发语言·学习·r语言
嵌入式×边缘AI:打怪升级日志2 小时前
从零开始学习 Linux SPI 驱动开发(基于 IMX6ULL + TLC5615 DAC)
linux·驱动开发·学习
时空自由民.2 小时前
嵌入式学习-构建系统(图形化IDE/Kconfig/手动makefile Cmake)
数据库·ide·单片机·学习
2301_780943842 小时前
第二阶段:Gem5基础学习
学习
我想我不够好。2 小时前
坚持到习惯为止
学习·学习方法
三品吉他手会点灯3 小时前
STM32F103 学习笔记-21-串口通信(第4节)—串口发送和接收代码讲解(下)
笔记·stm32·单片机·嵌入式硬件·学习
U盘失踪了3 小时前
学习记录:requests Django登录测试脚本(解决CSRF、重定向问题)
笔记·python·学习·django·csrf
minglie13 小时前
人的性质辨析
学习