AIr-Friends:集成 shell 与技能的 ACP 智能体自定义聊天机器人
jim60105/AIr-Friends
jim60105 的 AIr-Friends 是一个基于 ACP 智能体的自定义聊天机器人,目前支持 Discord 和 Misskey,可跨频道记住对话并将数据隔离在各用户工作区。它支持定时提醒、Git 备份记忆与笔记、按用户或上下文动态路由 LLM 模型(默认 gpt-5-mini),并可通过 Podman/Docker 一条命令部署。
Your AIr friends custom chatbot with integrated shell and skills. Powered by ACP AI agents, it remembers conversations across channels while keeping your data organized in isolated workspaces.
✨ Highlights
- 🤖 Multi-Platform: Currently works on Discord and Misskey
- 🧠 Persistent Memory: Remembers conversations across different channels
- 🗜️ Memory Maintenance: Optional scheduled agent task to summarize and compact old memories
- ⏰ Scheduled Reminders: Users can set one-time reminders via DM, delivered at the specified time
- 📝 Agent Knowledge Base: Personal workspace for long-term knowledge notes and reflections
- 🔒 Privacy First: Isolated workspaces per user with access control
- 💾 Git Backup: Automatic versioned backup of memories and notes to GitHub
- 🐳 Easy Deploy: One-command container deployment
- 🎨 Customizable: Template-based personality prompt system
- 🔌 Extensible: Skill-based architecture with external skill auto-installation
🚀 Quick Start
The recommended way to run AIr-Friends is by using containers:
-
Prepare .env file
# Download example file wget https://raw.githubusercontent.com/jim60105/AIr-Friends/master/.env.example -O .env # Edit with your credentials vim .env
-
Run with Podman (or Docker)
podman run -d --rm \ -v data:/app/data \ --env-file .env \ --name air-friends \ ghcr.io/jim60105/air-friends:latest
-
Or use Compose
wget https://raw.githubusercontent.com/jim60105/AIr-Friends/master/compose.yml podman compose up -d
That's it! Your bot should now be online.
🎨 Customizing Your Bot
Change the personality of your bot!
Override individual character prompt files — only the files you mount will be replaced; others keep their container defaults.
With Compose (recommended — see compose.yml):
volumes: - data:/app/data:Z # Mount only the prompt files you want to override - ./prompts/character_name.md:/app/prompts/character_name.md:ro,Z - ./prompts/character_info.md:/app/prompts/character_info.md:ro,Z - ./prompts/character_personality.md:/app/prompts/character_personality.md:ro,Z - ./prompts/character_speaking_style.md:/app/prompts/character_speaking_style.md:ro,Z - ./prompts/character_reference_terms.md:/app/prompts/character_reference_terms.md:ro,Z
With Podman/Docker run:
podman run -d --rm \ -v data:/app/data \ -v ./prompts/character_name.md:/app/prompts/character_name.md:ro \ -v ./prompts/character_info.md:/app/prompts/character_info.md:ro \ --env-file .env \ --name air-friends \ ghcr.io/jim60105/air-friends:latest
With Helm (see helm/ chart):
# values.yaml prompts: enabled: true files: character_name.md: | Yuna character_info.md: | An AI assistant
See Development Guide -- Customizing the Bot section for details.
🔐 Reply Policy
Control who can interact with your bot using the channels-based reply policy:
replyPolicy: "channels" # Options: all, public, channels channels: - id: "discord/account/123456789012345678" enabled: true spontaneousPost: false channelLurk: false rateLimitBypass: true yolo: true - id: "misskey/account/abcdef1234567890" enabled: true spontaneousPost: false channelLurk: false rateLimitBypass: false yolo: false - id: "discord/channel/873618490202931231" enabled: true spontaneousPost: true channelLurk: true yolo: false
See Development Guide -- Access Control & Reply Policy section for details.
🛡️ Rate Limiting
Prevent excessive API usage per user with configurable rate limiting:
rateLimit: enabled: false maxRequestsPerWindow: 10 windowMs: 600000 # 10-minute sliding window cooldownMs: 600000 # Cooldown after limit exceeded
⏰ Scheduled Reminders
Allow users to set one-time reminders via DM. The bot delivers them at the scheduled time:
reminders: enabled: false maxRemindersPerUser: 20 # Max active reminders per user minIntervalMs: 60000 # Minimum delay from now (1 minute) checkIntervalMs: 30000 # How often to check for due reminders
- DM-only: Reminders can only be set and are delivered in direct messages
- One-time: Each reminder fires exactly once (no recurring support)
- Restart-safe: Overdue reminders are picked up automatically after bot restart
- Skills:
set-reminder,cancel-reminder,list-reminders
🔀 Model Routing
Dynamically select LLM models per user or context to control costs and quality:
agent: model: "gpt-5-mini" # default fallback modelRouting: enabled: true rules: - match: { channel: "discord/account/12345678901234567" } model: "openrouter/deepseek/deepseek-v3.2" - match: { sessionType: "spontaneous" } model: "openrouter/deepseek/deepseek-v3.2"
Rules are evaluated in order (first-match wins). See Development Guide -- Model Routing for details.
🏗️ Architecture
AIr-Friends acts as an ACP (Agent Client Protocol) client, delegating AI reasoning to external agents while maintaining persistent memory:
┌─────────────────────────────────────────┐
│ Platform (Discord/Misskey) │
│ ↓ │
│ AIr-Friends (ACP Client) │
│ ↓ │
│ External AI Agent │
│ (OpenCode) │
│ ↓ │
│ Skills & Memory System │
└─────────────────────────────────────────┘
See Design Document for detailed architecture.
📦 Container Details
The official container image includes:
- Pre-installed AI agent binary (OpenCode CLI)
- Pre-installed OMP CLI (
omp), pinned by exact tag + per-arch SHA-256 checksums (ContainerfileOMP_VERSION); packaging only — OMP runtime enforcement is gated by the earlier OMP rows. See OMP Packaging. - Auto-approval mode enabled for isolated execution
- Health check endpoint on port 8080
- Default prompts at
/app/prompts(can be overridden)
🤝 ACP Agent Integration (OpenCode & OMP)
Two agent types are supported: opencode (the default when unset) and omp.
Select via agent.defaultAgentType in config or AGENT_DEFAULT_TYPE (also in
helm/values.yaml); unknown values are rejected at config load. Configuration
acceptance is distinct from launch availability — see
AGENTS.md.
OMP runs in two deployment postures: restricted (deployment-owned settings
overlay, trusted enforcement extension, native approval mode) and
native-YOLO (operator-approved; carries the LSP disable without restricted
denials). LSP is disabled in every agent and mode — OMP restricted and YOLO
via owned settings + --no-lsp, OpenCode build and yolo via per-agent
explicit denies. Details: OMP Spawn & Modes,
OMP Settings.
Honest status: the batch proposals are approved and their implementation lands through the applied changes; all seven user dispositions are DECIDED. Pinned incompatible/unresolved compatibility verdicts are unchanged, and automated unit and mock evidence does not certify native runtime enforcement — runtime verification remains user-owned and unverified in the single consolidated checklist docs/USER-RUNTIME-VERIFICATION.md.
🛠️ Development
See Development Guide for complete setup instructions.
License
GNU GENERAL PUBLIC LICENSE Version 3
Copyright (C) 2026 Jim Chen Jim@ChenJ.im.
This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with this program. If not, see https://www.gnu.org/licenses/.
来源:GitHub · github.com
