Dict.CN 在线词典, 英语学习, 在线翻译 ------------- MyGitee My腾云code My51cto

Happy_EveryDay

可以平凡 不可以平庸 无爱则无忧,无欲则无求,无怒而无敌,无怨才是佛。所有烦恼,都是放不下的执著 开源技群 328035181 MyGitee

博客园 首页 新随笔 管理

预期结果:
当你把这两个节点写好并在你之前用的那个工作流平台上测试时,输入 apple:

    1. 造句节点 会输出 I ate an apple yesterday.

    2. 翻译节点 会输出 我昨天吃了一个苹果。

 

现在,两个核心的“工人”(节点)都已经准备就绪:

  • SentenceConstructionNode 负责生产英文句子。

  • TranslationNode 负责把句子翻译成中文。

 

 

 

 1、pom

<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>3.4.4</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.sb</groupId>
<artifactId>zhipuai</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>zhipuai</name>
<description>zhipuai</description>
<properties>
<java.version>17</java.version>
<!-- <spring-ai.version>2.0.0-M5</spring-ai.version>-->
<spring-ai.version>1.1.2</spring-ai.version>
<spring-ai-alibaba.version>1.0.0.4</spring-ai-alibaba.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.ai</groupId>
<artifactId>spring-ai-starter-model-zhipuai</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba.cloud.ai</groupId>
<artifactId>spring-ai-alibaba-graph-core</artifactId>
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.ai</groupId>
<artifactId>spring-ai-bom</artifactId>
<version>${spring-ai.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<dependency>
<groupId>com.alibaba.cloud.ai</groupId>
<artifactId>spring-ai-alibaba-bom</artifactId>
<version>${spring-ai-alibaba.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>


2、application.yml

server:
port: 18091 # 应用监听端口,默认 18091
spring:
application:
name: sangeng-graph
ai:
zhipuai:
#api-key: ${ZHIPU_KEY} # 从环境变量 ZHIPU_KEY 读,不硬编码
api-key: "XXXXXXXXXXXXXXX" # 从环境变量 ZHIPU_KEY 读,不硬编码
chat:
options:
model: glm-4.6 # 用 GLM-4.6





3、controller

package com.sb.zhipuai.controller;

import com.alibaba.cloud.ai.graph.CompiledGraph;
import com.alibaba.cloud.ai.graph.OverAllState;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import java.util.Map;
import java.util.Optional;

@RestController
@RequestMapping("/graph")
public class GraphController {
private static final Logger log = LoggerFactory.getLogger(GraphController.class);

// 构造器注入 Spring 容器里那个 CompiledGraph
private final CompiledGraph compiledGraph;
private final CompiledGraph simpleGraph; // 对应 simpleGraph

public GraphController(
@Qualifier("quickStartGraph") CompiledGraph compiledGraph,
@Qualifier("simpleGraph") CompiledGraph simpleGraph) {
this.compiledGraph = compiledGraph;
this.simpleGraph = simpleGraph;
}

@GetMapping("/quickStartGraph")
public String quickStartGraph() {
Optional<OverAllState> overAllStateOptional = compiledGraph.call(Map.of()); // ← call → invoke
log.info("overAllStateOptional: {}", overAllStateOptional);
return "ok";
}

/**
* 造句翻译
* @param word
* @return
*/
@GetMapping("/simpleGraph")
public Map<String, Object> simpleGraph(@RequestParam("word") String word){
Optional<OverAllState> overAllStateOptional = simpleGraph.call(Map.of("word", word));
Map<String, Object> data = overAllStateOptional.map(OverAllState::data).orElse(Map.of());
return data;
}
}



4、GraphConfiguration

package com.sb.zhipuai.config;

import com.alibaba.cloud.ai.graph.*;
import com.alibaba.cloud.ai.graph.action.AsyncNodeAction;
import com.alibaba.cloud.ai.graph.action.NodeAction;
import com.alibaba.cloud.ai.graph.exception.GraphStateException;
import com.alibaba.cloud.ai.graph.state.strategy.ReplaceStrategy;
import com.sb.zhipuai.node.SentenceConstructionNode;
import com.sb.zhipuai.node.TranslationNode;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.ai.chat.client.ChatClient;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import java.util.Map;
import static com.alibaba.cloud.ai.graph.action.AsyncNodeAction.node_async;


//定义状态图 (状态,节点,边),编译生成 CompiledGraph 后注入 Spring 容器
@Configuration
public class GraphConfiguration {

private static final Logger log = LoggerFactory.getLogger(GraphConfiguration.class);

@Bean("quickStartGraph")
public CompiledGraph quickStartGraph() throws GraphStateException {

// 状态值:input1、input2 都用 ReplaceStrategy(新值覆盖旧值)
KeyStrategyFactory keyStrategyFactory = new KeyStrategyFactory() {
@Override
public Map<String, KeyStrategy> apply() {
return Map.of("input1", new ReplaceStrategy(),
"input2", new ReplaceStrategy());
}
};

// 定义创建状态图stateGraph
StateGraph stateGraph = new StateGraph("quickStartGraph", keyStrategyFactory);

// 定义节点 node1:打印当前状态,返回 input1=1, input2=1
stateGraph.addNode("node1", node_async(new NodeAction() {
@Override
public Map<String, Object> apply(OverAllState state) throws Exception {
log.info("node1 state: {}", state);
return Map.of("input1", 1, "input2", 1);
}
}));

// 定义node2:打印当前状态,返回 input1=2, input2=2
stateGraph.addNode("node2", node_async(new NodeAction() {
@Override
public Map<String, Object> apply(OverAllState state) throws Exception {
log.info("node2 state: {}", state);
return Map.of("input1", 2, "input2", 2);
}
}));
// 定义边:START → node1 → node2 → END
stateGraph.addEdge(StateGraph.START, "node1");
stateGraph.addEdge("node1", "node2");
stateGraph.addEdge("node2", StateGraph.END);

// 编译状态图,交回 Spring 容器
CompiledGraph compiledGraph=stateGraph.compile();
return compiledGraph;
}

@Bean("simpleGraph")
public CompiledGraph simpleGraph(ChatClient.Builder clientBuilder) throws GraphStateException {

// 定义状态键的更新策略
KeyStrategyFactory keyStrategyFactory = () -> Map.of("word", new ReplaceStrategy());

// 创建状态图
StateGraph stateGraph = new StateGraph("simpleGraph", keyStrategyFactory);

// 添加节点
stateGraph.addNode("SentenceConstructionNode",
AsyncNodeAction.node_async(new SentenceConstructionNode(clientBuilder)));

stateGraph.addNode("TranslationNode",
AsyncNodeAction.node_async(new TranslationNode(clientBuilder)));

// 定义边 (执行顺序)
stateGraph.addEdge(StateGraph.START, "SentenceConstructionNode");
stateGraph.addEdge("SentenceConstructionNode", "TranslationNode");
stateGraph.addEdge("TranslationNode", StateGraph.END);

// 编译状态图,放入容器
return stateGraph.compile();
}
}



5、Node

package com.sb.zhipuai.node;

import com.alibaba.cloud.ai.graph.OverAllState;
import com.alibaba.cloud.ai.graph.action.NodeAction;
import org.springframework.ai.chat.client.ChatClient;
import org.springframework.ai.chat.prompt.PromptTemplate;
import java.util.Map;

/**
* @author Administrator 造句节点
*/
public class SentenceConstructionNode implements NodeAction {

private final ChatClient chatClient;

public SentenceConstructionNode(ChatClient.Builder builder) {
// 构建 ChatClient 实例
this.chatClient = builder.build();
}

@Override
public Map<String, Object> apply(OverAllState state) throws Exception {
// 从 state 中获取要造句的单词,如果没有则使用空字符串
String word = state.value("word", "");

PromptTemplate promptTemplate = new PromptTemplate("你是一个英语造句专家,能够基于给定的单词进行造句。" +
"要求只返回最终造好的句子,不要返回其他信息。给定的单词:{word}"
);
promptTemplate.add("word", word);
String prompt = promptTemplate.render();
String content = chatClient.prompt()
.user(prompt)
.call()
.content();

// 把句子存入 state,键名定义为 "sentence"
return Map.of("sentence", content);
}
}


package com.sb.zhipuai.node;

import com.alibaba.cloud.ai.graph.OverAllState;
import com.alibaba.cloud.ai.graph.action.NodeAction;
import org.springframework.ai.chat.client.ChatClient;
import org.springframework.ai.chat.prompt.PromptTemplate;

import java.util.Map;

// 其他 import 保持和你造句节点一样即可
// import org.springframework.ai.chat.client.ChatClient;
// import org.springframework.ai.chat.prompt.PromptTemplate;
// import com.sangeng.workflow.NodeAction; (假设的包名)
// import com.sangeng.workflow.OverallState; (假设的包名)

/**
* @author Administrator 翻译节点
*/
public class TranslationNode implements NodeAction {

private final ChatClient chatClient;

public TranslationNode(ChatClient.Builder builder) {
this.chatClient = builder.build();
}


@Override
public Map<String, Object> apply(OverAllState state) throws Exception {
// 从 state 中获取要造句的单词,如果没有则使用空字符串
String sentence = state.value("sentence", "");

// 创建提示模板,定义AI翻译任务
PromptTemplate promptTemplate = new PromptTemplate("你是一个英语翻译专家,能够对句子进行翻译。" +
"要求只返回翻译的结果不要返回其他信息。要翻译的句子:{sentence}");

// 模板添加参数
promptTemplate.add("sentence", sentence);
String prompt = promptTemplate.render();

// 模型调用
String content = chatClient.prompt()
.user(prompt)
.call()
.content();

// 返回翻译结果,存入state
return Map.of("translation", content);
}
}



6、http://localhost:18091/graph/simpleGraph?word=sky

image

 

image

 

posted on 2026-09-19 03:41  2026cn  阅读(6)  评论(0)    收藏  举报