本文作者:OceanBase 资深技术专家 张易

摘要:
在 AI 时代,OceanBase 以混合搜索为核心的多模能力,从 AI Agent 的视角出发,为大模型提供高质量的上下文信息,在提升 AI 应用效果的同时显著降低运行成本,真正实现了技术与业务价值的统一。

在 AI 与数字化转型驱动的时代,企业正面临数据形态、处理速度与复杂性的剧增。近日,全球知名咨询机构 Forrester 在其最新报告《Multi-Model Data Platforms Landscape, Q4 2025》中指出,多模数据平台(MMDP)已成为应对现代应用复杂数据需求的关键趋势。报告将 MMDP 定义为“在一个数据库管理系统中支持多种数据模型”的统一平台,其核心价值在于简化技术栈、降低数据冗余并加速开发周期。

OceanBase作为“Notable Vendor”出现在该报告中,这不仅是对 OceanBase 多模一体化产品的认可,更预示着化繁为简、现代架构的数据时代即将来临。

在报告中,OceanBase 被认为是聚焦以下扩展用例的代表性厂商:

Agentic AI
Forrester 认为 MMDP 是 Agentic AI 的大脑与记忆。AI Agent 需要推理,它需要知道事实、拥有记忆并理解逻辑关系。MMDP 提供了向量检索(找相似)、图谱(找逻辑)、结构化数据(找事实)的统一平台,防止 AI 幻觉。

多模数据统一检索
Forrester 认为 MMDP 能为开发者提供一键“原子操作”。比如,用户修改资料,既要改结构化数据里的名字,又要改全文搜索里的索引,还要改图数据里的节点,过去这需要写很复杂的分布式事务代码,而 MMDP 允许用统一查询语言在一个步骤内完成跨模态的增删改查,保证数据一致性,极大简化开发。

推荐引擎
Forrester 认为 MMDP 能够提供比“猜你喜欢”更懂你的推荐。传统的推荐只看买了什么,现在的推荐要看用户的实时点击流(行为)、朋友买了什么(关系)、用户搜索的关键词(文本语义),结合了图计算(社交推荐)和多模态搜索(语义推荐),提供更精准的上下文感知推荐。

本文将深度解读 OceanBase 多模一体化能力,探讨其如何以原生一体化的架构,帮助企业架构师与 IT 决策者厘清正在面临的“架构之问”:是继续采用“烟囱式”的数据库组合,还是转向真正的一体化平台?

从“多”到“一”:终结架构碎片化,多模是 AI 时代的必然选择

长期以来,业界普遍采用“为专业场景选择专业工具”的理念,构建了所谓的“多语言持久化”(Polyglot Persistence)架构,即为不同数据模型部署独立的数据库系统。然而,这种模式在业务复杂性指数级增长的今天,其弊端日益凸显,逐渐演变为创新的沉重枷锁。

这种“数据库联邦”模式的困境,在许多积极拥抱 AI 的企业中表现得尤为突出。它们为了实现语义搜索、精确匹配与关系查询,被迫引入由关系数据库、搜索引擎与多种向量数据库构成的复杂技术栈。这不仅导致架构臃肿、运维成本高昂,更在稳定性、数据一致性与开发效率上带来了巨大挑战,形成了沉重的技术债务。

货拉拉在转型过程中的早期探索,便是一个深刻的例证,其面临的动态 Schema 变更、混合检索与多系统运维难题,正是这种碎片化架构的典型缩影。

这些痛点深刻揭示了“烟囱式”架构的本质缺陷——它将数据管理的复杂性转嫁给了应用和运维团队。正如 Forrester 报告所指出的,MMDP 的核心价值正是通过在一个数据库内部实现统一的数据存储、事务处理和治理,从根本上解决数据孤岛问题,降低总拥有成本(TCO)并提升业务敏捷性。


Forrester: MMDPs Enable Simpler Cross-Model Querying

解构 OceanBase:为 AI Agent 打造的混合搜索“大脑”

在 AI Agent 与大语言模型(LLM)引领技术浪潮的今天,数据库的角色正在被重新定义。它不再仅仅是数据的存储仓库,更是决定 AI 应用智能水平与运行成本的“上下文引擎”(Context Engine)。

正如 OceanBase CTO 杨传辉所言,“向量搜索只是 AI 数据库的初级阶段,最终所有向量搜索都会演进为混合搜索——能否支持混合搜索,正是衡量 AI 数据库核心实力的关键分水岭”。


OceanBase 的多模一体化实现混合搜索

OceanBase 的多模能力并非简单的“功能叠加”,而是根植于其原生一体化的分布式架构。这种架构将关系、向量、全文、JSON 等多种数据模型统一在单一引擎下,共享同一套存储、事务和查询优化器。其核心价值主张,正是从 AI Agent 的视角出发,通过强大的混合搜索能力,为大模型提供更高质量、更精准的上下文信息,从而在提升 AI 应用效果的同时,显著降低因 Token 消耗而产生的计算成本。

混合搜索:AI 时代的“上下文工程”基石

AI 应用,尤其是 RAG(检索增强生成)应用,其效果的优劣极大程度上依赖于提供给大模型的上下文质量。大模型虽然具备强大的计算能力,但缺乏长期记忆,这就需要数据库为其存储并管理上下文信息,同时精准输出大模型所需的上下文——这一过程被称为“上下文工程”(Context Engineering)。

一个典型的复杂查询,如“推荐附近 500 米内,人均消费低于 25 元,评价超过 4.5 分,且环境安静的咖啡厅”,单纯的向量或文本搜索都难以胜任。这需要一个能同时理解并处理多种数据维度的“大脑”。

OceanBase 的混合搜索能力,正是为解决这类多维度信息综合检索的难题而生。它将四种关键的搜索能力无缝融合在一个查询引擎中:

这种“多路召回,统一排序”的模式,让 OceanBase 能够先通过关系、标量数据进行高效过滤,大幅缩小检索范围,再在小范围内进行精准的向量或全文搜索。每一路检索都会产出部分结果,最终将各路结果融合,并经过全局重排序(Rerank),才能为大模型输出其真正需要的精准结果。


OceanBase 混合搜索机制

这种机制不仅极大地提升了查询的准确性(Recall)和精确率(Precision),更重要的是,它将最相关、最精炼的信息作为上下文喂给大模型,有效避免了无关信息对模型推理的干扰,并从根本上减少了昂贵的Token消耗,直接降低了AI应用的运行成本。

技术利器一:高性能向量搜索是混合搜索的基础

高性能且功能完备的向量搜索,是混合搜索的核心基础。目前,OceanBase 向量搜索性能已达到业界开源向量数据库的先进水平——无论是稠密向量还是稀疏向量,在向量数据库领域主流 Benchmark 测试中均表现突出。

在 VectorDBBench 的测试中,OceanBase 在不同过滤率下的性能全面占优。同时,OceanBase 的磁盘向量索引,在构建时间与存储占用两方面,也实现了业界领先。


OceanBase 向量性能测评

更重要的是,OceanBase 实现了向量搜索与全文搜索的深度融合,通过多路搜索显著提升召回效果。测试数据清晰呈现了不同搜索方式的召回表现:仅采用单一搜索路径(无论全文搜索、稠密向量还是稀疏向量),都难以达到最优召回效果;唯有将稀疏向量、稠密向量与全文搜索相结合,才能实现更优的召回表现,达成 1+1 > 2的协同效应。


OceanBase 多路召回评测

值得一提的是,这两大能力均构建于 OceanBase 数据库原生架构之上,天然继承了分布式架构的弹性扩展特性与对象存储的高效适配能力。

技术利器二:半结构化数据的高效处理(JSON)

在 AI 场景中,企业在处理海量 JSON 数据(如用户行为日志、订单轨迹、动态特征字段)时,普遍面临 Schema 重复存储导致空间浪费、按行存储导致压缩率低、查询性能低下等痛点。

OceanBase 针对性地设计了创新的存储方案。它采用 JSON 二进制存储,并创造性地实现了“列化拆分”。通过智能识别“高频列(Frequent Col)”与“稀疏列(Spare Col)”,将频繁访问的字段独立成列存储,稀疏字段则聚合存储。


OceanBase JSON 列化拆分机制

这种设计带来了显著的技术收益。首先是极致的压缩效率,拆分后的独立列可利用 OceanBase 成熟的列存编码能力进行高效压缩。在 TPCH-10G 数据集上的测试显示,其压缩比是传统文档数据库的 3 倍,直接降低了存储成本。

其次是查询性能的加速,查询特定字段时,只需读取对应列,极大减少了 I/O 开销。此外,用 JSON 格式动态扩展特征字段,还可帮助企业减少 30%-50% 的数据清洗成本。这一能力对于 AI 应用中频繁变化的特征工程尤为重要,使得企业无需频繁修改 Schema 即可灵活应对业务需求。

技术利器三:HTAP 能力支撑 AI 场景的元数据管理

在 AI 场景中,除了要开展多路搜索,还需妥善管理 AI 场景下的元数据。要做好 AI 数据库的元数据管理,不仅需要支持元数据的实时写入与事务一致性,还需实现元数据检索结果与多路搜索结果的 SQL 级联动。

在这方面,支持 HTAP 的关系型数据库是更优选择。通过将关系模型与向量、全文、JSON 能力深度融合,OceanBase 最终形成了全面的混合搜索能力。


OceanBase 如何解决 AI 场景元数据管理问题

例如,在知识库场景中,需要管理用户权限、文档分类、访问日志等大量元数据,同时还要进行文档的语义检索。传统方案需要在应用层协调关系数据库与向量数据库的查询结果,而 OceanBase 则可以通过一条 SQL 完成“先通过关系过滤确定用户可访问的文档范围,再在该范围内进行向量语义搜索”的复杂操作,极大地简化了开发逻辑并提升了查询效率。

一体化架构:从“数据库联邦”到“统一数据底座”

过去,企业为了实现类似的多模态处理能力,不得不拼凑一个由关系数据库、向量数据库、全文搜索引擎等多种产品组成的“数据库联邦”。这种“烟囱式”架构不仅运维复杂、成本高昂,更在数据一致性、开发效率和系统稳定性上带来了巨大挑战。

OceanBase 的一体化架构则试图改变这一局面,为企业 AI 应用提供坚实的统一数据底座。多个客户的成功实践,生动地诠释了这一价值。

蚂蚁集团“百宝箱”的智能体在线搜索就是一个典型案例。其复杂的地理位置、用户评分、消费水平和语义偏好混合查询需求,在 OceanBase 中通过一条 SQL 即可实现,完美替代了原先 Milvus + Zsearch + OceanBase 的复杂组合。这种将多路检索逻辑从业务层下沉到数据库内核的做法,极大地简化了业务实现,实现了在线高性能混合搜索。


蚂蚁集团百宝箱 Agent 在线搜索示例

货拉拉则基于 OceanBase 的混合搜索能力,构建了一站式的企业 AI 数据底座,支撑起包括知识库平台、AI Coding、Agent 平台、ChatBI、智能客服等多种 AI 应用。这不仅用单一技术栈取代了原有的 vsearch + Weaviate + Milvus 等多个开源组件,解决了系统的稳定性难题,还复用了 OceanBase 成熟的高可用能力,实现了 RPO=0、RTO<8 秒的金融级标准。

在具体应用中,货拉拉通过“资损代码识别”场景,利用历史案例向量化与实时代码相似度检索,有效规避了潜在的财务风险;在“数仓AI答疑助手”项目中,更是融合了向量、标量、全文关键字等多种检索方案,并结合重排序模型,显著降低了内部数据查询门槛和人力成本,提升了数据开发人员的效率。


货拉拉 AI 应用架构

中国联通利用 OceanBase 构建了拥有 10 亿级向量规模的公司级统一知识库平台。原先采用“关系数据库+Elasticsearch”的架构,在切换到 OceanBase 后,查询执行效率提升到原 Elasticsearch 方案的 2 倍,同时解决了复杂的用户-文档权限管理问题。通过融合关系查找与多路搜索,联通成功实现了知识库的精细化权限管控及灵活的用户间权限共享需求,支持公共文档与私有文档的统一管理。


中国联通 AI 应用架构图

飞猪也通过 OceanBase 统一了其智能体数据平台的后端,用一套系统替代了原先的分布式 KV + 分布式 Table + 搜索 + 向量的复杂架构。这不仅统一了技术栈,还实现了对知识库、Memory 等多种数据的统一支持,SQL 的简单易用性与稳定低延迟的特性,让开发团队能够更专注于业务创新。


飞猪 AI Agent 架构

这些案例共同证明,OceanBase 的一体化架构并非简单的功能聚合,而是通过在内核层面实现多模数据的统一管理与查询,从根本上解决了数据孤岛问题,降低了技术栈的复杂性,最终加速了AI应用的创新与落地。

从技术到业务:OceanBase 多模一体化的实践价值

技术的先进性最终需要通过业务价值来体现。从上述案例中,我们可以清晰地看到 OceanBase 多模一体化架构在 AI 时代所带来的三大核心价值:

第一,显著降低 AI 应用的运行成本。 通过混合搜索提供的精准过滤与排序机制,OceanBase 能够为大模型提供更高质量、更相关的上下文信息,从而大幅减少无效 Token 的消耗。在当前大模型推理成本居高不下的背景下,这种成本优化对企业而言具有直接的经济价值。

第二,简化技术栈,提升开发与运维效率。 一体化架构让企业无需在应用层协调多个异构数据库系统,开发者可以用熟悉的 SQL 语言完成复杂的多模查询,极大地降低了学习成本与开发复杂度。同时,统一的运维管理也减轻了 DBA 团队的负担,提升了系统的整体稳定性。

第三,加速 AI 应用的创新周期。 当数据基础设施变得简单、高效且可靠时,业务团队可以将更多精力投入到 AI 应用本身的创新上,而非陷入复杂的数据管道搭建与维护中。这种“基础设施即服务”的理念,正是 OceanBase 一体化架构的核心价值所在。

选择下一代数据基石,拥抱智能未来

Forrester 的报告揭示了多模一体化不仅是技术趋势,更是企业在 AI 时代保持竞争力的战略选择。面对日益复杂的数据环境,传统“烟囱式”的架构已难以为继。

OceanBase 提供的不仅是一个功能丰富的数据库,更是一个稳定、高效、面向未来的一体化数据基石。它通过在存储、查询、事务等层面的原生一体化设计,让企业能够更从容地应对数据融合的挑战,将宝贵的精力聚焦于业务创新本身。

特别是在 AI 时代,OceanBase 以混合搜索为核心的多模能力,从 AI Agent 的视角出发,为大模型提供高质量的上下文信息,在提升 AI 应用效果的同时显著降低运行成本,真正实现了技术与业务价值的统一。

对于正在寻求下一代数据架构的架构师和 IT 掌舵者而言,可以重新审视自身的技术栈,考虑 Forrester 倡导的多模数据处理平台,为企业的下一个十年发展奠定坚实基础。

欢迎访问 OceanBase 官网获取更多信息:https://www.oceanbase.com/

一、 为什么现代决策必须重视“嵌套式”映射?

在海量信息过载与认知负荷极度饱和的数字化协作中,企业的效率瓶颈已从“数据获取”转向“结构化关系的精准解析”。传统单层思维导图或线性列表往往导致“语义孤岛”,使关联关系被割裂,底层逻辑淹没在离散节点中。

引入嵌套式结构映射工具的核心价值在于:

  • 消除认知盲区:通过节点内部的无限嵌套,确保每一个细微变量都能在宏观结构中找到归属,而非悬浮存在。
  • 支撑多维关联穿透:支持在映射过程中实现跨层级穿透,从核心业务逻辑层瞬移至最边缘的支撑细节。
  • 实现拓扑知识对齐:通过多重包含关系,各模块的映射逻辑自动形成互联网络,确保团队对复杂系统认知的一致性。
  • 非线性问题模块化封装:将已验证的结构模型封装为嵌套组件,实现复杂方案在不同业务场景下的快速映射与调用。

二、 嵌套式映射的典型应用场景

  1. 复杂产品架构设计:将硬件、软件与服务模块进行多层嵌套映射,梳理系统间的调用逻辑。
  2. 战略目标拆解(OKR):从集团战略下钻至部门目标,再嵌套具体的执行行动,确保目标链条不断层。
  3. 大规模知识库构建:处理非线性、网状演化的知识体系,实现知识点之间的深度关联与层级索引。
  4. 业务流程复盘与审计:自动检测“预期架构”与“实际路径”的差异,识别逻辑断层风险。
  5. 跨团队认知同步:在大型项目中,通过统一的拓扑映射图谱,消除职能部门间的沟通壁垒。

三、 5款值得一试的嵌套式结构映射工具(精选推荐)

1. Heptabase

无限画布嵌套 + 视觉连通

  • 核心特性:核心优势在于白板级的自由嵌套,支持将映射逻辑转化为直观的可视化卡片。
  • 适配场景:深度学习、复杂课题研究、项目初期逻辑梳理。
  • 优势亮点:视觉呈现极具表现力,支持在宏观视角与微观细节间无缝切换。

2. Obsidian

关系型图谱 + 双向链接嵌套

  • 核心特性:通过双向链接构建隐性的嵌套结构,形成高度互联的网状图谱。
  • 适配场景:个人知识管理、非线性文档驱动型协作。
  • 优势亮点:极高的自定义程度,适合处理长期演化的、具有多重引用关系的复杂语义空间。

3. 板栗看板

垂直嵌套结构 + 可视化层级下钻

  • 核心特性:支持将归纳逻辑与执行链条深度融合,实现无限层级的可视化呈现。
  • 适配场景:需要“纵向对齐”的复杂研发团队、多层级项目追踪。
  • 优势亮点:不仅是看板,更是具备垂直下钻能力的执行引擎,确保每一条归纳都能精准回溯。

4. Airtable

多维矩阵映射 + 参数化管理

  • 核心特性:通过强关联的表项实现层级跳转,支持多视图(表格、看板、甘特图)切换。
  • 适配场景:大量标准化堆栈模块的参数化管理、结构化数据映射。
  • 优势亮点:强大的关系型数据库属性,适合需要对映射节点进行精细化属性定义的场景。

5. XMind / MindManager

经典结构化映射 + 树形嵌套

  • 核心特性:利用页面嵌套实现逻辑闭环,通过标准的层级结构展示隶属关系。
  • 适配场景:体系化归纳、会议纪要梳理、传统组织架构映射。
  • 优势亮点:上手门槛低,逻辑严密,适合对业务流程进行强逻辑性的垂直映射。

---

四、 实施中的设计建议与风险控制

  • 防止“认知黑洞”:建议嵌套深度控制在合理范围(如 5-7 层),并在工具中利用导航树或路径指示器防止迷失。
  • 动态激活映射资产:映射出的优质结构不应仅作存档,应转化为“项目模板”,实现一键复用以降低冷启动成本。
  • 定期进行结构“修剪”:随着认知迭代,应精简冗余层级,合并相似的嵌套单元,保持映射体系的干练。
  • 强化节点属性定义:在深层映射中,明确节点的“原子属性”,具备明确的标准化参数以支撑执行。

---

五、 Q\&A:关于嵌套式映射你可能遇到的问题

Q1:嵌套层级太深,找不到目标节点怎么办?

A:建议使用具备“深度检索”或“语义缩放”功能的工具。通过递归搜索算法,可以跨层级准确定位目标资产。

Q2:如何评估一个嵌套结构的价值?

A:可以采用递归评估逻辑,即顶层资产的价值由其所有子节点的执行质量或关联密度递归驱动,从而得出综合评分。

Q3:嵌套结构是否会导致协作成员更难理解?

A:恰恰相反。通过结构化映射,复杂的业务逻辑被模块化解构,成员可以顺着逻辑链条快速溯源,比线性文档更容易掌握全局。

---

六、 结语

嵌套式映射是管理复杂性的终极武器。 它不仅解决了“关系散乱”的问题,更通过严密的拓扑架构,将企业的每一次实践转化为可以层层剥离、精准复用的逻辑引擎。

当组织的知识与决策能以嵌套形式垂直/水平对齐时,团队才能在复杂的市场竞争中实现“深度思考”与“极速执行”的统一。

在认知负荷极度饱和的数字化协作中,企业的效率瓶颈已从“数据获取”转向“结构化关系的精准解析”。嵌套式结构映射工具不仅是静态的关系图谱,更是通过多维拓扑的逻辑映射,将错综复杂的业务网络转化为可视化、可横向/纵向关联的嵌套式语义资产的解析引擎。

一、 为什么现代决策必须重视“嵌套式”映射?

传统单层思维导图或线性列表往往导致“语义孤岛”:关联关系被割裂,底层逻辑被掩盖在离散的节点中。嵌套式结构映射工具的核心价值在于:

  • 消除认知盲区:通过节点内部的无限嵌套,确保每一个细微变量都能在宏观结构中找到归属,而非悬浮存在。
  • 支撑多维关联穿透:支持在映射过程中实现跨层级穿透,从核心业务逻辑层瞬移至最边缘的支撑细节。
  • 实现拓扑知识对齐:通过多重包含关系,各模块的映射逻辑自动形成互联网络,确保团队对复杂系统认知的一致性。
  • 非线性问题模块化封装:将已验证的结构模型封装为嵌套组件,实现复杂方案在不同业务场景下的快速映射与调用。

---

二、 嵌套式映射的技术路径:三维拓扑架构

构建嵌套式结构映射体系需要遵循“节点解构”与“映射关联”的逻辑:

  1. 宏观拓扑层(Macro Topology):定义映射的核心锚点,展示业务全局的价值流向、核心约束及系统边界。
  2. 嵌套关联层(Nested Relation):将核心节点拆解为具有从属或并列关系的二级映射空间,记录节点间的动态交互与因果链条。
  3. 元数据映射层(Metadata Mapping):位于映射的最深处,聚焦于具体数据的定义与参数,提供原子级的属性描述与验证标准。

---

三、 核心技术实现与算法示例

嵌套式结构映射工具的底层逻辑涉及节点深度遍历、环路一致性检测及关联路径优化算法。

1. 基于递归搜索的嵌套节点搜索(JavaScript)

在嵌套结构中,快速定位深层节点是映射的核心。以下为实现节点深度检索的逻辑:

JavaScript

/**
* 递归检索嵌套映射结构中的目标节点
* @param {Array} mapNodes 映射节点数组
* @param {string} targetId 目标节点ID
* @returns {Object|null} 匹配到的嵌套节点对象
*/
function findNestedNode(mapNodes, targetId) {

for (const node of mapNodes) {  
    if (node.id \=== targetId) return node;  
      
    // 如果存在嵌套子层级,则继续向下递归检索  
    if (node.nestedLayers && node.nestedLayers.length \> 0) {  
        const found \= findNestedNode(node.nestedLayers, targetId);  
        if (found) return found;  
    }  
}  
return null;  

}

2. Python:映射结构冗余度动态审计引擎

利用嵌套模型,自动检测节点间的重复映射与过度嵌套,识别认知冗余风险:

Python

class MappingAuditEngine:

def \_\_init\_\_(self):  
    \# 预设映射标准:节点类型 \-\> 推荐嵌套深度与关联密度  
    self.mapping\_benchmarks \= {  
        "Logic\_Flow": {"max\_depth": 5, "avg\_links": 3},  
        "Data\_Model": {"max\_depth": 3, "avg\_links": 8}  
    }

def verify\_mapping\_efficiency(self, current\_map, map\_type):  
    """对比实际嵌套深度与标准,识别冗余或过于复杂的映射点"""  
    std \= self.mapping\_benchmarks.get(map\_type)  
    if not std:  
        return "未定义的映射标准"

    actual\_depth \= self.\_get\_max\_depth(current\_map)  
    if actual\_depth \> std\['max\_depth'\]:  
        print(f"\[Map Alert\] 嵌套深度达 {actual\_depth} 层,已超出认知负荷阈值")  
        self.\_suggest\_flattening(current\_map)

def \_get\_max\_depth(self, node, level=1):  
    if not node.get('children'):  
        return level  
    return max(self.\_get\_max\_depth(c, level \+ 1) for c in node\['children'\])

3. SQL:嵌套节点关联路径与影响力分析

通过递归公用表表达式(CTE),查询特定节点在整个嵌套网络中的波及范围:

SQL

WITH RECURSIVE NodeImpactPath AS (

\-- 起始:选择目标嵌套节点  
SELECT id, node\_name, parent\_id, 1 AS impact\_level  
FROM map\_nodes WHERE id \= 'target\_node\_001'  
UNION ALL  
\-- 递归:向上或向下追踪所有受影响的嵌套关联单元  
SELECT mn.id, mn.node\_name, mn.parent\_id, nip.impact\_level \+ 1  
FROM map\_nodes mn  
INNER JOIN NodeImpactPath nip ON mn.parent\_id \= nip.id  

)
SELECT

node\_name,   
impact\_level,  
COUNT(\*) OVER() as total\_affected\_nodes  

FROM NodeImpactPath
ORDER BY impact\_level ASC;

---

四、 工具分类与选型思路

实施嵌套式结构映射时,工具的选择应基于对“空间展开能力”的需求:

  • 无限卡片嵌套类(如 Miro/板栗看板):核心优势在于白板级的自由嵌套与视觉连通,支持将映射逻辑转化为直观的视觉卡片。
  • 关系型图谱类(如 Obsidian/Logseq):通过双向链接构建隐性的嵌套结构,适合处理非线性、网状演化的知识体系。
  • 结构化映射类(如 MindManager/XMind):经典的层级嵌套工具,适合对业务流程、组织架构进行强逻辑性的垂直映射。

---

五、 实施中的风险控制与管理优化

  • 防止“无限嵌套导致的黑洞效应”:应设定合理的嵌套阈值(如不超过 7 层),并在工具中利用“缩放语义(Semantic Zooming)”技术,确保在高倍率缩放时仍能识别核心节点。
  • 动态同步映射资产:嵌套节点应具备实时更新能力,当底层数据发生变动时,高层嵌套结构的映射逻辑需自动完成一致性校验。
  • 定期进行结构“修剪”:随着映射逻辑的成熟,应合并相似的嵌套层级,保持映射图谱的清晰度与决策支持效能。

---

六、 结语

嵌套式结构映射是解析系统复杂性的手术刀。 它不仅解决了“关系散乱”的问题,更通过精密的多维结构,将企业零散的认知片段转化为具备高度逻辑自洽性的智能资产。当组织的思维能够以嵌套形式实现水平与垂直的完美对齐时,团队方能在剧烈的市场波动中实现“全局洞察”与“精准打击”的统一。

以前一个项目可能要 5 个程序员搞定的现在只要 2 个就可以了,但是产品经理是没办法被取代的!!强烈建议转岗,AI 根本没办法理解一个人应该如何使用产品,交互,比如按钮为什么会在这?

在全球金融市场中,日本股市(东京证券交易所 TSE)作为亚洲最重要的市场之一,拥有索尼、丰田、任天堂等众多核心资产。对于开发者而言,获取低延迟、高可靠的日本股票实时行情是构建量化系统或行情应用的关键。

本文将详细介绍如何利用 StockTV 金融 API 快速接入日本市场数据(countryId=35),并重点突出数据的实时性处理方案。


一、 接入准备:获取通行证

在开始对接前,您需要完成以下准备工作:

  1. 获取 API Key:通过官方渠道获取您的专属测试或正式 Key。
  2. 验证身份:在所有请求中,需通过 URL 参数 key=您的Key 进行鉴权。
  3. 数据格式:接口统一返回 JSON 格式,方便前端或后端直接解析。

二、 核心接口对接(日本市场专场)

1. 获取日本股票全列表

通过指定 countryId=35,您可以一次性拉取日本市场的股票基础信息及其实时概览。

  • 接口地址https://api.stocktv.top/stock/stocks
  • 请求示例
    https://api.stocktv.top/stock/stocks?countryId=35&pageSize=20&page=1&key=YOUR_KEY
  • 核心字段说明
  • last: 最新成交价(实时)。
  • chgPct: 涨跌幅(直接拼接 % 即可展示)。
  • time: 数据最后更新的时间戳,用于确保数据的实时性校验。

2. 精准查询特定日股实时行情

如果您已知股票代码(Symbol)或产品 ID(pid),可以使用查询接口获取更详细的实时快照。

  • 接口地址https://api.stocktv.top/stock/queryStocks
  • 参数示例?symbol=7203&key=YOUR_KEY(查询丰田汽车)。

3. 实时 K 线数据对接

StockTV 提供多种时间维度的 K 线数据,支持从 5分钟到月线的实时计算更新。

  • 接口地址https://api.stocktv.top/stock/kline
  • 参数配置
  • pid: 股票的唯一标识。
  • interval: PT5M (5分钟), PT1H (1小时), P1D (天) 等。
  • 实时性优势:K 线数据随市场价格波动实时合成,确保图表展示不滞后。

4. 日本市场涨跌榜(异动监控)

实时监控日本市场的领涨、领跌个股,帮助用户捕捉市场热点。

  • 接口地址https://api.stocktv.top/stock/updownList
  • 请求参数countryId=35&type=1(1为涨幅榜,2为跌幅榜)。

三、 追求极致实时性:HTTP vs WebSocket

为了满足不同场景对“实时”的定义,StockTV 提供了两种接入方式:

接入方式适用场景实时性特点
HTTP API列表展示、基础行情、离线分析定时轮询获取(如每秒请求一次)。
WebSocket交易终端、高频监控、实时图表毫秒级推送。服务器在价格变动的瞬间主动推送至客户端,延迟降至最低。
专业建议:如果您在开发高频交易系统或需要实时跳动价格的 App,请联系官方开启 WebSocket 接入权限。

四、 Python 实战代码:获取日股实时行情

以下代码演示了如何获取日本市场某只股票的最新价格:

import requests

def get_japan_stock_realtime(symbol):
    api_url = "https://api.stocktv.top/stock/queryStocks"
    params = {
        "symbol": symbol,
        "key": "YOUR_API_KEY" # 请替换为您的真实Key
    }
    
    response = requests.get(api_url, params=params)
    result = response.json()
    
    if result.get("code") == 200:
        data = result["data"][0]
        print(f"股票: {data['name']} ({data['symbol']})")
        print(f"最新价: {data['last']}")
        print(f"涨跌幅: {data['chgPct']}%")
        print(f"更新时间戳: {data['time']}")
    else:
        print("请求失败:", result.get("message"))

# 示例:查询索尼 (6758)
get_japan_stock_realtime("6758")

管理数千集群、数万 Redis 节点的规模化场景下,传统人工调度模式的效率瓶颈与稳定性风险日益凸显。信也科技通过构建Redis 实例自动化调度体系,以系统自动执行替代人工重复操作,实现资源精准管控与效率跃升,打造支撑业务缓存体系的核心技术基石。

一、演进起点:传统人工调度的痛点困局

信也科技Redis管理平台已承载上千集群、数万Redis-server节点、百台宿主机,内存使用率与分配率稳居业内第一梯队。但随着业务高速增长,传统手动调度模式的弊端逐渐暴露,成为运维效率与集群稳定性的制约因素:

  • 人力成本居高不下: 过保机器替换、资源打散迁移等重复性工作,每周需投入 2 人天专项人力,机械操作占比高,核心运维精力被严重分散;
  • 稳定性风险难以规避: 人工批量操作易出现漏操作、重复操作、误操作等问题,直接威胁集群可用性,引发业务故障隐患;
  • 响应速度滞后业务需求: 依赖 DBA 实时监控资源水位,无法快速响应突发内存使用率飙升场景,易引发性能瓶颈,影响业务体验。

针对上述痛点,我们内部负责 Redis 技术体系建设与运维的核心团队 —— 基石 Redis 团队,正式启动自动化实例迁移能力建设。核心目标是通过调度全流程自动化,实现 “高效精准、安全可靠、资源最优” 的集群管控效果,破解传统运维模式的困境。

二、方案设计:自动化调度的核心流程闭环

自动化调度以“系统自动执行+人工轻量管控”为核心,整体流程形成闭环,兼顾效率与可控性,分为4步:

  1. 筛选迁移对象: 系统基于预设阈值(如内存使用率、机器服役周期)自动识别待迁移节点/宿主机,也支持运维手动筛选;
  2. 创建迁移工单: 运维在平台发起工单,系统自动通知集群负责人及相关成员,确认后触发调度流程;
  3. 生成迁移任务: 系统根据资源分布、部署规则自动规划迁移路径、目标机器,无需人工干预;
  4. 自动化执行迁移: 系统全程自动完成“添加从节点→数据同步校验→主从切换→节点下线”,运维仅需监控进度。

image.png
Redis过保替换流程图

三、核心技术:自动化调度的高可用保障机制

自动化调度的核心挑战是迁移过程中“业务无感知”,因此我们为每一步调度环节都设计了自动化校验与容错机制,从技术层面筑牢迁移安全防线。

1. 添加从节点:规则化自动选址,筑牢基础

系统自动为待迁移节点创建替代从节点,严格遵循5大部署规则,平衡可用性与资源利用率:

  • 新节点与原节点同机房部署,降低网络延迟对同步的影响;
  • 规格、Redis版本与原节点完全一致,规避兼容性问题;
  • 同一集群节点分散部署在不同宿主机,避免单点故障牵连集群;
  • 宿主机内存分配上限设为90%,预留10%缓冲应对业务突发增长;
  • 优先选择剩余可用内存多的宿主机,提升整体资源利用率。

注:整个节点部署流程完全自动化,涵盖机器筛选、端口分配、槽位配置及主从关系建立等全环节,无需运维逐节点手动操作,大幅减少重复工作量。

2. 数据同步校验:自动化双重核查,确保一致

添加从节点后,系统自动调用info replication命令(Redis查看主从复制状态的核心命令)完成双重校验,仅通过校验方可进入下一步:

  • 主节点视角:新增从节点接入正常,同步状态state=onlineoffset≠0
  • 从节点视角:角色为slave,同步主节点数据与其一致,master_link_status:upmaster_repl_offset≠0
  • 二次校验:首次校验通过后,系统延迟30秒自动复核,规避redis主从节点瞬时同步异常的风险。

3. 主从切换:自动化按需触发,平稳过渡

  • 若原节点为从节点,则系统无需进行切换动作,直接执行后续下线流程;
  • 若原节点为主节点, 系统自动对新从节点执行cluster failover命令(Redis集群手动故障转移命令,此处由系统自动化调用),将其选举为新主节点,确保业务无感知。

4. 结果校验与异常回滚:自动化兜底

主从切换完成后,系统并不会直接进入原节点下线流程,而是先自动开展全节点穿透式核查,确保集群整体状态稳定后再推进后续操作:

  • 新主节点:角色为master,从节点数量≥1,同步状态均正常;
  • 所有从节点:同步目标为新主节点,无同步中断情况。

下线原节点前,系统还会自动校验业务连接是否完全迁移,确保无流量残留。同时支持一键回滚,若任一环节异常,系统可自动(或运维手动触发)回滚至迁移前状态,降低故障风险。

5. 自动化消息通知:全程透明可控

  • 工单创建、调度启动、完成/失败等关键节点,系统自动通知集群负责人及运维;
  • 调度失败(如宿主机资源不足、同步超时)时,实时推送告警并附异常日志,助力快速排查。

image.png
整体功能展示图

四、可视化管控:自动化调度的全生命周期监控

为保障自动化调度的可控性,平台配套了可视化任务管理界面,支撑运维对调度全流程进行轻量管控,实现“自动化执行+可视化监控”的双重保障:

  • 待执行任务:支持取消、修改执行时间、手动触发执行;
  • 执行中任务:实时展示迁移进度、各环节状态及校验日志,异常节点自动标红;
  • 历史任务:完整留存调度记录,支持按集群、时间检索,便于问题复盘与合规审计。

这套覆盖调度全生命周期的可视化管控能力,为 Redis 实例自动化调度方案的稳定落地、风险可控提供了关键支撑。经过多场景实际落地验证,该方案已充分适配业务需求,以下是经验总结与未来规划。

五、落地效果与经验总结

1. 核心落地效果

  • 资源利用率优化: 通过自动化调度动态平衡资源,宿主机内存使用率稳定控制在阈值内,兼顾高利用率与冗余缓冲;
  • 稳定性提升: 调度全流程自动化校验,彻底杜绝人工误操作,迁移零业务中断;
  • 效率激增: 自动化替代90%+人工调度工作,每周2人天的重复操作被解放,运维可聚焦核心优化工作;
  • 集群韧性增强: 调度规则强制实现节点分散部署,机器故障对集群的影响范围大幅缩小。

2. 可复用实战经验

  • 自动化优先保障数据一致性: 多维度自动化校验、二次复核是避免迁移故障的核心,比人工判断更精准高效;
  • 资源分配需“留有余地”: 90%内存分配阈值+同机房部署规则,平衡利用率与业务稳定性,该阈值可根据集群负载特性动态调整;
  • 自动化≠失控: 配套可视化监控、异常告警与回滚机制,才能让自动化调度更安全,降低运维心理负担;
  • 调度规则需贴合业务场景: 节点分散、版本一致等规则,需结合自身Redis集群架构(如主从、哨兵、集群模式)设计,避免通用规则适配偏差。

3. 技术展望

基于现有自动化能力,我们计划从“智能升级、链路完善、架构适配”三个方向持续迭代,让Redis实例调度更贴合复杂业务场景:

  • 全链路自动化: 完善集群自动部署、节点垂直扩缩容的自动化能力,形成Redis全生命周期管控闭环;
  • 智能化策略升级: 引入机器学习算法,基于历史资源使用数据预测集群负载趋势,实现调度任务的主动触发与最优路径规划;
  • 多架构兼容适配: 拓展对Redis Cluster、Redis Sentinel等主流架构的全面支持,覆盖更多业务场景的调度需求。

作者介绍

图片

图片

https://jt26wzz.com/posts/0014-the-dwarf-behind-the-debugger/

写了一篇新的技术博客,篇幅有点长,而且受限于个人水平,有些地方表达的不是很好,或者说有点详略不得当,不过还是把我目前对调试器的基本认知都写出来。

这里特意发个帖子,想和对这块感兴趣的人一起讨论讨论,特别是我有哪里理解不到位或者错误的地方,欢迎直接指出,毕竟我写博客的目的也是为了交流和自我提升。虽然我也可以让 AI 来 review 我的博客内容,但是我还是更倾向于和大家交流。

iPhone16

ios 版本:18.7.2

Telegram:12.3.2

现象:

打开 instant view 观看漫画或者图片时,有时整个 view 会不停地上下翻动,闪烁,然后闪退。
请问大家有遇到没?怎么解决?

目前在一家小企业做乙方项目负责人,最近招投标感觉竞争力越来越大,投标价越来越低。
这两年做的项目基本都不挣钱,也就保住部门正常运行。
同时也感觉到 AI 能力越来越强,肉眼可见的 AI 已经慢慢快要超过程序员(我们部门用 Java 搞工程化的)。
和好多甲方聊了聊,他们之前人少,所以有好多项目会外协。现在 AI 能力越来越强,他们之前会发标的项目,现在好多都内部研发人员用 AI 实现了。


所以不知道哪天我们部门就被撤掉了。


已经过了 35 了,再就业的可能性很小了,现在正在寻找失业后的方向。


有没有类似的同仁,大家有没有给自己留什么退路?

熟悉 Spring Boot 3 的开发者,都知道它在简化开发流程、提高开发效率方面的出色表现吧!但是,在实际业务场景中,大家肯定都碰到过这样的棘手问题:订单数据存放在 MySQL 里,库存数据在 PostgreSQL 中,用户数据又保存在 MongoDB 中,当多种数据源同时存在时,想要实现统一查询简直比登天还难。

所以呢,今天我就亮出我的“终极大招”——Apache Calcite,着重给大家讲讲它怎样与 Spring Boot 3 实现无缝集成,还会分享一些可以直接拿来使用的经典应用场景。掌握了这一招,多数据源查询的难题就能轻松解决啦!

一、核心认知:Apache Calcite 为何是多数据源查询的利器?

在动手集成前,咱们先把核心逻辑搞明白:为啥 Calcite 能成为多数据源查询的“万能钥匙”?它的核心优势到底在哪?

1.1 不止是查询引擎:Calcite 的核心定位

Apache Calcite 本质是一个动态数据管理框架,而非传统的数据库。它最核心的价值在于“解耦”——将数据存储与数据查询分离,无论数据存在哪里、是什么格式,都能通过统一的 SQL 接口进行查询。

说通俗点,Calcite 就像个“超级数据翻译官”——不管数据藏在哪个数据源里、是什么格式,你只要写一套标准 SQL,它就能翻译成对应数据源能懂的指令,最后把结果整理成统一格式返回。这也是它能搞定多数据源查询的核心秘诀!

1.2 Calcite 的核心能力拆解

统一 SQL 接口:支持标准 SQL,无论底层是关系型数据库(MySQL、PostgreSQL)、非关系型数据库(MongoDB、Redis),还是文件(CSV、Parquet)、大数据引擎(Hive、Spark),都能通过同一套 SQL 查询。

  1. 强大的查询优化:内置基于规则和成本的查询优化器,能自动优化 SQL 执行计划,提升查询效率,尤其是在复杂多表关联、跨数据源查询场景下,优化效果明显。
  2. 灵活的数据源适配:通过“适配器(Adapter)”机制适配不同数据源,社区已提供大量现成适配器,也支持自定义开发,适配特殊数据源。
  3. 轻量级集成:核心依赖体积小,无复杂依赖,可轻松集成到 Spring Boot、Spring Cloud 等主流 Java 开发框架中,无需单独部署独立服务(也支持独立部署)。

    二、重点实战:Spring Boot 3 集成 Calcite 核心步骤

    既然大家都熟悉 Spring Boot 3 的基础操作,我就不啰嗦项目搭建这些常规步骤了,直接聚焦 Calcite 集成的核心环节,每一步都附完整代码和避坑提醒,跟着做就能成!

2.1 核心依赖引入

第一步先引依赖,在 pom.xml 里加好 Calcite 核心包、对应数据源的适配器,再配上 MyBatis Plus 的核心依赖(替换掉原来的 Jdbc 依赖就行),具体如下:

<!-- Calcite 核心依赖 -->
<dependency>
    <groupId>org.apache.calcite</groupId>
    <artifactId>calcite-core</artifactId>
    <version>1.36.0</version> 
</dependency>

<!-- MySQL 适配器(用于适配 MySQL 数据源) -->
<dependency>
    <groupId>org.apache.calcite</groupId>
    <artifactId>calcite-mysql</artifactId>
    <version>1.36.0</version>
</dependency>

<!-- MongoDB 适配器(用于适配 MongoDB 数据源) -->
<dependency>
    <groupId>org.apache.calcite</groupId>
    <artifactId>calcite-mongodb</artifactId>
    <version>1.36.0</version>
</dependency>

<!-- Spring Boot 与 MyBatis Plus 集成核心依赖 -->
<dependency>
    <groupId>com.baomidou</groupId>
    <artifactId>mybatis-plus-boot-starter</artifactId>
    <version>3.5.5</version> <!-- 适配 Spring Boot 3 的稳定版 -->
</dependency>

<!-- 数据库连接池依赖(MyBatis Plus 需连接池支持) -->
<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>druid-spring-boot-starter</artifactId>
    <version>1.2.20</version>
</dependency>

这里有 3 个避坑点必须强调下:

  1. Calcite 所有组件版本要统一,不然容易出现类加载异常;
  2. MyBatis Plus 得选适配 Spring Boot 3 的版本(3.5.3+);
  3. 一定要加连接池依赖,不然 Calcite 数据源没法被 MyBatis Plus 正常管理。

    2.2 核心配置:Calcite 模型文件编写

    模型文件是 Calcite 识别数据源的关键,一般用 JSON 格式,放在 resources 目录下命名为 calcite-model.json 就行。下面给大家一个适配 MySQL 和 MongoDB 双数据源的示例,直接改改连接信息就能用:

{
  "version": "1.0",
  "defaultSchema": "ecommerce",
  "schemas": [
    {
      "name": "ecommerce",
      "type": "custom",
      "factory": "org.apache.calcite.adapter.jdbc.JdbcSchema$Factory",
      "operand": {
        "jdbcUrl": "jdbc:mysql://localhost:3306/ecommerce_order?useSSL=false&serverTimezone=UTC",
        "username": "root",
        "password": "123456",
        "driver": "com.mysql.cj.jdbc.Driver"
      }
    },
    {
      "name": "user_mongo",
      "type": "custom",
      "factory": "org.apache.calcite.adapter.mongodb.MongoSchema$Factory",
      "operand": {
        "host": "localhost",
        "port": 27017,
        "database": "user_db",
        "collection": "user_info"
      }
    }
  ]
}

几个关键配置给大家解释清楚,避免踩坑:

  1. defaultSchema:默认查询的 Schema,可省略,查询时需指定 Schema 名称(如 ecommerce.order、user_mongo.user_info)。
  2. factory:对应数据源的适配器工厂类,Calcite 已为主流数据源提供现成工厂,自定义数据源需实现自己的 Factory。
  3. operand:数据源连接参数,根据数据源类型不同配置不同参数(如 MySQL 的 jdbcUrl、MongoDB 的 host/port)。

    2.3 Spring Boot 集成 Calcite + MyBatis Plus 核心配置

    这一步是核心,主要分两步走:

    配置好 Calcite 数据源;
    让 MyBatis Plus 用上这个数据源,顺便把 mapper 扫描、分页插件这些基础参数配好。直接上配置类代码:

    import com.baomidou.mybatisplus.annotation.DbType;
    import com.baomidou.mybatisplus.autoconfigure.ConfigurationCustomizer;
    import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;
    import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor;
    import org.apache.calcite.jdbc.CalciteConnection;
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
    
    import javax.sql.DataSource;
    import java.sql.Connection;
    import java.sql.DriverManager;
    import java.util.Properties;
    
    @Configuration
    // MyBatis Plus  mapper 接口扫描(指定 mapper 包路径)
    @MapperScan(basePackages = "com.example.calcite.mapper")
    public class CalciteMybatisPlusConfig {
    
     // 1. 配置 Calcite 数据源(核心,与原逻辑一致)
     @Bean
     public DataSource calciteDataSource() throws Exception {
         Properties props = new Properties();
         props.setProperty("model", "classpath:calcite-model.json");
         Connection connection = DriverManager.getConnection("jdbc:calcite:", props);
         CalciteConnection calciteConnection = connection.unwrap(CalciteConnection.class);
         return calciteConnection.getDataSource();
     }
    
     // 2. 配置 MyBatis Plus 的 SqlSessionFactory,指定使用 Calcite 数据源
     @Bean
     public SqlSessionFactory sqlSessionFactory(DataSource calciteDataSource) throws Exception {
         MybatisSqlSessionFactoryBean sessionFactory = new MybatisSqlSessionFactoryBean();
         // 注入 Calcite 数据源
         sessionFactory.setDataSource(calciteDataSource);
         // 配置 mapper.xml 文件路径(如果使用 XML 方式编写 SQL)
         sessionFactory.setMapperLocations(new PathMatchingResourcePatternResolver()
                 .getResources("classpath:mapper/*.xml"));
         // 配置 MyBatis Plus 全局参数(可选)
         org.apache.ibatis.session.Configuration configuration = new org.apache.ibatis.session.Configuration();
         configuration.setMapUnderscoreToCamelCase(true); // 下划线转驼峰
         sessionFactory.setConfiguration(configuration);
         // 注入 MyBatis Plus 插件(如分页插件)
         sessionFactory.setPlugins(mybatisPlusInterceptor());
         return sessionFactory.getObject();
     }
    
     // 3. MyBatis Plus 分页插件(可选,复杂查询分页用)
     @Bean
     public MybatisPlusInterceptor mybatisPlusInterceptor() {
         MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
         interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL)); // 适配 Calcite 兼容的 MySQL 语法
         return interceptor;
     }
    
     // 4. 配置事务管理器(可选,需要事务支持时添加)
     @Bean
     public PlatformTransactionManager transactionManager(DataSource calciteDataSource) {
         return new DataSourceTransactionManager(calciteDataSource);
     }
    }

    核心逻辑给大家捋一捋:先通过 Calcite 创建统一的数据源,再把它注入到 MyBatis Plus 的 SqlSessionFactory 里。这样一来,咱们后续写代码就完全是 MyBatis Plus 的熟悉风格了,不管是 Mapper 接口还是 XML 映射文件,都能直接用,跨数据源查询的复杂逻辑全交给 Calcite 处理。

2.4 核心查询实现(MyBatis Plus 风格)

接下来就是大家最熟悉的查询实现环节了,我用 MyBatis Plus 最常用的“Mapper 接口+注解”和“XML”两种方式来演示,还是以 MySQL 订单表和 MongoDB 用户表的关联查询为例,大家可以根据自己的习惯选:

(1)定义实体类(对应跨数据源查询结果,可使用 lombok 简化代码)

import lombok.Data;

@Data
public class UserOrderVO {
    private String orderId;      // 订单 ID(来自 MySQL)
    private String orderTime;    // 下单时间(来自 MySQL)
    private BigDecimal amount;   // 订单金额(来自 MySQL)
    private String userName;     // 用户名(来自 MongoDB)
    private String phone;        // 手机号(来自 MongoDB)
    private String userId;       // 用户 ID(关联字段)
}

(2)定义 Mapper 接口(MyBatis Plus 风格,无需编写实现类)

import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.annotations.Select;
import java.util.List;

// 继承 BaseMapper,获得 MyBatis Plus 基础 CRUD 能力
public interface UserOrderMapper extends BaseMapper<UserOrderVO> {
    // 注解方式编写跨数据源关联 SQL
    @Select("SELECT " +
            "o.order_id AS orderId, o.order_time AS orderTime, o.amount, " +
            "u.user_name AS userName, u.phone, o.user_id AS userId " +
            "FROM ecommerce.order o " +  // ecommerce:MySQL 的 Schema;order:订单表
            "JOIN user_mongo.user_info u " +  // user_mongo:MongoDB 的 Schema;user_info:用户表
            "ON o.user_id = u.user_id " +
            "WHERE o.user_id = #{userId}")
    List<UserOrderVO> queryUserOrderByUserId(@Param("userId") String userId);

}

(3)编写 Service 层

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.stereotype.Service;
import java.util.List;

@Service
public class UserOrderServiceImpl extends ServiceImpl<UserOrderMapper, UserOrderVO> implements UserOrderService {
    @Override
    public List<UserOrderVO> getUserOrderByUserId(String userId) {
        // 调用 Mapper 接口方法,实现跨数据源查询
        return baseMapper.queryUserOrderByUserId(userId);
        // 若使用 XML 方式:return baseMapper.queryUserOrderByUserIdWithXml(userId);
    }
}

(4)编写 Controller 层

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;
import java.util.List;

@RestController
public class CrossDataSourceQueryController {
    @Autowired
    private UserOrderService userOrderService;

    @GetMapping("/user/order/{userId}")
    public List<UserOrderVO> queryUserOrder(@PathVariable String userId) {
        // 调用 Service 方法,返回跨数据源查询结果
        return userOrderService.getUserOrderByUserId(userId);
    }
}

最后再划 3 个重点,确保大家少走弯路:

  1. 实体类字段要和查询结果列名对应,用别名适配下划线转驼峰更省心;
  2. Mapper 接口继承 BaseMapper 后,MyBatis Plus 的分页、条件构造器这些功能都能直接用,复杂查询也能轻松搞定;
  3. 咱们写的都是标准 SQL,Calcite 会自动解析适配不同数据源,完全不影响大家原来的开发习惯。

    三、深度解析:Calcite 的经典使用场景

    讲完了集成步骤,再跟大家深度拆解下 Calcite 的经典落地场景。毕竟技术最终要服务于业务,这些场景都是我在实际项目中常用到的,拿来就能用!

第一个经典场景是多系统数据融合查询,这也是企业级中台的核心需求。做企业级中台的小伙伴肯定深有体会,大型企业里数据都是分散的——订单系统用 MySQL,用户系统用 MongoDB 存行为数据,库存系统用 PostgreSQL。要是想做“用户-订单-库存”全链路分析,传统做法得分别调三个系统的接口,再在业务层手动整合数据,不仅效率低,还容易出错。用 Calcite 分别适配这三个数据源后,只要写一套标准 SQL 就能实现跨数据源关联查询,咱们用 Spring Boot 3 搭好接口服务,业务层完全不用管数据存在哪,专注核心业务逻辑就行,亲测开发效率能提升 50%以上,再也不用写重复的接口调用和数据整合代码,而且 Calcite 的查询优化器会自动优化关联逻辑,查询效率也能跟上。

第二个场景是实时数据与离线数据联动查询,做电商的小伙伴应该经常遇到这类需求。比如实时订单数据存在 Kafka 里,历史订单数据存在 Hive 里,运营需要实时查看“今日订单+近 30 天历史订单”的汇总数据来做实时监控和决策。这种情况不用麻烦地把 Kafka 数据同步到 Hive,也不用把 Hive 数据同步到实时库,直接用 Calcite 的 Kafka 适配器(calcite-kafka)和 Hive 适配器(calcite-hive),就能把实时流数据和离线数据放到同一个查询体系里,写一条 SQL 就能实现“实时+离线”数据的联合查询,既省了大量数据同步成本,又能兼顾实时性和准确性,还支持增量查询。

第三个场景是自定义数据源适配,主要解决特殊格式数据查询的难题。企业里总有很多 CSV、Excel、Parquet 格式的文件数据,传统做法是先把这些文件导入数据库才能查询,步骤又多又耗时,尤其是临时做数据分析的时候,导入数据库的成本太高了。而 Calcite 内置了文件适配器(calcite-file),支持直接查询这些文件数据,根本不用导入数据库。咱们再结合 Spring Boot 3 的文件上传功能,还能实现“文件上传后直接用 SQL 查询”的需求,临时分析数据超方便。如果有企业内部的特殊格式文件,比如自定义的二进制文件,也可以自己实现 Calcite 的 SchemaFactory 和 TableFactory 接口,写个自定义适配器,就能适配这些特殊数据源了。

四、避坑指南:集成注意事项与优化建议

4.1 这些坑一定要避开!

  • 适配器版本要统一:Calcite 核心依赖和各数据源适配器的版本必须一致,不然很容易出现类加载异常,这个坑我踩过,大家一定要注意。
  • 模型文件配置要规范:Schema 名称、表名要清晰,别重复;数据源的地址、端口、账号密码这些连接参数一定要准确,错一个就会连接失败。
  • 要考虑数据源性能:跨数据源查询的性能取决于最慢的那个数据源,所以要确保每个数据源自身性能没问题,不然会拖慢整个查询。

    4.2 优化小技巧,查询更快更稳

  • 启用 Calcite 缓存:配置一下 Calcite 的元数据缓存和查询计划缓存,能减少重复解析和元数据查询的时间,提升查询效率。
  • 优化 SQL 写法:尽量避免复杂的多表关联,能把过滤条件下推到数据源的就尽量下推。虽然 Calcite 会自动优化,但手动优化后的效果会更好。
  • 自定义优化规则:如果是特别复杂的业务场景,可以自己实现 Calcite 的 OptimizerRule 接口,写自定义的查询优化规则,进一步提升查询效率。

    五、本文总结

    最后总结一下,对于熟悉 Spring Boot 3 的咱们来说,集成 Calcite 的关键就是理解它“统一查询”的核心思想,把模型文件写对、核心 Bean 配置好,就能快速实现多数据源查询能力了。https://mybj123.com/28732.html

36ecf4845e41c9282eecdb5b690cc65b_6390495865593148019638243.png

在金融科技(FinTech)进入 2026 年的今天,数字化转型已步入“无人区”。随着生成式 AI 与大模型在金融业务场景的广泛落地,金融软件系统的架构正经历从“云原生”向“AI 原生”的范式跃迁。然而,架构越先进,质量保障(QA)的压力就越大。传统的测试手段在面对微服务交织、逻辑动态变幻的金融交易系统时,日益显现出“力不从心”的疲态。

1月19日,这一局面迎来重要里程碑。由中国信通院、中国人工智能产业发展联盟(AIIA)牵头,联合 Testin云测、中国工商银行、国泰君安证券、海通证券等头部金融与技术机构共同编制的《面向软件工程的智能体技术和应用要求 第3部分:测试智能体》(以下简称《规范》)正式发布。这不仅是一份技术文件,更是金融行业在 AI 时代守住安全红线的“数字化白皮书”。

行业深蹲:金融软件质控的三大“效能黑洞”

长期以来,金融机构的研发效能被三个核心痛点紧紧拽住。

首先是高频迭代与回归压力的矛盾。在互联网金融产品竞争白热化的当下,某股份制银行的 App 每周更新频率甚至达到“一周三版”。传统的自动化测试依赖人工维护脚本,往往新功能还没测完,UI 布局又改了,导致脚本大面积报废。

其次是业务逻辑的深度耦合。金融交易链路长、涉及私有协议多,AI 辅助工具若不理解“贷款审批”或“清算对账”的领域上下文,生成的测试案例往往流于表面,无法触达深层逻辑漏洞。

最后是合规与容错率的极低门槛。金融系统一旦在生产环境出现 Bug,面临的是公关危机、监管处罚乃至经济损失。

技术破局:Testin云测如何重塑“智测大脑”?

作为本次《规范》的核心参编单位,Testin云测凭借连续多年深耕 AI 测试的经验,其技术实力在最新公布的“2025 AI 测试服务商”榜单中荣登榜首。其核心产品 Testin XAgent 成为金融企业破局的关键。

  1. 深度语义理解与 RAG 知识注入 传统的 AI 工具容易产生“幻觉”,这对追求绝对精确的金融业是致命的。Testin XAgent 引入了 RAG(检索增强生成)技术,将银行内部沉淀的 PRD 文档、接口规范、历史缺陷报告等私有知识进行向量化。这意味着,当测试人员输入“测试大额存单申购流程”时,AI 能够自动联想相关的限额逻辑、风控规则,生成的测试案例采纳率高达 60% 以上,实现了真正的“懂行测试”。
  2. 视觉自愈引擎攻克 UI 频繁变更 针对 UI 自动化的“脚本易碎”问题,Testin XAgent 率先将视觉大模型(VLM)与 OCR 技术融合。它赋予了智能体像人眼一样的感知力,不再机械地识别控件 ID。在实际应用中,即使 App 界面改版,智能体也能通过逻辑关联自动“认路”,将脚本稳定性拉升至 95% 以上。
  3. 跨平台的高精度闭环 金融 App 必须兼容上千款移动终端。Testin云测通过云端真机实验实验室,配合 AI 智能诊断功能,将原本需要人工排查 30 分钟的错误缩短至 5 分钟。在某大型股份制银行的实践中,回归测试周期从数周缩短至数天,业务场景覆盖率提升了 300%。

趋势洞察:从“成本中心”向“价值中心”的跃迁

《规范》明确了测试智能体需具备感知、记忆、规划、执行四大核心能力。这标志着测试工作正从人力密集型向机器智能驱动转变。

Testin云测 CEO 徐琨曾指出:“软件质量已成为数字经济时代的关键生产力。”对于金融机构而言,测试智能体不仅是省钱的工具,更是构建“数字免疫系统”的核心。通过 AI 的闭环反馈,企业能提前预判风险,将“事后发现”转变为“事前预防”。

随着标准化与智能化的同频共振,以 Testin云测为代表的领军厂商,正在 AI4SE 的新纪元中,助力金融科技夯实数字基石,催生出更具韧性、更敏捷的未来。

行业现状与核心挑战
工业大数据正成为制造业数字化转型的核心驱动力,但国内外的竞争格局却大有不同。国内企业近年来快速崛起,政策支持加上市场需求爆发,让这个领域充满活力。根据2023年中国工业互联网研究院的报告,国内工业大数据市场规模已突破千亿元,年增长率保持在20%以上。企业面临的主要挑战包括数据孤岛、技术集成难度高,以及中小型制造厂的应用成本问题。
解决方案的技术路径与创新
解决方案上,国内外企业各有千秋。国内公司更注重平台化和生态构建,国外企业则偏向底层技术深耕。创新方面,国内外都在推工业大模型,国内企业更注重大模型与垂直行业的结合,比如在汽车制造中优化生产流程,而国外公司则强调跨行业通用性。技术路径没有绝对优劣,关键看企业需求:如果要快速落地,国内方案可能更灵活;如果追求全球标准,国外巨头更有优势。
标杆案例:国内外企业实战解析
广域铭岛在国内有个经典案例,是跟一家大型汽车零部件厂合作,通过他们的平台实现了生产线的实时监控和预测性维护,结果设备停机时间减少了25%,每年节省成本上百万元。这个案例突出了数据驱动的价值,从采集到分析,全链条优化。
转到国外,西门子在欧洲的案例很亮眼,比如与宝马合作,利用MindSphere优化供应链,实时跟踪零部件状态,让库存周转率提高了20%。
GE数字的Predix平台则在能源领域发力,在一个风电项目中,通过大数据分析预测风机故障,将维护成本降低了15%。
这些案例显示,无论国内外,解决方案的核心都是解决实际问题:国内企业更擅长快速迭代和本土适配,国外公司则强在技术沉淀和全球化应用。如果你是企业决策者,选供应商时得掂量自家需求——要速度,看国内;要广度,考虑国外。总之,工业大数据不是虚的,它真能变出真金白银。

最近 vibe 了十几个 skill ,都是脚本/工具型的,有稳定的输入输出,比如输入一个图片,输出图片中的文字信息这种,后面可能会更多 skill ,也会有非常多的组合。

我平时需要经常调用这些组合出来的 tasks (其实就是 prompt 形式的自然语言输入),但现在最大的问题是,给出需求,AI 有时会跳过使用某个 skill 工具。我试了不少办法,似乎没有 100% 稳定的。

星球同学提问

甘哥你好,我是双非本,2硕,目前研1,打算研一下或研二上去找第一段实习,今天想跟你请教一下项目具体该如何准备。

从开学到现在我把通用基础大概学了一遍,然后写了一个内存池的小项目,这个项目网上资源也比较多了,我在写的时候大概就是先看一下框架图,了解框架后基本就是对着源码抄,这样一方面效率比较低,另一方面感觉自己在抄的过程中也没学到太多东西。

最近我想再做一个大项目放在简历上,所以想请教一下以什么样的思路去准备项目是比较正确的,是否需要自己手动把完全的项目搓出来,以及想问一下一个项目从开始学习,一直到写到简历上,大概的流程是怎样的,感谢甘哥解答。

阿甘回答

对于你的疑问,可以去《职业规划》知识库:

https://www.yuque.com/u41022237/bclo90/ttxnh88k7so0w9f8?singl... 《职业规划》

看看一下文章内容:

拿到一个学习项目,怎么快速掌握

面试的时候项目怎么聊,才能发挥最大的价值

编程项目怎么学习

拿到一个学习项目,怎么快速掌握

很多学员在学项目的时候,面对一份庞然的代码都感觉无从下手,不知道怎么掌握。

我认为可以分为如下几步,一步步来,捉个击破。

第一步:把项目跑起来,看看什么效果

第二步:理解清楚项目的架构,进行模块划分

第三步:模块化学习,重点是理解清楚设计逻辑

项目运行起来,看效果

如果是那种前后端的项目大家运行起来,项目效果一目了然,可以很清楚的知道都有什么功能。

但是cpp更多的岗位都是底层的,更多的是对外封装接口,供应用使用的。
这个时候怎么看,其实这种一般在开发的时候,都会有写对应的test测试程序的。我们可以执行对应的测试程序,然后输入
不同的命令,看看效果是怎么样的。

理解清楚项目的架构,进行模块的划分

不管是公司的还是开源的项目,一般都是有架构图。可以搜集下对应的架构图,了解下项目的基本框架。

再结合你你看的项目效果,划分出主要的功能模块。进行功能的划分

模块化学习,重点是理解清楚设计逻辑

说到代码逻辑的学习,有的人,可能首先会说从main函数开始看。

当然对待这种方法,我不可否认它存在的一定道理。比如针对一个小型项目,

可能就是一些函数的调用,顺序结构,这个从main函数,一步步看下去当然没有问题。

但是一个大的项目必然是多线程调用,以及一些事件信号异步的回调等等,这个时候如果你从main函数开始追,估计一会你就困的睁不开眼了。

所以这个时候,我认为最好的方式,就是根据你上面写的模块划分。选择你感兴趣的模块捉个击破。

为什么会推荐这种看法的,其实可以从一下几点分析:

(1)该模块代码产生的原因,项目的理解

(2)简历的书写

其实一个大项目,无非就是一个个小项目组合起来的吧。随着时间的推移,需求变多,导致开发的模块变多,最终称为大家所说的屎山代码。所以这个功能模块产生,可以理解成就是把该功能实现的逻辑堆砌在此项目上了。

推荐大家这么看,还有就是大家现在看项目肯定是为了写在简历上加分的,在简历写的时候也是写你实现了什么功能,功能有什么难点。所以,看也是模块的看,毕竟看懂了就可以立即写的简历上了。

咱们星球的项目的话,其实我认为完全没必要看代码了,这些都帮你们抽离转换成文字了,所以感觉没必要自己再去看了。写成高质量的文档了,什么时候高质量的文档,就是努力能一份,单纯看文档,大家就完全可以理解这项目,可以达到和面试官拉扯的水平。这也是最近一直在干的事情,节省大家的时间,减少大家的学习成本。

还有就是面试的时候没人感兴趣你的代码,以及项目展示的,除非你强烈主动要求,看代码也是为了理解清楚项目的逻辑
我认为单纯站在面试角度,代码都没必要看,更何况敲了。看别人项目代码,浪费这时间毫无作用。想看就多看看开源的,安卓源码,Linux内核的。别人的项目你拿来面试。别人也不是大拿,写的一堆屎对你有学习意义吗。为啥不看这些好的啊,经历了时间检验的。

面试的时候项目怎么聊,才能发挥最大的价值

最近很多同学在面试的时候,问项目的时候,不知道怎么聊,才能发挥出项目的最大值,回答到期待的面试官期待的得分点。

这里咱们主要聊聊cpp / c++相关的项目,cpp / c++其实主要岗位就是嵌入式开发,底层相关岗位。

专业领域性非常强,不同的方向,发现除了都用cpp / c++语言以外,技术栈天差地别。

对于像这种领域性比较强的项目,说想和面试官完全聊明白是很难的。因为很多面试官可能人家都不是搞网络的,或者说人家都不是搞底层网络的。(以AI智能网络诊断项目为例)其他项目也一样,比如自己实习。很可能大多数面试官不是搞你这个方向的人家都不懂。

那怎么才能发挥出这项目的价值,甚至说你实习的价值。那就要从你的简历书写,以及你的介绍,让面试官看到开发这个功能的难度,让面试官感觉到如果他来做这一块,做起来可能也会很棘手。最后的完成度可能还不如你。

让面试官感受到你这个人的开发能力,以及技术水平。让人家感觉如果把你招进来,快速学学他们这个方向的知识,也是可以快速上手干活的。

那对上面这些具体化,怎么让人家感受到你的开发能力以及技术水平呢。我们做开发的都知道,越接近底层,开发难度越大,对技术水平要求越高,所以要尽可能多的展现你对底层内核的理解能力。

那怎么让人家感受到你的开发能力呢,那就是比如你开发某个功能的时候,可以不仅仅是简单的介绍下功能的实现,也可以更多的说说你做这一块的一些前提的准备工作,方案的调研,功能的设计,让人家感受到你这个的人开发思维的一个完整性,仿佛一看就是一个开发的老手

编程项目怎么学习

星球很多同学,在做星球项目,或者做自己项目的时候,都会遇到各种坎坷,说看不懂,不理解。

那项目,一个从未接触过的项目应该怎么学习呢。

说方法之前,我们可以先对要学习的项目进行一个分类,分一下学习的两个境界。我认为可以整体分两类:

(1)一类是,自己学习,用于提升自己,用于跳槽,找工作给简历加分的 (个人项目)

(2)一类是,工作公司的项目,自己实际工作中的

对于个人项目,拿来面试。面试主要考察什么呢,你这个人设计能力的完善性,即你项目的某个功能,对于极端场景是否有考虑到。那这对于一个项目,熟悉到什么程度算可以了呢。主要就是项目的架构,项目功能的实现思路。对代码细节,写法没必要细究。

原因:

(1)相同的功能实现,不同的人可能就会有不同的写法,以及相同的人不同时期也会有不同的写法;

(2)面试重点是思维逻辑的交流,让人家可以听懂,可以认可,能够产生共鸣;毕竟人家也没看过你的代码,语法、写法人家也不知道,你说的这么细,反而让人家听不懂,效果还很差;

(3)这也是一直强调的,在学项目的时候也要注重文档的梳理编写。能够让一个搞python的,搞java的可以看懂,快速写出来。别说一堆自己项目自己命名,这确实详细,但是谁也看不懂,听不懂,那效果很差

公司的项目,我们进公司,主要是要解决项目bug,优化项目代码的,开发新功能的。解决项目的代码bug,肯定要能够精确定位,要对代码细节,调用过程了解,需要熟悉项目代码。

知道了对于不同场景下,项目的学习程度。那么再聊聊项目应该怎么学习。

相信很多同学,都再网上听过很多前辈分享的各种源码阅读方法。比如main函数开始追、分功能模块看、按住一个功能调用过程追等等。

在这里,主要想给大家强调的方法是什么呢?

借助AI,优先借助AI。

现在AI能力,确实足够强大了,比如gpt5、claude 4.5等等。并且像个人项目一般最多也就几万行,或者就算公司项目上亿行代码,但是到你部门负责的可能也就几万行,数十万行,代码量都不大。可以先让AI对你的项目代码分析分析,架构、功能,实现逻辑等等。先通过它帮助你了解百分之七八十,再自己慢慢解决剩下的百分之二十,效率会高很多,很给力。

可能有的同学,在知名公司工作,说公司内部模型,没有这最先进的,其实用你们公司目前内供的,我认为目前也是可以帮助你进行分析的。

(为什么会给大家强调这个呢,主要还是通过大家问我的一些技术问题项目问题发现,这些问题直接喂给AI基本就可以快速出方案进行解决,远远没必要在那里抓脑瞎。给大家写这个,就是让大家有用AI的意识,优先考虑,现在模型能力是够的了)

本文由mdnice多平台发布

作者:辰泉

提示:本文是 AgentRun Browser Sandbox 快速上手实践指南的姊妹篇,专注于高级集成方案、生产环境的最佳实践、性能优化和部署策略。如果您还没有完成基础学习,请先阅读《快速上手:LangChain + AgentRun 浏览器沙箱极简集成指南》

前言

在完成了 Browser Sandbox 的基础集成之后,本文将介绍高级集成方案(如 BrowserUse 框架)以及生产环境部署需要考虑的因素:如何管理 Sandbox 生命周期?如何优化性能和成本?如何保证系统的安全性和可观测性?本文将为您提供全面的高级应用和生产环境最佳实践指南。

基于 BrowserUse 集成 Browser Sandbox

image

效果截图

BrowserUse 是一个专门为 AI Agent 设计的浏览器自动化框架,支持视觉理解和智能决策。通过 AgentRun Browser Sandbox,您可以让 BrowserUse 在云端运行,享受 Serverless 架构的优势。

BrowserUse 架构概览

下图展示了 BrowserUse 与 Browser Sandbox 的集成架构:

image

架构特点:

  1. 智能决策循环: Agent 通过 LLM 分析页面截图,基于视觉理解生成操作指令,执行操作后继续循环,直到任务完成
  2. 无头浏览器控制: 通过 CDP 协议远程控制云端浏览器,Playwright 作为底层驱动,所有操作在云端执行
  3. 实时可视化: VNC 提供实时画面监控,方便调试和验证 Agent 行为

快速开始

安装依赖

pip install browser-use python-dotenv agentrun-sdk[playwright,server]

主要依赖说明:

  • browser-use:BrowserUse 核心库,支持多模态 LLM
  • agentrun-sdk[playwright,server]:AgentRun SDK,用于创建 Sandbox
  • python-dotenv:环境变量管理

配置环境变量

创建 .env 文件:

# DashScope API Key(用于 Qwen 模型)
DASHSCOPE_API_KEY=sk-your-dashscope-api-key
# AgentRun 认证信息
AGENTRUN_ACCOUNT_ID=your-account-id
ALIBABA_CLOUD_ACCESS_KEY_ID=your-access-key-id
ALIBABA_CLOUD_ACCESS_KEY_SECRET=your-access-key-secret
# Browser Sandbox 模板名称
BROWSER_TEMPLATE_NAME=sandbox-browser-demo

创建 Sandbox 并使用 BrowserUse

import asyncio
import os
from agentrun.sandbox import Sandbox, TemplateType
from browser_use import Agent, BrowserSession, ChatOpenAI
from browser_use.browser import BrowserProfile
from dotenv import load_dotenv
load_dotenv()
async def main():
    # 创建 Browser Sandbox
    sandbox = Sandbox.create(
        template_type=TemplateType.BROWSER,
        template_name=os.getenv("BROWSER_TEMPLATE_NAME"),
        sandbox_idle_timeout_seconds=3000
    )
    # 配置 Qwen 多模态模型
    llm = ChatOpenAI(
        model='qwen-vl-max',
        api_key=os.getenv("DASHSCOPE_API_KEY"),
        base_url="https://dashscope.aliyuncs.com/compatible-mode/v1"
    )
    # 创建浏览器会话
    browser_session = BrowserSession(
        cdp_url=sandbox.get_cdp_url(),
        browser_profile=BrowserProfile(
            headless=False,
            timeout=3000000,
            keep_alive=True
        )
    )
    # 创建 Agent 并执行任务
    agent = Agent(
        task="访问阿里云官网并总结主要产品分类",
        llm=llm,
        browser_session=browser_session,
        use_vision=True
    )
    result = await agent.run()
    print(f"任务结果: {result.final_result()}")
    # 清理资源
    await browser_session.stop()
    sandbox.delete()
if __name__ == "__main__":
    asyncio.run(main())

BrowserUse 高级配置

自定义浏览器行为

browser_profile = BrowserProfile(
    timeout=3000000,             # 超时时间(毫秒)
    keep_alive=True,             # 保持会话活跃
)

多步骤任务编排

async def complex_task():
    """复杂的多步骤任务"""
    sandbox = Sandbox.create(
        template_type=TemplateType.BROWSER,
        template_name=os.getenv("BROWSER_TEMPLATE_NAME"),
        sandbox_idle_timeout_seconds=3000
    )
    llm = ChatOpenAI(
        model='qwen-vl-max',
        api_key=os.getenv("DASHSCOPE_API_KEY"),
        base_url="https://dashscope.aliyuncs.com/compatible-mode/v1"
    )
    browser_session = BrowserSession(
        cdp_url=sandbox.cdp_url,
        browser_profile=BrowserProfile(keep_alive=True)
    )
    # 任务 1:信息收集
    agent1 = Agent(
        task="访问阿里云官网,收集产品分类信息",
        llm=llm,
        browser_session=browser_session,
        use_vision=True
    )
    result1 = await agent1.run()
    # 任务 2:基于第一步结果继续操作
    agent2 = Agent(
        task=f"基于以下信息:{result1.final_result()},访问每个产品分类并提取关键特性",
        llm=llm,
        browser_session=browser_session,
        use_vision=True
    )
    result2 = await agent2.run()
    # 清理资源
    await browser_session.stop()
    sandbox.delete()
    return result2.final_result()

集成 VNC 实时监控

import webbrowser
import urllib.parse
async def run_with_vnc_monitoring():
    """运行 BrowserUse 并启用 VNC 监控"""
    sandbox = Sandbox.create(
        template_type=TemplateType.BROWSER,
        template_name=os.getenv("BROWSER_TEMPLATE_NAME"),
        sandbox_idle_timeout_seconds=3000
    )
    # 获取 VNC URL 并打开查看器
    vnc_url = sandbox.get_vnc_url(),
    if vnc_url:
        # 修复 VNC URL 路径
        if vnc_url.endswith('/vnc'):
            vnc_url = vnc_url[:-4] + '/ws/livestream'
        # 在浏览器中打开 VNC 查看器
        encoded_url = urllib.parse.quote(vnc_url, safe='')
        viewer_url = f"file://path/to/vnc-viewer.html?url={encoded_url}"
        webbrowser.open(viewer_url)
        print(f"VNC 查看器已打开,可实时监控浏览器操作")
    # 创建并运行 Agent
    llm = ChatOpenAI(
        model='qwen-vl-max',
        api_key=os.getenv("DASHSCOPE_API_KEY"),
        base_url="https://dashscope.aliyuncs.com/compatible-mode/v1"
    )
    browser_session = BrowserSession(
        cdp_url=sandbox.get_cdp_url(),
        browser_profile=BrowserProfile(headless=False, keep_alive=True)
    )
    agent = Agent(
        task="访问淘宝首页并搜索商品",
        llm=llm,
        browser_session=browser_session,
        use_vision=True
    )
    result = await agent.run()
    # 清理资源
    await browser_session.stop()
    sandbox.delete()
    return result.final_result()

BrowserUse 最佳实践

  1. 启用视觉理解: 对于复杂页面,使用 use_vision=True 让 LLM 分析页面截图
  2. 保持会话活跃: 使用 keep_alive=True 避免频繁重建连接
  3. 合理设置超时: 根据任务复杂度调整 timeout 参数
  4. 复用 BrowserSession: 对于多步骤任务,复用同一个 BrowserSession 提高效率
  5. 结合 VNC 调试: 开发阶段启用 VNC 实时查看 Agent 行为

获取完整示例代码

本文中的所有示例代码都可以在以下仓库中找到:

# 克隆示例代码仓库
git clone https://github.com/devsapp/agentrun-sandbox-demos.git
# 进入项目目录
cd agentrun-browseruse-wth-sandbox-demo
# 安装依赖(注意需要安装 server 扩展)
pip install -r requirements.txt

配置环境变量

# 复制环境变量模板
cp env.example .env
# 编辑 .env 文件,填入您的配置信息
# 必需配置项:
# - DASHSCOPE_API_KEY: DashScope API Key(用于 Qwen 模型)
# - AGENTRUN_ACCOUNT_ID: AgentRun 账号 ID
# - ALIBABA_CLOUD_ACCESS_KEY_ID: 阿里云访问密钥 ID
# - ALIBABA_CLOUD_ACCESS_KEY_SECRET: 阿里云访问密钥 Secret
# - BROWSER_TEMPLATE_NAME: Browser Sandbox 模板名称

运行示例(两步运行设计)

本项目采用服务器-客户端的架构设计,需要分两步运行:

第一步:启动 VNC 查看器服务

# 在终端 1 中启动 VNC Web 服务器
python main.py
# 服务启动后会显示:
# VNC 查看器服务已启动: http://localhost:8000
# 访问 http://localhost:8000 可以实时查看浏览器操作

main.py 的作用:

  • 启动本地 Web 服务器,提供 VNC 实时查看界面
  • 提供 WebSocket 代理,连接 AgentRun Sandbox 的 VNC 服务
  • 允许您在浏览器中实时监控 Agent 的操作过程

第二步:运行 BrowserUse 示例

# 在终端 2 中运行示例代码
python examples/01_browseruse_basic.py
# 运行高级示例
python examples/02_browseruse_advanced.py

为什么需要两步运行?

  1. 实时监控: main.py 提供 VNC 查看器,可以实时看到 Agent 在浏览器中的操作
  2. 调试友好: 通过可视化界面,更容易理解 Agent 的决策过程和行为
  3. 服务解耦: VNC 服务和业务逻辑分离,可以同时运行多个示例而共用同一个查看器

运行流程图:

image

仓库内容包括:

  • main.py:VNC Web 服务器,用于实时监控
  • examples/01_browseruse_basic.py:基础集成示例
  • examples/02_browseruse_advanced.py:高级配置示例
  • examples/sandbox_manager.py:Sandbox 生命周期管理
  • vncviewer/:VNC 查看器前端和后端代码
  • 完整的环境配置和最佳实践代码

Sandbox 生命周期管理最佳实践

三种管理模式

根据不同的应用场景,我们推荐三种 Sandbox 管理模式:

image

方案对比:

image

单例模式实现

适合开发调试和多轮对话场景:

class SandboxManager:
    """单例模式 Sandbox 管理器"""
    _instance = None
    _sandbox = None
    def __new__(cls):
        if cls._instance is None:
            cls._instance = super().__new__(cls)
        return cls._instance
    def get_or_create(self):
        """获取或创建 Sandbox"""
        if self._sandbox is None:
            self._sandbox = Sandbox.create(
                template_type=TemplateType.BROWSER,
                template_name=os.getenv("BROWSER_TEMPLATE_NAME"),
                sandbox_idle_timeout_seconds=3000
            )
        return self._sandbox
    def destroy(self):
        """销毁 Sandbox"""
        if self._sandbox:
            self._sandbox.delete()
            self._sandbox = None
# 使用
manager = SandboxManager()
sandbox = manager.get_or_create()  # 首次创建
sandbox = manager.get_or_create()  # 复用现有实例

连接池模式实现

适合高并发生产环境:

from queue import Queue
from threading import Lock
class SandboxPool:
    """Sandbox 连接池"""
    def __init__(self, pool_size=5, max_idle_time=300):
        self.pool_size = pool_size
        self.max_idle_time = max_idle_time
        self.pool = Queue(maxsize=pool_size)
        self.lock = Lock()
        self._initialize_pool()
    def _initialize_pool(self):
        """初始化连接池"""
        for _ in range(self.pool_size):
            sandbox = self._create_sandbox()
            self.pool.put(sandbox)
    def _create_sandbox(self):
        """创建 Sandbox 实例"""
        return Sandbox.create(
            template_type=TemplateType.BROWSER,
            template_name=os.getenv("BROWSER_TEMPLATE_NAME"),
            sandbox_idle_timeout_seconds=self.max_idle_time
        )
    def acquire(self, timeout=30):
        """获取 Sandbox 实例"""
        try:
            sandbox = self.pool.get(timeout=timeout)
            if not self._is_alive(sandbox):
                sandbox = self._create_sandbox()
            return sandbox
        except:
            raise RuntimeError("获取 Sandbox 超时")
    def release(self, sandbox):
        """归还 Sandbox 实例"""
        if self._is_alive(sandbox):
            self.pool.put(sandbox)
        else:
            new_sandbox = self._create_sandbox()
            self.pool.put(new_sandbox)
    def _is_alive(self, sandbox):
        """检查 Sandbox 是否存活"""
        try:
            return hasattr(sandbox, 'sandbox_id')
        except:
            return False
# 使用
pool = SandboxPool(pool_size=5)
sandbox = pool.acquire()
try:
    # 使用 sandbox 执行任务
    pass
finally:
    pool.release(sandbox)

会话状态管理

支持多用户多会话场景:

import time
class SessionManager:
    """会话状态管理"""
    def __init__(self):
        self.sessions = {}  # session_id -> sandbox
    def create_session(self, session_id: str):
        """创建会话"""
        if session_id not in self.sessions:
            sandbox = Sandbox.create(
                template_type=TemplateType.BROWSER,
                template_name=os.getenv("BROWSER_TEMPLATE_NAME"),
                sandbox_idle_timeout_seconds=1800
            )
            self.sessions[session_id] = {
                'sandbox': sandbox,
                'created_at': time.time(),
                'last_used': time.time()
            }
        return self.sessions[session_id]['sandbox']
    def get_session(self, session_id: str):
        """获取会话"""
        if session_id in self.sessions:
            session = self.sessions[session_id]
            session['last_used'] = time.time()
            return session['sandbox']
        return None
    def cleanup_expired_sessions(self, max_idle_time=1800):
        """清理过期会话"""
        current_time = time.time()
        expired_sessions = []
        for session_id, session in self.sessions.items():
            if current_time - session['last_used'] > max_idle_time:
                expired_sessions.append(session_id)
        for session_id in expired_sessions:
            self.destroy_session(session_id)
    def destroy_session(self, session_id: str):
        """销毁会话"""
        if session_id in self.sessions:
            self.sessions[session_id]['sandbox'].delete()
            del self.sessions[session_id]

性能优化

超时时间配置

合理设置超时时间是平衡性能和成本的关键:

# 开发环境(调试用)
sandbox = Sandbox.create(
    template_name="dev-template",
    sandbox_idle_timeout_seconds=7200  # 2 小时
)
# 生产环境(单次任务)
sandbox = Sandbox.create(
    template_name="prod-template",
    sandbox_idle_timeout_seconds=300  # 5 分钟
)
# 长时间任务
sandbox = Sandbox.create(
    template_name="long-task-template",
    sandbox_idle_timeout_seconds=10800  # 3 小时
)

超时策略推荐:

image

Sandbox 复用策略

class SmartSandboxManager:
    """智能 Sandbox 复用管理器"""
    def __init__(self):
        self.sandboxes = {}  # key -> sandbox
        self.usage_count = {}  # key -> count
    def get_sandbox(self, user_id: str, session_id: str):
        """获取或创建 Sandbox(支持复用)"""
        key = f"{user_id}:{session_id}"
        if key not in self.sandboxes:
            self.sandboxes[key] = Sandbox.create(
                template_type=TemplateType.BROWSER,
                template_name=os.getenv("BROWSER_TEMPLATE_NAME"),
                sandbox_idle_timeout_seconds=1800
            )
            self.usage_count[key] = 0
        self.usage_count[key] += 1
        return self.sandboxes[key]
    def should_recreate(self, key: str, max_reuse=50):
        """判断是否需要重建(防止状态累积)"""
        return self.usage_count.get(key, 0) >= max_reuse
    def recreate_if_needed(self, key: str):
        """按需重建 Sandbox"""
        if self.should_recreate(key):
            if key in self.sandboxes:
                self.sandboxes[key].delete()
                del self.sandboxes[key]
                self.usage_count[key] = 0

错误处理和重试机制

使用 tenacity 库实现智能重试:

from tenacity import retry, stop_after_attempt, wait_exponential, retry_if_exception_type
class SandboxError(Exception):
    """Sandbox 操作异常"""
    pass
@retry(
    retry=retry_if_exception_type(SandboxError),
    stop=stop_after_attempt(3),
    wait=wait_exponential(multiplier=1, min=2, max=10)
)
def execute_with_retry(sandbox, operation):
    """带重试的操作执行"""
    try:
        return operation(sandbox)
    except ConnectionError:
        raise SandboxError("连接失败")
    except TimeoutError:
        raise SandboxError("操作超时")
    except Exception as e:
        print(f"操作失败: {e}")
        raise SandboxError(f"操作失败: {e}")
# 使用示例
def navigate_page(sandbox):
    with sync_playwright() as p:
        browser = p.chromium.connect_over_cdp(sandbox.cdp_url)
        page = browser.contexts[0].pages[0]
        page.goto("https://example.com", timeout=30000)
        return page.title()
result = execute_with_retry(sandbox, navigate_page)

安全性最佳实践

环境变量保护

import os
from dotenv import load_dotenv
load_dotenv()
# 验证必需的环境变量
required_vars = ["DASHSCOPE_API_KEY", "AGENTRUN_ACCOUNT_ID"]
missing_vars = [var for var in required_vars if not os.getenv(var)]
if missing_vars:
    raise ValueError(f"缺少必需的环境变量: {', '.join(missing_vars)}")
# 敏感信息不要硬编码
API_KEY = os.getenv("DASHSCOPE_API_KEY")
ACCESS_KEY_ID = os.getenv("ALIBABA_CLOUD_ACCESS_KEY_ID")
ACCESS_KEY_SECRET = os.getenv("ALIBABA_CLOUD_ACCESS_KEY_SECRET")

URL 白名单

ALLOWED_DOMAINS = [
    'example.com',
    'aliyun.com',
    'alibaba.com'
]
def is_url_allowed(url: str) -> bool:
    """检查 URL 是否在白名单中"""
    from urllib.parse import urlparse
    domain = urlparse(url).netloc
    return any(allowed in domain for allowed in ALLOWED_DOMAINS)
def safe_navigate(page, url: str):
    """安全导航"""
    if not is_url_allowed(url):
        raise ValueError(f"URL 不在白名单中: {url}")
    page.goto(url)

日志脱敏

import re
def sanitize_log(log_text: str) -> str:
    """日志脱敏"""
    # 脱敏 API Key
    log_text = re.sub(r'sk-[a-zA-Z0-9]{20,}', 'sk-***', log_text)
    # 脱敏 Access Key
    log_text = re.sub(r'LTAI[a-zA-Z0-9]{12,}', 'LTAI***', log_text)
    # 脱敏密码
    log_text = re.sub(r'password["\s:=]+[^"\s,}]+', 'password: ***', log_text, flags=re.IGNORECASE)
    return log_text
# 使用
print(sanitize_log(f"使用 API Key: {API_KEY}"))

可观测性与监控

日志记录最佳实践

import logging
from datetime import datetime
# 配置日志
logging.basicConfig(
    level=logging.INFO,
    format='%(asctime)s - %(name)s - %(levelname)s - %(message)s',
    handlers=[
        logging.FileHandler(f'sandbox_{datetime.now().strftime("%Y%m%d")}.log'),
        logging.StreamHandler()
    ]
)
logger = logging.getLogger(__name__)
class MonitoredSandboxManager:
    """带监控的 Sandbox 管理器"""
    def create_sandbox(self, **kwargs):
        """创建 Sandbox(带日志)"""
        start_time = time.time()
        logger.info(f"开始创建 Sandbox: {kwargs}")
        try:
            sandbox = Sandbox.create(**kwargs)
            duration = time.time() - start_time
            logger.info(f"Sandbox 创建成功: {sandbox.sandbox_id}, 耗时: {duration:.2f}s")
            return sandbox
        except Exception as e:
            duration = time.time() - start_time
            logger.error(f"Sandbox 创建失败: {e}, 耗时: {duration:.2f}s")
            raise
    def execute_task(self, sandbox, task_name: str, operation):
        """执行任务(带日志)"""
        start_time = time.time()
        logger.info(f"开始执行任务: {task_name}, Sandbox: {sandbox.sandbox_id}")
        try:
            result = operation(sandbox)
            duration = time.time() - start_time
            logger.info(f"任务执行成功: {task_name}, 耗时: {duration:.2f}s")
            return result
        except Exception as e:
            duration = time.time() - start_time
            logger.error(f"任务执行失败: {task_name}, 错误: {e}, 耗时: {duration:.2f}s")
            raise

指标收集

from dataclasses import dataclass
from typing import Dict, List
import json
@dataclass
class SandboxMetrics:
    """Sandbox 指标"""
    sandbox_id: str
    create_time: float
    destroy_time: float = None
    total_requests: int = 0
    failed_requests: int = 0
    total_duration: float = 0.0
class MetricsCollector:
    """指标收集器"""
    def __init__(self):
        self.metrics: Dict[str, SandboxMetrics] = {}
    def record_creation(self, sandbox_id: str):
        """记录创建"""
        self.metrics[sandbox_id] = SandboxMetrics(
            sandbox_id=sandbox_id,
            create_time=time.time()
        )
    def record_request(self, sandbox_id: str, duration: float, success: bool):
        """记录请求"""
        if sandbox_id in self.metrics:
            metric = self.metrics[sandbox_id]
            metric.total_requests += 1
            metric.total_duration += duration
            if not success:
                metric.failed_requests += 1
    def record_destruction(self, sandbox_id: str):
        """记录销毁"""
        if sandbox_id in self.metrics:
            self.metrics[sandbox_id].destroy_time = time.time()
    def export_metrics(self, filepath: str):
        """导出指标"""
        metrics_data = [
            {
                'sandbox_id': m.sandbox_id,
                'create_time': m.create_time,
                'destroy_time': m.destroy_time,
                'total_requests': m.total_requests,
                'failed_requests': m.failed_requests,
                'success_rate': (m.total_requests - m.failed_requests) / m.total_requests if m.total_requests > 0 else 0,
                'avg_duration': m.total_duration / m.total_requests if m.total_requests > 0 else 0,
                'lifetime': m.destroy_time - m.create_time if m.destroy_time else time.time() - m.create_time
            }
            for m in self.metrics.values()
        ]
        with open(filepath, 'w') as f:
            json.dump(metrics_data, f, indent=2)
# 使用
collector = MetricsCollector()
collector.record_creation(sandbox.sandbox_id)
# ... 执行任务 ...
collector.export_metrics('metrics.json')

成本优化

按需创建与销毁

class CostOptimizedManager:
    """成本优化的管理器"""
    def __init__(self, idle_threshold=300):
        self.idle_threshold = idle_threshold
        self.sandboxes = {}
        self.last_used = {}
    def get_sandbox(self, key: str):
        """获取 Sandbox(懒加载)"""
        if key not in self.sandboxes:
            self.sandboxes[key] = Sandbox.create(
                template_type=TemplateType.BROWSER,
                template_name=os.getenv("BROWSER_TEMPLATE_NAME"),
                sandbox_idle_timeout_seconds=self.idle_threshold
            )
        self.last_used[key] = time.time()
        return self.sandboxes[key]
    def cleanup_idle(self):
        """清理闲置 Sandbox"""
        current_time = time.time()
        to_remove = []
        for key, last_time in self.last_used.items():
            if current_time - last_time > self.idle_threshold:
                to_remove.append(key)
        for key in to_remove:
            if key in self.sandboxes:
                self.sandboxes[key].delete()
                del self.sandboxes[key]
                del self.last_used[key]
                logger.info(f"清理闲置 Sandbox: {key}")

批量任务处理

async def batch_process_tasks(tasks: List[str], pool_size: int = 5):
    """批量处理任务(复用 Sandbox)"""
    pool = SandboxPool(pool_size=pool_size)
    results = []
    for task in tasks:
        sandbox = pool.acquire()
        try:
            # 处理任务
            result = await process_task(sandbox, task)
            results.append(result)
        finally:
            pool.release(sandbox)
    return results

生产环境部署

环境配置

开发环境 (.env.dev):

# 开发环境配置
BROWSER_TEMPLATE_NAME=dev-browser-template
SANDBOX_IDLE_TIMEOUT=7200
POOL_SIZE=2
LOG_LEVEL=DEBUG

生产环境 (.env.prod):

# 生产环境配置
BROWSER_TEMPLATE_NAME=prod-browser-template
SANDBOX_IDLE_TIMEOUT=300
POOL_SIZE=10
LOG_LEVEL=INFO
ENABLE_METRICS=true
METRICS_EXPORT_INTERVAL=300

高可用架构

image

健康检查

from flask import Flask, jsonify
app = Flask(__name__)
manager = SandboxManager()
@app.route('/health')
def health_check():
    """健康检查端点"""
    try:
        # 检查 Sandbox 是否可用
        sandbox = manager.get_or_create()
        # 简单的健康检查
        is_healthy = hasattr(sandbox, 'sandbox_id')
        if is_healthy:
            return jsonify({
                'status': 'healthy',
                'sandbox_id': sandbox.sandbox_id,
                'timestamp': time.time()
            }), 200
        else:
            return jsonify({
                'status': 'unhealthy',
                'error': 'Sandbox not available'
            }), 503
    except Exception as e:
        return jsonify({
            'status': 'unhealthy',
            'error': str(e)
        }), 503
@app.route('/metrics')
def metrics():
    """指标端点"""
    collector = MetricsCollector()
    # 返回当前指标
    return jsonify({
        'total_sandboxes': len(collector.metrics),
        'timestamp': time.time()
    })

故障排查与常见问题

连接问题

问题:无法连接到 Sandbox

排查步骤

def diagnose_connection(sandbox):
    """诊断连接问题"""
    print(f"1. 检查 Sandbox ID: {sandbox.sandbox_id}")
    print(f"2. 检查 CDP URL: {sandbox.cdp_url}")
    # 测试 CDP 连接
    try:
        with sync_playwright() as p:
            browser = p.chromium.connect_over_cdp(sandbox.cdp_url)
            print("✓ CDP 连接成功")
            browser.close()
    except Exception as e:
        print(f"✗ CDP 连接失败: {e}")
    # 测试 VNC 连接
    print(f"3. VNC URL: {sandbox.vnc_url}")
    print("提示: 可以在浏览器中打开 VNC URL 测试连接")

超时问题

问题:任务执行超时

解决方案

def handle_timeout(sandbox, operation, max_retries=3):
    """处理超时(带重试)"""
    for attempt in range(max_retries):
        try:
            return operation(sandbox, timeout=30000)
        except TimeoutError:
            logger.warning(f"任务超时(尝试 {attempt + 1}/{max_retries})")
            if attempt == max_retries - 1:
                # 最后一次尝试失败,重建 Sandbox
                logger.error("多次超时,重建 Sandbox")
                sandbox.delete()
                sandbox = Sandbox.create(
                    template_type=TemplateType.BROWSER,
                    template_name=os.getenv("BROWSER_TEMPLATE_NAME")
                )
                return operation(sandbox, timeout=60000)

性能问题

问题:响应速度慢

优化建议

  1. 使用连接池:预先创建多个 Sandbox 实例
  2. 启用 keep_alive:保持浏览器会话,避免重复建立连接
  3. 合理设置超时:根据任务复杂度调整超时时间
  4. 并发控制:限制并发请求数,避免资源竞争
# 性能优化配置示例
browser_session = BrowserSession(
    cdp_url=sandbox.cdp_url,
    browser_profile=BrowserProfile(
        timeout=30000,          # 30秒超时
        keep_alive=True,        # 保持连接
        disable_security=False  # 保持安全检查
    )
)

错误码参考

image

总结

通过本指南,您已经掌握了:

  1. BrowserUse 集成: 如何使用 BrowserUse 框架实现智能浏览器自动化
  2. 生命周期管理: 三种 Sandbox 管理模式的选择和实现
  3. 性能优化: 超时配置、复用策略、错误重试机制
  4. 安全实践: 环境变量保护、URL 白名单、日志脱敏
  5. 可观测性: 日志记录、指标收集、监控告警
  6. 成本优化: 按需创建、闲置清理、批量处理
  7. 生产部署: 高可用架构、健康检查、故障排查

关注「阿里云云原生」公众号,后台回复:BrowserUse

获取参考代码

立即体验函数计算 AgentRun

函数计算 AgentRun 的无代码到高代码演进能力,现已开放体验:

  1. 快速创建:访问控制台(https://functionai.console.aliyun.com/cn-hangzhou/agent/explore),60 秒创建你的第一个 Agent
  2. 深度定制:当需要更复杂功能时,一键转换为高代码
  3. 持续演进:利用函数计算 AgentRun 的基础设施能力,持续优化你的 Agent

从想法到上线,从原型到生产,函数计算 AgentRun 始终是你最好的伙伴。欢迎加入“函数计算 AgentRun 客户群”,钉钉群号: 134570017218

快速了解函数计算 AgentRun:

一句话介绍:函数计算 AgentRun 是一个以高代码为核心的一站式 Agentic AI 基础设施平台。秉持生态开放和灵活组装的理念,为企业级 Agent 应用提供从开发、部署到运维的全生命周期管理。

image

函数计算 AgentRun 架构图

AgentRun 运行时基于阿里云函数计算 FC 构建,继承了 Serverless 计算极致弹性、按量付费、零运维的核心优势。通过深度集成 AgentScope、LangChain、RAGFlow、Mem0 等主流开源生态。函数计算 AgentRun 将 Serverless 的极致弹性、零运维和按量付费的特性与 AI 原生应用场景深度融合,助力企业实现成本与效率的极致优化,平均 TCO 降低 60% 。 

让开发者只需专注于 Agent 的业务逻辑创新,无需关心底层基础设施,让 Agentic AI 真正进入企业生产环境。

推荐阅读:

很多团队在业务发展到一定阶段后,都会认真评估一次:
用户行为分析系统,是继续用现成产品,还是自己搭一套?

实际上,当企业需要埋点分析时,往往已经没有太多时间成本可投入
业务方希望尽快看到数据结果,管理层关注投入产出比,而完全从零自建埋点系统,周期长、风险高、不可控。
因此,基于成熟开源方案快速上线,再按需求自己二开,是目前更常见、也更可控的一种选择。

这篇文章不讨论“埋点的重要性”,只做一件事:
以自建埋点分析系统为参照,给出一个成本参考,并对比基于 ClkLog 开源方案的实际投入。

完全自建一套埋点分析系统成本通常在几十万,且建设周期长、不可控因素多。
基于ClkLog开源方案搭建首期成本可控制在几万最快一周完成部署集成,可以快速交付使用,并具备持续扩展的能力。

一、自建埋点分析系统,通常需要哪些模块?
很多团队低估了“自建”的工作量,下面只列最基础、不可回避的部分
1.数据采集层(SDK + 埋点规范)
这个阶段往往被低估,但实际上 SDK 会长期伴随业务演进,需要持续维护。
2.数据接入与处理层
核心目标是稳定接住数据:常见技术栈包括接入服务 + Kafka / MQ。
3.数据存储层
通常会选择 ClickHouse / Doris / Druid 这类分析型数据库,同时需要设计分区、冷热数据策略。
4.复杂分析计算
这是自建中最耗精力的部分,很多团队会发现:统计不难,难的是保证分析口径正确且性能可用。
5.管理后台与可视化
这部分前端和交互成本往往被严重低估。
6.运维与长期维护
系统上线只是开始,后续还包括各项调优、异常排查等运维工作。

二、为什么很多团队不会选择「完全自建」?
问题不在“能不能做”,而在是否划算
●早期业务验证阶段,数据系统很难直接创造业务价值
●自建系统容错成本高,试错周期长
因此,越来越多团队会选择:
在成熟的开源埋点分析系统基础上建设,而不是从零开始。

三、ClkLog开源方案能解决什么问题?
ClkLog提供了一套可直接落地的开源埋点分析方案,不依赖第三方SaaS服务。全面覆盖了埋点系统中最重、最复杂的核心能力:

1.数据采集层
支持神策SDK与自研鸿蒙SDK
2.数据接受层
进行日志数据接收与存储
3.数据处理层
进行数据处理、归档等服务
4.数据存储层
使用clickhouse进行大量数据查询
5.数据可视化
内置多种成熟分析模型,开箱即用

企业无需从零搭建底层能力,只需要围绕自身业务场景完成部署、运维和少量定制,即可形成一套可用的自有埋点分析系统。

四、基于 ClkLog,企业实际需要投入哪些成本?
1. 基础运行环境(参考)
以 ClkLog 社区版为例,在 1万日活应用规模下,采用Docker方式部署,单台服务器即可满足基础使用需求。
推荐配置参考:8核CPU;32GB内存
在常见的云厂商环境中,约1-2万/年,即可覆盖服务器、云盘、流量、备份等成本。

2. 软件部署与集成
●获取ClkLog代码(Github/Gitee)
●自行部署ClkLog服务(docker部署最快10分钟完成)
●接入埋点SDK(兼容web/小程序/iOS/安卓等)
●常规运维数据库和服务
整体实施周期短,最快一天即可完成部署并交付使用。

3. 业务层面的工作
●埋点规范梳理
●事件与指标定义
●少量业务定制
ClkLog已经内置十几种行业标准分析模型,可供业务直接开箱使用。若还有更多定制业务需要分析,可以通过自定义事件或二次开发来实现,与完全自建相比,省去的是部门团队沟通、大量底层系统设计与长期维护成本。

五、写在最后
对于大多数团队来说,先把系统跑起来、用起来、产生价值,比一开始追求完美更重要。
如果团队希望:
●完全掌控数据
●又不想长期投入基础设施研发
●把精力更多放在业务分析而不是系统本身
那么,基于成熟开源方案搭建自己的埋点分析系统,是一个性价比较高、风险更可控的选择


在网络通信场景中,IP地址是设备接入网络的“身份凭证”,没有合法的IP地址,设备便无法与其他节点进行数据交互。而在规模较大的网络环境中,手动为每台设备配置IP地址不仅效率低下,还容易出现地址冲突、配置错误等问题。动态主机配置协议(DHCP)的出现,完美解决了这一痛点。本文,国科云将围绕DHCP展开详细解析,包括其定义、工作原理及核心优势。

一、DHCP的定义

DHCP,即动态主机配置协议,是一种基于UDP协议工作的应用层协议,其核心功能是为接入网络的设备(如电脑、手机、打印机等)自动分配IP地址及网关、子网掩码、DNS服务器地址等网络配置参数。DHCP采用“客户端-服务器”(C/S)架构,其中DHCP服务器负责管理IP地址池、存储网络配置信息,DHCP客户端则通过向服务器发送请求,获取所需的网络配置并完成自动配置,无需人工干预。

简单来说,DHCP就像是网络中的“IP地址管理员”,当新设备接入网络时,会主动向“管理员”申请IP地址,管理员根据预设规则分配可用地址,并告知设备其他必要的网络配置,设备凭借这些配置即可快速接入网络;当设备断开网络或地址租赁到期后,管理员会回收该IP地址,重新纳入地址池供其他设备使用,实现IP地址的高效复用。

二、DHCP的工作原理

DHCP的工作过程本质上是DHCP客户端与服务器之间的四次交互过程,通常称为“DHCP四次握手”,整个过程基于广播通信(因为客户端初始无IP地址,无法进行点对点通信),具体步骤如下:

第一步:客户端发送IP地址请求(DHCP Discover)

当DHCP客户端(如刚开机的电脑)接入网络后,由于尚未配置IP地址,会以广播形式发送DHCP Discover报文。该报文的目的IP地址为255.255.255.255(广播地址),源IP地址为0.0.0.0(未分配IP时的默认地址),报文内容主要是“请求IP地址及相关网络配置”。此时,网络中所有的DHCP服务器都会接收到该广播请求。

第二步:服务器响应地址offer(DHCP Offer)

DHCP服务器接收到DHCP Discover报文后,会从自身的IP地址池中选取一个未被占用的可用IP地址,同时准备好子网掩码、网关、DNS服务器地址、IP地址租赁期限等配置信息,然后以广播形式发送DHCP Offer报文进行响应。该报文的目的IP地址仍为255.255.255.255,源IP地址为DHCP服务器自身的IP地址,报文内包含了为客户端分配的候选IP地址及完整的网络配置参数。需要注意的是,若网络中有多台DHCP服务器,客户端会接收到多个DHCP Offer报文。

第三步:客户端选择IP地址并请求确认(DHCP Request)

DHCP客户端接收到一个或多个DHCP Offer报文后,会选择其中一个(通常是最先收到的)Offer,然后再次以广播形式发送DHCP Request报文。该报文的核心目的有两个:一是向选中的DHCP服务器确认接受其分配的IP地址;二是告知其他DHCP服务器“已选择其他服务器的IP地址,无需为自己保留地址”。报文内容中会明确标注选中的DHCP服务器IP地址及对应的候选IP地址。

第四步:服务器确认地址分配(DHCP ACK)

被选中的DHCP服务器接收到DHCP Request报文后,会确认自身分配的IP地址仍未被占用,然后以广播形式发送DHCP ACK报文(确认报文)。该报文包含了最终确认的IP地址、子网掩码、网关、DNS服务器地址、IP租赁期限等完整配置信息,告知客户端“地址分配成功,可使用该配置接入网络”。其他未被选中的DHCP服务器接收到DHCP Request报文后,会回收之前预留的IP地址,重新纳入地址池。

客户端接收到DHCPACK报文后,会根据其中的配置信息完成自身的网络参数设置,此时便拥有了合法的IP地址,可正常接入网络进行通信。此外,若客户端在IP租赁期限到期前需要继续使用该地址,会提前向DHCP服务器发送DHCPRenew报文申请续租;若服务器同意,会回复DHCPACK报文延长租赁期限;若服务器拒绝或未响应,客户端会在租赁到期后释放该IP地址,并重新发起DHCPDiscover请求流程。

三、DHCP有哪些核心优势?

DHCP作为网络配置管理的核心协议,其优势主要体现在简化管理、提高资源利用率、减少错误、增强灵活性等多个方面,具体如下:

1.简化网络管理,降低运维成本

在无DHCP的网络环境中,管理员需要手动为每台接入网络的设备配置IP地址、子网掩码、网关等参数。对于拥有数十台、数百台甚至数千台设备的企业网络或校园网络而言,手动配置不仅耗费大量的时间和人力成本,还需要管理员记忆大量的IP地址信息以避免冲突。而DHCP实现了网络配置的自动化,管理员只需在DHCP服务器上预设IP地址池、租赁期限、网关、DNS等参数,后续所有客户端均可自动获取配置,无需人工干预。即使网络中有新设备接入或设备位置变动,也无需重新配置,极大地简化了网络管理工作,降低了运维成本。

2.提高IP地址利用率,节约网络资源

IP地址是有限的网络资源,尤其是在IPv4协议环境下,IP地址短缺问题较为突出。手动配置IP地址时,通常采用“静态分配”方式,即给每台设备分配一个固定的IP地址。但实际上,很多设备并非全天候接入网络(如员工的笔记本电脑、访客的手机等),这些设备占用的静态IP地址在未接入网络时会处于闲置状态,无法被其他设备使用,导致IP地址资源浪费。而DHCP采用“动态分配”方式,IP地址仅在设备接入网络时分配,且有明确的租赁期限。当设备断开网络或租赁到期后,IP地址会被服务器回收,重新纳入地址池供其他设备使用,实现了IP地址的循环复用,显著提高了IP地址的利用率,有效节约了有限的网络资源。

3.减少配置错误,提升网络稳定性

手动配置网络参数时,很容易出现各种错误,例如IP地址输入错误、子网掩码配置错误、网关或DNS服务器地址填写错误等。这些错误会导致设备无法正常接入网络,或出现网络通信异常、数据传输失败等问题,排查和解决这些错误需要消耗额外的运维时间,影响网络的正常运行。而DHCP由服务器统一分配和管理网络配置参数,所有参数都是管理员预设的正确信息,客户端自动获取并应用这些参数,从根本上避免了人工配置可能出现的错误,有效提升了网络的稳定性和可靠性。

4.增强网络灵活性,适配动态网络环境

现代网络环境具有很强的动态性,设备的接入和断开非常频繁(如企业员工上下班接入/断开办公网络、商场访客接入公共WiFi等),同时网络拓扑也可能根据需求进行调整(如办公室搬迁、新增网络区域等)。静态IP地址分配方式难以适配这种动态环境,若设备位置变动或网络拓扑调整,需要重新手动修改设备的IP地址配置,操作繁琐且容易出错。而DHCP的动态分配方式能够完美适配动态网络环境:新设备接入时可快速获取IP地址,设备移动时无需重新配置;若网络拓扑调整或IP地址规划变更,管理员只需在DHCP服务器上修改相关参数,所有客户端即可在下次获取配置或续租时自动应用新的参数,无需逐一修改客户端配置,增强了网络的灵活性和可扩展性。

5.支持集中化管理,便于网络维护与升级

DHCP采用集中化管理模式,所有网络配置参数都集中存储在DHCP服务器上,管理员可以通过服务器统一监控IP地址的分配情况、查看设备接入记录、修改网络配置参数等。这种集中化管理方式便于管理员掌握整个网络的IP地址使用状态,及时发现和处理地址冲突、地址耗尽等问题;同时,当网络需要升级(如更换DNS服务器、调整网关地址)时,管理员只需在DHCP服务器上进行一次修改,即可同步到所有客户端,无需逐一操作客户端设备,极大地提高了网络维护和升级的效率。

在企业报表制作中,数据汇总(如行小计、列总计、分组合计)是核心需求之一。传统报表工具的汇总功能往往存在局限:要么只能固定在表格末尾显示总计,要么无法灵活适配复杂的分组布局,导致报表可读性差、分析效率低,难以满足多样化的业务展示需求。

为解决这一痛点,SpreadJS V19.0 报表插件重磅升级「设计器容器支持合计(行和列)」功能,允许开发者在 ReportSheet 容器中灵活添加行、列汇总数据,无需复杂配置即可实现多维度数据聚合,让报表数据更清晰、分析更高效。

在这里插入图片描述

一、核心功能亮点:打破汇总布局限制

SpreadJS V19.0 的设计器容器合计功能,以“灵活适配、高效聚合”为核心,带来三大核心亮点:

1. 多维度汇总支持,覆盖全场景需求

支持在容器中自由添加行汇总、列汇总或全维度汇总,满足不同报表场景:

  • 行汇总:在分组数据下方添加小计、累计值,清晰展示局部数据聚合结果;
  • 列汇总:在数据列右侧添加总计、平均值,直观呈现跨维度数据统计;
  • 全维度汇总:同时启用行、列汇总,构建立体式数据统计视图,适配复杂分析场景。

2. 灵活显示模式,适配自定义布局

支持根据业务需求自定义汇总的展示样式与位置,无需受固定模板限制:

  • 可选择汇总数据的显示位置(如分组内底部、表格末尾、列右侧);
  • 支持与现有报表布局无缝融合,适配主从报表、分组报表等复杂结构;
  • 汇总数据样式可自定义(字体、颜色、边框),与报表整体风格保持一致。

3. 非侵入式设计,不影响原始数据

汇总数据的生成基于原始数据源计算,不会修改或污染基础数据:

  • 自动同步原始数据变化,当报表数据源更新时,汇总结果实时刷新;
  • 汇总行/列独立于数据区,不影响筛选、排序等基础操作;
  • 支持一键隐藏/显示汇总数据,灵活适配不同阅读场景。

二、典型应用场景:让数据汇总更贴合业务

该特性适用于各类需要数据聚合的报表场景,尤其匹配以下业务需求:

  • 区域销售汇总报表:按省份、城市分组展示销售数据,在每组下方添加行小计,右侧添加全国列总计,快速对比区域业绩与整体表现;
  • 部门财务费用报表:按部门、费用类型展示支出数据,通过列汇总计算各费用类型总支出,行汇总展示部门总费用,清晰呈现成本结构;
  • 库存分析报表:按仓库、商品类别展示库存数据,行汇总计算单个仓库库存总量,列汇总统计同类商品总库存,助力库存优化决策;
  • 项目进度汇总报表:按项目、任务阶段展示进度数据,行汇总计算项目整体完成率,列汇总统计各阶段平均进度,直观把控项目进展。

三、技术优势:低代码配置,高效集成

作为 SpreadJS V19.0 报表插件的核心增强特性,设计器容器合计功能延续了产品“低代码、高兼容”的优势:

  • 可视化配置:通过 SpreadJS Designer 设计器即可完成汇总设置,无需编写复杂代码,开发者上手成本低;
  • 高兼容性:无缝兼容 ReportSheet 现有功能(如分组、筛选、分页),不影响已有报表结构;
  • 性能优化:汇总计算基于 SpreadJS 高效的计算引擎,大数据量场景下仍能保持快速响应;
  • 灵活扩展:支持通过 API 自定义汇总计算逻辑(如加权平均、环比增长),满足特殊业务需求。

四、使用注意事项:避坑指南

为确保功能正常使用,需注意以下几点:

  1. 若 List/Summary Groups 中未包含任何表字段,Totals 选项将被禁用,无法添加汇总;
  2. 仅当 Row Groups 或 Column Groups 中包含表字段时,对应的行/列汇总设置才会生效;
  3. 若在容器中手动添加了静态行或列,自动汇总功能将被禁用,需删除静态元素后重新启用;
  4. 当 Summary/List Groups 中包含列表类型字段时:

    1. 仅 Row Groups 有表字段:Row Groups 和 Summary/List Groups 需均为垂直展开;
    2. 仅 Column Groups 有表字段:Column Groups 和 Summary/List Groups 需均为水平展开。

结语

SpreadJS V19.0 推出的“设计器容器支持合计(行和列)”特性,彻底打破了传统报表汇总功能的布局限制,通过灵活的多维度汇总、可视化配置、高效的性能表现,让数据聚合更贴合业务需求,大幅提升报表的可读性与分析效率。

无论是简单的数值统计,还是复杂的分组聚合,该特性都能帮助开发者快速构建专业的汇总报表,无需投入大量开发成本。SpreadJS V19.0 即将正式发布,欢迎持续关注,届时可通过官网 Demo 体验设计器容器合计功能的强大能力,让你的报表数据更具价值!

扩展链接

可嵌入您系统的在线Excel

这里是 「RTE 开发者日报」,每天和大家一起看新闻、聊八卦。我们的社区编辑团队会整理分享 RTE(Real-Time Engagement) 领域内「有话题的技术」、「有亮点的产品」、「有思考的文章」、「有态度的观点」、「有看点的活动」,但内容仅代表编辑的个人观点,欢迎大家留言、跟帖、讨论。

本期编辑:@瓒an、@鲍勃

01 有话题的技术
1、亚马逊公布新款自研 AI 芯片 Trainium 3

日前,亚马逊云科技 CEO Matt Garman 在 re:Invent 2025 活动上,正式公布了亚马逊自研 AI 芯片 Trainium 系列的最新进展。

会上,Amazon Trainium 3 UltraServers 正式发布。

据介绍,这是亚马逊云科技首款搭载 3 纳米工艺 AI 芯片的服务器,相较 Amazon Trainium 2,不仅计算能力提升 4.4 倍、内存带宽提升 3.9 倍,每兆瓦算力可处理的 AI token 数量更实现了 5 倍增长。

服务器最高配置 144 个芯片,提供惊人的 362 petaflops FP8 计算能力。在运行 OpenAI 的 GPT-OSS-120B 模型时,每兆瓦输出 token 数是 Amazon Trainium 2 的 5 倍以上,实现超高能耗比。

同时,Matt Garman 还首次披露了 Amazon Trainium 4 芯片,并承诺将实现较 Amazon Trainium 3 六倍的 FP4 计算性能、四倍内存带宽和两倍高内存容量。

据悉,亚马逊云科技目前已完成超 100 万个 Trainium 2 芯片的规模化部署,为 Amazon Bedrock 中大部分推理工作提供核心算力支持,包括 Claude 最新一代模型的高效运行。

( @APPSO)

2、Meta Reality Labs 挖角苹果交互设计负责人 Alan Dye

今天凌晨,彭博社记者 Mark Gurman 发文透露,苹果人机交互设计副总裁 Alan Dye 被 Meta 挖角。

据悉,Dye 自 2015 年以来,一直担任苹果的用户界面设计团队的负责人。 而本次被挖角后,苹果将用长期设计师 Stephen Lemay 顶替 Dye 的岗位。

值得一提的是,Dye 曾负责监督 iOS 26、液态玻璃界面、Vision Pro 界面、watchOS,以及各种系统交互层面内容(如空间计算交互、灵动岛)。

报道指出,Dye 在乔布斯离开后,一直担任着重要角色:帮助公司定义了最新操作系统、App 以及设备的外观。另外,Dye 在苹果的团队也帮助开发一系列新的智能家居设备。

Meta 方面,随着 Dye 加入,该公司正在创立一个新的设计工作室,并且有 Dye 负责硬件、软件和 AI 集成方面的界面设计。

Dye 将向负责现实实验室的首席技术官 Andrew Bosworth 汇报工作,而现实实验室负责开发可穿戴设备,如智能眼镜和虚拟现实头戴式设备。Gurman 透露,Dye 将于 12 月 31 日正式开始担任团队首席设计官。

而且 Dye 还不是一个人走的,他还带走了苹果设计部门的高级总监 Billy Sorrentino。后者从 2016 年起就在苹果,主要负责 VisionOS 的用户界面设计。

( @APPSO)

3、小米卢伟冰:AI 与物理世界的深度结合是智能科技的下一站

12 月 3 日,@卢伟冰 在社媒发布卢伟冰答网友问第十二期,在回答「罗福莉加入了小米,未来在 AI 上会有什么新的战略」时表示:

其实我们在前几个季度就已经开始了在 AI 上的压强式投入,虽然不能透露太多,我们在 AI 大模型和应用方面的进展远超预期,我们认为 AI 与物理世界的深度结合是智能科技的下一站,小米也非常渴望人才尊重人才,也希望能够给优秀的人才提供好的发展平台。

95 后罗福莉出生于四川,父亲是一名电工,母亲是教师。她本人曾就读于四川宜宾市第一中学校 「清北班」,并以优异成绩考入北京师范大学,后被保送至北京大学深造。

在北大读硕士期间,她于 2019 年在人工智能领域顶级国际会议 ACL 上发表了 8 篇论文,其中 2 篇为第一作者。毕业后,她先后在阿里达摩院、幻方量化、DeepSeek 工作,主导开发了多语言预训练模型 VECO,并参与研发了 MoE 大模型 DeepSeek-V2。

11 月 12 日,罗福莉在朋友圈发文,正式宣布自己已经加入小米。

11 月 19 日消息,小米公司今日官宣,12 月 17 日,小米将在北京·国家会议中心举办「人车家全生态」合作伙伴大会。主论坛时间为上午 10:00-12:15,全程开放线上直播。

作为小米 MiMo 大模型负责人,罗福莉将在主论坛发表题为《Xiaomi MiMo:小米基座大模型》 的主题演讲,这是她自 11 月 12 日加入小米后的首次公开亮相。

(@荆楚网)

02 有亮点的产品
1、Peopleboxai 推出 Nova:首款「人性化」AI 面试官,优化招聘流程

Peopleboxai 发布了其 AI 产品「Nova」,号称是「人性化」的 AI 面试官。Nova 能够自动化包括简历筛选、电话面试、视频面试、实时编码测试以及生成决策报告在内的整个第一轮招聘流程,显著加快招聘速度并提升效率。

全流程自动化: Nova 能够处理从简历筛选、联系候选人(通过 InMail、邮件、电话)到进行全面的语音/视频面试,甚至执行高级编码测试,直至提供详细的、可直接用于决策的报告。
高度「人性化」体验: Nova 被设计成「最佳招聘官和面试官的数字孪生」,能够模拟自然的暂停、语气和「嗯」等语用标记,提供友好的、类似真人的互动体验,候选人对其评价很高。
定制化与智能化: 用户可以根据自己的需求定制 Nova 的面试风格,包括技能深度、难度、面试类型、语调和结构。Nova 还能从公司过往的招聘数据(职位描述、面试记录、ATS 笔记等)中学习,提升其判断能力。
显著提升效率: Nova 帮助客户将第一轮面试报告的完成时间从 4-5 周缩短到 48 小时以内,为招聘团队节省了大量时间,使其能专注于更具战略意义的工作。
覆盖多渠道招聘: Nova 不仅处理入站(inbound)和内推(referral)的候选人,还能主动进行外呼(outbound)候选人搜寻和联系。
Nova 产品已上线,用户可通过 Peopleboxai 官网了解更多信息并申请试用。

(@Y Combinator Launches)

2、理想汽车发布首款 AI 眼镜 Livis:标配蔡司镜片 补贴后售价 1699 元起

12 月 3 日,理想汽车举办线上发布会,正式推出其首款 AI 智能眼镜 Livis。售价 1999 元起,12 月 31 日前下订可享受 15% 政府补贴,补贴后价格仅为 1699 元起。

「一款以钢铁侠 AI 管家「贾维斯」为灵感命名的智能眼镜,试图将「理想同学」的 AI 能力从驾驶空间延伸至用户日常生活的每个角落。」

Livis 名称源于理想汽车与钢铁侠 AI 管家「Jarvis」的组合。

整机重量控制在 36 克,提供经典黑、科技灰和橄榄绿三种颜色,并可选亮光或磨砂材质。

Livis 全系产品标配蔡司镜片,涵盖近视镜片、光致变色镜片与墨镜片等多种类型,满足用户在不同场景下的视觉需求。

理想宣称 Livis 在研发过程中实现了五项关键突破,构成了产品核心竞争力的重要组成部分。

典型续航时间达 18.8 小时。Livis 标配类似 AirPods 的无线充电盒,便于随身携带和补能。同时,眼镜支持与理想汽车的车机系统无线快充,上车后放置在专属充电位进行充电。

在硬件配置上,Livis 搭载恒玄 BES2800 主控芯片和独立的 ISP 成像芯片,采用 SONY IMX681 摄像头,拥有 1200 万像素、支持 4K 照片以及电子防抖拍摄。

汽车联动场景是 Livis 最独特的卖点。通过蓝牙和 5G 网络,眼镜可无缝连接车辆,实现语音远程控车。用户可在百米范围内,通过语音指令操控电动侧滑门启闭、提前开启空调及座椅加热,甚至检查车辆续航和充电状态。

(@极客公园、@快科技)

3、豆包手机助手无法登录微信,双方回应

日前,字节跳动豆包团队与中兴合作发布了豆包手机助手技术预览版后,有试用 Nubia M153 工程样机的用户反馈,出现无法正常登陆微信的情况。

对于相关情况,豆包团队方面昨晚发文并做出回应。

豆包方面表示,其后续已下线了手机助手操作微信的能力。 目前,nubia M153 上被禁止登录的微信账号正陆续解封。

而微信相关人士也通过澎湃新闻回应,豆包手机助手无法正常登陆微信的微信并没有什么特别动作,「可能是中了本来就有的安全风控措施。」

针对此前曾有科技公司爆料「豆包手机助手存在侵犯用户隐私」的问题,团队方面强调,豆包手机助手不存在任何黑客行为。

据悉,此前上述公司曾表示豆包手机助手在努比亚手机上拥有 INJECT\_EVENTS 权限,该权限在安卓权限定义中属于操作系统高危权限,并且拿到该权限,要面临刑事责任。

豆包方面表示,INJECT\_EVENTS 确实是系统级权限,但拥有了该权限许可,相关产品才能跨屏、跨应用来模拟点击事件,完成用户操作手机的任务需求。

团队还强调,豆包手机助手需要用户主动授权,才可以调用该权限,使用操作手机功能。该权限的使用,豆包方面也在权限清单中进行了明确的披露。据了解,目前行业的 AI 助手,均需要使用该权限(或与其类似的无障碍权限)才能提供操作手机的服务。

豆包方面强烈表示,豆包手机助手也不会代替用户进行相关授权和敏感操作。

同时,豆包方面也对读取屏幕的隐私问题进行了回应。其表示,助手操作手机时需要读取屏幕(否则无法完成任务),但屏幕和操作过程都不会在服务器端留下存储,且所有的相关内容也都不会进入模型训练,确保用户隐私安全。

( @APPSO)

4、健康追踪应用 Healthify Ria 升级 AI 助手:支持实时语音与摄像头交互

健康追踪初创公司 Healthify 推出了其 AI 助手 Ria 的新版本,该版本支持通过语音和摄像头进行实时对话,并能理解超过 50 种语言(包括 14 种印度语言)以及混合语言输入。此举旨在通过更自然的交互方式,提升用户健康习惯养成的效率和用户粘性。

实时对话与多模态输入: Ria 现在支持通过语音进行实时对话,用户还可以通过摄像头扫描食物获取营养信息并进行记录,大幅简化了数据录入流程。
多语言与混合语言支持: Ria 能够理解超过 50 种语言,并支持 Hinglish、Spanglish 等混合语言输入,服务全球用户。
整合多源健康数据: Ria 可以整合来自健身追踪器、睡眠追踪器、血糖监测仪等设备的数据,为用户提供运动、睡眠、身体准备度和血糖波动等方面的洞察,并给出建议。
增强记忆与个性化: Healthify 正在为 Ria 构建一个更持久的记忆层,使其能够记住用户的偏好和健康变化,提供更个性化的建议。
教练与营养师辅助: Ria 将被整合到用户与教练、营养师的沟通中,协助双方快速调取数据、回答问题,并可转录通话内容,提取关键信息。
(@TechCrunch)

03 有态度的观点
1、《阿凡达》导演:对 AI 没意见,但要尊敬演员们

近日,导演詹姆斯·卡梅隆在《阿凡达 3》世界首映礼上称该片没有使用 AI 生成,随后他对 ComicBookcom 发表了自己对于生成式 AI 的应用看法。

卡梅隆表示,自己对生成式 AI 没有意见,但他强调:「我们拍《阿凡达》电影不使用它,我们尊敬并赞颂演员们,我们不用 AI 代替演员。」

同时,卡梅隆也表示,「这件事(生成式 AI)自会有方向,我想好莱坞会进行自我监管,但我们作为艺术家要找到出路,前提是我们得能存在。所以,比起别的东西,来自『大 AI』的生存威胁是最让我担忧的。」

值得一提的是,卡梅隆所提到的「大 AI」,是指人类利用 AI 的状况和其产生的问题,对应的「小 AI」是指更细节、技术性的层面,比如用 AI 生成内容。

在卡梅隆看来,AI 和人类未来有深切的担忧和存在危机,他认为「小 AI」各行业会找到应对和利用之法,但「大 AI」问题就不好说了。

卡梅隆还提到,若了解 AI,就会知道「校准」是个重大问题。「AI 必须被训练、教导,必须被约束去只做对人类好的事情。」其强调,「只有我们人类达成了共识,你才能对 AI 进行校准。」实weibo.com/ttarticle/p/show?id=2309405258765112312235 weibo.com/ttarticle/p/show?id=2309405258765418234403 weibo.com/ttarticle/p/show?id=2309405258765732806837 weibo.com/ttarticle/p/show?id=2309405258766038991500 weibo.com/ttarticle/p/show?id=2309405258766353826244 weibo.com/ttarticle/p/show?id=2309405258766764867606 weibo.com/ttarticle/p/show?id=2309405258767074984432 打实