税务问题求助!做一个奈飞小铺、银河录像局这种代充平台销售的产品是不是应该先找一个可以开票的上游?
我现在已经有了公司和 icp 许可证,如果做他们这种项目找一个能开票的上游是不是税务合规的关键。
xiaohack博客专注前沿科技动态与实用技术干货分享,涵盖 AI 代理、大模型应用、编程工具、文档解析、SEO 实战、自动化部署等内容,提供开源项目教程、科技资讯日报、工具使用指南,助力开发者、AI 爱好者获取前沿技术与实战经验。
我现在已经有了公司和 icp 许可证,如果做他们这种项目找一个能开票的上游是不是税务合规的关键。
我在桌子底下用电油汀,没用啊的,还是感觉脚冷的啊.
用电火箱的话,又感觉要盖东西,今天又换回这个了,感觉有点不方便
你们用的什么烤火呢?
大家好,我是良许。 在嵌入式开发中,GPIO(General Purpose Input/Output,通用输入输出)是我们接触最多的外设之一。 无论是点亮一个LED灯,还是读取按键状态,亦或是与其他芯片进行通信,都离不开GPIO的配置。 而GPIO的工作模式直接决定了引脚的电气特性和功能表现。 今天,我就来详细聊聊STM32中GPIO的八种工作模式,帮助大家彻底理解它们的区别和应用场景。 STM32的GPIO具有八种工作模式,可以分为四种输入模式和四种输出模式。 这些模式的设计非常灵活,能够满足各种应用场景的需求。 四种输入模式: 四种输出模式: 下面我将逐一详细介绍这八种模式的工作原理、特点以及典型应用场景。 输入浮空模式是GPIO最基本的输入模式。 在这种模式下,引脚既不接上拉电阻,也不接下拉电阻,完全处于"浮空"状态。 此时引脚的电平完全由外部电路决定,如果外部没有明确的高低电平信号,引脚的状态是不确定的,可能会受到外部干扰而产生随机的高低电平跳变。 特点: 应用场景: 比如,当外部按键电路已经有上拉电阻时,MCU的GPIO就可以配置为浮空输入,避免内部上拉电阻与外部电阻形成分压。 代码示例: 输入上拉模式是在浮空输入的基础上,内部连接了一个上拉电阻(通常为30~50kΩ)到VDD。 这样,当外部没有信号输入时,引脚会被上拉电阻拉到高电平状态,避免了浮空状态下的不确定性。 特点: 应用场景: 当按键未按下时,引脚保持高电平;按键按下后,引脚被拉到地,变为低电平。 这种方式简单可靠,是按键检测的标准配置。 代码示例: 输入下拉模式与上拉模式相反,内部连接了一个下拉电阻(同样是30~50kΩ)到GND。 当外部没有信号输入时,引脚会被下拉电阻拉到低电平状态。 特点: 应用场景: 比如某些传感器输出高电平表示有效信号,此时可以将GPIO配置为下拉输入,确保在没有信号时引脚保持低电平。 代码示例: 模拟输入模式是专门为ADC(模数转换器)设计的。 在这种模式下,GPIO引脚直接连接到ADC的输入通道,不经过施密特触发器,可以输入连续变化的模拟信号。 特点: 应用场景: 在这种模式下,GPIO不再作为数字IO使用,而是作为ADC的模拟输入通道。 代码示例: 推挽输出(Push-Pull)是最常用的输出模式。 在这种模式下,输出级由两个MOS管组成,一个连接VDD(P-MOS),一个连接GND(N-MOS)。 输出高电平时,P-MOS导通,引脚连接到VDD;输出低电平时,N-MOS导通,引脚连接到GND。 这种结构可以提供较强的驱动能力。 特点: 应用场景: 只要不需要多个设备共享同一条信号线,推挽输出都是首选。 代码示例: 开漏输出(Open-Drain)模式下,输出级只有一个N-MOS管连接到GND。 输出低电平时,N-MOS导通,引脚接地;输出高电平时,N-MOS关断,引脚呈现高阻态。 要输出高电平,必须外接上拉电阻。 特点: 应用场景: I2C是多主机总线,多个设备共享SDA和SCL两条线,必须使用开漏输出配合外部上拉电阻。 此外,开漏输出还可以用于电平转换,比如MCU是3.3V供电,但需要输出5V信号时,可以使用开漏输出配合5V上拉电阻。 代码示例: 推挽复用输出模式是推挽输出的复用版本。 在这种模式下,GPIO的控制权交给片上外设(如SPI、USART等),由外设自动控制引脚的输出。 特点: 应用场景: 比如SPI的MOSI、SCK引脚,USART的TX引脚等。 代码示例: 开漏复用输出模式是开漏输出的复用版本。 同样,GPIO的控制权交给片上外设,但输出特性为开漏。 特点: 应用场景: 当使用STM32的硬件I2C外设时,SCL和SDA引脚必须配置为开漏复用输出。 代码示例: 在实际开发中,如何选择合适的GPIO工作模式呢?这里给出一些实用建议: 4.1 输入模式选择: 4.2 输出模式选择: 4.3 速度等级选择: 5.1 为什么开漏输出需要上拉电阻? 没有上拉电阻时,输出高电平时引脚处于高阻态,无法驱动负载。 上拉电阻的作用是在N-MOS关断时将引脚拉到高电平。 5.2 推挽输出可以接上拉电阻吗? 推挽输出本身就能输出强高电平和强低电平,额外的上拉电阻只会增加功耗。 只有在需要提高驱动能力或进行电平转换时才需要。 5.3 多个GPIO可以连接在一起吗? 如果需要多个GPIO共享一条线,必须使用开漏输出。 5.4 复用功能如何配置? 不同的引脚支持的复用功能不同,需要查阅芯片数据手册中的引脚复用表。 通过以上详细的介绍,相信大家对STM32的GPIO八种工作模式有了深入的理解。 在实际项目中,正确选择GPIO的工作模式是保证系统稳定运行的基础。 希望这篇文章能帮助大家在嵌入式开发的道路上少走弯路,写出更加可靠的代码。 更多编程学习资源1. GPIO工作模式概述
1.1 输入浮空模式(GPIO_MODE_INPUT)
1.2 输入上拉模式(GPIO_MODE_INPUT,配合GPIO_PULLUP)
1.3 输入下拉模式(GPIO_MODE_INPUT,配合GPIO_PULLDOWN)
1.4 模拟输入模式(GPIO_MODE_ANALOG)
1.5 开漏输出模式(GPIO_MODE_OUTPUT_OD)
1.6 开漏复用输出模式(GPIO_MODE_AF_OD)
1.7 推挽输出模式(GPIO_MODE_OUTPUT_PP)
1.8 推挽复用输出模式(GPIO_MODE_AF_PP)2. 四种输入模式详解
2.1 输入浮空模式
输入浮空模式通常用于外部电路已经提供了明确的上拉或下拉电阻的场合。GPIO_InitTypeDef GPIO_InitStruct = {0};
// 使能GPIOA时钟
__HAL_RCC_GPIOA_CLK_ENABLE();
// 配置PA0为浮空输入
GPIO_InitStruct.Pin = GPIO_PIN_0;
GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
GPIO_InitStruct.Pull = GPIO_NOPULL;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
// 读取引脚状态
GPIO_PinState pinState = HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_0);2.2 输入上拉模式
输入上拉模式最常用于按键检测。GPIO_InitTypeDef GPIO_InitStruct = {0};
__HAL_RCC_GPIOA_CLK_ENABLE();
// 配置PA1为上拉输入,用于按键检测
GPIO_InitStruct.Pin = GPIO_PIN_1;
GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
GPIO_InitStruct.Pull = GPIO_PULLUP;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
// 检测按键是否按下(低电平有效)
if (HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_1) == GPIO_PIN_RESET) {
// 按键被按下
// 执行相应操作
}2.3 输入下拉模式
输入下拉模式适用于高电平有效的信号检测。GPIO_InitTypeDef GPIO_InitStruct = {0};
__HAL_RCC_GPIOB_CLK_ENABLE();
// 配置PB0为下拉输入
GPIO_InitStruct.Pin = GPIO_PIN_0;
GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
GPIO_InitStruct.Pull = GPIO_PULLDOWN;
HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
// 检测高电平有效信号
if (HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_0) == GPIO_PIN_SET) {
// 检测到高电平信号
// 执行相应操作
}2.4 模拟输入模式
模拟输入模式专门用于ADC采集模拟信号,比如读取温度传感器、光敏电阻、电位器等模拟量。GPIO_InitTypeDef GPIO_InitStruct = {0};
ADC_HandleTypeDef hadc1;
__HAL_RCC_GPIOA_CLK_ENABLE();
__HAL_RCC_ADC1_CLK_ENABLE();
// 配置PA4为模拟输入,用于ADC
GPIO_InitStruct.Pin = GPIO_PIN_4;
GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;
GPIO_InitStruct.Pull = GPIO_NOPULL;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
// ADC配置(简化示例)
hadc1.Instance = ADC1;
hadc1.Init.Resolution = ADC_RESOLUTION_12B;
hadc1.Init.DataAlign = ADC_DATAALIGN_RIGHT;
HAL_ADC_Init(&hadc1);
// 读取ADC值
HAL_ADC_Start(&hadc1);
HAL_ADC_PollForConversion(&hadc1, 100);
uint32_t adcValue = HAL_ADC_GetValue(&hadc1);3. 四种输出模式详解
3.1 推挽输出模式
推挽输出是GPIO最常用的输出模式,适用于驱动LED、控制继电器、输出PWM信号等场景。GPIO_InitTypeDef GPIO_InitStruct = {0};
__HAL_RCC_GPIOC_CLK_ENABLE();
// 配置PC13为推挽输出,用于控制LED
GPIO_InitStruct.Pin = GPIO_PIN_13;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);
// 点亮LED(假设低电平点亮)
HAL_GPIO_WritePin(GPIOC, GPIO_PIN_13, GPIO_PIN_RESET);
// 延时
HAL_Delay(1000);
// 熄灭LED
HAL_GPIO_WritePin(GPIOC, GPIO_PIN_13, GPIO_PIN_SET);3.2 开漏输出模式
开漏输出最典型的应用是I2C总线。GPIO_InitTypeDef GPIO_InitStruct = {0};
__HAL_RCC_GPIOB_CLK_ENABLE();
// 配置PB6和PB7为开漏输出,用于I2C(SCL和SDA)
GPIO_InitStruct.Pin = GPIO_PIN_6 | GPIO_PIN_7;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_OD;
GPIO_InitStruct.Pull = GPIO_PULLUP; // 如果外部没有上拉,可以使能内部上拉
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
// 模拟I2C起始信号
HAL_GPIO_WritePin(GPIOB, GPIO_PIN_7, GPIO_PIN_RESET); // SDA拉低
HAL_Delay(1);
HAL_GPIO_WritePin(GPIOB, GPIO_PIN_6, GPIO_PIN_RESET); // SCL拉低3.3 推挽复用输出模式
推挽复用输出主要用于SPI、USART等需要高速、强驱动能力的通信接口。GPIO_InitTypeDef GPIO_InitStruct = {0};
__HAL_RCC_GPIOA_CLK_ENABLE();
// 配置PA9为推挽复用输出,用于USART1_TX
GPIO_InitStruct.Pin = GPIO_PIN_9;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
GPIO_InitStruct.Alternate = GPIO_AF7_USART1; // 复用为USART1
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
// 后续由USART外设控制该引脚3.4 开漏复用输出模式
开漏复用输出主要用于I2C、SMBUS等需要多主机通信的总线。GPIO_InitTypeDef GPIO_InitStruct = {0};
__HAL_RCC_GPIOB_CLK_ENABLE();
// 配置PB8和PB9为开漏复用输出,用于I2C1(SCL和SDA)
GPIO_InitStruct.Pin = GPIO_PIN_8 | GPIO_PIN_9;
GPIO_InitStruct.Mode = GPIO_MODE_AF_OD;
GPIO_InitStruct.Pull = GPIO_PULLUP; // 使能内部上拉(外部也应有上拉电阻)
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
GPIO_InitStruct.Alternate = GPIO_AF4_I2C1; // 复用为I2C1
HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
// 后续由I2C外设控制该引脚4. 工作模式选择建议
STM32的GPIO还可以配置输出速度(Low、Medium、High、Very High),这会影响引脚的翻转速度和功耗。一般原则是:5. 常见问题与注意事项
因为开漏输出只能主动拉低,不能主动拉高。
可以,但通常没有必要。
如果都是推挽输出,绝对不能连接在一起!当一个输出高电平、另一个输出低电平时,会形成短路,可能烧毁芯片。
使用HAL库时,需要同时配置GPIO模式和复用功能。
最近想买衣服,taobao 搜索了‘帽衫’,居然是 TIM 代言的什么衣服品牌, 打开微博开平广告也是他, 在 B 站刷视频从来没有刷过相关内容的也给我推他, 他最近怎么这么活跃,搞得我很烦他现在

作为一个电子爱好者,经常在淘宝买一些电子元件、模块,有时候想买一个东西的时候会看看这个店铺里的其他商品,有没有我需要或感兴趣的,如果有的话就顺便买一些。最近两三年来一直都是这个使用习惯,25 年 12 月份被第一次被封,被封结果就是访问任何商品详情、店铺都是访问被拒绝,网页版也是。联系了客户端官方客服第二天解封,过了 20 天左右第二次被封,再次联系客服第二天解封,前两天又被封了,好家伙,这次连官方客服也联系不了了,联系官方客服也是访问被拒绝,打了客服电话竟然说我账号正常,网上查了下也有好多类似的情况



网站部署SSL证书的重要作用如下: 1.SSL证书可加密敏感信息使其不被泄露 使用SSL证书的主要原因是为了保障通过Internet发送的敏感信息能够加密,防止重要数据不被泄露。这很重要,因为您在Internet上进行计算机与服务器之间的信息传递,如果未使用SSL证书加密,则您传递的任何信息都有可能被第三方获取,包括您的信用卡号,用户名和密码以及其他敏感信息。使用SSL证书后,可以保障所有人都无法读取信息,这可以保护信息数据免受黑客或者用心不良的人的侵害。 2.SSL证书可提供身份验证,防止钓鱼网站 除信息加密外,SSL证书可提供身份验证。这意味着您可以确保将信息发送到正确的服务器,不用担心别人窃取您的信息。有效的防止第三方伪装成您的网站并欺骗您的用户,获取用户个人信息,造成或大或小的损失。而SSL证书是由受信任的CA机构颁发的,申请证书时会严格的验证企业/组织的信息。所以说,选择受信任的CA机构颁发的SSL证书非常的重要,CA机构会通过各种信息的验证才会颁发SSL证书,而且EV SSL证书需要比其他证书更多的验证资料。 3.SSL证书可增加信任度 安装SSL证书的网站在Web浏览器的地址栏可显示,绿色小锁图标,绿色地址栏,EV SSL证书还能显示企业/组织名称。以确保访问者知道其连接是受到保护的,可放心使用。这意味着当访问者看到这些提示信息会更信任您的网站。而且可以查看CA机构的颁发信息,以便为您的客户提供的更多信任。 HTTPS还可以防止网络钓鱼攻击。网络钓鱼电子邮件是冒充您网站来进行犯罪的,钓鱼电子邮件通常包含指向其网站的链接或使用中间人攻击来达到目的。由于这些违规现象无法获得正规CA机构颁发的SSL证书,因此他们无法完全冒充您的网站。这意味着您的用户陷入网络钓鱼网站的可能性很小。
有很多原因可以导致某些网站无法打开或加载缓慢。这些原因可以包括以下各种因素: 网络连接问题: 您的互联网连接可能存在问题,如断开、丢包或较低的带宽,这会导致网站加载缓慢或无法加载。 网站服务器问题: 如果目标网站的服务器出现问题,如服务器宕机、过载或网络故障,那么您将无法访问该网站。 DNS问题: DNS(域名系统)负责将域名解析为 IP 地址。如果DNS服务器出现问题,将导致域名解析失败,从而无法访问网站。 防火墙和安全软件: 防火墙或安全软件可能会阻止您访问某些网站,尤其是在其黑名单中的网站。 浏览器问题: 您使用的浏览器可能存在问题,例如缓存问题、插件冲突或过时的浏览器版本。 地理位置: 您的地理位置可能会影响到网站的加载速度。如果您与目标服务器之间的距离较远,加载速度可能较慢。 设备问题: 您的计算机或设备可能存在问题,如性能不足、过热或磁盘空间不足,这可能会导致网站加载缓慢。 网络流量: 网站所在的服务器可能正在经历高流量,这会导致加载速度变慢。 网站设计和优化: 一些网站可能设计不佳或未经过优化,导致加载时间较长。大量的大型媒体文件和广告也可能影响加载速度。 互联网服务提供商(ISP)问题: 您的ISP可能会对特定网站或内容进行流量限制,这可能会导致访问特定网站时速度较慢。 解决这些问题可能需要不同的方法。您可以尝试以下步骤来改善网站访问速度: 检查您的互联网连接,确保它稳定且具有足够的带宽。
清除浏览器缓存和Cookie。
使用不同的浏览器进行测试,以查看是否存在浏览器相关问题。
检查您的设备,确保它没有性能问题。
尝试使用不同的DNS服务器,如Google DNS 或 Cloudflare DNS。
联系您的ISP 以了解是否存在任何网络问题。
如果问题持续存在,可能需要进一步的网络故障排除或联系相关网络服务提供商或网站管理员以获取支持。
双击安装包 → 同意协议 → 自定义路径(无中文)→ 安装 → 重启一、下载
二、安装
三、创建虚拟机
四、常用操作
五、常见问题
在企业数字化转型中,CRM(客户关系管理)已从“客户信息存储工具”升级为“全链路业务协同平台”——覆盖获客-营销-竞品-项目-上下游的全流程,成为企业连接市场、客户与供应链的核心枢纽。本文基于超兔一体云、Copper CRM、 RSS 、Agile CRM、Highrise、微盟CRM、玄讯CRM等主流品牌的公开能力,从专业维度展开横向对比,解析各品牌的核心优势与适用场景。 本次对比围绕CRM的核心业务链路设计5个维度,覆盖企业从“获客”到“上下游协同”的全流程需求: 获客是CRM的起点,核心是多渠道线索整合与线索清洗效率。各品牌的能力差异直接决定了企业触达客户的广度与精准度: 关键结论: 营销的核心是“精准触达+效果可测”,各品牌的差异体现在营销物料的丰富度与数据决策的能力: 关键结论: 竞品管理的核心是“感知竞争态势,制定差异化策略” ,但多数品牌仅能实现“被动收集”,仅有超兔一体云提供主动竞品分析能力: 关键结论: 项目管理的核心是“覆盖不同项目类型,实现进度、成本、团队的协同”,各品牌的能力差异体现在对项目复杂度的支持: 关键结论: 上下游管理的核心是“打通企业与供应商/客户的数据壁垒,实现三流合一(物流/资金流/信息流)”,各品牌的能力差异体现在协同的深度: 关键结论: 基于5个维度的能力评分(1-5分,5为最高),各品牌的综合竞争力如下: 基于上述对比,各品牌的核心优势与适配企业可总结为: 企业选择CRM的核心逻辑是“需求适配”,需结合3个关键因素: 从本次对比可见,CRM的竞争已从“单一功能优势”转向“全链路能力整合”——超兔一体云通过多渠道获客、数据化营销、竞品策略支持、全类型项目管理、产业链协同的全链路能力,成为中大型企业数字化转型的首选;而Highrise、微盟、玄讯等垂直型CRM则通过“行业深度”占据细分市场;Copper、Agile等则通过“生态/成本”适配特定团队。 对企业而言,选择CRM的本质是选择“业务增长的底层支撑系统” ——需从“当前需求”与“未来扩张”双维度评估,最终实现“效率提升+竞争力增强”的价值最大化。 (注:文中功能相关描述均基于公开披露信息,具体功能服务与价格以厂商实际落地版本为准。)一、对比框架说明
二、各维度横向对比分析
(一)获客能力:从“流量覆盖”到“精准转化”的差异
品牌 核心获客能力 适用场景 超兔一体云 覆盖线上(百度/抖音/微信/小程序)+ 线下(地推/会销/工商搜客)全渠道;支持线索一键处理、归属地识别、活动效果评估 toB/toC全行业,需全渠道获客的企业 微盟CRM 整合微信/抖音/小红书等私域流量,通过会员积分、拼团满减实现获客与复购 美妆/服饰等线上零售品牌 玄讯CRM 快消行业专属:外勤拜访管理、终端数据采集、线下渠道获客 快消企业(如饮料、食品) Copper CRM 适配Google生态:网站表单/手机扫描→自动同步Google Contacts,减少手动录入 海外/跨境业务,依赖Google生态 Highrise 线索-销售-订单-供应商全链路覆盖,支持工程类项目的线索转化 工程/制造企业,长周期项目获客 RSS 基础线索跟踪,无精准获客功能 对获客需求简单的中小企业 (二)营销能力:从“手动执行”到“数据驱动”的升级
品牌 核心营销能力 优势亮点 超兔一体云 1. 营销物料库:话术武器云(标准化沟通话术)、文件武器云(产品资料/案例); 2. 数据引擎:转化分析、用户画像云图、活动成本均摊 数据驱动的精准营销,支持活动效果回溯 Agile CRM 邮件营销、社交媒体管理;免费版无限用户 初创团队的基础营销工具 微盟CRM 电商复购工具:会员积分、满减拼团、私域流量触达 线上零售的老客运营 Copper CRM Google Workspace协同(日历/文档/Drive);Gmail邮件追踪(记录客户互动) 依赖Google生态的营销协同 RSS 基础活动管理(计划/执行/监控),无自动化功能 简单活动的流程跟踪 (三)竞品管理:从“被动收集”到“主动策略”的突破
品牌 竞品管理能力 能力层级 超兔一体云 1. 竞品信息自动收集(产品/价格/市场份额); 2. 竞争关系管理(竞争事件记录、预警); 3. 差异化策略支持 主动型:从信息到策略的闭环 Copper CRM 通过客户互动记录(如“客户提及的竞品优势”)间接获取 被动型:依赖销售手动整合 其他品牌 无专门竞品模块 缺失型:无法满足复杂分析需求 (四)项目管理:从“进度跟踪”到“全流程协同”的深化
品牌 核心项目管理能力 适配项目类型 超兔一体云 1. 多跟单模型:小单快单(三一客)、商机跟单(中长单)、多方项目(大型项目); 2. 通用能力:360°视图、时间线、自动日报、行动记录分析 小单/中长单/大型项目全覆盖 Highrise 工程类项目:施工节点跟踪、材料采购、成本管控 工程/制造企业的长周期项目 Copper CRM 可视化项目管道+Google Calendar集成(同步日程/截止日期) 依赖Google生态的中小型项目 其他品牌 无原生项目管理功能或仅支持基础进度跟踪 简单项目的流程记录 (五)上下游管理:从“信息记录”到“全链路协同”的跨越
品牌 核心上下游能力 协同亮点 超兔一体云 OpenCRM业务伙伴共生平台: 1. 上游:询价/采购/付款/供应商评分; 2. 下游:报价/订单/物流/售后; 3. 共性能力:三流合一对账、全程追溯 产业链全流程协同,提升透明度 Highrise 线索-销售-订单-库存-供应商全链路覆盖 全流程数据打通 微盟CRM 与微盟商城无缝衔接:订单/库存/售后协同 电商上下游的订单协同 玄讯CRM 快消渠道库存监控:终端数据采集、库存预警 快消线下供应链的库存管理 Copper CRM 客户分层(组织型客户的上下级关联) 间接记录上下游关系 三、综合能力雷达图:各品牌的核心竞争力分布
品牌 获客 营销 竞品 项目 上下游 核心定位 超兔一体云 5 5 5 5 5 全链路协同型CRM,适合中大型企业 Highrise 4 2 1 4 4 工程类全流程CRM 微盟CRM 4 4 1 1 3 电商私域型CRM 玄讯CRM 3 2 1 1 3 快消外勤型CRM Copper CRM 3 2 1 3 2 Google生态型CRM Agile CRM 3 3 1 1 1 初创基础型CRM RSS 2 2 1 1 1 简单基础型CRM 四、品牌核心定位与适用场景
品牌 核心优势 适配企业类型 超兔一体云 全链路协同(获客-营销-项目-上下游);大型项目管理;产业链三流合一 需要数字化转型的中大型企业; 依赖全流程协同的制造/工程/服务企业 Highrise 工程类项目节点跟踪;材料采购与成本管控 工程施工、设备制造企业 微盟CRM 电商私域流量整合;会员复购工具 美妆、服饰、家居等线上零售品牌 玄讯CRM 快消外勤拜访管理;终端数据采集 饮料、食品、日化等快消企业 Copper CRM Google生态无缝集成;减少手动录入成本 海外/跨境业务;依赖Google Workspace的团队 Agile CRM 免费版无限用户;基础营销与客户管理 初创团队、小规模业务 RSS 界面简洁;基础客户与线索管理 对CRM需求简单的中小企业 五、选择建议:从“需求匹配”到“价值最大化”
六、结论:CRM的未来是“全链路协同”
Position节点是Shader Graph中用于获取三维空间坐标的核心工具,其输出结果受空间坐标系选择直接影响。该节点通过连接不同空间转换模块,可精准获取顶点或片元在特定坐标系下的位置信息,为开发者提供了强大的空间数据访问能力。在URP(Universal Render Pipeline)渲染管线中,其核心功能包括: 通过连接Position节点到BaseColor输出,可创建以物体中心为基准的渐变效果。这种效果在物体移动或旋转时保持不变,因为坐标系始终以物体中心为原点,适用于制作固定形态的材质变化,如UV动画或程序化纹理。 实现步骤: 应用场景: 将空间切换为World后,Position节点输出值会随物体在场景中的位置变化。这种效果常用于制作环境交互效果,如根据物体与场景中心的距离改变透明度。 实现步骤: 应用场景: 通过Position节点实现渐隐效果的核心是利用深度差值控制透明度。这种方法可精确控制粒子消失的过渡区域,通过调整Range参数可改变渐变范围,适用于制作溶解效果或环境粒子消散。 实现步骤: 应用场景:【Unity Shader Graph 使用与特效实现】专栏-直达
Unity URP Shader Graph Position节点:空间坐标与视觉效果的桥梁
注意:URP管线中需通过Graph Settings确认渲染管线类型,传统内置管线不支持Shader Graph功能
基础应用示例:基于距离的着色效果
对象空间下的距离着色
世界空间下的动态效果
进阶应用:渐隐粒子效果实现
原理与节点配置
性能优化技巧
常见问题与解决方案
坐标空间选择错误
透明效果异常
性能瓶颈
最佳实践与扩展应用
空间转换技巧
扩展应用场景
提示:URP管线中建议使用HDR颜色模式处理高动态范围效果,可通过Color节点的HDR选项启用,确保视觉效果更加真实
【Unity Shader Graph 使用与特效实现】专栏-直达
(欢迎
探讨,更多人加入进来能更加完善这个探索的过程,🙏)
简介: 在移动办公和远程协作成为常态的今天,高效的管理工具是团队保持生产力的核心。面对碎片化时间、多设备同步和即时协作的挑战,专为移动端优化的管理工具应运而生。它们通过直观的触控界面、实时同步能力和场景化功能,让团队管理随时随地进行。本文将解析移动端管理工具的关键价值,并为您精选几款高效应用,助力团队在移动时代游刃有余。 随着工作场景的日益灵活,我们处理事务的地点从固定工位扩展至通勤途中、家庭办公室甚至差旅途中的咖啡馆。传统的桌面端管理软件虽功能强大,但在移动场景下往往显得笨重且不便操作。此时,一款设计精良、体验流畅的移动端管理工具,就成为连接想法与行动、计划与执行的关键桥梁。 现代工作模式对管理工具提出了前所未有的要求。团队成员可能分布在不同的时区,项目更新需要即时传递,决策也不再局限于会议室内。这种去中心化、实时化的协作模式,暴露了传统管理方式的诸多痛点:信息更新滞后导致决策依据过时,复杂的桌面端操作在手机小屏幕上难以进行,多平台间数据不同步造成信息混乱。 此外,移动场景下的使用具有“碎片化”和“即时性”特征。使用者期望在几分钟甚至几十秒内完成任务查看、进度更新或简短批复。因此,移动端管理工具的核心挑战在于,如何在有限的屏幕空间和交互时间内,提供清晰的信息架构、极简的操作路径和无缝的协作体验。谁能解决这些挑战,谁就能真正释放移动团队的巨大潜力。 移动端管理工具的价值,绝非简单地将电脑界面移植到手机。其核心在于深度适配移动场景,解决特定痛点。首先,它通过推送通知、移动快捷操作(如语音录入、拍照上传)和离线支持等功能,确保管理行为永不掉线。即使在网络不稳定的环境下,也能记录想法或更新状态,待网络恢复后自动同步。 其次,优秀的移动端工具注重降低认知负荷。它采用符合移动设备习惯的导航(如底部标签栏、侧滑菜单),将关键信息前置,并简化复杂操作。这让团队成员在忙碌或移动中,也能轻松参与项目管理,而非管理工具的负担。 最后,它扮演着团队协作神经末梢的角色。通过移动端,审批可以即时完成,突发问题能够被迅速标记@负责人,项目进展得以一键分享给客户。它缩短了从发现问题到协调解决的闭环,将管理行为渗透到工作的每一个细微瞬间,真正实现了“管理无处不在”。 了解其核心价值后,以下几款工具在移动端的适配性和用户体验方面各有侧重,可供参考。 Trello 以其看板视图著称,移动端通过流畅的拖拽手势和快捷添加按钮(支持拍照、录音)来管理任务,适合需要轻量、可视化管理的场景。 板栗看板 在贴合国内团队使用习惯方面进行了设计,移动端视图切换流畅,并通过与常用办公软件打通、支持微信便捷分享等方式,降低内外协作的门槛。 Asana 在移动端对复杂的项目层级关系进行了清晰的呈现,其“收件箱”功能能聚合所有任务通知,帮助用户在移动状态下聚焦处理待办事项,适合管理多线任务。 Microsoft To Do 聚焦于个人与轻团队任务管理,移动体验以快速为核心。其手机桌面小组件和“我的一天”智能推荐功能,有助于利用碎片时间专注完成当日重点。 展望未来,移动端管理工具的进化将更深入地与人工智能和具体业务场景结合。场景智能感知将成为标配。工具能根据用户的地理位置、时间甚至手机使用状态,自动推送最相关的任务列表或提醒,实现真正的上下文感知管理。 语音与自然语言交互的地位将进一步提升。未来的工具不仅能通过语音创建任务,更能理解复杂的自然语言指令,并自动执行,让管理在“动口不动手”间完成。 最后,跨工具自动化工作流将在移动端轻松搭建。用户可以在手机上通过简易操作,将管理工具与其他常用应用连接,自动创建任务或流转信息,让移动端不仅是管理的终端,更是自动化流程的便捷触发与控制中心。01 挑战与契机:移动办公环境下的管理新需求
02 核心价值:为什么移动端专用管理工具不可或缺
03 实战解析:主流移动端管理工具特点概览
04 未来展望:智能化与场景融合的演进方向
import json
from datetime import datetime, timedelta
from typing import List, Dict, Optional
from enum import Enum
class TaskPriority(Enum):
LOW = "低"
MEDIUM = "中"
HIGH = "高"
URGENT = "紧急"
class ContextType(Enum):
LOCATION = "位置"
TIME = "时间"
DEVICE_STATUS = "设备状态"
CALENDAR = "日历"
class MobileTaskAssistant:
"""
移动端智能任务助手
模拟未来移动管理工具的智能情景感知与自动生成能力
"""
def __init__(self):
self.user_context = {}
self.task_templates = self._load_templates()
def _load_templates(self) -> Dict:
"""加载情景化任务模板库"""
return {
"meeting": {
"title": "会议跟进",
"default_steps": ["整理纪要", "分配行动项", "设置下次会议时间"],
"context_triggers": [ContextType.CALENDAR, ContextType.TIME]
},
"commute": {
"title": "通勤时间处理",
"default_steps": ["收听语音简报", "批复简易请求", "规划当日重点"],
"context_triggers": [ContextType.LOCATION, ContextType.TIME]
},
"focus": {
"title": "深度工作时段",
"default_steps": ["屏蔽非紧急通知", "启动专注计时器", "列出核心任务"],
"context_triggers": [ContextType.TIME, ContextType.DEVICE_STATUS]
}
}
def update_context(self, context_type: ContextType, value: str):
"""更新用户当前情景信息"""
self.user_context[context_type] = {
"value": value,
"updated_at": datetime.now().isoformat()
}
print(f"[情景更新] {context_type.value}: {value}")
def generate_contextual_tasks(self) -> List[Dict]:
"""基于当前多重情景生成智能任务建议"""
suggested_tasks = []
# 情景1:基于时间的建议(例如:周一上午9点)
if ContextType.TIME in self.user_context:
time_ctx = self.user_context[ContextType.TIME]
hour = datetime.fromisoformat(time_ctx['value']).hour
weekday = datetime.fromisoformat(time_ctx['value']).weekday()
if weekday == 0 and 8 <= hour < 10: # 周一上午
suggested_tasks.append({
"title": "准备本周团队周会材料",
"source": "时间情景触发",
"priority": TaskPriority.HIGH,
"estimated_duration": "30分钟"
})
# 情景2:基于位置的建议(例如:接近客户办公地点)
if ContextType.LOCATION in self.user_context:
loc = self.user_context[ContextType.LOCATION]['value']
if "客户" in loc or "Client" in loc:
suggested_tasks.append({
"title": f"回顾与{loc}相关的最新项目进展",
"source": "位置情景触发",
"priority": TaskPriority.MEDIUM,
"estimated_duration": "15分钟"
})
# 情景3:基于日历事件的建议
if ContextType.CALENDAR in self.user_context:
event = self.user_context[ContextType.CALENDAR]['value']
suggested_tasks.append({
"title": f"{event}的会前准备",
"source": "日历情景触发",
"priority": TaskPriority.HIGH,
"estimated_duration": "20分钟",
"template": self.task_templates.get("meeting")
})
return suggested_tasks
def create_task_from_voice(self, voice_command: str) -> Dict:
"""解析自然语言语音指令并创建结构化任务"""
# 简化模拟自然语言处理
voice_command_lower = voice_command.lower()
task = {
"title": "",
"steps": [],
"priority": TaskPriority.MEDIUM,
"created_via": "语音指令",
"raw_command": voice_command
}
# 关键词匹配(模拟NLU理解)
if "明天" in voice_command_lower:
due_date = (datetime.now() + timedelta(days=1)).strftime("%Y-%m-%d")
task["due_date"] = due_date
if "紧急" in voice_command_lower or "立刻" in voice_command_lower:
task["priority"] = TaskPriority.URGENT
# 提取任务标题(模拟信息提取)
import re
# 简单匹配“创建...任务”或“记得...”模式
pattern = r'(创建|记得|需要)(.+?)(任务|事情|事宜)'
match = re.search(pattern, voice_command)
if match:
task["title"] = match.group(2).strip()
else:
task["title"] = voice_command[:30] + "..."
print(f"[语音任务已创建] {task['title']} - 优先级: {task['priority'].value}")
return task
def get_mobile_optimized_view(self, full_task_list: List[Dict]) -> Dict:
"""为移动端小屏幕生成优化后的信息视图"""
mobile_view = {
"today_focus": [],
"quick_actions": [],
"notifications": []
}
now = datetime.now()
for task in full_task_list:
# 提取今日高优先级任务
if task.get('priority') in [TaskPriority.HIGH, TaskPriority.URGENT]:
if task.get('due_date') == now.strftime("%Y-%m-%d"):
mobile_view["today_focus"].append({
"id": task.get("id", ""),
"title": task["title"][:20] + ("..." if len(task["title"]) > 20 else ""),
"priority": task["priority"].value
})
# 生成快速操作建议
if "批复" in task["title"] or "审核" in task["title"]:
mobile_view["quick_actions"].append({
"type": "审批",
"task_title": task["title"],
"action": "approve_or_reject"
})
# 基于情景生成通知
if len(mobile_view["today_focus"]) > 5:
mobile_view["notifications"].append("您今日高优先级任务较多,建议重新评估优先级")
return mobile_view
# 使用示例
if __name__ == "__main__":
print("=== 移动端智能任务助手演示 ===\n")
# 1. 初始化助手
assistant = MobileTaskAssistant()
# 2. 模拟更新用户情景
assistant.update_context(ContextType.TIME, datetime.now().isoformat())
assistant.update_context(ContextType.LOCATION, "中关村客户大厦附近")
assistant.update_context(ContextType.CALENDAR, "10:30 产品需求评审会")
# 3. 获取情景化任务建议
print("\n--- 智能情景任务建议 ---")
suggested = assistant.generate_contextual_tasks()
for i, task in enumerate(suggested, 1):
print(f"{i}. {task['title']} [优先级: {task['priority'].value}]")
# 4. 处理语音指令
print("\n--- 语音指令处理示例 ---")
voice_task = assistant.create_task_from_voice("创建一个明天提交季度报告的紧急任务")
print(f"语音创建成功: {voice_task}")
# 5. 生成移动端优化视图
print("\n--- 移动端优化视图 ---")
sample_tasks = [
{"id": "1", "title": "批复张三的采购申请", "priority": TaskPriority.HIGH, "due_date": datetime.now().strftime("%Y-%m-%d")},
{"id": "2", "title": "完成产品需求文档", "priority": TaskPriority.URGENT, "due_date": datetime.now().strftime("%Y-%m-%d")},
voice_task
]
mobile_view = assistant.get_mobile_optimized_view(sample_tasks + suggested)
print(json.dumps(mobile_view, ensure_ascii=False, indent=2))提示:选择移动端管理工具时,除了功能,请务必考察其离线工作能力和数据同步稳定性,这是保证移动场景下体验流畅的基石。建议团队优先选择提供充足免费方案或试用的工具,让成员在实际移动场景中体验后再做决策。
简介:在数字化协作时代,支持无限画布的可视化工具正成为连接碎片化思想、构建系统知识的核心载体。与传统受限于固定页面或分页的工具相比,无限画布通过提供无边界的工作平面,允许用户自由组织思维导图、设计草图、项目看板与文档,实现信息从线性排列到空间关联的范式转变。这类工具融合了可视化、自由布局与实时协作,尤其适合应对复杂的创意构建、项目规划和战略梳理。未来,随着人工智能与空间计算技术的融入,无限画布将进化为更具沉浸感和智能辅助的“数字工作大脑”。 在日常工作与创意活动中,我们常常受限于传统文档、幻灯片或白板工具的固定边界。思绪是发散的,项目是动态的,但工具却是僵化的。无限画布(Infinite Canvas)正是为了打破这一束缚而生,它提供了一个可以无限缩放、延展和连接的数字平面,让想法得以自然生长和有机组织。 在知识工作领域,信息的组织方式正经历一场静默的革命。过去,我们依赖Word文档的线性叙述、PPT的逐页演示或传统白板的有限物理空间。这种方式在处理复杂系统、非线性思考或需要宏观与微观视角快速切换的任务时,往往显得力不从心。 传统工具的三大核心局限日益凸显: 与此同时,分布式团队、敏捷项目管理和设计思维等新型工作方式的普及,对工具的灵活性、可视化程度和实时协作能力提出了更高要求。无限画布工具正是回应这一需求的产物,它将工作空间从“页面”升级为“宇宙”,让每一个想法、任务或资料都能找到一个位置,并通过连线、嵌套、区域划分建立起丰富的上下文关系,从而实现思维和项目的全景式管理。 无限画布的核心价值在于它模拟并增强了人类思维的非线性、关联性特质。它不仅仅是一个更大的“纸”,而是一个多维度的信息组织和协作环境。 市场上有多种工具都提供了无限画布的核心体验,但在设计哲学、功能侧重和适用场景上各有不同。 Miro 是这一领域的全球领军者,以其丰富的模板库和强大的集成生态著称。它提供了从头脑风暴、用户体验设计、敏捷仪式到战略规划等数百个预制模板,团队可以一键生成适合的工作区。其插件系统允许无缝接入Jira、Notion、Figma等主流工具,使其成为跨团队、跨流程的协作中枢。Miro的画布性能优秀,即使承载大量元素也能保持流畅,非常适合大型、复杂的协作项目。 Figma FigJam 作为设计工具Figma的孪生产品,完美继承了其流畅的实时协作体验和精致的设计基因。它的核心优势在于与Figma设计文件的深度互通,设计师可以在设计稿和头脑风暴画布之间无缝切换,让创意到设计的链路极度顺滑。FigJam的工具集简洁而富有表现力,如表情符号反应、计时器、投票等,特别适合进行高效、互动的线上研讨会和工作坊。 板栗看板 作为一款在国内体验流畅的视觉化协作工具,在无限画布与本土化项目管理结合方面表现出色。它巧妙地将看板管理的敏捷性与无限画布的自由度相结合。团队不仅可以利用无限画布进行自由脑暴和方案梳理,还能一键将讨论结果转化为结构化的看板任务流。其实时协作、评论和任务指派功能深度贴合国内团队的使用习惯,且对中文排版和本地化服务的支持良好,为中小型团队提供了一个低门槛、高自由度的可视化协作入口。 Heptabase 则专注于个人知识管理与深度思考。它将无限画布与卡片盒笔记法相结合,用户可以将阅读笔记、思考碎片以卡片形式置于白板,并通过绘制连线构建知识网络。它的设计更倾向于构建个人第二大脑,帮助用户进行复杂的知识梳理、研究和写作准备,其双链笔记和可视化关联功能尤为强大。 无限画布的未来,将超越二维平面的协作,向更智能、更沉浸的方向演进。 无限画布的底层可以看作一个能无限扩展的坐标系统和对“对象”的管理。以下是一个高度简化的概念模型,展示了如何管理画布上的基础元素及其空间关系: 这个简易模型展示了无限画布底层管理的核心概念:对象的自由定位、对象间的关联连接以及基于坐标和缩放的视图管理。实际工具的实现远比此复杂,涉及高性能渲染、实时冲突解决、离线协同算法等前沿技术。 选择一款合适的无限画布工具,本质上是为团队选择一个动态、可扩展的协作环境和思维方式。它不再仅仅是记录结果的工具,更是承载思考过程、激发集体智慧的平台。01 挑战与机遇:从线性文档到空间化思维的演进
02 核心价值:无限画布为何重塑工作效率
03 实战解析:主流无限画布可视化工具深度评测
04 未来展望:AI与空间计算驱动的下一代无限画布
技术视角:一个简易的无限画布对象管理模型
class InfiniteCanvasObject:
"""代表无限画布上的一个基础对象(如文本、图形、便签)"""
def __init__(self, obj_id, content, obj_type="text"):
self.id = obj_id
self.content = content # 对象内容
self.type = obj_type # 对象类型:text, image, shape, sticky_note等
self.x = 0 # 画布上的x坐标
self.y = 0 # 画布上的y坐标
self.width = 100
self.height = 50
self.connections = [] # 与其他对象的连接线ID列表
class InfiniteCanvas:
"""无限画布的核心管理类"""
def __init__(self):
self.objects = {} # 存储所有对象:{obj_id: object}
self.connections = {} # 存储所有连接线
self.viewport_center = (0, 0) # 当前视图中心坐标
self.zoom_level = 1.0 # 当前缩放级别
def add_object(self, content, obj_type, x, y):
"""在指定坐标添加新对象"""
obj_id = f"obj_{len(self.objects)+1}"
new_obj = InfiniteCanvasObject(obj_id, content, obj_type)
new_obj.x, new_obj.y = x, y
self.objects[obj_id] = new_obj
return obj_id
def connect_objects(self, from_obj_id, to_obj_id, connection_type="line"):
"""在两个对象间创建连接"""
conn_id = f"conn_{len(self.connections)+1}"
self.connections[conn_id] = {
'from': from_obj_id,
'to': to_obj_id,
'type': connection_type
}
# 将连接ID添加到两个对象的关联列表中
if from_obj_id in self.objects:
self.objects[from_obj_id].connections.append(conn_id)
if to_obj_id in self.objects:
self.objects[to_obj_id].connections.append(conn_id)
return conn_id
def get_objects_in_view(self, viewport_width, viewport_height):
"""模拟获取当前视图区域内的对象(简化版:基于坐标范围筛选)"""
vx, vy = self.viewport_center
scale = self.zoom_level
# 计算视图边界
left = vx - viewport_width / (2 * scale)
right = vx + viewport_width / (2 * scale)
top = vy - viewport_height / (2 * scale)
bottom = vy + viewport_height / (2 * scale)
visible_objs = []
for obj in self.objects.values():
if (left <= obj.x <= right) and (top <= obj.y <= bottom):
visible_objs.append(obj)
return visible_objs
def zoom_to_fit(self, padding=50):
"""缩放并平移视图,使所有对象在视图中居中显示"""
if not self.objects:
return
# 计算所有对象的边界框
all_x = [obj.x for obj in self.objects.values()]
all_y = [obj.y for obj in self.objects.values()]
min_x, max_x = min(all_x), max(all_x)
min_y, max_y = min(all_y), max(all_y)
# 计算新的视图中心
self.viewport_center = ((min_x + max_x) / 2, (min_y + max_y) / 2)
# 计算合适的缩放级别(这是一个简化逻辑)
self.zoom_level = 0.8 # 示例值,实际应根据边界框和视图尺寸动态计算
print(f"视图已调整至中心 {self.viewport_center}, 缩放级别 {self.zoom_level}")
# 使用示例
if __name__ == "__main__":
# 创建一个无限画布
my_canvas = InfiniteCanvas()
# 添加几个对象(模拟头脑风暴)
idea1 = my_canvas.add_object("开发新功能:AI助手", "sticky_note", -200, 100)
idea2 = my_canvas.add_object("调研用户反馈", "sticky_note", -50, 150)
idea3 = my_canvas.add_object("设计交互原型", "sticky_note", 100, 50)
# 建立对象间的关联
my_canvas.connect_objects(idea1, idea2)
my_canvas.connect_objects(idea2, idea3)
# 模拟获取当前视图中的对象
print("当前视图中的对象:")
for obj in my_canvas.get_objects_in_view(800, 600):
print(f" - [{obj.type}] {obj.content} 位于 ({obj.x}, {obj.y})")
# 一键缩放至合适视图
my_canvas.zoom_to_fit()
如果说: 那么 2026 年,人工智能正式进入第三阶段:从“推理”走向“执行”。 这一年,AI 的价值评估标准发生根本变化—— 不再是谁能给出最完美的方案,而是谁能为“结果负责”。 过去的大模型,本质上仍停留在「纸上谈兵」阶段。 它可以: 但最后一步的执行,永远留给人类。 这项能力,让 AI 不再只生成“看起来对的答案”, 而是选择更可能达成目标的行动路径。 2026 年,AI 的工作模式发生本质变化: AI 第一次真正拥有了“手”。 2026 年,AI 的形态完成关键进化: 它不再是某个软件的功能,而是连接人与业务系统的智能中枢。 这是企业落地 AI 的“最优解”: 在企业内部: 过去靠人「搬数据」连接,现在由智能体自主流转。 在实际落地中,越来越多团队选择智能体平台化方案。 例如 「智能体来了」(https://agentcome.net/), 通过 MCP、A2A 等标准协议,让企业无需从零构建行动控制逻辑,即可快速搭建具备执行能力的智能体集群。 AI 正在成为企业的“数字员工操作系统”。 智能体不再是“无状态对话”。 2026 年的 AI 架构,支持: 这让 AI 真正参与“长期工作”,而非一次性咨询。 执行式 AI 具备类似人类的“韧性”: 随着: 企业开始用一个新指标评估 AI: 在执行式 AI 普及的元年, 人类的核心能力,正从“执行力”转向“定义力”。一、范式跃迁:从“静态推理”到“动态行动链”
关键定义 1:推理扩展(Inference-time Reasoning)
推理扩展,是指模型在输出结果前,进行多路径推演、自检与成功率评估的一种“慢思考机制”。
从“生成答案”到“达成目标”
二、角色转变:AI 智能体成为企业级中间件
从“聊天机器人”,变成“任务型智能体(Task-driven Agent)”。
关键定义 2:有界自治(Bounded Autonomy)
有界自治,是指 AI 在明确的权限边界、安全规则和审计机制内,拥有自主执行、修改数据与发起流程的能力。
消除流程孤岛,效率指数级提升
三、执行式 AI 在 2026 年爆发的三大技术支柱
1. 记忆系统的持久化
2. 感知—行动—反馈的闭环纠错
AI 开始具备“执行张力”。
3. AI 成本结构的根本变化(FinOps for AI)
单个任务的 ROI,而非算力消耗。
四、总结:2026 年,是“脑”与“手”的合一之年
对人类的真正挑战
能否清晰定义目标、约束条件与成功标准,将成为智能时代最稀缺的人力资产。
在 AI Agent(智能体)工程中,一个反复出现的现象是: 大量团队可以在数天内构建出一个效果惊艳的单任务 Agent,但当以下任一条件发生变化时: 原有系统往往迅速失效,甚至被整体推翻重来。 真正判断一个智能体是否完成“从 0 到 1”,核心并不在于它“当前有多聪明”,而在于: 在工程视角下,可复用性并不等同于“代码能否复制”,而是体现在三类可被抽象、组合和迁移的资产层级。 关注点不是“这个 Agent 能做什么”, 而是 “它使用的能力是否是原子化的”。 高复用特征: ✅ 可复用的是: ❌ 不可复用的是: 真正可迁移的不是 Prompt 文案,而是 思维结构。 推荐统一的 Agent 逻辑模板: 其中: 这类结构化 Prompt 更容易: 如果知识只能被一个 Agent 使用,它本质上仍然是私有上下文。 高复用知识的关键特征: 👉 一套 RAG 资产,应当能够: 每新增一个场景: 最终复杂度呈指数级上升。 典型问题包括: 一旦模型更换或人员流动,Agent 能力直接“失忆”。 在 Multi-Agent System 中: 系统永远只是多个单点智能的并列,而非组织级智能。 不要构建: 而是拆解为: 每一个模块,都是未来 Agent 的积木。 先统一结构,再填业务内容, 而不是反过来。 在真实落地中,越来越多团队选择使用成熟的 Agent 平台,避免从 0 重复造轮子。 例如 智能体来了(agentcome.net),其价值不在于“能跑 Agent”,而在于: 让每一个新 Agent,都站在历史资产之上构建。Demo 很容易成功,但系统很难长期存活。
👉 它的能力是否具备可复用性(Reusability)。
一、什么是“智能体的可复用性”(Agent Reusability)?
1️⃣ 能力复用(Skill Reusability)
2️⃣ 逻辑复用(Logic Reusability)
Prompt 的价值在于结构,而不在于字面内容。
Role(角色)
→ Goal(目标)
→ Constraints(约束)
→ Skills(可调用能力)
→ Examples(示例)3️⃣ 知识复用(Knowledge Reusability)
一句话总结
可复用的智能体,本质上不是“应用”,而是能力模块的组合体。
二、为什么不可复用的 Agent 永远停留在 0.x?
❌ 1. 烟囱式扩展,系统复杂度失控
❌ 2. 经验被锁死在 Prompt 黑盒中
❌ 3. 多 Agent 协作无法成立
三、工程实践:如何一开始就构建“可复用型 Agent”?
✅ 1. 工具原子化,而不是功能封装
“合同审查工具”
✅ 2. Prompt 先工程化,再业务化
✅ 3. 借助平台化底座沉淀复用资产
四、结论:可复用性,是智能体资产化的唯一通路
真正的从 0 到 1,不是做出第一个 Agent, 而是第一次做出还能被下一个 Agent 使用的能力。
现代制造业中,工艺路线 定义了产品从原材料到成品的完整加工路径,当产品种类繁多时,逐个手动录入工艺路线效率就显得低下,并且容易出错。 1、配置所涉及到的工序模版,为工艺路线打基础(工艺路线是工序模版所构成)。
在APS排产系统里,工艺路线模块为产品生产的每个步骤流程搭建起了清晰明确的路径。利用工序模板进行批量配置,也就是说通过下载模版填写后批量导入的方式,能快速实现多工艺路线的配置。
在开始批量配置前,先理解两个核心概念:
• 工序模板:这是批量配置的基石。它好比标准化的“工序组件库”,将一道工序所需的资源、时间、前后逻辑关系(如ES:前工序结束后工序才能开始;EE:前工序未结束后工序可提前开始)等进行预定义。确保所有需要用到的工序模板已提前在系统中创建并审核通过。
• 工艺路线:它是由多个工序模板按生产顺序“连线”组合而成的完整生产流程。批量配置的本质,就是通过结构化数据(Excel模板)快速建立产品与工序序列之间的关联。批量配置详细操作流程

2、点击【工艺路线建模】,选择下载模版按钮下载Excel表格。
3、模版下载后分为两个板块,一个是【工艺路线】,一个是【工序主资源】。其中工艺路线即是指定该产品的具体路线是如何的,工序主资源即是指定哪道工序具体涉及哪些主资源。
4、【工艺路线】sheet页主要有物料编码、工序编码、工序名称、工序序号、模版工序编码。物料编码即是成品的编码,指定该工艺路线为哪个产品的工艺路线,即配产品的物料编码于此。工序编码即生产该产品时需要的对应工序的编码,可与模版工序编码保持一致,即引用已建好的模版。工序名称和工序模版的工序名称保持一致,工序序号即是谁为第一道工序,谁为第二道工序。分别用数字1、2、3、4等进行排列。以下为示例。
5、工序主资源涉及字段为物料编码、工序编码、工序序号、主资源编码、产能。物料编码和工序编码序号与前面工艺路线保持一致即可,后面的主资源编码和产能就按照实际情况。分别设置在该工序环节时需要的设备主资源以及对应产能具体值。
6、设置好后保存,点击导入即可。
刚刚,阶跃星辰在其官方公众号发文宣布,人工智能领域知名专家印奇正式出任公司董事长,全面负责公司的整体战略节奏与技术方向制定。公司方面表示,印奇在人工智能技术演进、产业落地与组织建设等方面拥有长期而系统的实践经验,其加入将为阶跃星辰进入下一发展阶段提供更强的战略牵引力与执行确定性。 公开资料显示,印奇是中国人工智能产业的代表性人物之一,清华大学计算机系背景出身,长期深耕计算机视觉与人工智能基础技术研究。他是旷视科技的联合创始人之一,曾长期担任旷视 CEO,主导公司从学术研究走向大规模产业化落地,推动计算机视觉技术在城市物联网、供应链、消费电子等多个领域实现商业化。 在阶跃星辰的组织架构中,印奇将与公司 CEO 姜大昕、首席科学家张祥雨以及 CTO 朱亦博共同组成核心管理团队。该团队在基础模型研究、系统工程能力以及产业化推进等方面形成互补配置,构建起从前沿研究到商业落地的完整决策与执行链条。 阶跃星辰方面介绍,公司近年来围绕基础大模型持续加大投入,已在语言基模型、多模态模型以及端云协同模型等方向形成了具备国际竞争力的技术体系。在模型结构设计、训练效率、推理性能与系统协同等关键能力上,公司认为自身已经“跑出世界领先水平”。 在应用层面,阶跃星辰正围绕汽车、手机与穿戴式设备、具身机器人等核心终端场景,加快构建“AI+终端”的商业化体系。公司明确表示,“基础大模型”与“AI+终端”并行推进,是其长期坚定不移的战略选择。通过将通用模型能力与具体终端形态深度耦合,阶跃希望推动人工智能从“云端能力”向“场景智能”演进。 值得注意的是,印奇目前同时担任千里科技董事长,在人工智能与汽车产业结合方面已有较为成熟的实践经验。千里科技长期聚焦智能汽车相关技术与产品,涵盖感知、决策、系统集成等多个环节。阶跃星辰表示,未来将与千里科技进一步深化合作,在智能汽车及更广泛的终端场景中协同推进“AI+终端”战略落地,加速技术能力向产品与规模化应用转化。
穿着浑身刺挠,不在家的时候又不方便脱下来找,兄弟们怎么处理的
提高游戏服务器的安全性和防护机制对于保护玩家数据、游戏平衡性和用户体验至关重要。我们可以从服务器端安全、数据安全、DDoS防护、日志监控等方面来提高游戏服务器的安全性。 服务器端的安全是比较重要的一点。建议用户及时更新游戏服务器和操作系统的补丁和安全更新,以修复已知的漏洞和安全问题。在安全配置方面,可以通过配置服务器端防火墙、入侵检测系统(IDS)、入侵防御系统(IPS)等安全设备,限制对服务器的访问和保护敏感数据。同时,也可以使用SSL/TLS等加密协议保护游戏服务器和客户端之间的通信,防止数据被窃取和篡改。最后也可以限制对服务器的远程访问和管理权限,采用多因素身份验证等安全措施保护管理员账号。 数据安全防护也比较重要,主要体现在数据加密、反作弊系统及数据验证三个方面。对存储在服务器上的敏感数据(如用户密码、个人信息)进行加密存储,保护数据不被恶意获取。部署反作弊系统和游戏防作弊引擎,检测和阻止作弊行为,维护游戏的公平性和平衡性。对客户端发送的数据进行严格验证和过滤,防止恶意数据包和数据篡改攻击。 DDOS攻击防护也很重要,使用DDoS防护服务提供商提供的流量清洗服务,过滤和屏蔽DDoS攻击流量,保护服务器免受攻击。配置网络设备和防火墙,限制并发连接数、数据包频率等参数,减缓DDoS攻击对服务器的影响。使用CDN(内容分发网络)服务来分发游戏内容和数据,减轻游戏服务器的负载和DDoS攻击压力。 日志记录和监控也是提高游戏服务器安全性的重要步骤,定期记录游戏服务器的运行日志和安全事件日志,以便分析和调查安全事件。配置实时监控系统监控服务器的性能和安全状态,及时发现异常行为和安全威胁。 最后,需要进行定期漏洞扫描和渗透测试,定期对游戏服务器进行漏洞扫描和安全评估,发现并修复潜在的安全漏洞和弱点。进行定期的渗透测试,模拟黑客攻击和渗透行为,评估游戏服务器的安全性和弹性。 渗透测试(德迅云安全) ● 安全性漏洞挖掘 找出应用中存在的安全漏洞。安全应用检测是对传统安全弱点的串联并形成路径,最终通过路径式的利用而达到模拟入侵的效果。发掘应用中影响业务正常运行、导致敏感信息泄露、造成现金和信誉损失的等的漏洞。 ● 漏洞修复方案 渗透测试目的是防御,故发现漏洞后,修复是关键。安全专家针对漏洞产生的原因进行分析,提出修复建议,以防御恶意攻击者的攻击。 ● 回归测试 漏洞修复后,对修复方案和结果进行有效性评估,分析修复方案的有损打击和误打击风险,验证漏洞修复结果。汇总漏洞修复方案评估结果,标注漏洞修复结果,更新并发送测试报告。 综上所述,提高游戏服务器的安全性和防护机制需要综合考虑网络安全、数据安全、防作弊、DDoS攻击防护、日志和监控、社区管理等多个方面,采取多层次、多维度的安全措施和防护策略,确保游戏服务器的稳定运行和用户数据的安全保护。
在人工智能快速发展的今天,Agent(智能体)已成为连接大语言模型与实际应用场景的关键桥梁。现代Agent不仅能够理解自然语言指令,更重要的是能够通过工具调用(Tool Calling)主动执行操作,完成复杂的任务。从代码编写、数据分析到网页浏览、文件操作,Agent正在重塑我们与计算机交互的方式。 OpenManus是一个开源的通用AI Agent框架,它展示了如何构建一个功能完整、架构清晰的现代Agent系统。本文将以OpenManus项目为蓝本,系统性地解答现代Agent构建中的四个核心问题: 通过深入分析OpenManus的代码实现,我们将构建对现代Agent架构的完整认知,为构建自己的Agent系统提供实践指导。 现代Agent系统通常采用分层架构,每一层负责不同的职责。OpenManus采用了清晰的四层架构设计: 核心功能: 这种设计将"决策"和"执行"解耦,使得Agent的思考过程更加清晰可控。 定义了Agent系统的核心数据结构: 工具系统是Agent能力的核心扩展点: 所有工具都继承自 以 工具描述的质量直接影响LLM的选择准确性。好的描述应该: 在Agent类定义时,通过 这种方式适合在Agent初始化时就确定可用的工具。 OpenManus支持通过MCP(Model Context Protocol)协议动态连接远程工具服务器: MCP工具的工作流程: 工具必须转换为LLM可理解的格式。 这个工具列表会被传递给LLM,LLM根据工具描述和当前上下文,决定调用哪些工具。 Agent调用工具的过程遵循ReAct模式,分为三个阶段: Agent分析当前状态,决定需要调用哪些工具: LLM接收的信息包括: LLM基于这些信息,生成结构化的工具调用决策。 Agent执行LLM决定的工具调用: 工具执行结果被添加到对话历史,供下一轮思考使用: 完整的执行循环在 每一步都是完整的think-act循环,直到任务完成或达到最大步数。 ReAct(Reasoning + Acting)是现代Agent的核心模式,它将Agent的执行分为三个环节: 这三个环节循环往复,直到任务完成。 这种设计的优势: Agent的思考能力主要依赖于精心设计的提示词: System Prompt:定义Agent的角色和能力边界 Next Step Prompt:指导Agent如何选择工具 工具描述:每个工具的name、description、parameters共同构成LLM决策的依据 LLM的function calling能力使得Agent能够进行结构化决策: LLM的处理过程: LLM返回的格式: Agent的状态转换遵循明确的状态机: 状态转换通过上下文管理器安全控制: 卡死检测机制: 当检测到卡死时,Agent会添加提示词引导改变策略: 某些工具具有特殊语义,如 对话历史包含完整的交互序列: Agent的上下文由三部分构成: 这种动态上下文调整使得Agent能够根据当前任务状态,提供更精准的决策。 设计新工具时,遵循以下原则: 示例:设计一个文件搜索工具 提示词优化是提升Agent性能的关键: 系统提示词: 下一步提示词: 工具描述: 示例:优化后的系统提示词 调试Agent需要系统化的方法: 日志记录:在关键节点添加详细日志 示例:调试工具 Token管理: 工具选择优化: 并发执行: 缓存机制: 示例:工具结果缓存 通过深入分析OpenManus项目,我们总结出现代Agent系统的核心要素: OpenManus的架构设计具有以下优势: 现代Agent技术仍在快速发展,未来可能的方向包括: 构建现代Agent是一个系统工程,需要深入理解LLM能力、工具设计、系统架构等多个方面。OpenManus项目为我们提供了一个优秀的参考实现,展示了如何将理论转化为实践。 通过本文的系统性分析,我们希望读者能够: 现代Agent技术正在快速发展,期待更多开发者加入这个领域,共同推动AI Agent技术的进步。 参考资料:一、引言
二、项目结构与核心代码架构
2.1 分层架构设计
基础层(Base Layer):
app/agent/base.pyBaseAgent是所有Agent的抽象基类,提供了Agent运行的基础设施:class BaseAgent(BaseModel, ABC):
name: str # Agent唯一标识
description: Optional[str] # Agent描述
system_prompt: Optional[str] # 系统级指令
next_step_prompt: Optional[str] # 下一步行动提示
llm: LLM # 大语言模型实例
memory: Memory # 记忆存储
state: AgentState # 当前状态(IDLE/RUNNING/FINISHED/ERROR)
max_steps: int = 10 # 最大执行步数
current_step: int = 0 # 当前步数
state_context上下文管理器实现安全的状态转换update_memory()方法统一管理对话历史run()方法实现主执行循环,包含步数限制和卡死检测async def run(self, request: Optional[str] = None) -> str:
if request:
self.update_memory("user", request)
async with self.state_context(AgentState.RUNNING):
while (self.current_step < self.max_steps and
self.state != AgentState.FINISHED):
self.current_step += 1
step_result = await self.step() # 执行单步
if self.is_stuck(): # 检测是否卡死
self.handle_stuck_state()
思考层(Reasoning Layer):
app/agent/react.pyReActAgent实现了经典的ReAct(Reasoning + Acting)模式,将Agent的执行分为思考和行动两个阶段:class ReActAgent(BaseAgent, ABC):
@abstractmethod
async def think(self) -> bool:
"""处理当前状态并决定下一步行动"""
@abstractmethod
async def act(self) -> str:
"""执行已决定的行动"""
async def step(self) -> str:
"""执行单步:思考然后行动"""
should_act = await self.think()
if not should_act:
return "Thinking complete - no action needed"
return await self.act()
工具调用层(Tool Call Layer):
app/agent/toolcall.pyToolCallAgent在ReAct模式基础上,实现了具体的工具调用机制:class ToolCallAgent(ReActAgent):
available_tools: ToolCollection # 可用工具集合
tool_choices: TOOL_CHOICE_TYPE = ToolChoice.AUTO
tool_calls: List[ToolCall] = Field(default_factory=list)
async def think(self) -> bool:
# 调用LLM,传入工具列表
response = await self.llm.ask_tool(
messages=self.messages,
system_msgs=[Message.system_message(self.system_prompt)],
tools=self.available_tools.to_params(), # 工具列表
tool_choice=self.tool_choices,
)
# 解析LLM返回的工具调用
self.tool_calls = response.tool_calls if response else []
# ...
async def act(self) -> str:
# 执行工具调用
for command in self.tool_calls:
result = await self.execute_tool(command)
# 将结果添加到记忆
tool_msg = Message.tool_message(
content=result,
tool_call_id=command.id,
name=command.function.name,
)
self.memory.add_message(tool_msg)
应用层(Application Layer):
app/agent/manus.pyManus是具体的业务Agent实现,配置了实际可用的工具集合:class Manus(ToolCallAgent):
name: str = "Manus"
system_prompt: str = SYSTEM_PROMPT.format(directory=config.workspace_root)
# 配置工具集合
available_tools: ToolCollection = Field(
default_factory=lambda: ToolCollection(
PythonExecute(), # Python代码执行
BrowserUseTool(), # 浏览器操作
StrReplaceEditor(), # 文件编辑
AskHuman(), # 人工交互
Terminate(), # 终止工具
)
)
2.2 核心代码模块
数据模型:
app/schema.pyclass Message(BaseModel):
role: ROLE_TYPE # user/assistant/system/tool
content: Optional[str]
tool_calls: Optional[List[ToolCall]]
tool_call_id: Optional[str] # 关联工具调用结果
base64_image: Optional[str] # 支持多模态
LLM封装:
app/llm.pyLLM类提供了统一的大模型接口,关键方法:ask_tool():支持function calling的调用方法,接收工具列表并返回工具调用决策async def ask_tool(
self,
messages: List[Union[dict, Message]],
system_msgs: Optional[List[Union[dict, Message]]] = None,
tools: Optional[List[dict]] = None,
tool_choice: TOOL_CHOICE_TYPE = ToolChoice.AUTO,
) -> ChatCompletionMessage:
# 格式化消息
messages = self.format_messages(messages, supports_images)
# 计算token并检查限制
input_tokens = self.count_message_tokens(messages)
if not self.check_token_limit(input_tokens):
raise TokenLimitExceeded(...)
# 调用API
response = await self.client.chat.completions.create(
model=self.model,
messages=messages,
tools=tools,
tool_choice=tool_choice,
)
return response.choices[0].message
工具系统:
app/tool/三、工具如何被添加到Agent
3.1 工具的定义与实现
工具基类设计
BaseTool,它定义了工具的标准接口:class BaseTool(ABC, BaseModel):
name: str # 工具名称,必须唯一
description: str # 工具描述,LLM据此决定是否使用
parameters: Optional[dict] # JSON Schema格式的参数定义
@abstractmethod
async def execute(self, **kwargs) -> Any:
"""工具执行逻辑,子类必须实现"""
pass
def to_param(self) -> Dict:
"""转换为OpenAI function calling格式"""
return {
"type": "function",
"function": {
"name": self.name,
"description": self.description,
"parameters": self.parameters,
},
}
工具实现示例
PythonExecute工具为例:class PythonExecute(BaseTool):
name: str = "python_execute"
description: str = "Executes Python code string..."
parameters: dict = {
"type": "object",
"properties": {
"code": {
"type": "string",
"description": "The Python code to execute.",
},
},
"required": ["code"],
}
async def execute(self, code: str, timeout: int = 5) -> Dict:
"""执行Python代码"""
# 使用多进程执行,支持超时控制
with multiprocessing.Manager() as manager:
result = manager.dict({"observation": "", "success": False})
proc = multiprocessing.Process(
target=self._run_code, args=(code, result, safe_globals)
)
proc.start()
proc.join(timeout)
# ...
return dict(result)
3.2 Agent中的工具配置
静态工具配置
Field(default_factory=...)配置工具集合:class Manus(ToolCallAgent):
available_tools: ToolCollection = Field(
default_factory=lambda: ToolCollection(
PythonExecute(),
BrowserUseTool(),
StrReplaceEditor(),
AskHuman(),
Terminate(),
)
)
动态工具添加
ToolCollection提供了动态添加工具的方法:class ToolCollection:
def __init__(self, *tools: BaseTool):
self.tools = tools
self.tool_map = {tool.name: tool for tool in tools}
def add_tool(self, tool: BaseTool):
"""添加单个工具"""
if tool.name in self.tool_map:
logger.warning(f"Tool {tool.name} already exists, skipping")
return self
self.tools += (tool,)
self.tool_map[tool.name] = tool
return self
def add_tools(self, *tools: BaseTool):
"""批量添加工具"""
for tool in tools:
self.add_tool(tool)
return self
MCP工具的动态添加
class Manus(ToolCallAgent):
mcp_clients: MCPClients = Field(default_factory=MCPClients)
async def connect_mcp_server(
self, server_url: str, server_id: str = "", use_stdio: bool = False
) -> None:
"""连接MCP服务器并添加其工具"""
if use_stdio:
await self.mcp_clients.connect_stdio(server_url, [], server_id)
else:
await self.mcp_clients.connect_sse(server_url, server_id)
# 获取新工具并添加到可用工具集合
new_tools = [
tool for tool in self.mcp_clients.tools
if tool.server_id == server_id
]
self.available_tools.add_tools(*new_tools)
list_tools()获取服务器提供的工具列表MCPClientTool代理class MCPClientTool(BaseTool):
"""MCP工具的代理,执行时调用远程服务器"""
session: Optional[ClientSession] = None
server_id: str = ""
original_name: str = ""
async def execute(self, **kwargs) -> ToolResult:
"""通过MCP协议调用远程工具"""
result = await self.session.call_tool(self.original_name, kwargs)
return ToolResult(output=result.content)
3.3 工具Schema转换
to_param()方法将工具转换为OpenAI function calling格式:def to_param(self) -> Dict:
return {
"type": "function",
"function": {
"name": self.name,
"description": self.description,
"parameters": self.parameters, # JSON Schema格式
},
}
ToolCollection.to_params()将所有工具转换为列表:def to_params(self) -> List[Dict[str, Any]]:
return [tool.to_param() for tool in self.tools]
四、Agent如何调用这些工具
4.1 工具调用的完整流程
Step 1: 思考阶段(think)
async def think(self) -> bool:
# 1. 添加下一步提示到消息历史
if self.next_step_prompt:
user_msg = Message.user_message(self.next_step_prompt)
self.messages += [user_msg]
# 2. 调用LLM,传入工具列表
response = await self.llm.ask_tool(
messages=self.messages, # 对话历史
system_msgs=[Message.system_message(self.system_prompt)],
tools=self.available_tools.to_params(), # 工具列表
tool_choice=self.tool_choices, # AUTO/REQUIRED/NONE
)
# 3. 解析LLM返回的工具调用
self.tool_calls = response.tool_calls if response else []
content = response.content if response else ""
# 4. 创建Assistant消息并添加到记忆
assistant_msg = Message.from_tool_calls(
content=content, tool_calls=self.tool_calls
)
self.memory.add_message(assistant_msg)
return bool(self.tool_calls)
Step 2: 执行阶段(act)
async def act(self) -> str:
if not self.tool_calls:
return self.messages[-1].content or "No action to execute"
results = []
for command in self.tool_calls:
# 执行单个工具调用
result = await self.execute_tool(command)
# 将结果封装为ToolMessage
tool_msg = Message.tool_message(
content=result,
tool_call_id=command.id,
name=command.function.name,
)
self.memory.add_message(tool_msg)
results.append(result)
return "\\n\\n".join(results)
Step 3: 结果反馈
async def execute_tool(self, command: ToolCall) -> str:
name = command.function.name
# 1. 查找工具实例
if name not in self.available_tools.tool_map:
return f"Error: Unknown tool '{name}'"
# 2. 解析参数
args = json.loads(command.function.arguments or "{}")
# 3. 执行工具
result = await self.available_tools.execute(name=name, tool_input=args)
# 4. 处理特殊工具(如Terminate)
await self._handle_special_tool(name=name, result=result)
# 5. 格式化结果
observation = f"Observed output of cmd `{name}` executed:\\n{str(result)}"
return observation
4.2 核心代码流程
ToolCollection.execute():工具执行入口
async def execute(
self, *, name: str, tool_input: Dict[str, Any] = None
) -> ToolResult:
# 1. 根据名称查找工具
tool = self.tool_map.get(name)
if not tool:
return ToolFailure(error=f"Tool {name} is invalid")
try:
# 2. 调用工具的execute方法
result = await tool(**tool_input)
return result
except ToolError as e:
return ToolFailure(error=e.message)
工具选择策略
tool_choice参数控制LLM的工具选择行为:if self.tool_choices == ToolChoice.REQUIRED and not self.tool_calls:
# 要求调用工具但LLM没有返回,可能需要重试
return True
if self.tool_choices == ToolChoice.AUTO and not self.tool_calls:
# 自动模式,如果没有工具调用但有文本内容,继续
return bool(content)
4.3 执行循环
BaseAgent.run()中实现:async def run(self, request: Optional[str] = None) -> str:
if request:
self.update_memory("user", request)
results: List[str] = []
async with self.state_context(AgentState.RUNNING):
while (
self.current_step < self.max_steps and
self.state != AgentState.FINISHED
):
self.current_step += 1
# 执行单步:think -> act
step_result = await self.step()
# 检测是否卡死
if self.is_stuck():
self.handle_stuck_state()
results.append(f"Step {self.current_step}: {step_result}")
return "\\n".join(results)
五、Agent是如何思考的
5.1 ReAct模式:推理与行动循环
实现机制
async def step(self) -> str:
should_act = await self.think() # 思考:分析并决策
if not should_act:
return "Thinking complete - no action needed"
return await self.act() # 行动:执行工具
5.2 LLM驱动的决策机制
提示词工程
SYSTEM_PROMPT = (
"You are OpenManus, an all-capable AI assistant, aimed at solving any task "
"presented by the user. You have various tools at your disposal that you can "
"call upon to efficiently complete complex requests. Whether it's programming, "
"information retrieval, file processing, web browsing, or human interaction "
"(only for extreme cases), you can handle it all."
"The initial directory is: {directory}"
)
NEXT_STEP_PROMPT = """
Based on user needs, proactively select the most appropriate tool or combination
of tools. For complex tasks, you can break down the problem and use different tools
step by step to solve it. After using each tool, clearly explain the execution
results and suggest the next steps.
If you want to stop the interaction at any point, use the `terminate` tool/function call.
"""
Function Calling机制
response = await self.llm.ask_tool(
messages=self.messages, # 完整的对话历史
system_msgs=[Message.system_message(self.system_prompt)],
tools=self.available_tools.to_params(), # 工具schema列表
tool_choice=self.tool_choices, # 选择策略
)
{
"content": "我需要先查看文件内容,然后进行编辑", # 思考过程
"tool_calls": [
{
"id": "call_abc123",
"type": "function",
"function": {
"name": "str_replace_editor",
"arguments": '{"command": "view", "path": "/path/to/file"}'
}
}
]
}
5.3 状态管理与循环控制
Agent状态机
class AgentState(str, Enum):
IDLE = "IDLE" # 空闲,等待任务
RUNNING = "RUNNING" # 执行中
FINISHED = "FINISHED" # 任务完成
ERROR = "ERROR" # 发生错误
@asynccontextmanager
async def state_context(self, new_state: AgentState):
previous_state = self.state
self.state = new_state
try:
yield
except Exception as e:
self.state = AgentState.ERROR
raise e
finally:
self.state = previous_state
执行循环控制
while (
self.current_step < self.max_steps and
self.state != AgentState.FINISHED
):
self.current_step += 1
step_result = await self.step()
# 卡死检测
if self.is_stuck():
self.handle_stuck_state()
def is_stuck(self) -> bool:
"""检测Agent是否陷入循环"""
if len(self.memory.messages) < 2:
return False
last_message = self.memory.messages[-1]
if not last_message.content:
return False
# 检查是否有重复的assistant消息
duplicate_count = sum(
1 for msg in reversed(self.memory.messages[:-1])
if msg.role == "assistant" and msg.content == last_message.content
)
return duplicate_count >= self.duplicate_threshold
def handle_stuck_state(self):
stuck_prompt = (
"Observed duplicate responses. Consider new strategies and avoid "
"repeating ineffective paths already attempted."
)
self.next_step_prompt = f"{stuck_prompt}\\n{self.next_step_prompt}"
特殊工具处理
Terminate工具会终止Agent执行:async def _handle_special_tool(self, name: str, result: Any, **kwargs):
if not self._is_special_tool(name):
return
if self._should_finish_execution(name=name, result=result, **kwargs):
logger.info(f"Special tool '{name}' has completed the task!")
self.state = AgentState.FINISHED
5.4 上下文感知与记忆管理
Memory机制
Memory类维护完整的对话历史:class Memory(BaseModel):
messages: List[Message] = Field(default_factory=list)
max_messages: int = Field(default=100)
def add_message(self, message: Message) -> None:
self.messages.append(message)
# 限制消息数量,保留最近的
if len(self.messages) > self.max_messages:
self.messages = self.messages[-self.max_messages:]
User: "帮我创建一个Python脚本"
Assistant: [思考过程] [tool_calls: python_execute]
Tool: [执行结果]
Assistant: [分析结果] [tool_calls: str_replace_editor]
Tool: [文件创建结果]
Assistant: "脚本已创建完成"
上下文构建
async def think(self) -> bool:
# 检查是否在使用浏览器
browser_in_use = any(
tc.function.name == BrowserUseTool().name
for msg in recent_messages
if msg.tool_calls
for tc in msg.tool_calls
)
# 如果使用浏览器,添加浏览器上下文
if browser_in_use:
self.next_step_prompt = (
await self.browser_context_helper.format_next_step_prompt()
)
return await super().think()
六、架构图与数据流
6.1 Agent执行流程图
6.2 工具调用序列图
6.3 类继承关系图
6.4 数据流图
七、实践建议
7.1 如何设计新工具
description字段应该详细说明工具的用途、使用场景和限制ToolResult,包含成功结果或错误信息class FileSearchTool(BaseTool):
name: str = "file_search"
description: str = (
"Search for files in a directory tree matching a pattern. "
"Supports glob patterns and regex. Returns list of matching file paths."
)
parameters: dict = {
"type": "object",
"properties": {
"directory": {
"type": "string",
"description": "Root directory to search in (absolute path)",
},
"pattern": {
"type": "string",
"description": "Search pattern (glob or regex)",
},
"recursive": {
"type": "boolean",
"description": "Whether to search recursively",
"default": True,
},
},
"required": ["directory", "pattern"],
}
async def execute(
self, directory: str, pattern: str, recursive: bool = True
) -> ToolResult:
try:
# 验证路径安全性
if not Path(directory).is_absolute():
return self.fail_response("Directory must be absolute path")
# 执行搜索
matches = await self._search_files(directory, pattern, recursive)
return self.success_response({"files": matches})
except Exception as e:
return self.fail_response(f"Search failed: {str(e)}")
7.2 如何优化提示词
SYSTEM_PROMPT = """You are OpenManus, a capable AI assistant.
Your capabilities:
- Execute Python code for data processing and analysis
- Browse the web to gather information
- Edit files using safe string replacement
- Interact with users when clarification is needed
Working directory: {directory}
Important guidelines:
- Always verify file paths before operations
- Use sandboxed execution for untrusted code
- Ask for confirmation before destructive operations
- Explain your reasoning at each step
"""
7.3 如何调试Agent行为
agent.memory.messages,验证对话历史的正确性max_steps=1限制,逐步观察Agent的行为async def debug_agent(agent: ToolCallAgent, request: str):
"""调试Agent执行过程"""
print(f"Request: {request}")
print(f"Available tools: {[t.name for t in agent.available_tools.tools]}")
# 单步执行
agent.max_steps = 1
await agent.run(request)
# 检查记忆
print("\\nMemory contents:")
for i, msg in enumerate(agent.memory.messages):
print(f"{i}. {msg.role}: {msg.content[:100]}")
if msg.tool_calls:
print(f" Tool calls: {[tc.function.name for tc in msg.tool_calls]}")
7.4 性能优化建议
from functools import lru_cache
from datetime import datetime, timedelta
class CachedTool(BaseTool):
_cache: Dict[str, Tuple[Any, datetime]] = {}
_cache_ttl: timedelta = timedelta(minutes=5)
async def execute(self, **kwargs) -> ToolResult:
cache_key = str(sorted(kwargs.items()))
# 检查缓存
if cache_key in self._cache:
result, timestamp = self._cache[cache_key]
if datetime.now() - timestamp < self._cache_ttl:
return result
# 执行工具
result = await self._execute_impl(**kwargs)
# 更新缓存
self._cache[cache_key] = (result, datetime.now())
return result
八、总结
8.1 现代Agent的核心要素
8.2 OpenManus架构的优势
8.3 未来发展方向
8.4 结语