```Agent-O-rama:用Java或Clojure构建LLM代理```
Agent-o-rama: build, trace, evaluate, and monitor LLM agents in Java or Clojure

原始链接: https://blog.redplanetlabs.com/2025/11/03/introducing-agent-o-rama-build-trace-evaluate-and-monitor-stateful-llm-agents-in-java-or-clojure/

## Agent-o-rama:适用于 JVM 的可扩展 LLM 代理 Agent-o-rama 是一个全新的开源库,用于构建可扩展且具有状态的 LLM 代理,专为 Java 和 Clojure 开发人员设计。它解决了 JVM 生态系统中一个差距——目前由 Python AI 工具主导——它将类似 LangGraph 和 LangSmith 的功能(如结构化代理图、追踪和评估)直接带到这些语言中。 该库允许开发人员将代理定义为函数图,自动捕获详细的追踪信息,并提供一个 Web UI 用于实验、评估和监控(包括延迟和 token 使用量)。它支持流式传输,并与现有工具(如数据库和 API)无缝集成,同时将所有数据保留在您的基础设施中以确保隐私和控制。 Agent-o-rama 部署在“Rama”集群上,提供从单节点本地设置到数千个节点的扩展能力(需要商业许可)。提供了一个完整的示例代理(研究重点),展示了一个简单的开发流程。该项目旨在抽象 Rama 分布式编程模型的复杂性,使其力量可用于 LLM 代理开发,同时也作为 Rama 实际应用的一个示例。 可以通过邮件列表和 Slack 频道获取资源和社区支持。

Agent-o-rama 是一个用于构建、追踪、评估和监控 LLM 代理的新型 Java/Clojure 框架。由 Apache Storm 的主要开发者创建,它旨在成为一个完整的代理平台,与 JetBrains 的 Koog 等工具有所区别。 开发者强调的关键区别包括:Agent-o-rama 支持跨集群的**分布式执行和扩展**,而 Koog 在单个进程内运行。AOR 提供**内置的部署、存储、实验和可观察性**功能——包括“首次标记时间”等详细遥测数据——而 Koog 缺乏这些功能,需要用户集成单独的工具来实现。 本质上,Agent-o-rama 为管理 LLM 代理提供了一个更全面和可扩展的解决方案,重点在于易用性和内置的分析能力。项目负责人可以解答关于其技术细节的问题。
相关文章

原文

We’ve just open-sourced Agent-o-rama, a library for building scalable and stateful LLM agents on the JVM. Agent-o-rama provides two first-class APIs, one for Java and one for Clojure, with feature parity between them.

AI tooling today is overwhelmingly centered on Python, and while the JVM ecosystem has seen growing support through libraries like LangChain4j, it lacks the kind of integrated tooling that lets developers evaluate, observe, and deploy LLM-based systems rigorously and at scale. Available tools are fragmented or complex to set up, and nothing handles the entire workflow from development to production with proper observability.

Agent-o-rama fills that gap. It brings the same ideas popularized by LangGraph and LangSmith – structured agent graphs, tracing, datasets, experiments, evaluation – but makes them native to Java and Clojure. LLMs are powerful but inherently unpredictable, so building applications with LLMs that are helpful and performant with minimal hallucination requires being rigorous about testing and monitoring.

Agents are defined as simple graphs of Java or Clojure functions that execute in parallel. Agent-o-rama automatically captures detailed traces and includes a web UI for offline experimentation, online evaluation, and time-series telemetry (e.g. model latency, token usage, database latency). It also supports streaming, with a simple client API to stream model calls or other outputs from nodes in real time. Agent-o-rama extends the ideas from LangGraph and LangSmith with far greater scalability, full parallel execution, and built-in high-performance data storage and deployment.

Agent-o-rama is deployed onto your own infrastructure on a Rama cluster. Rama is free to use for clusters up to two nodes and can scale to thousands with a commercial license. Every part of Agent-o-rama is built-in and requires no other dependency besides Rama. Agent-o-rama also integrates seamlessly with any other tool, such as databases, vector stores, external APIs, or anything else. Unlike hosted observability tools, all data and traces stay within your infrastructure.

Example agent

Let’s take a look at an example agent! This is a research agent from the examples/ directory in the project. In that directory you’ll find equivalent Java and Clojure versions.

You’ll need Java 21 installed and API keys for OpenAI and Tavily (Tavily’s free tier is sufficient). Put the API keys in environment variables like so:

1
2

export OPENAI_API_KEY=your_openai_key_here
export TAVILY_API_KEY=your_tavily_key_here

To run the agent, clone Agent-o-rama and follow these instructions (for Java or Clojure, whichever you prefer):

1
2
3
4
5
6
7
8
9

# Java instructions
cd examples/java
./run-example com.rpl.agent.research.ResearchAgentExample

# Clojure instructions
cd examples/clj
lein repl
(require '[com.rpl.agent.research-agent :as research-agent] :reload)
(research-agent/run-agent)

This runs Rama’s “in-process cluster” (IPC) and launches the research agent on it. You’ll get a prompt at the terminal to enter a research topic. The agent will generate a set of analyst personas to analyze the topic, and you’ll be prompted again whether you want to give feedback on the generated analysts. Once you tell the agent you have no more feedback, it will spend a few minutes generating the report, including using information it finds through web searches and through Wikipedia, and then the final report will be printed.

As the report is being generated or when it’s finished, you can open the Agent-o-rama UI at http://localhost:1974 .

Here’s an example back and forth:

Enter a topic: What's the influence and legacy of Billy Wilder?

Do you have any feedback on this set of analysts? Answer 'yes' or 'no'.

{"role" "Film Historian", "affiliation" "University of California, Los Angeles", "name" "Dr. Lucy Reynolds", "description" "Specializes in post-war American cinema and the contributions of filmmakers like Wilder. Focuses on Wilder's stylistic innovations and narrative techniques, exploring how they shaped modern filmmaking."}
{"role" "Cultural Critic", "affiliation" "Film Critic Magazine", "name" "Michael Chen", "description" "Analyzes the social and cultural impacts of Wilder's films, particularly in relation to gender and race issues. Concerned with how Wilder's work reflects and influences societal norms."}
{"role" "Cinema Studies Scholar", "affiliation" "New York University", "name" "Professor John Hartman", "description" "Investigates the legacy of classic Hollywood directors, with an emphasis on Wilder. His work focuses on the interplay between commercial success and artistic integrity in Wilder's films."}
{"role" "Screenwriter and Director", "affiliation" "Independent Filmmaker", "name" "Emma Thompson", "description" "Explores the thematic elements in Wilder's storytelling, particularly humor and satire. Engages with Wilder's ability to blend genres and how this influences contemporary narrative structures."}
>> no

# The Enduring Influence of Billy Wilder

## Introduction

Billy Wilder's legacy in Hollywood cinema is marked by his unparalleled ability to blend commercial success with artistic integrity. This report delves into Wilder's impact, highlighting his innovative storytelling techniques and social critiques through iconic films like "Sunset Boulevard," "The Apartment," and "Double Indemnity." We explore how his personal experiences shaped his keen observational skills and narrative style, as well as how his work laid the groundwork for contemporary storytelling and the exploration of gender dynamics. Ultimately, Wilder’s films illustrate the enduring relevance of balancing humor, critique, and emotional depth in cinema.

---

Billy Wilder stands as a towering figure in cinema, adept at fusing commercial viability with artistic integrity. His films often strike a delicate balance between engaging mainstream audiences and provoking critical reflection on serious themes, as exemplified in "Sunset Boulevard" (1950). This film vividly critiques the dark side of fame and highlights Wilder's unique ability to craft narratives that resonate deeply with viewers while navigating complex moral landscapes. His background as an Austrian émigré and early career as a screenwriter supplied him with the observational prowess necessary to convey the multifaceted nature of human experiences, allowing his work to transcend mere entertainment and engage with profound social commentary [1].

Wilder's amalgamation of humor and satire serves as a compelling vehicle for addressing serious social issues, influencing contemporary screenwriters to adopt similar techniques. Films like "Some Like It Hot" and "The Apartment" showcase his signature style, where humor enriches the narrative while prompting reflection on societal norms and human behavior. This approach remains pervasive in the works of modern filmmakers, illustrating Wilder's constructed legacy in storytelling that encourages the interplay of comedic elements and deeper thematic explorations. Notable contemporary films such as "The Big Sick" and "Parasite" echo these traditions, suggesting that humor can coexist with critical commentary and profound moral questions [2].

Central to Wilder's storytelling innovations is his ability to meld humor with dark themes, employing non-linear narratives and flashbacks in movies like "Double Indemnity" and "The Apartment." These techniques reveal complex character motivations and provide a framework for rich, layered narratives. Wilder’s knack for sharp dialogue and intricate comedic timing enhances this social commentary, resonating with audiences across generations. The blend of genres within his films also paved the way for a more diverse cinematic landscape, allowing modern filmmakers to challenge conventions and push creative boundaries [3].

Particularly significant is Wilder's exploration of gender dynamics in "The Apartment," where the protagonist Fran Kubelik's experiences reflect the challenges faced by women within a patriarchal corporate structure. The film critiques the objectification of women through key scenes and deft cinematography, simultaneously highlighting moral ambiguity and emotional depth. This examination of gender roles emphasizes the importance of authentic relationships in a transactional world, underlining the resonance of Wilder's critiques within contemporary discussions surrounding gender and power [4].

In conclusion, Billy Wilder's influence is multifaceted, shaping both the narrative and thematic dimensions of modern cinema. His legacy emerges from an enduring ability to captivate audiences while addressing the intricacies of human behavior, societal constructs, and moral dilemmas. Through a unique blend of artistry and commercial appeal, Wilder set a standard for storytelling that continues to inspire filmmakers and storytellers today.


---

## Conclusion

Billy Wilder's cinematic legacy is a testament to his exceptional ability to balance artistry and commercial appeal. His films, including "Sunset Boulevard," "The Apartment," and "Double Indemnity," not only entertained audiences but also provoked critical thought on profound societal themes and human dynamics. Through innovative storytelling techniques and a distinctive blend of humor and critique, Wilder paved the way for contemporary writers and filmmakers. His enduring influence can be seen in the way modern narratives confront gender dynamics and moral complexities, demonstrating that engaging storytelling can exist alongside rich thematic exploration. Ultimately, Wilder's impact remains a vital reference point in the evolution of cinema.

## Sources
[1] Interview with Professor John Hartman on the legacy of Billy Wilder.  
[2] https://glcoverage.com/2025/01/23/billy-wilder-screenwriting-tips/  
[3] Culture Vulture | Counter Culture  
[4] Breaking Down the Storytelling in Billy Wilder's 'The Apartment' https://nofilmschool.com/apartment-storytelling-breakdown  
[5] Analysis of ‘The Apartment’ – Infinite Ocean - Mawr Gorshin  https://mawrgorshin.com/2022/08/20/analysis-of-the-apartment/  
[6] On its 60th anniversary, Billy Wilder’s The Apartment looks like an indictment of toxic masculinity - AV Club  https://www.avclub.com/on-its-60th-anniversary-billy-wilder-s-the-apartment-l-1844004988  

If you click on the research agent in the UI, you’ll see this:

The invoke there is what we just ran. Clicking on it brings up the trace for the invoke:

On the right is aggregated statistics of everything that happened during the agent’s execution. You can see how many tokens it used, and if it did any database reads/writes you’d see stats about those too. If the agent invokes other agents, you can see a breakdown of stats by agent as well.

Clicking on the “write-report” node brings up a detailed trace of what happened when that node executed:

This node did one LLM call, and you can see the arguments to that LLM, what was returned, and stats on the call in the “Operations” section. The code for this node is just this:

JavaClojure

1
2
3
4
5
6
7
8
9

.node("write-report", "finish-report", (AgentNode agentNode, String sections, String topic) -> {
  ChatModel openai = agentNode.getAgentObject("openai");
  String instructions = String.format(REPORT_WRITER_INSTRUCTIONS, topic, sections);
  List<ChatMessage> chatMessages = Arrays.asList(
    new SystemMessage(instructions),
    new UserMessage("Write a report based upon these memos."));
  String report = openai.chat(chatMessages).aiMessage().text();
  agentNode.emit("finish-report", "report", report);
})

1
2
3
4
5
6
7
8
9
10
11
12

(aor/node
 "write-report"
 "finish-report"
 (fn [agent-node sections topic]
   (let [openai (aor/get-agent-object agent-node "openai")
         instr  (report-writer-instructions topic sections)
         text   (chat-and-get-text
                 openai
                 [(SystemMessage. instr)
                  (UserMessage. "Write a report based upon these memos.")])]
     (aor/emit! agent-node "finish-report" "report" text)
   )))

This code says that the node’s name is “write-report”, the node emits to the node “finish-report”, and the node’s implementation is the given function. The agentNode / agent-node argument is how you interact with the graph to return a result, emit to other nodes, or get agent objects like models, database connections, or anything else. When you emit to other nodes, you simply say what node you want to emit to and what arguments to pass to that node. Agent nodes run on virtual threads, so they can be efficiently written in a blocking style like this.

That’s most of what’s involved in programming agents with Agent-o-rama! There’s a bit more to learn with aggregation and how to declare agent objects, and this is all documented on the programming agents guide. The rest of using Agent-o-rama is creating and managing datasets, running experiments, setting up online evaluation and other actions on production runs, and analyzing agent telemetry.

Also, you can see from this code and the trace that model calls are automatically traced – this node didn’t have to record any tracing info explicitly. Though you can include your own info in traces with a simple API (see this Javadoc and this Clojuredoc).

Let’s take a look at running this on a real cluster! Let’s quickly set up a cluster locally by following these instructions:

  1. Download the latest Rama release from here.
  2. Unpack the release somewhere.
  3. Run: ./rama devZookeeper &
  4. Run: ./rama conductor &
  5. Run: ./rama supervisor &
  6. Visit: http://localhost:8888 . When the page loads, the cluster is ready.
  7. Download the latest Agent-o-rama release from here.
  8. Unpack it somewhere.
  9. Run: ./aor --rama /path/to/rama-root &

Next, to deploy you need to build a jar first. Here’s how to build either the Java or Clojure version from the Agent-o-rama project:

1
2
3
4
5
6
7

# For Java version  
cd examples/java
mvn clean package -Dmaven.test.skip=true

# For Clojure version
cd examples/clj
lein uberjar

The Java version will build target/java-examples-with-dependencies.jar , and the Clojure version will build target/agent-o-rama-examples-1.0.0-SNAPSHOT-standalone.jar .

Next, to deploy the module just run this command:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17

# Deploy the module (Java uberjar)
./rama deploy \
  --action launch \
  --jar /path/to/java-examples-with-dependencies.jar \
  --module com.rpl.agent.research.ResearchAgentModule \
  --tasks 4 \
  --threads 2 \
  --workers 1

# Deploy the module (Clojure uberjar)
./rama deploy \
  --action launch \
  --jar /path/to/agent-o-rama-examples-1.0.0-SNAPSHOT-standalone.jar \
  --module com.rpl.agent.research-agent/ResearchAgentModule \
  --tasks 4 \
  --threads 2 \
  --workers 1

Now it’s up and running! You can view the agent in the UI at http://localhost:1974 and play with it. From the agent screen you can invoke the agent with the arguments ["", {"topic": "your topic here"}] . On the trace, you’ll be able to see any human input prompts the agent makes and respond to them there.

Rama handles all of storage, deployment, and scaling. There are no other dependencies needed to run this. Setting up a production cluster is only slightly more work, and there are one-click deploys for AWS and for Azure.

Resources

Check out these resources to learn more or get involved:

Conclusion

Agent-o-rama lets developers gain the benefits of Rama without needing to learn it. Rama’s distributed programming model is powerful but has a learning curve: it introduces a rich dataflow API and uses compound data structures for indexing instead of fixed data models. Agent-o-rama abstracts away those concepts into a familiar API so developers can take advantage of Rama’s strengths for the specific domain of building LLM agents.

For those who want to learn how to program Rama directly, Agent-o-rama also serves as a great example of Rama in practice. The backend is about 15K lines of code and the front-end about 11K, yet together they form a complete, end-to-end distributed system with a diverse feature set. Along with our Twitter-scale Mastodon implementation, it shows the breadth of what can be built with Rama.

We’d love to hear what you build with Agent-o-rama. Join the rama-user mailing list or the #rama channel on the Clojurians Slack to ask questions, share feedback, or discuss ideas with others using Agent-o-rama.

If you’d like to talk directly with us about Agent-o-rama, whether to exchange ideas, get technical guidance, or explore working together on building an LLM agent, you can book a call with us.

联系我们 contact @ memedata.com