AI-Browser:为AI智能体构建可编程浏览器操作环境的开源框架

news2026/5/3 7:23:29
1. 项目概述与核心价值最近在折腾一个挺有意思的开源项目叫“AI-Browser”。光看名字你可能觉得这又是一个把大语言模型LLM和浏览器简单绑定的玩具。但当我深入研究了 Jun-Murakami/AI-Browser 这个仓库后发现它的设计思路和实现细节远比想象中要扎实和实用。它本质上是一个为AI智能体Agent提供稳定、可编程、可观察的浏览器操作环境的框架。简单来说它让AI拥有了一个“手”和“眼睛”可以像真人一样去浏览网页、点击按钮、填写表单、提取信息并且整个过程是可控、可调试的。为什么这很重要在AI应用开发中让模型与真实世界交互一直是个难题。网页是现代信息和服务的主要载体但让AI直接操作浏览器面临着稳定性差页面加载时间不确定、状态难以追踪DOM结构动态变化、操作反馈不明确点击成功与否等一系列挑战。AI-Browser 正是为了解决这些问题而生。它通过一套精心设计的API和状态管理机制将杂乱的浏览器操作抽象成清晰的指令和事件让开发者能够专注于构建AI的逻辑而不是在如何稳定地点击一个按钮上耗费精力。这个项目非常适合两类人一是正在构建需要与网页交互的AI智能体的开发者比如自动化客服、数据抓取Agent、网页测试机器人等二是对AI Agent技术感兴趣想通过一个具体、可运行的项目来理解智能体如何感知和操作环境的学习者。接下来我将从设计思路、核心实现、实操部署到避坑经验为你完整拆解这个项目。2. 项目整体设计与架构拆解2.1 核心设计哲学将浏览器视为确定性环境很多自动化工具如Selenium, Puppeteer把浏览器当作一个“黑盒”来驱动发送点击指令然后等待页面变化。这种方式对人类脚本是可行的但对AI来说信息不足。AI需要明确知道1当前环境状态是什么2我执行了动作后环境变成了什么3我的动作成功了吗AI-Browser 的核心设计哲学是将非确定性的浏览器环境通过封装和状态管理变成一个对AI而言相对确定和可观察的环境。它主要做了以下几层抽象状态抽象层不仅仅返回网页的HTML源码而是提供结构化的页面描述。这可能包括关键元素的定位、可交互组件的列表按钮、输入框、链接、页面的大致语义摘要等。这样AI接收到的不是一堆杂乱标签而是已经过初步处理的“环境观察值”。动作抽象层将底层浏览器操作如element.click()封装成高级、语义化的指令比如click(button_id‘submit’)或type(input_id‘search’, text‘hello’)。同时框架会负责执行这些指令并捕获执行结果成功、失败、超时以及执行后环境的状态变化。反馈与奖励机制为AI的每一步操作提供明确的反馈。例如点击后页面是否跳转输入后是否有错误提示出现这相当于给AI提供了强化学习中的“奖励信号”使其能评估自己动作的有效性。这种设计使得AI Agent的决策循环Observe - Think - Act能够清晰、稳定地运行在浏览器这个复杂环境之上。2.2 技术栈与架构选型分析浏览项目代码可以看到其技术栈的选择非常务实旨在平衡功能、性能和易用性。后端/驱动层几乎可以肯定基于Playwright或Puppeteer。这两个是现代浏览器自动化的主流选择支持无头模式、跨浏览器Chromium, Firefox, WebKit并且提供了强大的API来控制网络、拦截请求、模拟设备等。从项目名和趋势看使用Playwright的可能性更大因为它对异步操作的支持更好且自带智能等待等高级特性更适合AI这种需要处理不确定延迟的场景。AI集成层这是项目的灵魂。它需要将页面状态转化为AI能理解的提示词Prompt并将AI输出的自然语言指令解析成具体的浏览器操作。这里通常会用到LangChain或LlamaIndex这类AI应用框架来构建链Chain或者直接使用大模型提供的Function Calling函数调用能力。项目很可能定义了一套标准的“工具”Tools如navigate_to_url,extract_text,click_element然后让AI模型来调用这些工具。状态管理与观察器一个独立的模块持续监控浏览器页面的DOM变化、网络请求、控制台日志等。它负责生成“状态快照”这个快照不会包含整个DOM那太庞大而是经过筛选和摘要的信息比如“页面标题是‘登录’发现一个ID为‘username’的输入框一个ID为‘password’的密码框和一个文本为‘登录’的按钮。”控制中枢Agent Core协调以上所有模块。它接收观察器的状态调用AI模型进行决策将AI输出的指令解析并分发给浏览器驱动执行然后等待下一次状态更新形成闭环。这种架构的优势在于模块间解耦良好。你可以更换不同的AI模型GPT-4, Claude, 本地模型也可以调整状态观察的粒度而不会影响核心的控制流程。3. 核心模块深度解析与实操要点3.1 环境状态观察器AI的“眼睛”这是决定AI感知能力的关键。一个糟糕的观察器会让AI“看”不到关键信息从而做出错误决策。核心实现思路观察器不会傻傻地每次都抓取全部document.body.innerHTML。这样做数据量大、噪声多且很多内容如脚本、样式对AI决策无用。通常的策略是关键元素提取使用选择器CSS Selector 或 XPath聚焦于可交互和内容型元素。例如提取所有button,input,a,[role“button”]以及具有大量文本的div,p,span。元素属性摘要对于每个提取的元素收集对其决策至关重要的属性可交互元素id,name,type(对于input),value,placeholder,aria-label, 以及可见的文本内容innerText。内容元素id,className, 以及文本内容的摘要如前200个字符。页面结构扁平化与序列化将提取的元素列表整理成一个结构化的文本描述或者更高级的一种树状或图状的表示。简单的实现可能就是一个格式化字符串页面状态 - 标题 “示例登录页” - 可交互元素 1. [INPUT] id“username”, placeholder“请输入用户名” 2. [INPUT] id“password”, type“password”, placeholder“请输入密码” 3. [BUTTON] id“login-btn”, text“登录” - 主要内容区域 - 文本“欢迎回来请登录您的账户。”实操要点与避坑指南注意动态内容加载。现代网页大量使用JavaScript动态加载内容。观察器必须在每次“观察”前确保页面已经到达一个“稳定状态”。Playwright的wait_for_load_state(‘networkidle’)是一个常用方法但需要合理设置超时阈值。更好的做法是结合自定义等待条件比如等待某个特定元素出现。心得给元素打上唯一“指纹”。id并不总是可靠可能动态生成或重复。一个更稳健的方法是使用XPath或基于位置的CSS选择器来生成元素的唯一标识符。例如结合标签名、兄弟节点索引和关键属性来生成一个稳定的“元素指纹”供后续操作使用。AI-Browser 的内部很可能实现了这样一套元素定位和标识机制。3.2 指令解析与执行器AI的“手”AI模型如GPT输出可能是“点击登录按钮。” 执行器需要将这句话准确无误地映射到具体的浏览器操作。核心实现思路这通常通过Function Calling或Tool Use来实现。开发者预定义好一套工具函数并描述其功能和参数。AI模型在思考后会选择调用哪个工具并生成符合要求的参数。例如定义工具{ “name”: “click_element”, “description”: “点击页面上指定的元素”, “parameters”: { “type”: “object”, “properties”: { “element_fingerprint”: { “type”: “string”, “description”: “要点击的元素的唯一标识符” } }, “required”: [“element_fingerprint”] } }AI在理解了页面状态其中包含了一个标识符为fingerprint_login_btn的按钮后可能会输出{“tool_call”: “click_element”, “arguments”: {“element_fingerprint”: “fingerprint_login_btn”}}。执行器收到后便通过浏览器驱动执行page.click(selector_for_fingerprint)。实操要点与避坑指南注意操作的副作用与等待。一个点击操作可能触发页面跳转、弹窗、或异步加载。执行器不能执行完点击就立刻认为动作结束。它必须与观察器联动等待下一个“稳定状态”的出现或者捕获可能出现的异常如导航。通常执行器会设置一个操作后等待期并监控页面URL、主要元素等是否发生变化。心得增加操作确认与重试机制。网络不稳定或页面响应慢可能导致操作“看似失败”。一个健壮的执行器应该包含重试逻辑。例如点击后如果目标元素在预期时间内没有消失或发生变化可以尝试再次点击最多重试2-3次。同时可以为关键操作如表单提交定义“成功/失败”的判定条件如URL跳转到特定模式或出现“成功”提示文本为AI提供更清晰的奖励信号。3.3 AI智能体决策循环的实现这是将“眼睛”和“手”连接起来的大脑。一个典型的决策循环代码如下所示概念性伪代码async def agent_loop(initial_url): # 1. 初始化浏览器和环境 browser, page await init_browser() await page.goto(initial_url) # 2. 定义AI模型例如通过OpenAI API llm ChatOpenAI(model“gpt-4”, temperature0) # 3. 定义工具集并将其绑定到LLM tools [click_tool, type_tool, navigate_tool, extract_tool] agent initialize_agent(tools, llm, agent_type“structured-chat”) # 4. 主循环 max_steps 20 for step in range(max_steps): # 4.1 观察获取当前页面状态描述 page_state await observer.get_state(page) # 4.2 思考与决策将状态和历史组成Prompt询问AI下一步做什么 # 这里需要精心设计Prompt包含目标、历史动作、当前状态、工具描述 prompt construct_prompt(goal“登录并查看首页通知”, statepage_state, historyaction_history) ai_response await agent.arun(prompt) # 这里会触发AI选择工具并生成参数 # 4.3 解析与执行解析AI返回的工具调用指令 tool_name, tool_args parse_ai_response(ai_response) action_result await executor.execute(tool_name, tool_args, page) # 4.4 记录与学习将动作和结果存入历史 action_history.append((tool_name, tool_args, action_result)) # 4.5 检查终止条件是否达成目标或陷入死循环 if check_goal_achieved(page, goal): print(“目标达成”) break if is_stuck_in_loop(action_history): print(“可能陷入循环终止。”) break await browser.close()循环设计的关键点Prompt工程这是AI-Browser项目中最具技巧性的部分。Prompt需要清晰定义AI的角色“你是一个网页操作助手”、目标“请完成登录”、可用工具、以及状态信息的格式。好的Prompt能极大提升AI动作的准确率。历史管理MemoryAI需要有短期记忆记住它之前做过什么避免重复动作或陷入循环。通常需要将最近几步的状态动作结果三元组作为上下文提供给AI。终止条件必须设置最大步数防止AI在某个页面上无限尝试。同时可以定义目标达成条件如检测到特定URL或文本让Agent在完成任务后自动停止。4. 本地部署与核心环节实现假设我们要在本地运行一个最基本的AI-Browser实例目标是让AI自动在某个测试网站完成登录。4.1 环境准备与依赖安装首先你需要一个Python环境建议3.9。然后安装核心依赖。由于AI-Browser本身可能还在迭代我们可以基于其思想用主流库搭建一个简化版。# 创建项目目录并进入 mkdir ai-browser-demo cd ai-browser-demo python -m venv venv # 激活虚拟环境 (Windows: venv\Scripts\activate) source venv/bin/activate # 安装浏览器自动化驱动和AI框架 pip install playwright openai langchain # 安装Playwright所需的浏览器 playwright install chromium这里我们选择Playwright作为浏览器驱动OpenAI API和LangChain作为AI智能体的实现框架。LangChain提供了现成的Agent执行器能大大简化工具调用和循环逻辑。4.2 构建核心工具函数我们定义两个最基础的工具获取页面状态和点击元素。import asyncio from playwright.async_api import async_playwright from langchain.tools import tool from langchain.agents import AgentType, initialize_agent from langchain.chat_models import ChatOpenAI import os # 设置你的OpenAI API Key os.environ[“OPENAI_API_KEY”] “your-api-key-here” class BrowserEnv: def __init__(self): self.playwright None self.browser None self.page None async def start(self): self.playwright await async_playwright().start() self.browser await self.playwright.chromium.launch(headlessFalse) # 有头模式便于调试 self.page await self.browser.new_page() async def goto(self, url): await self.page.goto(url) # 等待页面基本加载完成 await self.page.wait_for_load_state(“networkidle”) async def close(self): await self.browser.close() await self.playwright.stop() # 工具1获取页面可交互元素状态 tool async def get_page_state(page) - str: “”” 获取当前页面的可交互元素状态摘要。返回一个描述字符串。 “”” # 这里是一个简化的实现提取所有按钮和输入框 elements_info [] # 获取按钮 buttons await page.query_selector_all(“button, input[type‘submit’], input[type‘button’]”) for i, btn in enumerate(buttons): text await btn.inner_text() or await btn.get_attribute(“value”) or “” btn_id await btn.get_attribute(“id”) or f“button_{i}” elements_info.append(f“[BUTTON] id/element: {btn_id}, text: {text}“) # 获取输入框 inputs await page.query_selector_all(“input[type‘text’], input[type‘password’], input[type‘email’], textarea”) for i, inp in enumerate(inputs): inp_id await inp.get_attribute(“id”) or f“input_{i}” placeholder await inp.get_attribute(“placeholder”) or “” elements_info.append(f”[INPUT] id/element: {inp_id}, placeholder: {placeholder}“) # 获取页面标题 title await page.title() state_description f“页面标题: ‘{title}’\n可交互元素:\n” “\n”.join(elements_info) return state_description # 工具2点击页面元素 tool async def click_element(page, element_description: str) - str: “”” 根据描述点击页面上的一个元素。 element_description: 从get_page_state中获取的元素描述字符串例如 ‘[BUTTON] id/element: loginBtn, text: Sign In’ “”” # 这是一个非常简单的匹配逻辑。实际项目需要更鲁棒的定位器。 try: # 尝试提取id import re match re.search(r“id/element:\s*(\w)”, element_description) if match: element_id match.group(1) # 先尝试通过id点击 await page.click(f“#{element_id}”) return f“成功点击了ID为 ‘{element_id}’ 的元素。” else: # 如果没有id尝试通过文本点击不推荐容易误点 text_match re.search(r“text:\s*(.)”, element_description) if text_match: text text_match.group(1).strip() await page.click(f“button:has-text(‘{text}’)“) return f“成功点击了文本为 ‘{text}’ 的按钮。” else: return “无法从描述中定位元素。” except Exception as e: return f“点击操作失败: {str(e)}” # 注意为了简化这里将page对象作为参数传入工具。在完整Agent中通常通过回调或绑定环境来实现。4.3 组装智能体并运行任务现在我们将工具、模型和环境组装起来形成一个简单的智能体。async def main(): # 1. 初始化浏览器环境 env BrowserEnv() await env.start() await env.goto(“https://example.com/test-login”) # 替换为你的测试登录页 # 2. 初始化AI模型和工具 llm ChatOpenAI(model“gpt-3.5-turbo”, temperature0) # 使用gpt-3.5-turbo以节省成本 tools [get_page_state, click_element] # 3. 创建Agent。注意这里我们使用了一个简化版的初始化。 # LangChain的Agent需要更复杂的setup以下代码为概念演示。 # 实际中你需要使用正确的AgentType和工具绑定方式。 from langchain.agents import AgentExecutor, create_react_agent from langchain.prompts import PromptTemplate # 创建一个简单的ReAct风格的Prompt prompt PromptTemplate.from_template( “”” 你是一个网页操作AI。你的目标是{goal} 当前页面状态 {state} 你有以下工具{tools} 请根据目标决定使用哪个工具并给出完整的工具调用参数。 你的思考过程应该简短。 动作格式使用工具名和参数例如get_page_state 或 click_element “[BUTTON] id/element: submit, text: Submit” “”” ) # 这里简化处理实际请参考LangChain最新文档创建Agent agent create_react_agent(llm, tools, prompt) agent_executor AgentExecutor(agentagent, toolstools, verboseTrue) # 4. 定义任务目标 goal “找到登录表单输入用户名‘demo’和密码‘pass’并点击登录按钮。” # 5. 执行第一步获取初始状态 initial_state await get_page_state.invoke({“page”: env.page}) print(“初始状态:”, initial_state) # 6. 将状态和目标交给Agent决策这里只模拟一步 # 注意完整的Agent循环需要处理多步交互这里仅为示例。 input_to_agent {“goal”: goal, “state”: initial_state, “tools”: “get_page_state, click_element”} # 由于工具需要page对象这里无法直接运行完整Agent。实际项目需要将env封装成Tool的上下文。 print(“说明完整的Agent执行循环需要更复杂的集成此处演示核心概念。”) # 一个可行的思路是将BrowserEnv实例的方法直接包装成LangChain Tool。 # 7. 关闭环境 await env.close() if __name__ “__main__”: asyncio.run(main())这个简化示例展示了核心流程启动浏览器、定义工具、获取状态、意图让AI决策。一个成熟的AI-Browser项目如Jun-Murakami/AI-Browser会将这些步骤封装得更加完善、鲁棒并提供更丰富的工具集输入文本、滚动、截图、提取信息等。5. 常见问题、排查技巧与优化方向在实际开发和运行AI-Browser类项目时你会遇到一系列典型问题。以下是我在实践中总结的排查清单和优化建议。5.1 稳定性问题元素定位失败或操作超时这是最常见的问题。AI指示点击一个按钮但执行器找不到它。可能原因及排查页面未加载完成观察器在页面仍在加载时就进行了快照。解决在get_page_state工具中加入更稳健的等待如await page.wait_for_selector(“body”)并结合wait_for_load_state。动态内容元素是JavaScript后来生成的。解决观察器需要针对这类页面进行“主动探测”或者使用Playwright的page.wait_for_selector在操作前等待特定元素出现。可以为工具增加重试逻辑。iframe或Shadow DOM目标元素嵌套在iframe或Shadow Root内。解决观察器需要能穿透这些边界。Playwright提供了frame.locator()和element.shadow_root来处理需要在状态提取和元素定位逻辑中特别处理。选择器不稳定依赖的id或class是动态生成的。解决采用更稳定的定位策略如使用>

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2577550.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

SpringBoot-17-MyBatis动态SQL标签之常用标签

文章目录 1 代码1.1 实体User.java1.2 接口UserMapper.java1.3 映射UserMapper.xml1.3.1 标签if1.3.2 标签if和where1.3.3 标签choose和when和otherwise1.4 UserController.java2 常用动态SQL标签2.1 标签set2.1.1 UserMapper.java2.1.2 UserMapper.xml2.1.3 UserController.ja…

wordpress后台更新后 前端没变化的解决方法

使用siteground主机的wordpress网站,会出现更新了网站内容和修改了php模板文件、js文件、css文件、图片文件后,网站没有变化的情况。 不熟悉siteground主机的新手,遇到这个问题,就很抓狂,明明是哪都没操作错误&#x…

网络编程(Modbus进阶)

思维导图 Modbus RTU(先学一点理论) 概念 Modbus RTU 是工业自动化领域 最广泛应用的串行通信协议,由 Modicon 公司(现施耐德电气)于 1979 年推出。它以 高效率、强健性、易实现的特点成为工业控制系统的通信标准。 包…

UE5 学习系列(二)用户操作界面及介绍

这篇博客是 UE5 学习系列博客的第二篇,在第一篇的基础上展开这篇内容。博客参考的 B 站视频资料和第一篇的链接如下: 【Note】:如果你已经完成安装等操作,可以只执行第一篇博客中 2. 新建一个空白游戏项目 章节操作,重…

IDEA运行Tomcat出现乱码问题解决汇总

最近正值期末周,有很多同学在写期末Java web作业时,运行tomcat出现乱码问题,经过多次解决与研究,我做了如下整理: 原因: IDEA本身编码与tomcat的编码与Windows编码不同导致,Windows 系统控制台…

利用最小二乘法找圆心和半径

#include <iostream> #include <vector> #include <cmath> #include <Eigen/Dense> // 需安装Eigen库用于矩阵运算 // 定义点结构 struct Point { double x, y; Point(double x_, double y_) : x(x_), y(y_) {} }; // 最小二乘法求圆心和半径 …

使用docker在3台服务器上搭建基于redis 6.x的一主两从三台均是哨兵模式

一、环境及版本说明 如果服务器已经安装了docker,则忽略此步骤,如果没有安装,则可以按照一下方式安装: 1. 在线安装(有互联网环境): 请看我这篇文章 传送阵>> 点我查看 2. 离线安装(内网环境):请看我这篇文章 传送阵>> 点我查看 说明&#xff1a;假设每台服务器已…

XML Group端口详解

在XML数据映射过程中&#xff0c;经常需要对数据进行分组聚合操作。例如&#xff0c;当处理包含多个物料明细的XML文件时&#xff0c;可能需要将相同物料号的明细归为一组&#xff0c;或对相同物料号的数量进行求和计算。传统实现方式通常需要编写脚本代码&#xff0c;增加了开…

LBE-LEX系列工业语音播放器|预警播报器|喇叭蜂鸣器的上位机配置操作说明

LBE-LEX系列工业语音播放器|预警播报器|喇叭蜂鸣器专为工业环境精心打造&#xff0c;完美适配AGV和无人叉车。同时&#xff0c;集成以太网与语音合成技术&#xff0c;为各类高级系统&#xff08;如MES、调度系统、库位管理、立库等&#xff09;提供高效便捷的语音交互体验。 L…

(LeetCode 每日一题) 3442. 奇偶频次间的最大差值 I (哈希、字符串)

题目&#xff1a;3442. 奇偶频次间的最大差值 I 思路 &#xff1a;哈希&#xff0c;时间复杂度0(n)。 用哈希表来记录每个字符串中字符的分布情况&#xff0c;哈希表这里用数组即可实现。 C版本&#xff1a; class Solution { public:int maxDifference(string s) {int a[26]…

【大模型RAG】拍照搜题技术架构速览:三层管道、两级检索、兜底大模型

摘要 拍照搜题系统采用“三层管道&#xff08;多模态 OCR → 语义检索 → 答案渲染&#xff09;、两级检索&#xff08;倒排 BM25 向量 HNSW&#xff09;并以大语言模型兜底”的整体框架&#xff1a; 多模态 OCR 层 将题目图片经过超分、去噪、倾斜校正后&#xff0c;分别用…

【Axure高保真原型】引导弹窗

今天和大家中分享引导弹窗的原型模板&#xff0c;载入页面后&#xff0c;会显示引导弹窗&#xff0c;适用于引导用户使用页面&#xff0c;点击完成后&#xff0c;会显示下一个引导弹窗&#xff0c;直至最后一个引导弹窗完成后进入首页。具体效果可以点击下方视频观看或打开下方…

接口测试中缓存处理策略

在接口测试中&#xff0c;缓存处理策略是一个关键环节&#xff0c;直接影响测试结果的准确性和可靠性。合理的缓存处理策略能够确保测试环境的一致性&#xff0c;避免因缓存数据导致的测试偏差。以下是接口测试中常见的缓存处理策略及其详细说明&#xff1a; 一、缓存处理的核…

龙虎榜——20250610

上证指数放量收阴线&#xff0c;个股多数下跌&#xff0c;盘中受消息影响大幅波动。 深证指数放量收阴线形成顶分型&#xff0c;指数短线有调整的需求&#xff0c;大概需要一两天。 2025年6月10日龙虎榜行业方向分析 1. 金融科技 代表标的&#xff1a;御银股份、雄帝科技 驱动…

观成科技:隐蔽隧道工具Ligolo-ng加密流量分析

1.工具介绍 Ligolo-ng是一款由go编写的高效隧道工具&#xff0c;该工具基于TUN接口实现其功能&#xff0c;利用反向TCP/TLS连接建立一条隐蔽的通信信道&#xff0c;支持使用Let’s Encrypt自动生成证书。Ligolo-ng的通信隐蔽性体现在其支持多种连接方式&#xff0c;适应复杂网…

铭豹扩展坞 USB转网口 突然无法识别解决方法

当 USB 转网口扩展坞在一台笔记本上无法识别,但在其他电脑上正常工作时,问题通常出在笔记本自身或其与扩展坞的兼容性上。以下是系统化的定位思路和排查步骤,帮助你快速找到故障原因: 背景: 一个M-pard(铭豹)扩展坞的网卡突然无法识别了,扩展出来的三个USB接口正常。…

未来机器人的大脑:如何用神经网络模拟器实现更智能的决策?

编辑&#xff1a;陈萍萍的公主一点人工一点智能 未来机器人的大脑&#xff1a;如何用神经网络模拟器实现更智能的决策&#xff1f;RWM通过双自回归机制有效解决了复合误差、部分可观测性和随机动力学等关键挑战&#xff0c;在不依赖领域特定归纳偏见的条件下实现了卓越的预测准…

Linux应用开发之网络套接字编程(实例篇)

服务端与客户端单连接 服务端代码 #include <sys/socket.h> #include <sys/types.h> #include <netinet/in.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <arpa/inet.h> #include <pthread.h> …

华为云AI开发平台ModelArts

华为云ModelArts&#xff1a;重塑AI开发流程的“智能引擎”与“创新加速器”&#xff01; 在人工智能浪潮席卷全球的2025年&#xff0c;企业拥抱AI的意愿空前高涨&#xff0c;但技术门槛高、流程复杂、资源投入巨大的现实&#xff0c;却让许多创新构想止步于实验室。数据科学家…

深度学习在微纳光子学中的应用

深度学习在微纳光子学中的主要应用方向 深度学习与微纳光子学的结合主要集中在以下几个方向&#xff1a; 逆向设计 通过神经网络快速预测微纳结构的光学响应&#xff0c;替代传统耗时的数值模拟方法。例如设计超表面、光子晶体等结构。 特征提取与优化 从复杂的光学数据中自…