This example demonstrates most of the core features of ADL through a bookstore chatbot that supports return policy inquiries, online ordering, and personalized book recommendations. The source code is available here.
The store_policy_kb agent handles questions about return policies by retrieving answers from internal documents, the website, and frequently asked questions. Whenever a user’s concern matches available information, the agent provides the relevant response.
The book_recommendation agent interacts with users to learn about their reading preferences. It searches the book database by genre and suggests top-selling titles that match the user’s interests.
Finally, the order agent manages the purchasing process. It confirms the items the user wants to buy and places the order. If the user expresses interest in exploring more options, this agent will call on the book_recommendation agent to continue the recommendation flow.
store_policy_kb:
type: kb agent
description: I can answer questions related to the store’s policy.
sources:
- https://www.bookstores.com/policies/shipping
- https://www.bookstores.com/about
faq:
- q: Thanks, bye
a: Looking forward to serving you next time.
book_recommendation:
type: llm agent
description: I can recommend books to customers.
args:
- genre
- book_name
- book_info
- book_wanted
prompt: |
1. Ask the user if they have a preferred book genre.
2. If the user has a favorite book, call the "query_book_genre" function based on their favorite book to obtain the "genre".
3. Using the genre, call the "find_bestsellers" function to recommend relevant books to the user. Then ask user if they need to order this one.
4. If the user agree, append this book to argument "book_wanted", which should be an array, and then complete this agent.
uses:
- query_book_genre
- find_bestsellers
order:
type: flow agent
description: I can place an order.
args:
- books
- order_status
fallback: "Sorry, I didn’t understand that. Could you rephrase it?"
steps:
- bot: "I’ll place the order for you."
- label: confirm_books
- bot: "You have selected these books so far: ${books}. Would you like to add anything else to your order?"
- user
- if: the user claims "Yeah", "Do you have other types of books?"
then:
- call: book_recommendation
- next: confirm_books
- else if: the user claims "No", "I don’t have anything else I want to buy."
then:
- next: start_ordering_operation
else:
- next: confirm_books
tries: 3
start_ordering_operation:
- call: place_order
args:
ordered_book: books
date: triage.date
- if: place_order.status == True
then:
- return: success, Order placed successfully.
else:
- return: error, Order failed.
triage:
type: ensemble agent
description: Select an agent to respond to the user.
args:
- date
- book
contains:
- store_policy_kb
- book_recommendation:
args:
book_wanted: ref book
- order:
args:
books: ref book
steps:
- call: get_date
- set:
date: get_date.today
- bot: "Hi, I’m your bookstore assistant. How can I help you?"
exit: default
main:
type: flow agent
steps:
- call: triage
Below is a simple implementation of the custom functions involved. You can also connect your own database or implement any custom logic you need.
from datetime import date
import random
books = {
"The Time Traveler's Diary": {
"genre": "Fiction",
"description": "A man discovers a journal that allows him to revisit moments in history and rewrite fate.",
"rating": 4.5,
},
"Quantum Realities": {
"genre": "Science",
"description": "An accessible explanation of quantum physics and its implications for reality.",
"rating": 4.2,
},
"The Dragon's Pact": {
"genre": "Fantasy",
"description": "A young mage forms a forbidden alliance with a dragon to save her crumbling kingdom.",
"rating": 4.7,
},
"Deep Work": {
"genre": "Non-fiction",
"description": "Guidance on how to focus in a distracted world and achieve meaningful productivity.",
"rating": 4.6,
},
"The Memory Garden": {
"genre": "Fiction",
"description": "An elderly woman tends a magical garden where forgotten memories bloom anew.",
"rating": 4.4,
},
"AI and the Future of Thinking": {
"genre": "Science",
"description": "Explores how artificial intelligence is transforming the way humans reason and solve problems.",
"rating": 4.3,
},
"The Last Enchanter": {
"genre": "Fantasy",
"description": "An orphan discovers he’s the final heir to an ancient magical order and must fight dark forces.",
"rating": 4.6,
},
"Atomic Habits": {
"genre": "Non-fiction",
"description": "A proven system for building good habits and breaking bad ones.",
"rating": 4.9,
},
"The Paper City": {
"genre": "Fiction",
"description": "In a crumbling metropolis made of paper, a journalist uncovers a conspiracy that could ignite a revolution.",
"rating": 4.3,
},
"The Moonstone Tower": {
"genre": "Fantasy",
"description": "A knight seeks a legendary tower that grants wishes—but only at a cost.",
"rating": 4.1,
},
}
def get_date():
today = date.today()
formatted = today.strftime("%Y-%m-%d")
return [{"status": "success"},
{"arg": "today", "value": formatted}]
def query_book_genre(book_name):
genres = ["Fiction", "Non-fiction", "Fantasy", "Science"]
genre = random.choice(genres)
if books.get(book_name):
genre = books.get(book_name)['genre']
print(f"The genre is : {genre}")
return [{"arg": "genre", "value": genre}]
def find_bestsellers(genre = None):
"""If a specific genre is given, the function returns the best-selling book description in that genre;
otherwise, it returns the overall best-seller.
"""
cand = []
bestseller = {}
if genre is not None:
for name, info in books.items():
if info["genre"].lower() == genre.strip().lower():
cand.append({"name": name, "info": info})
else:
for name, info in books.items():
cand.append({"name": name, "info": info})
sorted_cand = sorted(cand, key=lambda x: x["info"]["rating"], reverse=True)
bestseller = sorted_cand[0]
print(f"The bestseller is: {bestseller['name']}, the description: {bestseller['info']['description']}")
return [{"arg": "book_info", "value": bestseller['info']['description']},
{"arg": "book_name", "value": bestseller["name"]}]
def place_order(ordered_book, date):
return [{"bot": "Okay, your order is all set!"},
{"arg": "status", "value": True}]