智能体系统
入门使用
java
import dev.langchain4j.agentic.Agent;
import dev.langchain4j.service.UserMessage;
import dev.langchain4j.service.V;
public interface CreativeWriter {
@UserMessage("""
你是一位创意作家。
请围绕给定主题,写一个不超过三句话的故事。
只输出故事,不要输出其他内容。
主题是:{{topic}}.
""")
@Agent(name = "generateStory",
value = "根据特定的主题来创作一个故事",
description = "根据特定的主题来创作一个故事",
outputKey = "story")
String generateStory(@V("topic") String topic);
}
java
public class AgenticTest extends BaseTest {
@Test
void test() {
CreativeWriter creativeWriter = AgenticServices
.agentBuilder(CreativeWriter.class)
.chatModel(BASE_MODEL)
.outputKey("story")
.build();
String content = creativeWriter.generateStory("搞笑");
System.out.println(content);
}
}
AgenticScope,存储了Agent流转的数据
Sequential workflow
java
public interface StyleEditor {
@UserMessage("""
你是一位专业编辑。
请分析并改写以下故事,使其更符合"{{style}}"风格,并与之更加连贯一致。
只返回故事内容,不要返回其他任何内容。
故事内容为:"{{story}}"。
""")
@Agent("编辑故事以更好地适配特定风格")
String editStory(@V("story") String story, @V("style") String style);
}
public interface AudienceEditor {
@UserMessage("""
你是一位专业编辑。
请分析并改写以下故事,使其更符合目标受众"{{audience}}"的需求。
只返回故事内容,不要返回其他任何内容。
故事内容为:"{{story}}"。
""")
@Agent("编辑故事以更好地适配特定受众")
String editStory(@V("story") String story, @V("audience") String audience);
}
java
public class AgenticTest extends BaseTest {
@Test
void test() {
CreativeWriter creativeWriter = AgenticServices
.agentBuilder(CreativeWriter.class)
.chatModel(BASE_MODEL)
.outputKey("story")
.build();
AudienceEditor audienceEditor = AgenticServices
.agentBuilder(AudienceEditor.class)
.chatModel(BASE_MODEL)
.outputKey("story")
.build();
StyleEditor styleEditor = AgenticServices
.agentBuilder(StyleEditor.class)
.chatModel(BASE_MODEL)
.outputKey("story")
.build();
UntypedAgent novelCreator = AgenticServices
.sequenceBuilder()
.subAgents(creativeWriter, audienceEditor, styleEditor)
.outputKey("story")
.build();
Map<String, Object> input = Map.of(
"topic", "龙与巫师",
"style", "奇幻",
"audience", "年轻人和成年人"
);
String story = (String) novelCreator.invoke(input);
System.out.println(story);
}
}
单个代理也可以用UntypedAgent来定义
java
UntypedAgent creativeWriter = AgenticServices.agentBuilder()
.chatModel(BASE_MODEL)
.description("根据特定的主题来创作一个故事")
.userMessage("""
你是一位创意作家。
请围绕给定主题,写一个不超过三句话的故事。
只输出故事,不要输出其他内容。
主题是:{{topic}}.
""")
.inputKey(String.class, "topic")
.returnType(String.class)
.outputKey("story")
.build();
可以将 UntypedAgent 接口替换为一个更具体的接口
java
public interface NovelCreator {
@Agent
String createNovel(@V("topic") String topic, @V("audience") String audience, @V("style") String style);
}
java
NovelCreator novelCreator = AgenticServices
.sequenceBuilder(NovelCreator.class)
.subAgents(creativeWriter, audienceEditor, styleEditor)
.outputKey("story")
.build();
String story = novelCreator.createNovel("龙与巫师", "年轻人", "奇幻");
System.out.println(story);
循环
java
public interface StyleScorer {
@UserMessage("""
你是一位评论家。请根据故事与"{{style}}"风格的契合程度,为以下故事打出 0.0 到 1.0 之间的评分。
只返回评分,不要输出其他任何内容。故事内容为:"{{story}}"
""")
@Agent("Scores a story based on how well it aligns with a given style")
double scoreStyle(@V("story") String story, @V("style") String style);
}
java
@Test
void test02() {
CreativeWriter creativeWriter = AgenticServices
.agentBuilder(CreativeWriter.class)
.chatModel(BASE_MODEL)
.outputKey("story")
.build();
StyleEditor styleEditor = AgenticServices
.agentBuilder(StyleEditor.class)
.chatModel(BASE_MODEL)
.outputKey("story")
.build();
StyleScorer styleScorer = AgenticServices
.agentBuilder(StyleScorer.class)
.chatModel(BASE_MODEL)
.outputKey("score")
.build();
UntypedAgent styleReviewLoop = AgenticServices
.loopBuilder()
.subAgents(styleScorer, styleEditor)
.maxIterations(5)
.testExitAtLoopEnd(true)
.exitCondition( (agenticScope, loopCounter) -> {
double score = agenticScope.readState("score", 0.0);
return loopCounter <= 3 ? score >= 0.8 : score >= 0.6;
})
.build();
StyledWriter styledWriter = AgenticServices
.sequenceBuilder(StyledWriter.class)
.subAgents(creativeWriter, styleReviewLoop)
.outputKey("story")
.build();
String story = styledWriter.writeStoryWithStyle("dragons and wizards", "comedy");
}