Feishu-focused bot service with pluggable LLM backend
Project description
MA-Agent
一个专注于飞书生态的 Python Bot 项目骨架,建议按「先终端、后飞书」顺序推进:
- 先在终端完成多轮对话验证
- 可直接调用大模型接口(
/api/llm/chat) - 内置 OpenAI 兼容协议客户端(也可切回
echo) - 飞书 webhook 保留为后续对接能力
1. 项目结构
feishubot/
├── src/feishubot/
│ ├── app.py # FastAPI 应用
│ ├── ai/ # 模型与工具调用骨架目录
│ │ ├── core/ # 通用 schema / registry / error
│ │ ├── providers/ # 各模型适配器(openai/anthropic/gemini...)
│ │ ├── tools/ # 工具定义与实现
│ │ ├── orchestrator/ # Agent 执行编排层
│ │ ├── prompts/ # Prompt 模板
│ │ ├── memory/ # 会话状态抽象
│ │ └── configs/ # 路由与工具配置样例
│ ├── config.py # 环境配置
│ ├── channel/ # 消息通道抽象层(默认 feishu)
│ ├── feishu.py # 飞书 API 客户端(官方 lark-oapi SDK)
│ ├── llm_client.py # 大模型抽象与 OpenAI 兼容客户端
│ └── main.py # 启动入口
├── .env.example
├── pyproject.toml
└── README.md
2. 快速开始
2.0 使用 uvx 直接运行(推荐发布版)
发布到 PyPI 后,可不克隆仓库直接运行:
# 1) 先执行交互式配置(会写入 ~/.feishubot/.env)
uvx --from MA-Agent feishubot setup
# 2) 直接启动终端对话
uvx --from MA-Agent feishubot chat
# 3) 或启动网关
uvx --from MA-Agent feishubot gateway --host 0.0.0.0 --port 8000
配置文件说明:
- 默认环境文件路径:
~/.feishubot/.env - 默认工具配置路径:
~/.feishubot/tools.toml - 若当前目录存在
.env,会优先读取当前目录配置(便于本地开发) - 可通过
FEISHUBOT_ENV_FILE显式指定环境文件:
FEISHUBOT_ENV_FILE=~/work/feishubot/.env uvx --from MA-Agent feishubot chat
一键下载并运行(推荐):
bash <(curl -fsSL https://raw.githubusercontent.com/wsmxd/feishubot/main/scripts/bootstrap.sh)
可选参数:
# 下载后仅初始化,不自动启动
bash <(curl -fsSL https://raw.githubusercontent.com/wsmxd/feishubot/main/scripts/bootstrap.sh) -- --run none
# 启动 HTTP 网关
bash <(curl -fsSL https://raw.githubusercontent.com/wsmxd/feishubot/main/scripts/bootstrap.sh) -- --run gateway
- 创建并激活虚拟环境
- 安装uv依赖:
pipx install uv
- 开启虚拟环境(python版本3.14):
uv venv --python 3.14
macOS / Linux:
source .venv/bin/activate
Windows PowerShell:
.venv\Scripts\Activate.ps1
- 安装项目依赖:
uv sync
- 启动网关服务:
feishubot gateway --reload --host 0.0.0.0 --port 8000
- 快速配置(推荐首次执行):
feishubot setup
会进入交互式向导,快速选择 LLM 提供商(echo / openai_compatible)并写入 .env。
当前内置大模型预设:qwen、kimi、deepseek。
该向导会写入 LLM_MODELS_CONFIG_PATH 和 LLM_ACTIVE_MODEL,用于维护多个模型并快速切换。
在默认配置下,还会自动创建 ~/.feishubot/tools.toml 作为工具运行配置。
说明:
FEISHU_APP_ID、FEISHU_APP_SECRET建议在 setup 时填写(长连接必需)FEISHU_VERIFICATION_TOKEN、FEISHU_ENCRYPT_KEY为可选字段(开发阶段可留空)
3. 先在终端跑通对话
配置好 .env 后可直接进入终端对话:
feishubot chat
可选参数:
feishubot chat --user-id demo-user --system-prompt "你是一个简洁的助手"
兼容旧命令(仍可用):
feishubot-chat --user-id demo-user
退出方式:输入 exit / quit / /exit,或按 Ctrl+C。
工具层配置(可选):
- 默认读取
tools.default.toml(仓库根目录,真实运行配置) - 通过
AI_TOOLS_CONFIG_PATH覆盖配置文件路径(可参考src/feishubot/ai/configs/tools.example.toml) - 支持
enabled_tools控制可用工具集合 soul_memory默认启用,模型会在识别到稳定用户画像信息时写入SOUL.md- 支持
routing.<tool>.timeout_seconds覆盖工具默认超时 - 支持
terminal.blocked_commands定义禁用命令片段(命中即拒绝执行)
4. 再调通 HTTP 大模型接口
- 在
.env中配置(单模型或多模型二选一):
LLM_PROVIDER=openai_compatibleLLM_BASE_URL=https://api.openai.com(或你的网关地址)LLM_API_KEY=<你的密钥>LLM_MODEL=<你的模型名>
多模型模式(推荐):
LLM_ACTIVE_MODEL=qwenLLM_MODELS_CONFIG_PATH=src/feishubot/ai/configs/model_routes.example.toml
切换模型时只需修改 LLM_ACTIVE_MODEL,然后重启 feishubot chat 或 gateway 进程。
- 调用接口测试:
curl -X POST http://127.0.0.1:8000/api/llm/chat \
-H "Content-Type: application/json" \
-d '{
"message": "你好,给我一段简短的项目启动建议",
"user_id": "demo-user"
}'
也支持更适合 curl 的统一入口:
curl "http://127.0.0.1:8000/api/chat?message=你好&user_id=demo-user"
curl -X POST http://127.0.0.1:8000/api/chat \
-H "Content-Type: application/x-www-form-urlencoded" \
--data-urlencode "message=你好,给我一个简短回复"
/api/chat 和 /api/llm/chat 现在是同一个网关能力的两个别名,后续飞书侧转发时可以直接复用这套请求格式。
核心人格文件运行时路径默认为 ~/.feishubot/SOUL.md(可通过 SOUL_PROMPT_PATH 覆盖);src/feishubot/ai/prompts/system/SOUL.md 仅作为初始模板。后续如果需要更新用户姓名、称呼、习惯或爱好,可通过 soul_memory 工具或 save_soul_prompt() 写回运行时文件。
5. 飞书侧配置(后续)
- 在飞书开发者后台创建应用并开启机器人能力
- 先把本地网关暴露为公网地址(任选一种)
# 方案 A: Cloudflare Tunnel(推荐稳定)
cloudflared tunnel --url http://127.0.0.1:8000
# 方案 B: ngrok
ngrok http 8000
- 拿到公网 URL 后,设置事件订阅请求地址为:
https://<your-domain>/webhook/feishu/events - 建议先在飞书后台点一次「发送测试事件」,确认网关可达
- 在
.env中填写:FEISHU_APP_IDFEISHU_APP_SECRETFEISHU_VERIFICATION_TOKEN(可选,按你启用方式)FEISHU_ENCRYPT_KEY(可选)DEFAULT_CHANNEL=feishu(默认值;后续可扩展其他 channel)GATEWAY_INTERNAL_API_KEY(可选,配置后/api/feishu/push与/api/feishu/relay需携带x-api-key)
5.1 内部主动推送 API(可选)
除了飞书事件回调链路,也支持内部服务主动调用 API 向飞书发消息。
- 直接推送文本到飞书:
curl -X POST http://127.0.0.1:8000/api/feishu/push \
-H "Content-Type: application/json" \
-H "x-api-key: <GATEWAY_INTERNAL_API_KEY>" \
-d '{
"receive_id": "oc_xxx",
"receive_id_type": "open_id",
"text": "来自内部系统的通知"
}'
- 先调用 LLM 再把回复推送到飞书:
curl -X POST http://127.0.0.1:8000/api/feishu/relay \
-H "Content-Type: application/json" \
-H "x-api-key: <GATEWAY_INTERNAL_API_KEY>" \
-d '{
"message": "请用一句话总结今天待办",
"receive_id": "oc_xxx",
"receive_id_type": "open_id",
"user_id": "internal-service"
}'
receive_id_type 常见值:open_id(用户)、chat_id(群聊)。
5.2 事件处理模式
项目已接入飞书官方 lark-oapi SDK 事件分发器,支持两种订阅模式:
默认策略:优先使用官方 SDK 长连接;当长连接不可用或建连失败时,自动 fallback 到 webhook 网关模式。
- 长连接模式(推荐开发调试)
feishubot events --log-level INFO
- 对应飞书后台订阅方式:使用长连接接收事件
- 无需公网回调地址
- 若长连接失败,会自动启动 webhook 网关(默认
0.0.0.0:8000)
可选参数:
# 调整 fallback 网关端口
feishubot events --fallback-port 9000
# 禁用 fallback(长连接失败时直接报错退出)
feishubot events --no-fallback-webhook
- 开发者服务器模式(Webhook)
feishubot gateway --host 0.0.0.0 --port 8000
- 对应飞书后台订阅方式:将事件发送至开发者服务器
- 事件地址使用:
https://<your-domain>/webhook/feishu/events
说明:
- 已注册
im.message.receive_v1事件处理。 - 回调处理逻辑会快速应答,再异步调用 LLM 并发送回复,避免超过 3 秒导致重推。
5.3 常见问题
- 报错:
FEISHU_APP_ID and FEISHU_APP_SECRET are required for long connection mode.
- 原因:长连接模式必须有应用凭证
- 处理:在
.env中填写FEISHU_APP_ID、FEISHU_APP_SECRET后重启
- 报错:
connecting through a SOCKS proxy requires python-socks
- 原因:当前网络走了 SOCKS 代理,WebSocket 缺少代理依赖
- 处理:执行
uv add python-socks,然后重启feishubot events
- 启动命令找不到:
feishubot: command not found
- 处理 A:先激活虚拟环境再执行命令
- 处理 B:使用
uv run feishubot events --log-level INFO
6. 接入大模型说明
当前在 llm_client.py 提供了:
LLMClient抽象接口EchoLLMClient(本地调试)OpenAICompatibleLLMClient(兼容 OpenAI Chat Completions 协议)
保留统一接口,方便后续扩展「工具调用」「多 Agent」「任务执行器」。
7. 下一步建议
- 增加飞书消息去重(基于
event_id) - 增加签名校验与加解密
- 增加指令路由(如
/plan、/run) - 持久化会话上下文(Redis / PostgreSQL)
8. License
本项目使用 Apache-2.0 许可证,详见 LICENSE。
9. CI 与 PR 合并策略
项目已提供 GitHub Actions 工作流:
.github/workflows/ci.yml:在 PR 和mainpush 时自动执行 Ruff 格式检查、Ruff lint/安全规则检查、语法检查、基础导入检查、测试(若存在tests/).github/CODEOWNERS:指定代码所有者审阅(默认@wsmxd)
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file ma_agent-0.1.2.tar.gz.
File metadata
- Download URL: ma_agent-0.1.2.tar.gz
- Upload date:
- Size: 48.3 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
287c61c9c2174cd1942e2b80b100e9e1da2a53e753280720eef24370372caca1
|
|
| MD5 |
e841febf0959d241198c776cd13ba7c5
|
|
| BLAKE2b-256 |
69507460aefbefd9b26f52f1814558f6ba4590aef0ba4ae94a59336814ec738c
|
Provenance
The following attestation bundles were made for ma_agent-0.1.2.tar.gz:
Publisher:
release.yml on wsmxd/feishubot
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
ma_agent-0.1.2.tar.gz -
Subject digest:
287c61c9c2174cd1942e2b80b100e9e1da2a53e753280720eef24370372caca1 - Sigstore transparency entry: 1284683892
- Sigstore integration time:
-
Permalink:
wsmxd/feishubot@57c1e30d7aadb568c253d3e220419faeb2306a16 -
Branch / Tag:
refs/tags/v0.1.2 - Owner: https://github.com/wsmxd
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@57c1e30d7aadb568c253d3e220419faeb2306a16 -
Trigger Event:
push
-
Statement type:
File details
Details for the file ma_agent-0.1.2-py3-none-any.whl.
File metadata
- Download URL: ma_agent-0.1.2-py3-none-any.whl
- Upload date:
- Size: 60.2 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
6672e4bdd970ea246c5ad385e1da7b53ebe7e99b225d9127dac926abdfb98d36
|
|
| MD5 |
b8a1d58ee8d279890e3a51878f649b17
|
|
| BLAKE2b-256 |
4795b5b0f9f1a4153b615a42da48662268cf322e9f94977ec69ed2d2c769e94f
|
Provenance
The following attestation bundles were made for ma_agent-0.1.2-py3-none-any.whl:
Publisher:
release.yml on wsmxd/feishubot
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
ma_agent-0.1.2-py3-none-any.whl -
Subject digest:
6672e4bdd970ea246c5ad385e1da7b53ebe7e99b225d9127dac926abdfb98d36 - Sigstore transparency entry: 1284684065
- Sigstore integration time:
-
Permalink:
wsmxd/feishubot@57c1e30d7aadb568c253d3e220419faeb2306a16 -
Branch / Tag:
refs/tags/v0.1.2 - Owner: https://github.com/wsmxd
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@57c1e30d7aadb568c253d3e220419faeb2306a16 -
Trigger Event:
push
-
Statement type: