New otobo ai services coming soon!
2.3K
This project provides a modular, standalone RAG (Retrieval-Augmented Generation) hosting service designed to integrate with the OTOBO ticket system. It enables easy experimentation and deployment of multiple custom RAG pipelines. Each RAG module defines its own retrieval/generation logic and API schema, loaded dynamically at runtime.
The system uses LangGraph, LangChain, and ChromaDB to support flexible embedding and LLM-powered generation. It exposes a REST API via FastAPI for ingesting content and interacting with configured RAGs.
Further an MCP and a chat interface are included to enable agents to interface with an LLM directly that is capable to call actions in OTOBO. The chat interface is provided by https://github.com/open-webui/open-webui
You may find documentation on how to use this with OTOBO here: https://doc.otobo.org
Clone the repository and set up the environment using Docker Compose:
git clone [email protected]:RotherOSS/otobo-ai.git
cd otobo-ai
Example RAG definitions are provided under rag_examples.
If you use this setup with OTOBO, choose the default.
It supports Tickets, FAQ and Documentation.
Copy the RAG description to your RAG definition folder.
cp -r rags_examples/default rags
All RAG definitions placed here are exposed at the web service. You may tune it to your liking, or create a new one!
Create a .env file in the root directory to configure environment variables:
cp .docker_compose_env_ai .env
Edit the .env file to set your desired configuration options.
The file is self-documented.
Important
For usage with an OTOBO docker setups, docker compose v2 is required.
Use Docker Compose to build and run the server:
docker compose up --build --detach
The docker compose.yaml mounts the local ./rags directory into the container as src/rags, enabling external customization.
All endpoints are mounted under /otobo-ai/, secured with API key authentication via the get_api_key dependency.
PUT /otobo-ai/embedding/ingest/Ingest a single data item for embedding.
Input:
{
"type": "documentation",
"content": [[{ "type": "text", "text": "your content here" }]],
"embed_content_types": ["text"],
"store_fulltext": false
}
Response: 200 OK or 500 Internal Server Error
PUT /otobo-ai/embedding/ingest-many/Ingest a batch of data items for embedding.
Input:
{
"type": "faq",
"content": [
[
{ "type": "question", "text": "What is OTOBO?" },
{ "type": "answer", "text": "A ticketing system." }
],
[
{ "type": "question", "text": "In what language is OTOBO written?" },
{ "type": "answer", "text": "In Perl." }
]
],
"embed_content_types": ["question"],
"store_fulltext": true,
"fulltext_types": ["answer"]
}
Response: 200 OK or 500 Internal Server Error
Each registered RAG module is exposed under:
POST /otobo-ai/{rag_name}/invokeRun the full RAG process (retrieve and generate).
Input:
{
"input": {
"question": "What is OTOBO?",
"do_scoring": true
},
"config": {},
"kwargs": {}
}
Output:
{
"output": {
"question": "What is OTOBO?",
"generation": "OTOBO is an open-source ticketing system.",
"score": 0.87
},
"metadata": {
"run_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"feedback_tokens": [
{
"key": "score-feedback",
"token_url": "https://feedback.example.com/token/3fa85f64",
"expires_at": "2025-04-06T08:05:36.868Z"
}
]
}
}
Each RAG can define its own input/output models, but this is the expected default format.
Note that only the input and output fields are relevant for usage within OTOBO, the other fields are automatically provided by LangServe
Each RAG lives in its own folder under rags/, structured as follows:
rags/
└── my_custom_rag/
├── graph.py
├── chains.py # optional
├── io_models.py
└── prompts/
└── prompt.txt
graph.py
Must define a graph object using StateGraph, compiled with graph = workflow.compile().
io_models.py
Must define:
class RAGInput(BaseModel): ...
class RAGOutput(BaseModel): ...
These models define the request and response schema for your RAG.
chains.py
Use this to separate LangChain logic or define chains used in your workflow.
prompts/
Store custom prompt templates here. Load them with Path(__file__).parent / "prompts" / "prompt.txt".
graph.pyworkflow = StateGraph(GraphState)
workflow.add_node("retrieve", retrieve)
workflow.add_node("generate", generate)
workflow.set_entry_point("retrieve")
workflow.add_edge("retrieve", "generate")
workflow.add_edge("generate", END)
graph = workflow.compile()
All RAGs in rags/ are auto-registered by register_rags(app) on startup.
If files or required types are missing, the module will be skipped with a warning.
This project supports dynamic loading of RAG modules at runtime via the register_rags(app: FastAPI) function.
At startup, the server scans the src/rags/ directory for subdirectories containing a graph.py file.
Each graph.py must define a graph object with a .with_config(config) method.
These are registered as individual FastAPI routes under /otobo-ai/{rag_name}, protected by API key.
Each RAG module must follow this structure:
graph.py defining the LangGraph workflow (graph)io_models.py defining the input/output types (RAGInput and RAGOutput)chains.py, prompt templates, and other helpersOnly rag_examples/ is version-controlled. The src/rags/ directory is .gitignored so users can safely define custom modules without affecting the repo.
src/
├── rags/ ← not version controlled
│ ├── simple_rag/ ← copy or create your RAG modules here
│ │ ├── graph.py
│ │ ├── chains.py
│ │ ├── io_models.py
│ │ └── prompts/
│ └── ...
└── ...
rag_examples/ ← reference implementations
├── simple_rag/
└── ...
To update the dependencies in a controlled way:
In requirements.txt, remove version pins from most packages.
Keep pins only for critical compatibility fixes.
Before:
uvicorn==0.25.0
fastapi==0.108.0
# critical compatibility fixes
numpy==1.26.4
After:
uvicorn
fastapi
# critical compatibility fixes
numpy==1.26.4
docker compose build
docker compose up
Ensure it runs without version issues.
Verify ingestion and RAG endpoints still work correctly.
After confirming stability, inspect the installed versions:
docker compose run --rm otobo-ai pip list
Use the output to update requirements.txt with the final versions used.
Example:
uvicorn==0.34.0
fastapi==0.115.0
# critical compatibility fixes
numpy==1.26.4
git add requirements.txt
git commit -m "Update pinned dependencies"
Content type
Image
Digest
sha256:993b1e291…
Size
193.2 MB
Last updated
16 days ago
docker pull rotheross/otobo-ai-services