第 18 章 · 跑通 AI 图:CompiledGraph 的 compile、invoke、stream

LangGraph图工作流设计:状态驱动的AI工程化实践 AI工作流编排正从线性链式(Chain)向状态驱动的图结构(Graph)演进,其核心在于将控制流与业务逻辑解耦,通过显式节点(Node)、条件边(Edge)和强类型状态(State)构建可预测、可观测、可审计的生产级系统。LangGraph以图模型还原真实业务复杂性——支持条件分支、并行执行、循环重入与人工干预,尤其适合医保预审、金融风控、智能客服等需高确定性与合规追溯的场景。本文聚焦LangGraph中State契约设计、Node可测试性规范及Checkpointer在K8s环境下的高可用配置,提供从概念 阅读详情

版本:LangGraph4j 1.8.25

目标:蓝图 compile 成 CompiledGraph 之后,怎么用 invoke / stream 跑起来;两套 Config 各管什么;跑的时候状态怎么一步步变。

本章不接模型、不落盘。

先分清两套配置:CompileConfig 在编译时定一次;RunnableConfig 每次运行可换。中间的 CompiledGraph 编译一次,反复 invoke / stream。


18.1 compile:从蓝图到可执行实例

StateGraph 是可变蓝图。对外跑的是:

CompiledGraph<S> compiled = stateGraph.compile();
// 或带配置:
CompiledGraph<S> compiled = stateGraph.compile(compileConfig);

compile 大致做三件事:

  1. 校验拓扑:有没有从 START 出去的边、边是否指向不存在的节点、条件映射是否为空等。失败抛 GraphStateException。

  2. 收成可执行结构:节点动作和边整理进内部表,运行时按表推进。

  3. 固化 CompileConfig:这份配置跟着 CompiledGraph 走,运行时不再改。

无参 compile() 使用默认 CompileConfig,其中 recursionLimit = 25。

CompileConfig compileConfig = CompileConfig.builder()
        .recursionLimit(25)
        .graphId("hello-run")   // 进程里多张图并存时好区分,可选
        .build();
项含义
recursionLimit单次运行最多走多少步,默认 25,必须 > 0
graphId这张图的标识,可选

实践三点:

  1. compile 一次,复用 CompiledGraph。不要每个请求重新 addNode / addEdge 再 compile。

  2. compile 之后不要再改原来的 StateGraph,还指望已发布的实例跟着变。要改拓扑,改完再 compile 出新实例。

  3. 在 Spring 里通常做成单例 Bean;请求里只换输入和 RunnableConfig。


18.2 一整段能跑的代码

下面用 START → greet → polish → END。先跑通,后面几节按这段拆。

import static org.bsc.langgraph4j.StateGraph.END;
import static org.bsc.langgraph4j.StateGraph.START;
import static org.bsc.langgraph4j.action.AsyncNodeAction.node_async;
​
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
​
import org.bsc.langgraph4j.CompileConfig;
import org.bsc.langgraph4j.CompiledGraph;
import org.bsc.langgraph4j.GraphRepresentation;
import org.bsc.langgraph4j.RunnableConfig;
import org.bsc.langgraph4j.StateGraph;
import org.bsc.langgraph4j.action.NodeAction;
import org.bsc.langgraph4j.state.AgentState;
import org.bsc.langgraph4j.state.Channel;
import org.bsc.langgraph4j.state.Channels;
​
public class RunCompiledGraph {
​
    public static class DemoState extends AgentState {
        public static final String REPLY = "reply";
        public static final String LOGS = "logs";
​
        public static final Map<String, Channel<?>> SCHEMA = Map.of(
                REPLY, Channels.base(() -> ""),
                LOGS, Channels.appenderWithDuplicate(ArrayList::new)
        );
​
        public DemoState(Map<String, Object> initData) {
            super(initData);
        }
    }
​
    public static void main(String[] args) throws Exception {
        NodeAction<DemoState> greet = state -> {
            String name = state.<String>value("name").orElse("world");
            return Map.of(
                    DemoState.REPLY, "Hello, " + name + "!",
                    DemoState.LOGS, List.of("greet")
            );
        };
​
        NodeAction<DemoState> polish = state -> Map.of(
                DemoState.REPLY, state.<String>value(DemoState.REPLY).orElse("") + " ✓",
                DemoState.LOGS, List.of("polish")
        );
​
        CompiledGraph<DemoState> compiled = new StateGraph<>(DemoState.SCHEMA, DemoState::new)
                .addNode("greet", node_async(greet))
                .addNode("polish", node_async(polish))
                .addEdge(START, "greet")
                .addEdge("greet", "polish")
                .addEdge("polish", END)
                .compile(CompileConfig.builder()
                        .recursionLimit(25)
                        .graphId("hello-run")
                        .build());
​
        // invoke:只要最终状态
        var runConfig = RunnableConfig.builder().threadId("demo-1").build();
        compiled.invoke(Map.of("name", "LangGraph4j"), runConfig)
                .ifPresent(s -> {
                    System.out.println(s.value(DemoState.REPLY).orElse(""));
                    System.out.println(s.value(DemoState.LOGS).orElse(List.of()));
                });
        // → Hello, LangGraph4j! ✓
        // → [greet, polish]
​
        // stream:逐步看节点
        var streamConfig = RunnableConfig.builder()
                .threadId("demo-2")
                .streamMode(CompiledGraph.StreamMode.VALUES)
                .build();
        compiled.stream(Map.of("name", "Tom"), streamConfig)
                .forEachAsync(out ->
                        System.out.println(
                                out.node()
                                        + " | END=" + out.isEND()
                                        + " → " + out.state().data()))
                .join();
​
        System.out.println(compiled.getGraph(
                GraphRepresentation.Type.MERMAID, "Run Demo", true).content());
    }
}

18.3 跑的时候状态怎么变

输入:{name: LangGraph4j}。schema 里 reply 默认 "",logs 默认空列表。name 不在 schema 里,按覆盖合入。

步骤动作合并后状态(要点)
0输入合入name=LangGraph4j,reply="",logs=[]
1跑 greet,返回 reply + logs=[greet]reply=Hello, LangGraph4j!,logs=[greet]
2跑 polish,改写 reply,返回 logs=[polish]reply=Hello, LangGraph4j! ✓,logs=[greet, polish](追加)
3边到 ENDinvoke 返回这一份最终状态

执行循环:

初始 state = Channel 默认值 + 输入
循环,直到走到 END,或步数超过 recursionLimit:
  取下一节点 → 执行 → partial Map → 按 Channel 合并 → 按边求下一跳
invoke → 最终 State
stream → 一路上的 NodeOutput

直线两三个节点碰不到 recursionLimit。图上有环又退不出去时,会打满上限后停——先保证有退出边,再考虑调大上限。


18.4 invoke 与 stream

上图同一张图、两种用法:左边 invoke 只要最终状态;右边 stream 按帧吐出 NodeOutput。

方法返回适用
invoke(inputs) / invoke(inputs, config)Optional<State>同步接口、断言最终字段
invokeFinal(input, config)Optional<NodeOutput<State>>还要最终那一帧的节点名
stream(inputs) / stream(inputs, config)AsyncGenerator<NodeOutput<State>>看轨迹、按节点推送

底层都是按边推进;invoke 相当于把 stream 跑完,只取最后一帧的 state()。

输入除了 Map,还可以包 GraphInput:

import org.bsc.langgraph4j.GraphInput;
​
compiled.invoke(GraphInput.args(Map.of("name", "Tom")), runConfig);
compiled.invoke(GraphInput.noArgs(), runConfig);  // 无业务输入,用 Channel 默认值起步

日常直接传 Map 即可,内部会变成 GraphInput.args(...)。

stream 时每一帧是 NodeOutput:

方法含义
node()当前节点 id;结束帧为 __END__
state()合并到目前为止的完整状态,不是节点返回的那一小段 Map
isSTART() / isEND()是否 __START__ / __END__ 帧

所以 polish 帧上的 logs 已经是 [greet, polish]。forEachAsync 里处理完本帧即可;要等全部跑完,对返回的 CompletableFuture 调 join()。

StreamMode.VALUES(默认)逐步给出合并后的业务状态。枚举里还有 SNAPSHOTS;看节点进度用 VALUES。

stream 输出大致像:

greet | END=false → {name=Tom, reply=Hello, Tom!, logs=[greet]}
polish | END=false → {name=Tom, reply=Hello, Tom! ✓, logs=[greet, polish]}
__END__ | END=true → {…同上…}

(是否多一帧 __START__,以本机输出为准。)


18.5 RunnableConfig:每次运行可换什么

对照开篇配图的右栏:

RunnableConfig runConfig = RunnableConfig.builder()
        .threadId("user-42-req-7")
        .streamMode(CompiledGraph.StreamMode.VALUES)
        .addMetadata("userId", "42")   // 可选,便于日志关联
        .build();
项含义
threadId这一次运行的标识。多路请求各自换一个
streamModeVALUES:逐步业务状态
addMetadata请求级标签,可选

和 CompileConfig.graphId 不是一回事:graphId 管「哪张图」,threadId 管「这一次运行」。

同一份 CompiledGraph 连续跑两次:

compiled.invoke(Map.of("name", "A"), RunnableConfig.builder().threadId("t-a").build());
compiled.invoke(Map.of("name", "B"), RunnableConfig.builder().threadId("t-b").build());
CompileConfigRunnableConfig
何时定compile(...) 时每次 invoke / stream
本章用到的recursionLimit、graphIdthreadId、streamMode、metadata
生命周期跟着 CompiledGraph 固定每次运行新建一份即可

18.6 导出拓扑

// 第三个参数:是否打印条件边(有分支时建议 true)
System.out.println(compiled.getGraph(
        GraphRepresentation.Type.MERMAID, "Run Demo", true).content());

StateGraph 在 compile 前也能导出;compile 之后用 CompiledGraph.getGraph 看的是实际要跑的那份。条件边对不上、漏接 END,对着图容易发现。


18.7 常见问题

现象处理
invoke 得到空 Optional看是否中途抛错;直线图正常跑完应有最终状态
stream 里 state() 不像节点返回值那是合并后的全量状态;partial 已按 Channel 合进去
两次请求结果互相干扰每次运行设不同的 threadId
Mermaid 里看不到条件边getGraph(type, title, true)
改了节点或边,行为还是旧的重新 compile,换掉旧的 CompiledGraph
有环时跑到一半停是否打满 recursionLimit;先修退出边,再调上限
每个请求都 new StateGraph + compile启动时 compile 一次,请求里只 invoke / stream

请求级差异(谁在跑、要不要逐步输出、日志标签)写在 RunnableConfig 上,不要为此重建整张图。

用LangGraph构建可追溯的投资组合分析图工作流 投资组合分析本质上是多阶段、带反馈、需人工干预的决策过程,而非单点计算任务。传统链式流程与LLM代理难以应对金融场景中的条件分支、状态一致性及业务规则显性化需求。LangGraph通过状态图(StateGraph)将控制流与数据流解耦,支持条件跳转、节点幂等性与业务语义化状态管理,显著提升分析可审计性、协作效率与解释能力。结合Polars内存优化、浮点安全比较、超时熔断等工程实践,该方案已在券商私有云环境稳定支撑500只股票级组合分析。本文聚焦LangGraph在量化投研中的落地范式,涵盖图结构设计、节点原 阅读详情

相关推荐

LangGraph + Redis 实现 AI Agent 持久化状态管理

AI Agent 的核心挑战在于维持跨轮次、高并发、可恢复的上下文状态——这本质上是‘有状态工作流’的工程问题。其原理依赖于将运行时状态从易失性内存(如 Python 进程)解耦至外部存储,通过原子操作、TTL 自动过期与结构化数据模型保障一致性与时效性。技术价值体现在可靠性提升(防失忆/防串扰)、水平扩展能力增强(支持微服务与多实例)及调试可观测性改善。典型应用场景包括客服对话路由、多步骤科研分析、金融支付协同等需长期记忆的生产级 Agent 系统。本文聚焦 LangGraph 的 StateGraph

weixin_34221112的博客 488

JB3-9-SpringAI(一)

基础对话,通义千问,SpringAI,SpringAIAlibaba,AI对话,文生图,文生音频,文生视频,AI记忆,RAG,ETL,向量库,ToolCalling,MCP,Graph 等。

周航宇的博客 3924

本地智能体实战:Ollama+LangGraph构建可审计的合同审查系统

智能体(Agent)是具备感知、规划与执行能力的AI系统,其核心在于状态管理与工作流编排。在数据合规要求日益严格的背景下,本地化部署成为破解隐私与效能矛盾的关键路径——通过将模型推理、状态存储和流程调度全部收敛于内网环境,实现对敏感文本的端到端可控处理。Ollama提供轻量级、OS-native的本地大模型运行时,支持模型版本化、安全加固与离线迁移;LangGraph则以状态驱动图范式,保障工作流可追溯、可中断、可审计。该技术组合已广泛应用于法务合规、金融风控与医疗IT等强监管场景,支撑PDF解析、条款抽取

weixin_30245867的博客 733

AI Agent开发四阶实战路径:Python→LangGraph→CrewAI→AutoGen

AI Agent是让大模型从‘能回答’走向‘能做事’的核心范式,其本质是基于状态流转与工具协同的可控执行系统。理解Agent需先掌握状态管理原理——LangGraph通过图结构与不可变State实现可中断、可审计的确定性流程;而Python在此并非入门语言,而是定义数据契约(TypedDict/Pydantic)、异常语义(细粒度except)和环境ABI兼容性的工程协议。技术价值在于闭环落地能力:替代Excel手工汇总、解析多源PDF生成PPT、支撑真实业务工单分派等场景。本文聚焦2024–2025年高频

weixin_34167819的博客 402

RAG 2.0:基于LangGraph的实时Web数据增强与状态化工作流

RAG(检索增强生成)作为大语言模型落地的关键技术,正从静态文档检索迈向动态、可编程、可验证的智能体范式。其核心演进在于突破传统单线程瀑布流限制,引入有状态图编排(如LangGraph)实现条件分支、并行调度与中间态持久化,并深度融合实时Web数据接入能力——涵盖反爬适配、多源可信度评分、HTML/JSON/PDF混合内容语义归一等工程级处理。该架构不仅提升答案时效性与鲁棒性,更支撑金融舆情监控、政策合规追踪、竞品动态感知等强实时、高可信场景。本文聚焦RAG 2.0的范式迁移本质,详解LangGraph如何

weixin_30274627的博客 539

SpringBoot+Vue+MySQL 高校学科竞赛平台 完整可运行版(源码+文档)

本项目基于SpringBoot+Vue+MySQL构建高校学科竞赛管理平台,覆盖学生、教师、领队教师、管理员四大角色,实现竞赛发布、报名、刷题、评分、公示等全流程闭环管理。系统架构清晰,技术主流,配套完整源码、数据库脚本、万字论文、开题报告、答辩PPT及部署文档,支持一键运行,适用于毕业设计、课程设计及院系二次开发,真正实现“开箱即用”。

招风的黑耳优快云 156

InnoDB 内存结构总览:Change Buffer、AHI 与 Log Buffer

本文系统梳理InnoDB内存结构中的ChangeBuffer、Adaptive Hash Index(AHI)与LogBuffer。ChangeBuffer缓存二级索引页不在内存时的变更,减少随机IO,仅在页加载时合并;聚簇索引修改立即执行,因数据本身不可延后。AHI基于高频等值查询自动构建哈希索引,加速定位,仅支持等值操作。LogBuffer为redo log内存缓冲,配合磁盘日志实现崩溃恢复。三者均服务于性能优化,其中ChangeBuffer与AHI共享BufferPool空间,而LogBuffer独立

bksczm的博客 289

STM32CubeIDE之SHT3X温湿度传感器移植HAL库

有了前面的OLED的学习,这个学习起来也很快。 分以下几步走 1.你要有个温度传感器,SHT3X这个型号的,因为我要讲这个 2.你要有个STM32开发板(我用的是STM32L431RCT) 3.顺便找台电脑下载一个STM32CubeIDE 4.简单的找一个SHT3X的驱动,我是去某宝嫖的,一般卖这个的都有,这个驱动分两个文件,是.c和.h的,我直接把这两个放在下边 读了我上一篇的人,看这个应该很熟悉吧,一样的套路,学习方法是一样的,你就照搬就行 下面是sht3x.c的原文档,里面有个CRC..

qq_47736089的博客 2315

V8 机制、手写核心函数与 TypeScript 类型体操

或固定初始化(如数组先定长、对象先给全字段)保持类型与形状稳定;这些都比"换框架"更基础。只能处理纯数据(丢函数、Date、RegExp、循环引用报错)。生产级深拷贝要处理:原始值短路、循环引用、V8(Chrome / Node 的 JS 引擎)不是"解释一行跑一行"那么简单,它用。图:V8 执行流程——解释执行 + 热点优化,优化失败会 Deopt 回退。JS 内存自动管理,但"自动"不等于"不会漏"。是"固定间隔最多执行一次"。手写 Promise 是"懂异步"的试金石。是"停下后才执行最后一次",

qq_38468358的博客 346

STM32驱动GP2Y1010AU0F红外PM2.5传感器:从采样时序到浓度标定

在嵌入式环境监测项目中,模拟传感器输出信号的准确采集是系统可靠性的基石。许多工程师在接触红外散射式粉尘传感器时,常因不了解其特殊的脉冲驱动与采样保持机制,导致ADC读数异常。红外散射原理通过检测颗粒物散射光强来估算粉尘浓度,其输出信号并非稳定直流,而是与LED脉冲同步的短时窗口电压。理解这一时序特征,并掌握在STM32平台上通过定时器与ADC协同完成微秒级精准采样的方法,是获取有效数据的关键。该技术广泛应用于室内空气质量检测、空气净化器控制及DIY环境监测节点等场景。本文以GP2Y1010AU0F为例,详细

weixin_29159127的博客 283

CCS20实战入门:第一个工程搭建示例

通过实际操作演示如何在ccs20中创建并配置首个开发项目,涵盖环境设置与基础调试步骤,帮助新手快速上手ccs20集成开发环境,提升嵌入式开发效率。

weixin_31185473的博客 885

Spring Boot 数据源与 MyBatis(-Plus) 自定义配置详解

本文详解 Spring Boot 中单数据源环境下 HikariCP 与 MyBatis-Plus 的自定义配置。通过手动声明 SqlSessionFactory,实现下划线转驼峰、日志输出、一级缓存策略等精细化控制。结合 HikariCP 核心参数调优(如最大连接数、连接生命周期),确保高性能与稳定性。适用于仅需访问单一数据库的场景,避免多数据源复杂性,兼顾性能与可维护性。

BADAO_LIUMANG_QIZHI的博客 198

DeepSeek揭秘:构建高效反洗钱智能监控系统的全流程与代码实例

在金融领域,反洗钱(AML)是一项至关重要的任务。随着金融交易的复杂性和规模不断增长,传统的手工监控方法已无法满足现代金融系统的需求。因此,开发一个智能监控系统来自动识别和报告可疑交易变得尤为重要。本文将详细介绍如何使用DeepSeek技术构建一个高效的反洗钱智能监控系统,并提供相关的代码实例。

理论都是虚的,代码才是王道。 884

Java EE 进阶:8.MyBatis 操作数据库(入门)(第一弹)

Java EE 进阶:8.MyBatis 操作数据库(入门)(第一弹)

要努力去发光,而不是被照亮~ 130

【机器学习-09】特征工程

特征工程是机器学习模型构建的初步工作,但它的重要性却贯穿整个模型生命周期。在进行特征工程时,我们需要充分利用数据科学的知识和技巧,结合具体的应用场景和业务需求,来制定出最合适的特征提取和转换策略。只有这样,我们才能为机器学习模型提供最有价值的输入,从而使其发挥出最大的潜力。总之,特征工程是机器学习中的一项关键任务,它需要我们用心去探索、去实践、去创新。只有不断地优化和完善特征工程的过程,我们才能构建出更加准确、更加可靠的机器学习模型,为实际应用带来更大的价值。

qq_38614074的博客 2万+

三维重建(十三)——多视角重建

本文综述了多视角三维重建技术,涵盖静态和动态场景的重建方法。介绍了从图像获取到纹理映射的SFM流程,以及非刚性重建(NRSFM)的挑战和解决方案。重点探讨了基于可微渲染的重建方法,以及数据采集策略、相机标定和同步技术。文章还讨论了如何用单视角相机模拟多视角重建,总结了关键技术和未来研究方向。

河海大学研究生在读的学习笔记 1058

【从零理解 Spring AI · 12】MCP 的两种角色:做客户端还是做服务端

上一篇讲了 MCP 的概念:标准协议、三大角色、M+N 替代 M×N。

nice_lcj520的博客 501

STM32(HAL库)软件IIC驱动OLED

本文通过STM32F103C8T6单片机(HAL库)通过软件IIC方式对OLED进行驱动。

weixin_44597885的博客 9762

LeetCode Hot 100 二叉树专题(二)3 题(Java)

本篇文章共 3 题:543. 二叉树的直径、102. 二叉树的层序遍历、108. 将有序数组转换为二叉搜索树。 每道题都统一按「① 题目分析 & 解题思路 → ② 常见解法(附代码)及讲解 → ③ 知识点总结」的顺序组织;代码使用 Java 编写,节点定义沿用 LeetCode 默认的 TreeNode。

2401_88612756的博客 365

基于遗传算法的码头泊位分配调度优化问题求解

例如,基因型为 [3, 1, 4, 2] 表示第一艘停靠在第三个泊位,第二艘停靠在第一个泊位,以此类推。同时,该码头有 n 艘船需要停靠,每艘船的货物数量、船长、船宽都不同,需要根据其特性来分配合适的泊位,并确定每个泊位的使用时间,以最大化码头的使用效率。码头的泊位分配调度是一个关键的物流问题,它涉及到船舶的进出港、货物的装卸和存储等多个方面,因此对其进行优化是至关重要的。根据得到的最优个体,可以得到每个泊位停靠的船只、使用时间等信息,从而确定码头的泊位分配调度方案。% 不同船只的货物数量。

uote_e的博客 1075

廖雪峰Python教程[完整版]

廖雪峰的python教程整理的,已经排好版了,而且还是完整的,适合小白

JDK 下载安装:装完 Java 提示「不是内部或外部命令」?环境变量没配

JDK 是写 Java 程序必须装的东西。它包含运行 Java 的虚拟机(JRE)和编译 Java 的编译器(javac)——装了它,能跑、.java文件能编译成可执行程序。免费,学习和小规模生产都不花钱。

科小怪的博客 635

老版QQ原生表情gif动态

这是老版的QQ表情,不过全是动态的的,Windows照片查看器是不会动的,可以右击用浏览器打开查看,再说一遍是老版的,只是分享给宁愿用老版也要动态的人。

java框架大全

java框架大全

qq_39326137的博客 183

SAP B1中文培訓教材_SDK

公司内部培训资料,对开发工具 ,DIAPI, UIAPI,Add-ON有详细解说

蓝牙模块HM-10手册

蓝牙模块HM-10手册,该手册对蓝牙模块HM-10进行了详细的介绍和使用方法以及一些AT指令。

Java 多态 学习笔记

多态是面向对象编程的重要特性,指同一操作作用于不同对象时产生不同行为。其核心在于“父类引用指向子类对象”,结合方法重写实现运行时动态绑定。多态使代码更灵活、可扩展,如用Person p = new Student();统一处理各类人员注册,无需修改调用逻辑。但多态无法直接调用子类特有方法,需通过instanceof判断并强制转换。编译时看左边(类型),运行时看右边(实际对象),实现解耦与维护便利。

AA_AA114514的博客 361

SecureRandom做随机源,这个Java随机字符串工具类有3个方法

本文分享一款JDK17环境下的Java随机字符串工具类,内置3个开箱即用的方法,全部采用SecureRandom加密安全随机源,不存在弱随机、可预测、取模偏差等问题。工具类支持默认62字符集随机串、纯数字随机串、自定义字符集随机串三种生成模式,支持Unicode码点级别的字符集处理,兼容Emoji等增补字符,边界处理严格,异常信息明确,适合验证码、邀请码、盐值、随机口令、短链码等场景,源码可直接复制使用。

Java后端 | AI智能体应用实战派 | 电脑技能行家 299

IDEA 简介:从零认识 IntelliJ IDEA

IDEA 全称,是由 JetBrains 公司开发的一款主流 Java 集成开发环境(IDE)。它集代码编辑、编译、调试、测试、版本控制、构建管理等功能于一体,被大量 Java 开发者视为日常开发的首选工具。所谓 IDE(Integrated Development Environment,集成开发环境),就是把写代码所需的各类工具整合到同一个界面中。相比只用文本编辑器加命令行编译,IDE 能显著减少重复操作,让开发者把精力集中在业务逻辑上。

ztI10的博客 152

Java实现批量线段相交检测(跨积判定+扫描线优化与踩坑复盘)

【代码】Java实现批量线段相交检测(跨积判定+扫描线优化与踩坑复盘)

m0_64476639的博客 329
上一篇: 第 17 章 · 编排 AI 流程:StateGraph 节点、条件边与意图路由
下一篇: 第 19 章 · AI 工具循环与条件路由:管住 recursionLimit
AI深栈
博客等级 码龄14年 1粉丝 22原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值