keelchat

Describe a chatbot. Chat with it. Run it yourself.

In keelchat, a bot is one short YAML file: what it is for, what it asks, its rules and limits, and when it hands over to a person. Say what yours should do in a sentence or two; a model writes the file and keelchat checks that it builds.

Press Try this bot to talk to it here, ask for changes in plain words, then clone the repo and run it on your own machine. It's open source (Apache-2.0).

support_assistant.yaml

This file is the whole bot. keelchat's runtime runs it: the steps, the rule, the limits and the handoff.

# A generic support assistant: consent, a short form, answers from a knowledge base. Uses only built-in capabilities.
agent: support-assistant
charter: >
  Help customers with orders, returns and account questions. Friendly, concise.
  Out of scope: legal advice, medical advice, anything unrelated to the store.
languages: [en, es]
small_talk: brief                  # "how's your day?": one friendly line, then back to the question
tools: [knowledge_search]          # extras; flow steps bring their own tools
flow:
  - greet_consent
  - form_fill:
      think: true                  # plan each reply first: what they need, what is unknown, which rules apply
      curious: true                # one follow-up when an answer is too thin to act on (e.g. "it's broken")
      fields:
        - name: order_number
          ask: What is your order number?
          expect: An order number in any format, such as ORD-12345 or #98765
        - name: issue
          ask: What went wrong with the order?
          expect: A short description of the problem
          optional: true
      closing: I've passed this to our support team. They'll email you about it within one working day.
rules:                             # apply only on the messages they fit (docs/WRITING_AN_AGENT.md#rules)
  - name: damaged_item
    when: the customer says an item arrived damaged or broken
    then: say a free replacement can be sent, and ask for the order number if it is not known yet
guardrails:
  input: [prompt_injection, sql_injection]
  output: [pii, profanity, no_legal_advice]
limits: {reasks: 3, digressions: 3}
memory:
  - field: preferred_contact
    extract: How they prefer to be contacted (email, phone, chat)
    type: email|phone|chat
    half_life: 90d
handoff:                           # pass to a person (the handoff inbox): when asked, or after too many failed answers
  when: [user_request, max_reasks]
  # notify: handoff_webhook          # also POST each handoff to your helpdesk (HANDOFF_URL)