关键要点
研究人员让LLM代码助手利用LangChain4j文档和API,自行设计并实现了一个多智能体编码系统。
这个自建编码智能体成功修复了真实Bug,通过了测试,并通过LangChain4j暴露了自身的执行流程。
对比两种智能体模式后发现,更严格的工作流模式通过消除LLM引发的协调开销,比监督者模式快3倍。
通过新引入的MonitoredAgent接口,可以清晰获取智能体调用报告和系统拓扑。
实验中,同样的智能体设计在旧款、廉价模型上陷入工具调用循环失败,而新款模型则成功完成任务。
实验概述
研究人员进行了一次元实验:将LangChain4j文档交给代码助手,要求它基于文档构建一个“自己的版本”。具体而言,希望设计一个多智能体系统,能够像人类工程师那样编写、测试和调试代码。
LLM能够根据文档构建自身版本,这既说明LangChain4j API足够清晰易用,也表明框架提供了足够编排能力,使生成的系统能端到端运行真实的调试任务。
该项目还帮助测试了LangChain4j新的监控工具——当让AI构建另一个AI时,必须看清内部发生了什么。本文详细介绍实验过程及结果,相关项目代码可在此仓库获取。
“氛围编码”一个智能体系统
为了让代码助手构建第一个智能体编码器,研究人员编写了以下提示:
学习LangChain4j智能体框架的文档和源码,基于它设计一个克隆你自己的智能体编码器。
经过几分钟思考,助手决定使用LangChain4j的监督者模式(supervisor pattern),并提出了初始架构:
public interface SupervisorCoderSystem {
@SupervisorAgent(description = """
一个多智能体编码助手,可以探索代码库、规划实现、编写/编辑代码、运行构建/测试。
它编排专门的子智能体来完成编码请求。
""", subAgents = {
ExplorerAgent.class,
PlannerAgent.class,
ImplementerAgent.class,
ExecutorAgent.class
})
@Override
String code(@K(UserRequest.class) String request,
@K(WorkingDirectory.class) String workingDirectory);
@SupervisorRequest
static String request(@K(UserRequest.class) String userRequest,
@K(WorkingDirectory.class) String workingDirectory) {
return "将'" + workingDirectory + "'作为工作目录,完成以下用户请求:" + userRequest;
}
}助手还设计并开发了四个子智能体,以及它们的系统消息和用户消息:探索智能体探索现有代码,规划智能体制定行动计划,实现智能体按计划编写代码,执行智能体编译并运行代码。每个子智能体都配备了合适的工具:文件系统浏览器、代码编辑器、代码运行器等。
第一次迭代的结果令人印象深刻。现实中“专业”代码助手通常也遵循类似的模式:执行探索、规划、实现、执行四个步骤,并以监督者方式编排——这与实验中生成的实现一致。
代码助手能够设计和实现这样一个系统,表明它对自己的内部工作方式有一定了解,并能够将这种理解转化为具体的智能体系统设计。
让智能体编码器投入工作
为了测试设计出的智能体编码器,研究人员让它编写一些有Bug的代码,然后用新创建的系统来修复。助手生成了一个Calculator类,包含四个有细微Bug的方法:
public class Calculator {
public int sum(List<Integer> numbers) {
int total = 0;
for (int i = 0; i <= numbers.size(); i++) { // Bug: 应该是 i < numbers.size()
total += numbers.get(i);
}
return total;
}
public double average(List<Integer> numbers) {
if (numbers.isEmpty()) return 0;
return sum(numbers) / numbers.size(); // Bug: 整数除法,应转为double
}
public int max(List<Integer> numbers) {
if (numbers.isEmpty()) throw new IllegalArgumentException("列表不能为空");
int max = 0; // Bug: 如果所有数都是负数,会返回0
for (int n : numbers) {
if (n > max) max = n;
}
return max;
}
public long factorial(int n) {
if (n < 0) throw new IllegalArgumentException("n必须非负");
long result = 1;
for (int i = 1; i < n; i++) { // Bug: 应包含n,即 i <= n
result *= i;
}
return result;
}
}接着生成了一个测试,将包含Calculator的文件夹克隆到临时目录,执行LangChain4j智能体编码器:
@Test
void workflow_should_fix_buggy_calculator() throws Exception {
var coder = CoderAgenticSystem.supervisorCoder(coderModel());
Path source = Path.of("src/test/resources/buggy-project");
Path workDir = Path.of("/tmp/buggy-calculator");
String result = coder.code(
"测试当前失败,因为Calculator.java存在Bug。请修复它。",
workDir.toAbsolutePath().toString());
assertThat(result).isNotBlank();
System.out.println("结果: " + result);
}运行代码时,使用了OpenAI的gpt-4o模型,因为它是LangChain4j默认的模型,且支持工具调用。然而结果并不理想,几分钟后出现错误:
dev.langchain4j.agentic.agent.AgentInvocationException: Failed to invoke agent method: public abstract...模式对比:监督者 vs 工作流
由于监督者模式需要LLM在每次子智能体调用前后进行决策,这带来了显著的协调开销。研究人员转而尝试更严谨的工作流模式(workflow pattern),该模式将智能体编排为固定顺序,仅在必要时才调用LLM。
工作流模式执行速度比监督者模式快3倍,因为它消除了大部分LLM之间的上下文切换。实验数据表明,监督者模式需要7次LLM调用才能完成修复,而工作流模式仅需2次。
模型选择的影响
实验还测试了更便宜的模型(如gpt-4o-mini),结果该模型陷入了工具调用循环,无法完成任务。而使用较新的gpt-5-mini模型则成功修复了所有Bug。这说明模型的质量对智能体系统的可靠性至关重要。
监控智能体调用
LangChain4j新引入的MonitoredAgent接口可以生成智能体调用报告,显示每次调用的输入、输出、耗时等。研究人员利用该接口分析了系统的拓扑结构和工作流。
总结
这个实验展示了一种有趣的元编程能力:LLM可以利用现有框架文档构建出能自我修复的智能体系统。工作流模式在效率上优于监督者模式,而模型选择直接决定系统成败。LangChain4j提供了足够的API和监控工具来支撑这类实验。