Category Archives: Development

How Does LLM and Agents interact with External World?

As AI Agents is gaining serious traction to make artificial intelligence not just responsive, but autonomous and proactive, this kind of questions became more frequent between developers and executives.

To help anyone diving into the world of AI Agents, here is a quick tutorial of the most important feature you must understand to connect Agents with external world: Tools, also known as Function Calls.

What are Tools (Function Calls)?

In the context of AI Agents, Tools are external functions or APIs that the agent can “call” to perform specific tasks. Think of them as skills the agent can activate when needed. They’re NOT built into the model itself, but are instead defined by the developer and exposed to the agent.

For example:

  • A calculator function
  • A file reader
  • A web search API
  • A custom business logic function

These Tools allow the agent to go beyond text generation and interact with the world in real-time.

How Does It Work?

The figure below illustrates how the Tools/Function Call process works with LLMs:

Image

Step 1: Define Your Tools

Tools are defined essentially by:

  • A name
  • A description (what it does, so AI can understand when to use it)
  • A schema of expected inputs

In the example, suppose we have the following Tools:

  • searchOnInternet: Given a search query, it’ll make a search on the Web, and return a list of titles and descriptions from the Internet.
  • addNumbers: Given two numbers, it’ll return sum the numbers and return the result.

Step 2: Merge User Prompt with Tools

When USER asks for “Summary of the latest news”. Before sending any message to the LLM, our application adds the available Tools to the prompt. Like the example below:

Step 3: Let LLM Decide

With the prompt above, we do let LLM know the available Tools, and infer the best answer for the USER prompt. Which in this case, might be asking to call searchOnInternet function with the query “letest+news” to have more context. The response looks like:

Step 4: Execute the Tool and Send Result

With the “tool_call” in the LLM response, your application should parse the arguments and execute the requested Tool (searchOnInternet). After executing the Tool, the application should send the conversation history with the result to the LLM again.

Step 5: LLM Final Answer

Now, with the conversation history, and the result of the Tool call, if LLM understand it has enough context to answer the USER request, it will generate then the final response:

Implementing it With Langchain4J

Implementing all these steps from scratch can be cumbersome. Fortunately, you can use libraries like Langchain4J to handle the details and streamline the process. Here is a simple implementation for the example:

Conclusion

Tools (Function Calls) are the bridge between the language model’s intelligence and real-world utility, and understanding how it works before diving into the world of Agents and Agentic AI, is crucial. Without tools, an agent is just a chatbot. With tools, it becomes a powerful, proactive assistant capable of taking meaningful actions on your behalf.

Now that you understand how the process works under the hood, it’s easier to see why solutions like Anthropic’s Model Context Protocol (MCP) are gaining traction. In the enterprise world, you wouldn’t want to redefine tool descriptions for every system you integrate with. Having a standard improves maintainability and reusability. But let’s save that topic for the next article.

If you’d like to see more examples using Java and Langchain4J,, I’ve published a repository with runnable samples on my Github. Feel free to check it out—and if you find it helpful, consider giving it a star! 😊

What has been your biggest challenges when implementing AI Agents? I’m excited to hear your stories and insights in the comments below!

Thoughtworks TechRadar brings AI

A few weeks ago, I held an amazing workshop on AI for software engineers eager to learn the fundamentals and create their first application integrated with AI models!

AI became an intrinsic topic in the tech world and can be overwhelming to keep updated.

It’s beneficial to rely on summaries that highlight key topics, which is why I regularly consult Thoughtworks Tech Radar for invaluable insights.

And what is interesting, they already added some topics on AI in the latest version released this month (April)!

I gave special attention to the topics below 🙂

  • Retrieval Augmented Generation: I’ve covered RAG on my workshop and it proved to become the preferred pattern to improve the quality of LLM responses
  • LLM-powered Autonomous Agents: LLM agents allow those models to perform a variety of human-language based tasks.
  • LiteLLM: We don’t have a de facto framework to work with AI models yet. I’ve been using Langchain for popularity, but worth keeping track of other options.
  • Nemo-Guadrails: One of the major challenges in deploying AI solutions is ensuring safety measures and addressing unforeseen behaviors. It’s good to see the advances over this topic to enable production ready solutions.

You can check the complete radar here!

How about you? What are your favorite topics on the radar? 🙂

Exploring the Essentials of LLM-Powered Java Applications

The integration of Large Language Models (LLMs) into Java applications is a major leap forward in the field of software development. These models open up new possibilities for automating and enhancing tasks through natural language understanding and generation.

To effectively utilize these capabilities, one must grasp several key concepts I’ve highlighted in the following video recorded with formidable people at Jacksonville JUG meetup!

Source Code used in this presentation can be found on the GitHub repo here.

Fundamental Concepts for LLM

Decoding Models in Java Applications

Central to LLM-powered applications are the models themselves. These Large Language Models, like OpenAI’s GPT and Google’s Gemini, are advanced AI tools to process and generate natural language. In Java applications, these models can significantly extend functionalities, from text generation to complex query handling. Selecting the right model is critical, as it defines your application’s scope and capabilities.

The Significance of Prompts

Prompts serve as the primary mode of communication between your Java application and the LLM. They are instructions or queries that guide the model in producing the desired output. For instance, prompts can be creatively designed to craft narratives or answer specific questions. Their adaptability is a key strength, allowing for diverse applications ranging from creative writing assistance to technical problem-solving.

Navigating Memory Management in Java Applications with LLMs

Handling memory in LLMs is not like some people may think. These models are stateless, so they essentially don’t store or “learn” anything new from previous prompt. To maintains a conversational history, we must send the conversation history with the new prompt, preserving the context of interactions. This is what leads to a relevant and coherent responses from the LLM.

Enhancing Functionality with Retrieval Augmented Generation

Retrieval Augmented Generation (RAG) elevates the capabilities of your application by enabling the LLM to access and incorporate external information. This method is particularly beneficial for circumventing token limitations and for specializing the model in certain knowledge areas. RAG involves extracting relevant data from external sources to inform the LLM’s responses, ensuring accuracy and depth in the output.

The Role of Agents in Java Applications with LLMs

Agents in this context refer to mechanisms that delegate specific tasks to be called by the model. This setup enables complex functionalities within the Java application, allowing the LLM to perform intricate tasks by interacting with predefined functions. This concept showcases the versatility of LLMs in handling diverse and complex tasks within a Java environment.

Conclusion

Embarking on the development of a Java application powered by a Large Language Model is an exciting and promising endeavor. By understanding the nuances of Models, Prompts, Memory, Retrieval Augmented Generation, and Agents, developers can fully harness the capabilities of LLMs. As this technology continues to evolve, keeping up with these foundational concepts will be crucial for creating innovative and efficient Java applications.

For those looking to delve deeper into the world of LLM-powered Java applications, I hope you have enjoyed the video and content! Whether you are a seasoned developer or just starting out, the journey into the realm of LLMs in Java applications is both fascinating and rewarding.

Tiny Tips: Build and export results with Docker

Hello and welcome to our tiny tip of the day!

I wish to build an experimental standalone binary app in controlled environment and just pull out the results on my machine, so I can avoid installing all the build dependencies.

Shouldn’t Docker help me with such thing? And sure it DOES xD!

I’ve mainly used Docker to create runnable images with web applications exposing their ports, so this was new for me! I hope you find it simple and useful too!

1. Create your build Dockerfile as usual and then add a scratch images to expose only the result files:

# Dockerfile with conventional Java Application build with Gradle
FROM eclipse-temurin:17-jdk-jammy as build

WORKDIR /app

COPY build.gradle .
COPY gradlew .
COPY settings.gradle .
COPY gradle/ ./gradle
COPY src/ ./src

RUN ./gradlew build

# Expose /build content 
FROM scratch AS binaries
COPY --from=build /app/build /

scratch is the minimal image used to create base images in Docker

2. Build image with output and target params

In your preferred terminal, navigate at your Dockerfile directory and run the following command:

docker build --output=<OUTPUT_PATH> --target=<TARGET_NAME> .

TARGET_NAME: the instruction name inside your Dockerfile where you’ve placed the result files.

OUTPUT_PATH: the path on your machine to where you want to copy the result files

For the Dockerfile sample above, run the following command to get the output in the ./bin folder:

And… Dekiagari (Voila)!

Check the ./bin folder created with all the generated resources resulting from the build action.

Read the complete documentation from official Docker website here 🙂

Hope you find it useful! You can fund the sample code in my repository here. Have a nice coding day!

4 Great Architects to Follow [2]

In this post, I’m sharing some famous Software Architects that you probably heard of before, and I’m sure you’re using some of their content or tools on your project 🙂

Robert C. Martin

Image

The Clean series author, also known as Uncle Bob. Robert Cecil Martin heavily contributed to the software development industry helping innumerable developers around the world to become better professionals by spreading best practices and architecture patterns.

Father of SOLID principle and author of Clean Code and Clean Architecture, Uncle Bob keeps lecturing professional developers to improve their coding skills and shares his thoughts on social media.

Martin Fowler

Image

Martin Fowler is an unparalleled reference in Software Architecture topics. Author of popular titles such as Refactoring and Enterprise Application Architectures, Martin keeps his blog updated with modern challenges and solutions to make development routine easier and help build useful software.

One of my favorite content from Martin is Who Needs An Architect where he starts a journey to define Software Architecture with many other big names in the industry.

Simon Brown

Image

Simon Brown is a renowned speaker and content creator, and his biggest contribution to the development community is the widely adopted C4 software architecture model.

The C4 model is an easy-to-learn, developer-friendly approach to creating software architecture diagrams, which helps explore a set of hierarchical abstractions of a solution architecture (software systems, containers, components, and code).

If you need to create consistent and clear solution architectural diagrams, I do totally recommend going through the C4 model to help you!

Sam Newman

Image

Sam Newman is a definitive reference if you want to go deeper into Microservices! He is an author, speaker, and independent consultant specializing in cloud, continuous delivery, and microservices.

Author of Building Microservices and Monolith to Microservices, with the revamp of so many web applications to distributed architectures, it’s a great and reliable source to guide your tradeoffs with confidence.

That’s it! Hope you enjoy those guys contents! Did you know them? Have I missed some one from your list? Share your references!

Always Free Cloud Services

After hosting The Senior Journey session, sponsored by Oracle Cloud, I was so impressed with their always free tier package!

We can achieve so many things with that! From running simple experiments to publish small production level solutions! All for free!

That made me curious!

What other cloud providers free tier offers, such as in Amazon, Google and Microsoft?

I end up finding this GitHub repository collecting all these information for us 😀

To have a quick view:

1. AWS Free Tier

Always Free

  • Amazon DynamoDB (NoSQL): 25 GB of storage
  • AWS Lambda (FaaS): 1 Million free requests per month
  • Amazon SNS: 1 Million publishes

2. Azure Free Tier

Free for Limited-time

  • US$200 credit for 30 days
  • Popular services free for 12 months

Always Free

  • 54+ other services free always

3. Google Cloud Free Tier

Always Free

  • Compute VM: 0.25 vCPU, 1G RAM (only on us-west1, us-central1 and us-east1)
  • 1GB of network egress (except China and Australia)
  • 5GB Storage (only on us-west1, us-central1, us-east1, asia-east1 and europe-west1)

4. Oracle Cloud Free Tier

Free for Limited-time

  • US$300 credit for 30 days
  • Up to eight instances across all available services
  • Up to 5 TB of storage

Always Free

  • Compute:
    • 2 AMD-based VMs: 0.25 vCPU and 1 GB RAM each;
    • 4 Arm-based VMs: 24 GB RAM total, 3,000 vCPU hours and 18,000 GB hours per month;
  • 2 Block Volumes Storage, 200 GB total;
  • 10 GB Object Storage – Standard;
  • 10 GB Object Storage – Infrequent Access;
  • 10 GB Archive Storage;
  • 10TB of network egress;
  • Load Balancer;
  • Monitoring and Notifications;
  • Two Oracle Autonomous Databases incl. Oracle Application Express (APEX), Oracle SQL Developer etc.

Not bad uhh?! Have you already created your own Cloud account? Or made use of these amazing services and try some interesting Cloud Architectures? Share in the comments 🙂

How to create a System Design?

Whenever we start building a new solution, or review an existing one for improvements, experienced developers starts from the System Design.

Today I’ve watched an interesting video about System Design Interview: A Step-by-Step Guide by Alex Xu.

Even if you’re not preparing for an interview process, they are useful steps to guide your Architecture discussions!

  1. Understand the problem and establish the design scope
  2. Propose high-level design and get buy in
  3. Design deep dive
  4. Wrap up

Alex Xu is the author of the best seller “System Design Interview” book and ByteByteGo blog, which I highly recommend to follow if you have interest on this kind of contents!

Hope you enjoy the content! Would be happy to hear your thoughts! 🙂