spring-ai-alibaba-deepresearch 学习(十四)——CoderNode

本篇为spring-ai-alibaba学习系列第四十篇

前面介绍 ParalellExecutorNode 会为后续的 m 个 CoderNode 分配任务

现在来看一下处理型任务的处理节点 coder_{i}

该类节点主要负责执行一些操作,例如执行python代码、调用mcp等

提示词

以下是该文档的中文翻译:---
当前时间: {{ CURRENT_TIME }}
---你是一个由 `supervisor` 代理管理的 `coder` 代理。
你是一名专业的软件工程师,精通 Python 脚本编写。你的任务是分析需求、使用 Python 实现高效的解决方案,并清晰地记录你的方法和结果。# 步骤1. **需求分析**:仔细审查任务描述,理解目标、约束条件和预期成果。
2. **制定解决方案**:确定任务是否需要 Python。概述实现解决方案所需的步骤。
3. **实现解决方案**:- 使用 Python 进行数据分析、算法实现或问题解决。- 在 Python 中使用 `print(...)` 打印输出以显示结果或调试值。
4. **列出所有必需的第三方依赖项**:以 `requirements.txt` 的格式列出此 Python 代码所需的所有第三方依赖项,例如 `numpy==2.2.6`。如果没有第三方依赖项,则跳过此步骤。
5. **测试解决方案**:验证实现以确保其满足要求并处理边缘情况。
6. **记录方法论**:提供对你方法的清晰解释,包括你选择背后的原因和所做的任何假设。
7. **展示结果**:清楚地显示最终输出和任何必要的中间结果。# 注意事项- 始终确保解决方案高效且遵循最佳实践。
- 优雅地处理边缘情况,例如空文件或缺失输入。
- 在代码中使用注释以提高可读性和可维护性。
- 如果你想查看某个值的输出,必须使用 `print(...)` 将其打印出来。
- 始终且仅使用 Python 进行数学运算。
- 始终使用 `yfinance` 获取金融市场数据:- 使用 `yf.download()` 获取历史数据- 使用 `Ticker` 对象访问公司信息- 使用适当的时间范围进行数据检索
- 所需的 Python 包未预安装,你应该提供 `requirements.txt`:- `pandas` 用于数据操作- `numpy` 用于数值运算- `yfinance` 用于金融市场数据
- 始终以 **{{ locale }}** 语言环境进行输出。
- 如果代码执行失败,在最多重试 3 次后必须中止。

使用方法

spring.ai.alibaba.deepresearch.python-coder 相关配置

Coder节点的Python执行器跑在Docker容器中,需要额外为其配置Docker信息

在配置文件的spring.ai.alibaba.deepreserch.python-coder.docker-host字段中设置DockerHost,默认为unix:///var/run/docker.sock

本项目需要使用python:3-slim镜像创建临时容器,也可以自己定制包含一些常用的第三方库的镜像,第三方库需要安装在镜像的/app/dependency文件夹里,在配置文件中设置spring.ai.alibaba.deepreserch.python-coder.image-name的值指定镜像名称

节点产出

coder_content_{i}:码农节点大模型返回的响应数据

源码跟踪

跟踪:在 DeepResearchConfiguration 中,会根据用户配置的码农节点个数生成 m 个coder_{i} 节点实例,类型为 CoderNode,每个节点有唯一的节点 id;

添加从 paralell_executor 到 coder_{i} 的边和从 coder_{i} 到 research_team 的边,这意味着 m 个 coder_{i} 节点会并行处理

创建时需要4个参数 coderAgent, String.valueOf(i), reflectionProcessor, mcpProviderFactory

i 为当前节点编号

coderAgent:ChatClient类型,添加了 coder 提示词,并注册了一个可以执行 python 代码的工具

reflectionProcessor:反思处理器

mcpProviderFactory:mcp提供者工厂

研究:CoderNode 的 apply 方法整体流程如下:

1)首先获取研究计划中属于当前节点需要处理的步骤

2)若开启反思且步骤状态为待反思,则进入反思处理逻辑,反思通过则修改状态为完成,否则修改状态为待处理

3)修改步骤状态为处理中

4)若开启mcp,将mcp注册进 coderAgent,然后将当前步骤内容及反思内容传入 coderAgent 获取响应

5)根据是否开启反思,将步骤状态修改为待反思或完成

附 apply 方法源码

    public Map<String, Object> apply(OverAllState state) throws Exception {logger.info("coder node {} is running for thread: {}", executorNodeId, state.value("thread_id", "__default__"));Plan currentPlan = StateUtil.getPlan(state);Map<String, Object> updated = new HashMap<>();Plan.Step assignedStep = findAssignedStep(currentPlan);if (assignedStep == null) {logger.info("No remaining steps to be executed by {}", nodeName);return updated;}// Handle reflection logicif (reflectionProcessor != null) {ReflectionProcessor.ReflectionHandleResult reflectionResult = reflectionProcessor.handleReflection(assignedStep, nodeName, "coder");if (!ReflectionUtil.shouldContinueAfterReflection(reflectionResult)) {logger.debug("Step {} reflection processing completed, skipping execution", assignedStep.getTitle());return updated;}}// Mark step as processingassignedStep.setExecutionStatus(StateUtil.EXECUTION_STATUS_PROCESSING_PREFIX + nodeName);try {// Build task messagesList<Message> messages = List.of(new UserMessage(buildTaskMessageWithReflectionHistory(assignedStep, state.value("locale", "en-US"))));logger.debug("{} Node message: {}", nodeName, messages);// 调用agentvar requestSpec = coderAgent.prompt().messages(messages);// 使用MCP工厂创建MCP客户端AsyncMcpToolCallbackProvider mcpProvider = mcpFactory != null? mcpFactory.createProvider(state, "coderAgent") : null;if (mcpProvider != null) {requestSpec = requestSpec.toolCallbacks(mcpProvider.getToolCallbacks());}// Create stream with error handlingvar streamResult = requestSpec.stream().chatResponse().doOnError(error -> StateUtil.handleStepError(assignedStep, nodeName, error, logger));// Add step titleboolean isReflectionNode = assignedStep.getReflectionHistory() != null&& !assignedStep.getReflectionHistory().isEmpty();String prefix = isReflectionNode ? StreamNodePrefixEnum.CODER_REFLECT_LLM_STREAM.getPrefix(): StreamNodePrefixEnum.CODER_LLM_STREAM.getPrefix();String nodeNum = NodeStepTitleUtil.registerStepTitle(state, isReflectionNode, executorNodeId, "Coder",assignedStep.getTitle(), prefix);logger.info("CoderNode {} starting streaming with key: {}", executorNodeId, nodeNum);var generator = StreamingChatGenerator.builder().startingNode(nodeNum).startingState(state).mapResult(response -> {// Only handle successful responses - errors are handled in doOnErrorString coderContent = response.getResult().getOutput().getText();assignedStep.setExecutionStatus(ReflectionUtil.getCompletionStatus(reflectionProcessor != null, nodeName));assignedStep.setExecutionRes(Objects.requireNonNull(coderContent));logger.info("{} completed, content: {}", nodeName, coderContent);updated.put("coder_content_" + executorNodeId, coderContent);return updated;}).buildWithChatResponse(streamResult);updated.put("coder_content_" + executorNodeId, generator);return updated;}catch (Exception e) {// Handle any exception that occurs before or during stream setupStateUtil.handleStepError(assignedStep, nodeName, e, logger);return updated;}}

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

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

相关文章

基于STM32设计的激光充电控制系统(华为云IOT)_277

文章目录 一、前言 1.1 项目介绍 【1】项目开发背景 【2】设计实现的功能 【3】项目硬件模块组成 【4】设计意义 【5】国内外研究现状 【6】摘要 1.2 设计思路 1.3 系统功能总结 1.4 开发工具的选择 【1】设备端开发 【2】上位机开发 1.5 参考文献 1.6 系统框架图 1.7 系统原理…

【牛客拼数最大对比从左至右每位break与continue】2022-11-5

缘由牛客拼数最大问题&#xff0c;不从结果出发那种做法-编程语言-CSDN问答 思路倒序数后从右逐位比较大小 int 反序数(int n) {int nn 0;while (n)nn nn * 10 n % 10, n / 10;return nn; } void 牛客拼数位最大对比() {//4 7 13 4 246;3 13 312 343;3 1 2 3int a[20]{}, x…

【考研C语言编程题】数组元素批量插入实现(含图示+三部曲拆解)

【考研C语言编程题】数组元素批量插入实现&#xff08;含图示三部曲拆解&#xff09; 一、题目要求 编写C语言程序&#xff0c;实现将数组b的所有元素批量插入到数组a的指定位置&#xff08;位置从0开始计数&#xff09;。要求严格遵循“腾出空间→插入元素→更新长度”的操作三…

监控系统 | 脚本案例

1、监控系统中的cpu、内存、硬盘、、使用率超过80%进行邮件告警&#xff08;可使用邮箱QQ&#xff09;详细步骤说明&#xff1a;1. 脚本初始化#!/bin/bash&#xff1a;指定使用bash shell执行dateMax80&#xff1a;设置资源使用率阈值&#xff08;80%&#xff09;2. 资源监控CP…

Vulkan 学习(20)---- UniformBuffer 的使用

目录UniformBufferDescriptorSetLayout 和 VkBuffer顶点着色器定义描述符布局(DescriptorSetLayout)创建 UniformBuffer描述符池(DescriptorSet Pool)描述符集(DescriptorSet)更新描述符集使用描述符集使用多个 DescriptorUniformBuffer 本篇文档是通过 Uniform Buffer 的使用…

[光学原理与应用-461]:波动光学 - 波片实现偏振态的转换或调整

波片&#xff08;Wave Plate&#xff09;是一种基于双折射效应的光学元件&#xff0c;其核心功能是通过控制光波中寻常光&#xff08;o光&#xff09;和非寻常光&#xff08;e光&#xff09;的相位差&#xff0c;实现偏振态的转换或调整。以下是波片的主要功能及其原理的详细说…

Flutter之riverpod状态管理详解

一、riverpod状态管理中所涉及到的provider对比分析Provider 类型核心用途最佳适用场景优势劣势/注意事项Provider(v1)暴露一个恒定不变的&#xff08;或不需要Riverpod管理的&#xff09;对象或值。依赖注入&#xff08;如&#xff1a;Repository, Logger, ApiClient&#xff…

昇腾310i Pro固件说明

目录 驱动和固件 驱动固件文件 firware固件 24.2版本对应的固件 驱动和固件共同文件 烧结到flash中的固件 总结 启动流程 固件关系猜测 启动关键信息 efuse atu大小 GPU的bar 总结 驱动和固件 以最新的25.2 对应的驱动和固件为例说明&#xff1a; 驱动固件文件…

【LeetCode热题100道笔记】二叉树的右视图

题目描述 给定一个二叉树的 根节点 root&#xff0c;想象自己站在它的右侧&#xff0c;按照从顶部到底部的顺序&#xff0c;返回从右侧所能看到的节点值。 示例 1&#xff1a; 输入&#xff1a;root [1,2,3,null,5,null,4] 输出&#xff1a;[1,3,4] 解释&#xff1a;示例 2&am…

Redis《RedisSerializer》

文章目录RedisSerializer为什么要使用如何使用RedisSerializer总结RedisSerializer 为什么要使用 RedisTemplate 有默认的序列化器&#xff0c;但默认使用的 JdkSerializationRedisSerializer 存在一些问题&#xff1a; 序列化后的数据包含类信息等额外内容&#xff0c;导致…

基于开源AI大模型AI智能名片S2B2C商城小程序的文案引流与社交传播运营策略研究

摘要&#xff1a;本文聚焦开源AI大模型AI智能名片S2B2C商城小程序&#xff0c;探讨其文案引流与社交传播运营策略。阐述文案在引流中的重要性&#xff0c;分析开源AI大模型AI智能名片S2B2C商城小程序的特性&#xff0c;研究文案设计策略、社交传播机制及运营策略实施与效果评估…

NGINX vs HAProxy vs LVS:优势与选型分析

目录 1. 负载均衡的江湖:三巨头初探 2. NGINX:全能选手的多面魅力 NGINX 核心优势 NGINX 的短板 NGINX 实战案例 3. HAProxy:调度大师的精细之道 HAProxy 核心优势 HAProxy 的短板 HAProxy 实战案例 4. LVS:内核猛兽的极致性能 LVS 核心优势 LVS 的短板 LVS 实…

AI+ 行动意见解读:音视频直播SDK如何加速行业智能化

引言&#xff1a;国家战略、技术基座与行业落地 8 月底&#xff0c;国务院发布了《“人工智能”行动意见》&#xff0c;明确将人工智能提升为继“互联网”之后的新一轮国家级战略抓手。这份文件的关键词已经不再是“连接”与“优化”&#xff0c;而是“重塑”与“跃迁”&#…

2025年华为HCIA人工智能认证发展前景如何?客观分析!

大家好&#xff01;7月世界人工智能大会即将揭幕首款重载机器人&#xff0c;AI产业化进程再次加速。不少朋友开始转移关注到和它有一点点关系的——华为HCIA-AI Solution认证&#xff08;人工智能解决方案工程师&#xff09;&#xff0c;但它是否真能搭上这趟技术快车&#xff…

AutoGPT 原理与实践:从AI助理到“自主任务完成者” (人工智能入门系列)

Elon Musk 曾预言&#xff0c;“AIAgent 终将比人类聪明&#xff0c;并能自动完成大部分工作&#xff0c;这既是机遇也是威胁。” 而 AutoGPT&#xff0c;正是当前 AI 领域涌现出的、最能体现这一预言雏形的产品。它不再是那个需要你一句一句精确指令的“AI助手”&#xff0c;而…

自适应滤波器:Ch4 最小均方(LMS)算法

随机梯度下降算法简介 之前的章节中介绍了利用最速下降算法可以实现维纳滤波器的最优解&#xff08;LMMSE&#xff09;&#xff0c;其最优解的形式为&#xff1a; w0R−1Pw_{0} R^{- 1}Pw0​R−1P 它基于两个假设&#xff1a;环境的联合平稳&#xff0c;即输入u(n)u(n)u(n)以及…

AI生成内容的版权问题解析与实操指南

针对个人使用AI工具生成视频/音乐的版权问题深度解析&#xff0c;从法律归属、侵权边界到确权实操&#xff0c;结合最新司法实践提炼核心要点&#xff1a; 一、版权归属核心逻辑&#xff1a;人类智力投入的可视化 当用户深度参与创作过程时&#xff0c;可主张版权。关键看操作…

4.2 机器学习 - 欠拟合和过拟合

模型训练的核心挑战是让模型既 “学好” 训练数据&#xff0c;又能 “适应” 新数据。欠拟合&#xff08;Underfitting&#xff09;和过拟合&#xff08;Overfitting&#xff09;是阻碍这一目标的两大典型问题&#xff0c;其本质是 “模型复杂度” 与 “数据复杂度” 不匹配。本…

LeetCode 468. 验证IP地址 - 详细解析

文章目录LeetCode 468. 验证IP地址 - 详细解析题目描述IPv4验证规则&#xff1a;IPv6验证规则&#xff1a;最优Java解决方案&#xff08;注释完整版&#xff09;关键变量含义及代码技巧代码技巧详解1. 前导零检查的最佳实践2. IPv6为什么不能用Character.isDigit()3. 针对性注释…

新能源研发,用新型实验记录本:ELN

新能源&#xff08;材料&#xff09;研发如火如荼&#xff0c;竞争激烈。以电池为例&#xff0c;新能源汽车的崛起、储能技术的突破&#xff0c;让电池成为了能源领域的“新宠”。电池研发已经成为热门赛场&#xff0c;各研发团队都在与时间赛跑&#xff0c;试图维持优势或弯道…