Skip to content

WhyQLate/inputM

Repository files navigation

AI 输入法 Agent

输入法即 Agent — 语音输入 + 猫娘人格补正 + OpenHuman 智能体接入 + Evolver 自进化

功能概览

  • 语音输入:按住快捷键说话,FunASR/Whisper STT 识别,候选栏立即显示原话
  • 实时转写:录音过程中定时显示中间识别结果(FunASR 伪流式,可通过 STT_STREAMING_ENABLED 开关)
  • 人格补正:LLM 用指定人格(默认猫娘)的语气补正文本,流式打字机效果
  • 场景感知:自动检测前台窗口(IDE/聊天/浏览器/办公等 7 类),让补正更贴合当前场景
  • 方言识别:FunASR 支持 6 种方言(普通话/粤语/四川话/上海话/闽南语/客家话)
  • 意见反馈:对补正不满意时再按快捷键说出意见,Agent 根据意见重新补正
  • 智能体执行:意见中需要查阅数据/搜索时,OpenHuman Agent 真实执行操作,结果融入补正
  • 后台处理项:OpenHuman 唤起后,候选栏 ✓ 变为 →,点击 → 派发到后台,桌宠头顶显示转圈处理项,完成后变 ✓,支持多个并发叠加
  • 自定义人格:右键桌宠可添加/删除自定义人格(ID + 名称 + 风格提示),无需改配置文件
  • 人格市场:通过 CLI /persona market 从 EvoMap Hub 下载人格或上传自定义人格共享
  • 多 LLM Provider:内置 8 种 provider 预设(OpenAI/DeepSeek/千问/SiliconFlow/Ollama/Anthropic/Moonshot/自定义),CLI /llm 一键切换
  • 隐私模式:CLI /privacy on 启用后不写入 memory 和信号日志,用于"临时对话"
  • CLI 流式输出:双击桌宠打开 CLI,OpenHuman 的思考过程、工具调用、返回结果实时流式显示
  • 历史记录面板:CLI /history 打开三标签页面板(对话历史/用户信号/进化产物)
  • 数据导出:CLI /export 导出 JSON/Markdown 格式的对话/信号/进化产物
  • 记忆系统:所有对话记录存入 JSON 文件记忆,支持上下文检索
  • 自进化:Evolver 定期分析对话记录,自动优化 Agent 配置和 prompt
  • 桌宠 UI:桌面悬浮桌宠,双击进入 CLI 终端模式
  • 安全加固:SSRF 防护(DNS 解析 + IP 黑名单)、会话 ID 白名单校验、子进程引用管理、危险工具审批

系统要求

  • Python: 3.12+
  • 操作系统: Windows 10/11
  • LLM API: 任何兼容 OpenAI Chat Completions 的 API
  • 麦克风: 用于语音输入(可选)
  • Node.js(可选): Evolver 自进化需要 Node.js 18+
  • Rust(可选): 从源码构建 OpenHuman 需要 Rust 1.93+

快速开始

1. 安装依赖

cd inputM
pip install -e ".[all]"

如需运行测试套件(137 个用例):

pip install -e ".[dev]"
python -m pytest

2. 配置 LLM API Key

编辑 config/.env,填入你的 API 信息:

LLM_API_KEY=sk-your-actual-api-key
LLM_BASE_URL=https://api.siliconflow.cn/v1
LLM_MODEL=deepseek-ai/DeepSeek-V4-Flash

常用服务配置:

服务 LLM_BASE_URL LLM_MODEL
OpenAI https://api.openai.com/v1 gpt-4o-mini / gpt-4o
DeepSeek https://api.deepseek.com/v1 deepseek-chat
通义千问 https://dashscope.aliyuncs.com/compatible-mode/v1 qwen-plus
SiliconFlow https://api.siliconflow.cn/v1 deepseek-ai/DeepSeek-V4-Flash
Anthropic https://api.anthropic.com/v1 claude-3-5-haiku-latest
Moonshot Kimi https://api.moonshot.cn/v1 moonshot-v1-8k
本地 Ollama http://localhost:11434/v1 qwen2.5:7b

CLI 快捷切换:启动后在 CLI 终端输入 /llm list 查看所有 provider,/llm switch deepseek 一键切换(自动设置 base_url 和 model)。

3. 启动

python start.py

启动后桌面出现桌宠,系统托盘出现图标。此时人格补正和记忆功能已可用。


OpenHuman 智能体配置(可选)

人格补正默认仅用 LLM 生成。配置 OpenHuman 后,意见反馈中需要执行操作(查阅数据、搜索信息等)时,Agent 会真实执行操作并将结果融入补正。

项目已内置 OpenHuman 核心源码(openhuman/ 目录),支持三种启动方式。

方式一:从内置源码编译启动(推荐,无需额外下载)

项目 openhuman/ 目录包含 OpenHuman Core 的完整 Rust 源码,可直接编译为 openhuman-core.exe

编译环境要求

  • Rust 1.93+(含 MSVC 工具链)
  • LLVM 18+(提供 libclang.dll,用于 whisper-rs-sys 的 bindgen)
  • CMake 3.20+(用于编译 whisper.cpp)

编译步骤

# 1. 设置环境变量(PowerShell)
$env:LIBCLANG_PATH = "F:\LLVM\bin"           # libclang.dll 所在目录
$env:CMAKE_GENERATOR = "Visual Studio 16 2019"  # 或 VS 17 2022
$env:CMAKE_GENERATOR_PLATFORM = "x64"
$env:CARGO_TARGET_DIR = "F:\oh-target"       # 编译产物输出目录(避免 C 盘空间不足)
$env:TMP = "F:\tmp"; $env:TEMP = "F:\tmp"    # 临时目录重定向

# 2. 编译(首次约 10 分钟,whisper.cpp 编译较慢)
cd openhuman
cargo build -j 1                             # -j 1 限制并行,避免链接器锁文件

# 3. 编译产物
# F:\oh-target\debug\openhuman-core.exe  (~130 MB)

启动服务

# 设置环境变量(OPENHUMAN_AGENTBOX_MODE=1 绕过后端 session 检查,允许使用自定义 LLM provider)
$env:OPENHUMAN_AGENTBOX_MODE = "1"

# 启动服务(端口 6186,与 config/.env 中 OPENHUMAN_BASE_URL 一致)
F:\oh-target\debug\openhuman-core.exe serve --port 6186

# 启动后会在 ~/.openhuman/core.token 自动生成鉴权 Token
# 看到以下日志表示成功:
# [core] OpenHuman core is ready — listening on http://127.0.0.1:6186

重要:必须设置 OPENHUMAN_AGENTBOX_MODE=1,否则 Agent 调用会报 SESSION_EXPIRED: backend session not active 错误。该环境变量允许 headless 模式下使用自定义 LLM provider(如 SiliconFlow),无需登录 OpenHuman 云后端。

配置 LLM Provider(首次启动后执行一次,配置持久化到 ~/.openhuman/users/local/config.toml):

# 读取 Token
$token = Get-Content "$env:USERPROFILE\.openhuman\core.token" -Raw

# 1. 配置 LLM(以 SiliconFlow + DeepSeek-V4-Flash 为例)
#    重要:workload provider 必须用 "slug:model" 格式,不能用裸 slug(如 "openai")
#    slug "custom" 对应 OpenHuman 自动创建的 Custom cloud provider 条目
$headers = @{ "Authorization" = "Bearer $($token.Trim())"; "Content-Type" = "application/json" }
$body = @{
    jsonrpc = "2.0"; id = 1
    method = "openhuman.inference_update_model_settings"
    params = @{
        inference_url = "https://api.siliconflow.cn/v1"
        api_key = "sk-your-api-key-here"  # 替换为你的 API Key
        default_model = "deepseek-ai/DeepSeek-V4-Flash"
        chat_provider = "custom:deepseek-ai/DeepSeek-V4-Flash"
        agentic_provider = "custom:deepseek-ai/DeepSeek-V4-Flash"
        reasoning_provider = "custom:deepseek-ai/DeepSeek-V4-Flash"
        memory_provider = "custom:deepseek-ai/DeepSeek-V4-Flash"
        coding_provider = "custom:deepseek-ai/DeepSeek-V4-Flash"
        vision_provider = "custom:deepseek-ai/DeepSeek-V4-Flash"
        heartbeat_provider = "custom:deepseek-ai/DeepSeek-V4-Flash"
        learning_provider = "custom:deepseek-ai/DeepSeek-V4-Flash"
        subconscious_provider = "custom:deepseek-ai/DeepSeek-V4-Flash"
    }
} | ConvertTo-Json -Depth 3
Invoke-WebRequest -Uri "http://127.0.0.1:6186/rpc" -Method POST -Body $body -Headers $headers -UseBasicParsing

# 2. 禁用 web_search(managed 模式需要后端 session,headless 模式不可用)
$body2 = @{
    jsonrpc = "2.0"; id = 2
    method = "openhuman.config_update_search_settings"
    params = @{ engine = "disabled" }
} | ConvertTo-Json -Depth 3
Invoke-WebRequest -Uri "http://127.0.0.1:6186/rpc" -Method POST -Body $body2 -Headers $headers -UseBasicParsing

# 3. 禁用 cloud embeddings(headless 模式无后端 session,embedding 会失败)
$body3 = @{
    jsonrpc = "2.0"; id = 3
    method = "openhuman.config_update_memory_settings"
    params = @{ embedding_provider = "none" }
} | ConvertTo-Json -Depth 3
Invoke-WebRequest -Uri "http://127.0.0.1:6186/rpc" -Method POST -Body $body3 -Headers $headers -UseBasicParsing

工具可用性说明

  • 可用工具get_timehttp_request(直接访问网页)、run_code(Node.js/Python)、 文件操作、delegate_tools_agent(委托子 Agent)、research(委托 researcher 子 Agent)等
  • 不可用工具web_search(需配置 Brave API Key 或后端 session)、 apify_scrape(需后端 session)、managed 集成(twilio、google_places 等)
  • 💡 替代方案:Agent 可用 http_request 工具直接访问网页,替代 web_search
  • 🔧 启用 web_search:注册 Brave Search API(免费 2000 次/月), 然后执行 config_update_search_settings 设置 engine = "brave"brave_api_key

输入法会自动从 ~/.openhuman/core.token 读取 Token,无需手动配置 OPENHUMAN_AUTH_TOKEN

如需查看 Token:

Get-Content "$env:USERPROFILE\.openhuman\core.token"

方式二:安装桌面应用

  1. OpenHuman Releases 下载 Windows .msi 安装包
  2. 安装并启动 OpenHuman 桌面应用(桌面模式自动生成 Token 到 ~/.openhuman/core.token
  3. 输入法自动读取 Token,无需额外配置

方式三:Docker 部署

docker run -d --name openhuman-core -p 6186:6186 \
  -e OPENHUMAN_CORE_TOKEN="$(openssl rand -hex 32)" \
  -e BACKEND_URL=https://api.tinyhumans.ai \
  -v openhuman-workspace:/home/openhuman/.openhuman \
  ghcr.io/tinyhumansai/openhuman-core:latest

Docker 模式需手动设置 OPENHUMAN_AUTH_TOKEN 环境变量为上面生成的 Token。

验证连接

启动输入法后,日志中出现以下信息表示 OpenHuman 已连接:

OpenHuman 智能体已连接: http://127.0.0.1:6186 version=0.57.x

也可手动验证:

# 健康检查
Invoke-WebRequest http://127.0.0.1:6186/health -UseBasicParsing

# JSON-RPC 调用
$token = Get-Content "$env:USERPROFILE\.openhuman\core.token"
Invoke-WebRequest http://127.0.0.1:6186/rpc -Method POST `
  -Body '{"jsonrpc":"2.0","id":1,"method":"core.version","params":{}}' `
  -Headers @{ "Authorization" = "Bearer $token" } `
  -ContentType "application/json"

OpenHuman Agent 配置

OpenHuman 的 Agent 配置通过 TOML 文件管理:

  • 内置 Agent: openhuman/src/openhuman/agent_registry/agents/<agent_id>/agent.toml
  • 自定义 Agent: ~/.openhuman/agents/*.toml$OPENHUMAN_WORKSPACE/agents/*.toml

工具权限通过 [autonomy] 配置块控制,可在 OpenHuman 设置界面(Settings → Agent access)或通过 RPC openhuman.config_update_autonomy_settings 修改。


Evolver 自进化配置(可选)

Evolver 定期分析 memory 中的对话记录,自动生成进化基因(prompt 优化、配置调整、技能建议),应用到 OpenHuman Agent。

1. 安装 Node.js

Evolver 需要 Node.js 18+。从 nodejs.org 下载安装。

2. 配置 Evolver 路径

编辑 config/.env

EVOLVER_ENABLED=true
EVOLVER_PATH=./evolver
EVOLVE_STRATEGY=balanced
EVOLVER_POLL_INTERVAL=300
  • EVOLVER_PATH 指向 Evolver 项目目录(含 index.js 的目录)
  • EVOLVE_STRATEGY 进化策略:balanced(均衡)/ aggressive(激进)/ conservative(保守)
  • EVOLVER_POLL_INTERVAL 轮询间隔(秒,默认 300 = 5 分钟)

3. 进化产物

Evolver 生成的进化产物:

产物 文件 作用
进化基因 evolver/genes.json prompt 更新、配置调整、技能建议
进化胶囊 evolver/capsules.json 成功进化快照
进化事件 evolver/events.jsonl 进化事件日志

进化基因会自动应用到 OpenHuman:

  • prompt_update → 更新 Agent 的 system prompt
  • behavior_tuning → 调整运行时配置参数
  • skill_suggestion → 写入 data/skills/*.md 供 Agent 发现

降级行为

  • Node.js 未安装 → Evolver 静默降级,不影响其他功能
  • OpenHuman 不可用 → 进化产物写入本地文件,不应用到 Agent

完整配置说明

config/.env — 主配置

配置项 默认值 说明
LLM 配置
LLM_API_KEY (必填) LLM API 密钥
LLM_PROVIDER custom LLM provider 预设(openai/deepseek/qwen/siliconflow/ollama/anthropic/moonshot/custom)
LLM_BASE_URL (随 provider) API 基础 URL,未设置时回退到 provider 预设
LLM_MODEL (随 provider) 模型名称,未设置时回退到 provider 预设
LLM_TIMEOUT 60 请求超时(秒)
记忆系统
MEMORY_STORAGE_PATH ./data/memory 对话记忆存储路径
CONTEXT_TOKEN_BUDGET 32000 上下文检索 Token 预算
AUTO_ARCHIVE_THRESHOLD 50 对话归档阈值
Agent 人格
PERSONA 猫娘 人格名称(可改为傲娇少女、温柔学姐等)
PERSONA_ID cat 人格 ID(cat/business/自定义)
隐私模式
PRIVACY_MODE false 隐私模式(启用后不写入 memory 和信号日志,可用 CLI /privacy 切换)
OpenHuman 智能体
OPENHUMAN_ENABLED true 是否启用
OPENHUMAN_BASE_URL http://127.0.0.1:6186 服务地址
OPENHUMAN_AUTH_TOKEN (自动读取) RPC 鉴权 Token,留空自动从 ~/.openhuman/core.token 读取
OPENHUMAN_AGENT_ID (空) Agent profile ID(留空用默认)
OPENHUMAN_TIMEOUT 86400 Agent 回复超时(秒,86400=实质不限制,后台处理项跟踪进度)
OPENHUMAN_BINARY (空) OpenHuman 可执行文件路径(留空自动查找 ~/.cargo/bin 和源码编译产物)
Evolver 自进化
EVOLVER_ENABLED true 是否启用
EVOLVER_PATH (空) Evolver 项目路径
EVOLVE_STRATEGY balanced 进化策略
EVOLVER_POLL_INTERVAL 300 轮询间隔(秒)
A2A_HUB_URL https://evomap.ai EvoMap A2A Hub URL

config/inputmethod.env — 输入法配置

配置项 默认值 说明
STT_ENGINE auto STT 引擎(auto/funasr/whisper,auto 优先 funasr)
STT_MODEL paraformer-zh STT 模型(FunASR: paraformer-zh / Whisper: tiny/base/small/medium)
STT_LANGUAGE zh 语音识别语言
STT_DEVICE auto 推理设备(auto/cpu/cuda)
STT_COMPUTE_TYPE int8 计算精度
STT_DIALECT mandarin 方言(mandarin/cantonese/sichuan/shanghai/minnan/hakka,可用 CLI /dialect 切换)
STT_STREAMING_ENABLED false 实时转写开关(录音过程中显示中间识别结果)
STT_STREAMING_INTERVAL 1.5 实时转写轮询间隔(秒)
VOICE_HOTKEY ctrl+alt+v 语音输入快捷键
QUICK_HOTKEY ctrl+alt+q 快速唤起快捷键
PET_SIZE 64 桌宠尺寸
SILENCE_DURATION 2.0 静默停止秒数

使用方法

语音输入 + 人格补正

  1. 在任意应用文本框中聚焦光标
  2. 按住 Ctrl+Alt+V 开始录音(桌宠变为聆听状态)
  3. 说话,说完后松开 Ctrl+Alt+V
  4. 候选栏立即弹出,显示:
    • 原话:语音识别原文
    • 人格补正:猫娘语气补正(流式打字机效果逐步显示)
  5. 点击候选 或按 数字键 1-2 选择
  6. 选中文本自动填入当前输入框
  7. Esc 取消

意见反馈(对补正不满意时)

  1. 候选栏可见时,再按 Ctrl+Alt+V 进入意见反馈模式
  2. 说出你的意见(如"别加那么多喵"、"查一下今天天气"等)
  3. 候选栏清除除原话外的候选,显示你的意见
  4. Agent 根据意见重新生成补正:
    • 风格意见(如"正式一点")→ 直接调整补正风格
    • 操作意见(如"查一下天气")→ OpenHuman Agent 执行操作,结果融入补正
  5. 新的补正流式显示,选择即可填入

快速唤起模式

  1. Ctrl+Alt+Q
  2. 弹出输入对话框,手动输入文本
  3. 后续流程同语音输入(原话 + 人格补正)

CLI 终端模式

  1. 双击桌宠 打开 CLI 终端
  2. 首次打开时显示连接状态:
    • 已接入 OpenHuman Agent (v0.57.x),可直接对话与执行操作。 — Agent 模式
    • OpenHuman 未连接,使用纯 LLM 对话模式。 — 回退模式
  3. 输入文本并回车,与 Agent 对话:
    • OpenHuman 已连接: 消息直接发送给 OpenHuman Agent,支持工具调用(查阅数据、搜索、文件操作等)
    • OpenHuman 未连接: 回退到纯 LLM 对话
  4. 流式输出:Agent 的思考过程、工具调用、返回结果实时显示在终端中:
    • 思考: ... — 主 Agent 思考增量累积显示(不刷屏)
    • [agent_id#iteration] 思考: ... — 子 Agent 思考增量按迭代分组累积
    • 调用工具: 工具名(参数) — 每次工具调用追加新行
    • 工具返回: 结果摘要 — 工具返回结果追加新行
    • 等待审批: 工具名(已自动批准) — 工具审批状态
    • 完成:最终回复 — Agent 完成后的最终回复
  5. 点击 "填入" 按钮将回复注入当前焦点窗口

CLI 终端使用独立的对话线程(cli_<session_id>),与语音输入的对话线程隔离,互不干扰。

CLI 命令速查

在 CLI 终端中输入 / 开头的命令管理系统配置:

命令 说明
/help 显示所有可用命令
/privacy [on|off|status] 隐私模式开关(启用后不写入 memory 和信号日志)
/dialect <方言> 切换 STT 方言(mandarin/cantonese/sichuan/shanghai/minnan/hakka)
/llm list 列出所有 LLM provider 预设
/llm switch <provider> 切换 LLM provider(自动设置 base_url 和 model)
/persona list 列出所有人格(预设 + 自定义)
/persona <名称> 切换到指定人格
/persona market search <关键词> 搜索 EvoMap Hub 人格市场
/persona market upload 上传当前人格到 Hub 共享
/persona market install <asset_id> 从 Hub 下载并安装人格
/export [json|markdown] [all|memory|signals|genes] 导出数据到 data/memory/exports/
/history 打开历史记录面板(对话/信号/进化产物三标签页)

桌宠头顶处理项(后台任务可视化)

当 OpenHuman 唤起处理时,用户无需等待,可将任务派发到后台:

  1. OpenHuman 唤起:意见反馈需要执行操作时,人格补正行的 ✓ 自动变为 →
  2. 点击 → 派发:候选栏关闭,桌宠头顶出现处理项卡片(转圈动画 + 任务摘要)
  3. 后台处理:OpenHuman 在后台继续执行,用户可继续其他输入
  4. 完成通知:处理完成后转圈变为 ✓,点击 ✓ 恢复候选框显示结果
  5. 并发叠加:支持多个后台处理项同时存在,在桌宠头顶向上叠加

处理项跟随桌宠位置移动,拖拽桌宠时处理项自动跟随。

自定义人格

通过右键桌宠菜单管理人格,无需修改配置文件:

  1. 右键桌宠 → 显示人格切换菜单
  2. 预设人格:猫娘、商务助手
  3. 添加自定义人格 → 填写对话框:
    • 人格 ID(英文唯一标识,如 pirateloli
    • 显示名称(如 海盗萝莉
    • 风格提示(描述语气风格,如 说话像海盗,自称"本船长"
  4. 删除自定义人格 → 从子菜单选择删除
  5. 自定义人格持久化到 ~/.inputmethod/personas.json,重启不丢失
  6. 自定义人格的桌宠资产回退到猫娘样式

桌宠交互

  • 拖拽:按住桌宠拖动到任意位置
  • 双击:打开/关闭 CLI 终端
  • 状态:待机 / 聆听 / 思考 / 离线

系统托盘

  • 右键托盘图标:显示桌宠 / 隐藏桌宠 / 退出

架构

inputM/
├── inputmethod/              # 输入法主包
│   ├── app.py                # 主应用入口(事件循环 + CLI 命令分发 + 流式转写集成)
│   ├── config.py             # 配置加载(LLM provider 预设 + 隐私模式 + 方言)
│   ├── agent/                # AI 候选生成
│   │   ├── candidates.py     # 候选生成器(人格补正 + OpenHuman 接入)
│   │   ├── ops.py            # Agent 操作
│   │   ├── tools.py          # LLM 工具定义(get_current_date)
│   │   ├── context_sensing.py # 场景感知(前台窗口检测 + 7 类应用规则)
│   │   └── evomap_hub.py     # EvoMap Hub 客户端(资产查询 + 人格市场)
│   ├── stt/                  # 语音识别
│   │   ├── engine.py         # STT 引擎(FunASR/Whisper + 流式接口 + 6 方言)
│   │   └── capture.py        # 麦克风音频捕获(含 buffer snapshot 支持实时转写)
│   ├── ui/                   # 桌面 UI
│   │   ├── pet.py            # 桌宠悬浮窗(含右键人格菜单、自定义人格管理)
│   │   ├── candidate_bar.py  # 候选栏(支持流式追加/打字机/✓→→动态切换)
│   │   ├── cli_terminal.py   # CLI 终端(含流式进度更新 + CLI 命令分发)
│   │   ├── task_overlay.py   # 桌宠头顶处理项叠加层(后台任务可视化)
│   │   ├── history_panel.py  # 历史记录面板(三标签页:对话/信号/进化产物)
│   │   └── tray.py           # 系统托盘
│   ├── tools/                # 维护工具
│   │   └── data_exporter.py  # 数据导出(JSON/Markdown 双格式)
│   ├── input/                # 文本注入
│   │   └── injector.py       # 剪贴板+模拟粘贴
│   └── hotkey/               # 全局快捷键
│       └── manager.py        # Windows API 快捷键管理器
├── evomap/                   # 核心服务模块
│   ├── adapters/             # 适配器
│   │   ├── llm_adapter.py    # LLM 适配器(OpenAI 兼容,含流式)
│   │   ├── file_memory.py    # 文件记忆系统(含会话 ID 校验)
│   │   ├── openhuman_adapter.py  # OpenHuman JSON-RPC 客户端(含 SSRF 防护 + SSE 流式)
│   │   └── evolver_adapter.py    # Evolver 进化引擎适配器(含子进程管理)
│   ├── evolution/            # 自进化模块
│   │   ├── manager.py        # 进化管理器(轮询+消费循环)
│   │   └── consumer.py       # 进化产物消费者(应用到 OpenHuman)
│   └── pipeline/             # 管道
│       ├── agent.py          # LLM 推理管道
│       ├── context.py        # 上下文增强管道
│       ├── memory.py         # 记忆存储管道(含隐私模式跳过)
│       ├── signal_logger.py  # 用户行为信号记录(含隐私模式跳过)
│       └── route_evolver.py  # 路由进化器(误判检测 + 关键词进化)
├── openhuman/                # OpenHuman Core 源码(Rust,可编译为 openhuman-core.exe)
│   ├── src/                  # Rust 源码
│   ├── Cargo.toml            # Rust 依赖声明
│   └── rust-toolchain.toml   # Rust 工具链版本
├── tests/                    # pytest 测试套件(137 个用例)
├── config/                   # 配置文件
│   ├── .env                  # 主配置(LLM/OpenHuman/Evolver/STT/隐私模式)
│   ├── .env.example          # 配置模板(不含密钥,含所有 provider 示例)
│   └── inputmethod.env       # 输入法配置
├── data/                     # 运行时数据
│   ├── memory/               # 对话记忆 + 信号 + 进化产物 + 导出
│   └── skills/               # Evolver 生成的技能文件
├── assets/pet/               # 桌宠素材
├── start.py                  # 启动脚本
├── pyproject.toml            # 依赖声明(含 dev 测试依赖 + pytest 配置)
└── README.md                 # 本文件

数据流

语音输入: Ctrl+Alt+V → 录音 → FunASR/Whisper STT → 候选栏显示原话
  → [实时转写] 录音中定时 recognize_partial 显示中间结果
  → [场景感知] 检测前台窗口,注入 LLM prompt
  → LLM 流式生成人格补正(打字机效果)→ 存入 memory(隐私模式下跳过)

意见反馈: 候选栏可见时 Ctrl+Alt+V → 录音 → STT 识别意见
  → 清除其他候选 → 显示意见
  → LLM 判断是否需要执行操作
    → 需要: OpenHuman Agent 执行操作 → ✓ 变为 → → 点击 → 派发后台 → 桌宠头顶处理项
    → 不需要: 直接根据意见调整补正
  → LLM 流式生成新补正 → 存入 memory(隐私模式下跳过)

后台处理: 点击 → → 候选栏关闭 → 桌宠头顶处理项(转圈)
  → OpenHuman 后台执行 → CLI 实时显示思考/工具调用/返回
  → 完成后转圈变 ✓ → 点击 ✓ 恢复候选框 → 结果填入

自进化: Evolver 定期轮询 memory → 分析对话记录 → 生成进化基因
  → EvolutionConsumer 应用到 OpenHuman(更新 prompt/配置/技能)
  → RouteEvolver 分析路由日志 → 优化 LLM/OpenHuman 分流关键词

降级行为

缺失依赖 降级行为
LLM_API_KEY 未配置 桌宠显示离线状态,候选生成不可用
FunASR 回退到 Whisper STT(中文识别效果略差)
faster-whisper + FunASR 均未安装 语音输入不可用,快速唤起仍可使用
实时转写关闭(STT_STREAMING_ENABLED=false 录音过程中不显示中间结果,松开快捷键后一次性识别
隐私模式启用(/privacy on 不写入 memory 和信号日志,对话不留痕
OpenHuman 未运行 意见反馈中跳过 Agent 操作,仅做纯 LLM 补正,→ 按钮不出现
OpenHuman Token 未找到 同上(环境变量和 ~/.openhuman/core.token 均未设置时降级)
Evolver 未配置/Node.js 未安装 自进化静默降级,不影响其他功能
pyperclip/keyboard 文本注入不可用,候选仍可显示
PyQt6 无法启动(UI 核心依赖)

安全

SSRF 防护

OpenHuman Agent 通过 http_request 工具访问外部 URL 时,适配器层(openhuman_adapter.py)内置 SSRF 防护:

  • 协议白名单:仅允许 http/https,拒绝 file/ftp/javascript/data
  • IP 黑名单:禁止访问私有地址(10.x/172.16-31.x/192.168.x)、环回地址、链路本地、保留地址
  • IPv4-mapped IPv6 归一化:防止 ::ffff:127.0.0.1 等映射地址绕过
  • 载波级 NAT 拦截:拦截 100.64.0.0/10 段
  • DNS 解析校验:域名解析后校验所有 IP,防止域名绕过(如 evil.com → 127.0.0.1)
  • 云元数据黑名单:禁止 169.254.169.254metadata.google.internal 等云平台元数据地址

会话 ID 校验

文件记忆系统(file_memory.py)对所有会话 ID 做白名单校验(^[A-Za-z0-9_-]+$),防止路径遍历攻击。

子进程管理

  • Evolver 子进程启动前校验 index.js 存在性,防止路径注入
  • OpenHuman 子进程保存引用,支持优雅终止(SIGTERM → kill)
  • CREATE_NO_WINDOW 标志防止子进程弹出控制台窗口

其他

  • 自定义人格文件权限限制为 0600(POSIX)
  • 危险工具(shell/file_write)需审批,非危险工具自动批准
  • 隐私模式不写入 memory 和信号日志
  • config/inputmethod.env 已加入 .gitignore,防止敏感配置泄露

桌宠素材

将 GIF 动画文件放入 assets/pet/ 目录:

assets/pet/
├── idle.gif      # 待机动画
├── listening.gif # 聆听动画
├── thinking.gif  # 思考动画
└── offline.gif   # 离线动画

未提供 GIF 时,桌宠显示自绘 emoji 表情。

常见问题

Q: 启动后桌宠显示离线状态?

A: LLM API 未配置或不可用。检查 config/.env 中的 LLM_API_KEYLLM_BASE_URLLLM_MODEL

Q: 按快捷键没反应?

A: 快捷键使用 Windows API RegisterHotKey 注册。如果快捷键被其他程序占用,修改 config/inputmethod.env 中的 VOICE_HOTKEYQUICK_HOTKEY

Q: 语音识别很慢/首次卡住?

A: 首次使用时 STT 引擎需要下载模型:

  • FunASR(默认,STT_ENGINE=auto 优先):paraformer-zh 模型约 900MB,从 ModelScope 下载
  • Whisper(回退):base 模型约 150MB,从 HuggingFace 下载

如需更快速度:

  • FunASR:首次加载约 50 秒,后续从本地缓存加载(应用启动时自动后台预加载)
  • Whisper:将 STT_MODEL 改为 tiny
  • 启用实时转写(STT_STREAMING_ENABLED=true)可减少等待感,录音过程中显示中间结果

Q: 候选文本没有自动填入输入框?

A: 检查 pyperclipkeyboard 是否已安装。某些应用可能阻止模拟按键,可在 CLI 终端中使用"填入"按钮。

Q: 如何切换人格?

A: 右键桌宠 → 选择人格(猫娘/商务助手/自定义)。也可以通过右键菜单"添加自定义人格"创建新人格,填写 ID、名称和风格提示即可,无需改配置文件,即时生效。自定义人格持久化到 ~/.inputmethod/personas.json

Q: OpenHuman 连接失败?

A:

  1. 确认 OpenHuman 服务正在运行(openhuman-core.exe run 或桌面应用已启动)
  2. 检查 OPENHUMAN_BASE_URL 端口是否与 OpenHuman 启动端口一致(默认 6186)
  3. 检查 Token 是否可用:环境变量 OPENHUMAN_AUTH_TOKEN 优先;未设置则自动从 ~/.openhuman/core.token 读取
  4. 手动验证服务:Invoke-WebRequest http://127.0.0.1:6186/health -UseBasicParsing
  5. 查看启动日志是否有 OpenHuman 智能体已连接 信息

Q: CLI/语音意见调用 Agent 失败(超时 60s)?

A: Agent 调用失败通常有以下原因:

  1. SESSION_EXPIRED: backend session not active — 未设置 OPENHUMAN_AGENTBOX_MODE=1 环境变量。

    • 修复:重启 OpenHuman 时设置 $env:OPENHUMAN_AGENTBOX_MODE = "1"
  2. Agent 无 LLM 可用 — 未配置 LLM provider,或 workload provider 格式错误。

    • 修复:执行 README 中"配置 LLM Provider"步骤
    • 关键:workload provider 必须用 custom:deepseek-ai/DeepSeek-V4-Flash 格式(slug:model), 不能用裸 slug 如 "openai"(会被 migrate 脚本清除)
    • 验证:查看 OpenHuman 日志是否有 [provider:custom] outbound chat/completions ->
  3. SSE 事件未收到 — adapter 通过 SSE /events 端点获取回复。

    • 验证:Invoke-WebRequest -Uri "http://127.0.0.1:6186/events?client_id=test" -Headers @{Authorization="Bearer $token"} -UseBasicParsing

Q: Agent 说"后端会话已过期,无法使用联网工具"?

A: 这是因为 web_search 等 managed 工具需要 OpenHuman 云后端 session,headless 模式下不可用。

解决方案

  1. 禁用 web_search(已默认禁用):config_update_search_settings 设置 engine = "disabled"
  2. 使用 http_request 替代:Agent 可用 http_request 工具直接访问网页(无需后端 session)
  3. 启用 Brave Search:注册 Brave Search API 免费版(2000 次/月), 然后执行:
    $body = @{ jsonrpc="2.0"; id=1; method="openhuman.config_update_search_settings";
        params=@{ engine="brave"; brave_api_key="your-brave-api-key" } } | ConvertTo-Json -Depth 3
    Invoke-WebRequest -Uri "http://127.0.0.1:6186/rpc" -Method POST -Body $body -Headers $headers -UseBasicParsing

Q: Agent 子 Agent(researcher/tools_agent)调用失败?

A: 子 Agent 使用 agentic_provider 配置。如果设为 openhuman(默认),会走 managed 后端导致 SESSION_EXPIRED。

  • 修复:确保 agentic_provider = "custom:deepseek-ai/DeepSeek-V4-Flash"slug:model 格式)
  • 验证:日志应显示 [subagent_runner] role=agentic ... resolved via workload factory model=deepseek-ai/DeepSeek-V4-Flash

Q: Evolver 自进化不工作?

A:

  1. 确认 Node.js 已安装(node --version
  2. 确认 EVOLVER_PATH 指向正确的 Evolver 目录(含 index.js
  3. 查看日志是否有 Evolver 自进化已启动已降级 信息
  4. Evolver 不可用时不影响其他功能,仅自进化暂停

Q: 记忆数据存在哪里?

A: 对话记忆以 JSON 文件存储在 data/memory/ 目录:

  • sessions/ — 当前会话对话历史
  • archives/ — 归档的旧对话

可以直接查看或备份这些文件。Evolver 会分析这些记录进行自进化。

Q: 如何修改快捷键?

A: 编辑 config/inputmethod.env 中的 VOICE_HOTKEYQUICK_HOTKEY。格式为 ctrl+alt+vctrl+shift+space 等。避免使用系统保留快捷键(如 ctrl+space)。

Q: 有哪些 CLI 命令可用?

A: 在 CLI 终端(双击桌宠打开)输入 /help 查看所有命令。常用命令:

命令 作用
/privacy on 启用隐私模式(不写入 memory 和信号日志)
/dialect cantonese 切换到粤语识别
/llm switch deepseek 切换 LLM provider
/persona market search 猫娘 搜索人格市场
/export markdown all 导出全部数据为 Markdown
/history 打开历史记录面板

许可证

本项目采用 AGPL-3.0 许可证。

  • openhuman/ 目录内的 OpenHuman Core 源码遵循其原始许可证(见 openhuman/LICENSE
  • 其余代码(inputmethod/evomap/tests/ 等)采用 AGPL-3.0

About

Input method with evomap and openhuman

Resources

Stars

Watchers

Forks

Releases

Packages

Contributors

Languages