前言

当 ChatGPT 掀起大语言模型浪潮时,很多人以为 AI 的终点就是对话机器人。但 2024-2025 年的行业走向告诉我们:真正的赛点在于 Agent(智能体)——能够自主规划、调用工具、记忆上下文、在多端运行的 AI 系统。

本文将围绕开源明星项目 Hermes Agent,从零开始,手把手带你搭建一套完整的、开源可用的 AI Agent 系统。全程干货,无充值入口,无废话营销

📢 郑重声明:本文不是软文,不是推广,不是"日赚百万"的套路。而是一份实打实的工程实践指南——从环境准备到 Docker 部署,从向量数据库选型到多端接入,从成本控制到可视化监控,涵盖你搭建一个生产级 AI Agent 需要知道的全部知识点。

在这里插入图片描述


一、Hermes Agent 是什么?深入解剖开源自治式AI智能体

1.1 从"会说话"到"会办事"的跨越

传统大语言模型(LLM)本质上是文本生成器——你输入 prompt,它输出文字。但真正的生产力场景需要的是:任务导向的自主行动者

举一个具体的例子:

  • 传统 LLM:你问"帮我查一下上海今天的天气,然后通知团队明天下午3点开会"
  • 它会回答:“好的,上海今天天气晴,气温22-28度。我无法帮你发通知,因为我没有执行能力。”
  • Hermes Agent:你下达同样的指令,它会:
    1. 调用天气 API 查询上海实时天气
    2. 查询你的日历,找到明天下午3点的时间段
    3. 向团队成员发送日历邀请
    4. 将天气信息整合进通知内容
    5. 返回完整的执行报告

这就是自治式 Agent 与传统对话机器人的本质区别:能规划、能行动、能记忆、能进化

1.2 Hermes Agent 的核心定位

Hermes Agent 是一个基于开源大语言模型(如 Qwen、DeepSeek、Llama 等)构建的自治式 AI 智能体框架。它的核心目标是:

让任何开发者都能以模块化、低成本的方式,搭建一个"能看、能搜、能记、能干、能在多端跑"的私人 AI 助手。

它不是另一个"套壳 GPT",而是一个完整的 Agent 基础设施——你可以在上面:

  • 接入任何兼容 OpenAI API 的 LLM(本地 or 云端)
  • 自由扩展工具链(写 Python 函数即可注册新工具)
  • 替换向量数据库(ChromaDB / Qdrant / Milvus / Pgvector 随意切换)
  • 接入任何消息渠道(微信 / Telegram / Slack / 飞书 / 企业微信)
  • 自定义记忆策略(短期对话 / 长期知识库 / 结构化偏好)
  • 监控所有关键指标(Token 消耗 / 响应延迟 / 工具调用 / 错误率)

1.3 核心特性一览

特性 说明 技术实现
多模型支持 OpenAI 兼容 API,可接入 Qwen/DeepSeek/Llama 等 LLM Router + Adapter Pattern
长期记忆 向量数据库持久化记忆,支持语义检索 ChromaDB / Qdrant / Milvus
全网搜索 Tavily、Brave Search、DuckDuckGo 等搜索集成 Multi-Provider Fallback
工具链 40+ 内置工具(代码执行、文件读写、API调用等) Toolformer + LangChain
自我进化 反思-规划-执行-学习(ReAct + Self-Refine) Self-Refinement Loop
多端接入 微信、Telegram、Slack、企业微信、飞书 Channel Router
可视化监控 Prometheus + Grafana / 内置 Dashboard OpenTelemetry
成本控制 Token 计费、预算上限、模型智能路由 Cost Calculator

1.4 完整技术架构图

┌──────────────────────────────────────────────────────────────────────┐
│                        Hermes Agent 完整技术架构                        │
├──────────────────────────────────────────────────────────────────────┤
│                                                                      │
│  ┌─────────────┐   ┌─────────────┐   ┌──────────────┐   ┌────────┐ │
│  │   WeChat    │   │  Telegram   │   │    Slack     │   │ 飞书   │ │
│  │  (企业微信)  │   │   Bot       │   │   Workspace  │   │ Webhook│ │
│  └──────┬──────┘   └──────┬──────┘   └──────┬───────┘   └───┬────┘ │
│         │                 │                  │              │      │
│         └─────────────────┼──────────────────┴──────────────┘      │
│                           ▼                                         │
│                 ┌─────────────────┐                                 │
│                 │  Channel Router │ ← 消息协议统一化/限流/鉴权       │
│                 └────────┬────────┘                                 │
│                          ▼                                          │
│              ┌───────────────────────┐                              │
│              │     Message Normalizer │  ← 文本/图片/语音/文件统一   │
│              └───────────┬───────────┘                              │
│                          ▼                                          │
│                  ┌───────────────┐                                  │
│                  │  Intent Parser │ ← 理解用户意图,决定是否需要     │
│                  └───────┬───────┘    Agent介入还是直接回复           │
│                          ▼                                          │
│              ┌───────────────────────┐                               │
│              │     Orchestrator       │  ← 任务编排/多步骤协同/异常处理│
│              └───────────┬───────────┘                               │
│                          │                                           │
│    ┌──────────────────────┼──────────────────────┐                    │
│    ▼                      ▼                      ▼                  │
│ ┌──────┐           ┌──────────┐           ┌──────────┐            │
│ │Planner│           │  Memory  │           │  Tools    │            │
│ │(ReAct)│           │ (VectorDB)│           │  Chain   │            │
│ │+ Self │           │          │           │          │            │
│ │Refine │           └──────────┘           └──────────┘            │
│ │Loop   │                  │                                        │
│ └──────┘                  ▼                                         │
│                  ┌────────────────┐                                  │
│                  │ Memory Router  │ ← 短期对话/长期记忆/偏好/知识库   │
│                  └────────┬───────┘                                  │
│                           ▼                                          │
│                  ┌────────────────┐                                  │
│                  │  Context Builder│  ← 自动压缩/摘要/上下文注入     │
│                  └────────┬───────┘                                  │
│                           ▼                                          │
│                  ┌─────────────────┐                                │
│                  │   LLM Router     │  ← 模型路由/负载均衡/成本控制   │
│                  └────────┬─────────┘                                │
│                           │                                          │
│         ┌─────────────────┼─────────────────┐                       │
│         ▼                 ▼                 ▼                      │
│   ┌──────────┐     ┌──────────┐     ┌──────────┐                   │
│   │ Observa- │     │  Cost    │     │ Security │                   │
│   │ bility   │     │  Control │     │  Gate    │                   │
│   │(Prometheus│     │(Budget/  │     │(输入过滤/│                   │
│   │ + Grafana)│     │Routing)  │     │ 越权防护)│                   │
│   └──────────┘     └──────────┘     └──────────┘                   │
│                                                                      │
│         ┌──────────────────────────────────────┐                   │
│         │         Supported LLM Backends        │                   │
│         │  OpenAI │ Anthropic │ DeepSeek │ Qwen │                   │
│         │  Llama  │ Groq     │ Ollama  │ Gemini│                   │
│         └──────────────────────────────────────┘                   │
└──────────────────────────────────────────────────────────────────────┘

1.5 Hermes Agent vs 同类开源项目对比

项目 语言 记忆 工具 多端 自我进化 维护活跃度
Hermes Agent Python 完整向量DB方案 40+ 6+ ✅ ReAct+Self-Refine
LangChain Python/JS 有限 丰富
AutoGPT Python 丰富 ✅ 反思
CrewAI Python 中等
Dify.AI Python 部分 丰富 6+ ⚠️ 部分
Coze 云服务 丰富 丰富 极高(商业)

二、毛坯 vs 满配:你的 Agent 要什么档位?

2.1 需求评估矩阵

在动手之前,先评估一下你的真实需求。不同档位的功能差异和成本差异都很大:

档位 适合人群 核心组件 月均成本 部署时间
毛坯版 尝鲜/本地调试 Hermes CLI + 本地模型 ¥0 15分钟
基础版 个人助手日常使用 CLI + 搜索 + 简单记忆 ¥30-80 30分钟
专业版 开发者/小团队 全工具链 + 多模型路由 + ChromaDB ¥200-500 1-2小时
满配版 企业级/高并发 多端 + 监控 + 微调 + Qdrant + 分布式 ¥1000+ 3-6小时

2.2 各档位功能对比

毛坯版:    [基础CLI] → 直接对话,无记忆,无工具
基础版:    [CLI] + [搜索] + [短期记忆] → 日常问答够用
专业版:    [CLI] + [搜索] + [向量记忆] + [40+工具] + [多模型] → 完整Agent体验
满配版:    [专业版] + [多端接入] + [监控] + [成本管控] + [高可用] → 企业级生产系统

建议:如果是第一次接触,从毛坯版起步,逐步升级到基础版。切忌上来就搞满配——复杂度和收益不一定成正比。


三、8大阶段搭建完整 Agent 系统


阶段1:基础CLI安装——所有平台的完整指南

3.1.1 环境要求详解

在安装之前,确认你的环境满足以下要求:

组件 最低要求 推荐配置 备注
Python 3.10 3.11-3.12 推荐使用 uv 管理 Python 版本
Node.js 18+ 20 LTS 仅用于 Web UI,不需要可不装
RAM 8GB 16GB+ 纯 API 模式 4GB 即可
磁盘 5GB 20GB+ 含 Docker 镜像和向量数据库数据
网络 能访问 LLM API 科学上网 国内需配置镜像或使用国内模型
3.1.2 macOS 安装(Homebrew + uv)
# 方式一:Homebrew(推荐 macOS 用户)
brew tap hermes-agent/tap
brew install hermes-agent

# 方式二:uv(最快,全平台通用)
# 安装 uv
curl -LsSf https://astral.sh/uv/install.sh | sh

# 用 uv 安装 hermes-agent
uv pip install hermes-agent --system

# 验证安装
hermes --version
# 预期输出: hermes-agent x.x.x

# 如果提示 command not found,手动添加到 PATH
echo 'export PATH="$HOME/.local/bin:$PATH"' >> ~/.zshrc
source ~/.zshrc
3.1.3 Linux 安装
# Ubuntu / Debian
sudo apt update
sudo apt install python3.11-venv python3-pip git curl

# 安装 uv
curl -LsSf https://astral.sh/uv/install.sh | sh
source ~/.bashrc  # 或 ~/.zshrc

# 安装 hermes-agent
uv pip install hermes-agent --system

# 验证
hermes --version
# CentOS / RHEL / Fedora
sudo dnf install python3 python3-pip git curl

curl -LsSf https://astral.sh/uv/install.sh | sh
source ~/.bashrc

uv pip install hermes-agent --system
hermes --version
3.1.4 Windows 安装(PowerShell + winget)
# 方式一:winget(Windows 10 1903+ / Windows 11)
winget install hermes-agent.hermes

# 方式二:pipx 隔离安装
python -m pip install pipx
pipx install hermes-agent

# 方式三:直接 pip(不推荐污染全局环境)
pip install hermes-agent

# 验证
hermes --version

⚠️ Windows 特别提醒:强烈建议使用 WSL2(见下一节)进行开发,Windows 原生环境在 Docker 和某些 Python 包上有兼容性问题。

3.1.5 WSL2 安装——Windows 用户的最佳体验

WSL2(Windows Subsystem for Linux 2)让你在 Windows 中运行一个完整的 Linux 内核,性能损耗极低,体验接近原生 Linux。

# Step 1: 启用 WSL2(PowerShell 管理员模式)
wsl --install

# Step 2: 重启电脑,然后进入 WSL
wsl

# Step 3: 在 WSL 中安装依赖
sudo apt update && sudo apt upgrade -y
sudo apt install python3.11-venv python3-pip git curl build-essential

# Step 4: 安装 uv
curl -LsSf https://astral.sh/uv/install.sh | sh

# 自动添加到 PATH
echo 'export PATH="$HOME/.local/bin:$PATH"' >> ~/.bashrc
source ~/.bashrc

# Step 5: 安装 hermes-agent
uv pip install hermes-agent --system

# Step 6: 安装 Docker Desktop(WSL2 集成)
# 下载:https://www.docker.com/products/docker-desktop/
# 安装时勾选 "Use WSL 2 instead of Hyper-V"

# Step 7: 验证 Docker 在 WSL2 中可用
docker --version
docker compose version

WSL2 访问 Windows 文件:你的 Windows 磁盘挂载在 /mnt/c/mnt/d 等位置。
推荐做法:在 WSL2 home 目录(~)工作,Windows 文件放在 /mnt/c/Projects 之类的位置。

3.1.6 Docker 一键部署(所有平台,推荐生产使用)

Docker 是最省心的方案——环境隔离、版本一致、卸载干净。

# docker-compose.yml
version: '3.8'

services:
  hermes:
    image: hermesai/agent:latest
    container_name: hermes-agent
    hostname: hermes-agent
    ports:
      - "8000:8000"    # REST API
      - "3000:3000"    # Web Dashboard
      - "8001:8001"    # WebSocket(多端接入)
    environment:
      # LLM 配置
      - LLM_PROVIDER=openai
      - LLM_API_KEY=${OPENAI_API_KEY}
      - LLM_BASE_URL=https://api.openai.com/v1
      - LLM_MODEL=gpt-4o-mini
      - LLM_TEMPERATURE=0.7
      - LLM_MAX_TOKENS=4096
      
      # 记忆配置
      - MEMORY_PROVIDER=chroma
      - CHROMA_HOST=chroma
      
      # 搜索配置
      - SEARCH_PROVIDER=tavily
      - TAVILY_API_KEY=${TAVILY_API_KEY}
      
      # 日志
      - LOG_LEVEL=INFO
      - LOG_FORMAT=json
      
      # 安全
      - ALLOW_UNSAFE_TOOLS=false
      - READ_ONLY_MODE=false
      
    volumes:
      - ./data:/app/data          # 持久化数据
      - ./config:/app/config      # 配置文件
      - ./tools:/app/tools        # 自定义工具
      - ./logs:/app/logs          # 日志文件
    depends_on:
      chroma:
        condition: service_healthy
    restart: unless-stopped
    healthcheck:
      test: ["CMD", "curl", "-f", "http://localhost:8000/health"]
      interval: 30s
      timeout: 10s
      retries: 3
      start_period: 40s

  chroma:
    image: chromadb/chroma:latest
    container_name: hermes-chroma
    hostname: hermes-chroma
    ports:
      - "8001:8000"
    volumes:
      - ./chroma_data:/chroma/chroma
    restart: unless-stopped
    healthcheck:
      test: ["CMD", "curl", "-f", "http://localhost:8000/api/v1/heartbeat"]
      interval: 30s
      timeout: 5s
      retries: 3

  # 可选:本地 Embedding 模型(节省 API 成本)
  # 如果使用 OpenAI Embedding,可跳过此服务
  nomic-embedding:
    image: ghcr.io/nomic-ai/nomic-embed-text-server:latest
    container_name: hermes-embedding
    hostname: hermes-embedding
    ports:
      - "8080:8080"
    restart: unless-stopped
    # 注意:Apple Silicon Mac 或 Linux ARM64 才推荐
    # platform: linux/amd64  # x86_64 平台强制用 amd64

networks:
  default:
    name: hermes-network
# 启动所有服务
docker compose up -d

# 查看服务状态
docker compose ps

# 查看日志(实时)
docker compose logs -f hermes

# 查看资源占用
docker stats

# 停止服务
docker compose down

# 完整重启(清除缓存)
docker compose down -v && docker compose up -d
3.1.7 基础配置文件详解
# config/basic.yaml —— 最小配置示例
# 位置: ~/.hermes/config.yaml 或项目目录/config/basic.yaml

agent:
  name: "Hermes"
  personality: "helpful_assistant"
  language: "zh-CN"          # 中文界面
  timezone: "Asia/Shanghai"
  system_prompt: |            # 自定义系统提示词
    你是一个专业、友好、高效的 AI 助手。
    - 回答简洁有力,避免冗长
    - 代码示例要带注释
    - 不确定时主动说明局限性

# LLM 配置(支持 OpenAI / Anthropic / DeepSeek / Ollama / Azure OpenAI 等)
llm:
  provider: "openai"                    # openai / anthropic / ollama / deepseek / azure
  api_key: "${OPENAI_API_KEY}"          # 从环境变量读取(安全)
  base_url: "https://api.openai.com/v1" # API 代理地址(可选)
  model: "gpt-4o-mini"                  # 主模型
  # model: "deepseek-chat"              # 国产替代,便宜好用
  # model: "qwen-plus"                  # 阿里通义千问
  
  # 推理参数
  temperature: 0.7                       # 0=确定性强,1=创意性强
  max_tokens: 4096                       # 单次最大输出
  top_p: 0.9
  frequency_penalty: 0.0
  presence_penalty: 0.0
  timeout: 60                            # 请求超时(秒)

# 记忆配置
memory:
  enabled: true
  type: "chroma"                         # chroma / qdrant / milvus / pgvector / memory
  persist_path: "./data/memory"          # 本地存储路径
  
  # Embedding 配置(向量化模型)
  embedding:
    provider: "ollama"                   # ollama / openai / azure
    # 使用 Ollama 本地模型(免费,推荐)
    model: "nomic-embed-text"
    base_url: "http://localhost:11434"
    # 使用 OpenAI(精准但收费)
    # provider: "openai"
    # model: "text-embedding-3-small"
    # api_key: "${OPENAI_API_KEY}"
    # 维度:text-embedding-3-small = 1536维

  # 检索策略
  retrieval:
    top_k: 5                              # 返回 Top 5 条记忆
    min_score: 0.5                        # 最低相似度阈值
    auto_archive_days: 90                 # 90天前的记忆自动归档

# 日志配置
logging:
  level: "INFO"                          # DEBUG / INFO / WARNING / ERROR
  file: "./data/logs/hermes.log"
  max_size_mb: 100
  backup_count: 5
  format: "%(asctime)s - %(name)s - %(levelname)s - %(message)s"
# 初始化项目结构
hermes init my-agent
cd my-agent

# 查看目录结构
tree .  # 或在 Windows: Get-ChildItem -Recurse

# 预期输出:
# my-agent/
# ├── config/
# │   └── basic.yaml
# ├── data/
# │   ├── memory/
# │   ├── logs/
# │   └── cache/
# ├── tools/                    # 自定义工具目录
# │   └── __init__.py
# ├── .env                      # 环境变量(API Keys)
# └── hermes.db                 # SQLite 元数据库

# 创建目录
mkdir -p config data/logs data/memory tools

# 复制基础配置
cp ~/.hermes/config.yaml config/basic.yaml

# 启动服务
hermes run --config config/basic.yaml

# 后台运行(Linux/macOS/WSL)
nohup hermes run --config config/basic.yaml > logs/hermes.log 2>&1 &
echo $! > .hermes.pid

# 测试安装
hermes chat "你好,请用三句话介绍你自己"

验证安装成功的标准输出

✅ Hermes Agent 启动成功
📌 REST API:    http://localhost:8000
📌 Web Dashboard: http://localhost:3000
📌 WebSocket:    ws://localhost:8001
📌 健康检查:     http://localhost:8000/health

阶段2:长期记忆——向量数据库深度集成

3.2.1 为什么 Agent 需要记忆?

没有记忆的 Agent,每次对话都是"金鱼记忆"——无法理解你的项目背景、代码风格、偏好习惯。向量数据库(Vector Database)让 Agent 具备了跨会话的语义记忆能力

具体来说,记忆系统解决了三个核心问题:

  1. 上下文长度限制:GPT-4o 的上下文窗口是 128K tokens,但塞太多历史对话会导致"大海捞针"(needle in haystack)问题,模型容易忽略关键信息。向量检索只召回最相关的记忆。
  2. 成本控制:每次对话塞入大量历史,Token 消耗是灾难级的。向量检索让你只花最少的钱获取最大收益。
  3. 知识积累:好的记忆系统能让 Agent 从每次交互中学习,越用越懂你。
3.2.2 向量数据库选型指南
数据库 部署难度 数据规模 性能 适用场景
ChromaDB ⭐ 零难度 <100万向量 ⭐⭐⭐⭐ 个人/小团队,首选
Qdrant ⭐⭐ Docker <10亿向量 ⭐⭐⭐⭐⭐ 中大规模生产环境
Milvus ⭐⭐⭐ 复杂 数十亿+ ⭐⭐⭐⭐⭐ 超大规模企业
Pgvector ⭐⭐ 需数据库 <1000万 ⭐⭐⭐ 已有 PostgreSQL
FAISS ⭐ 本地 取决于 RAM ⭐⭐⭐⭐⭐ 完全离线/嵌入式
Weaviate ⭐⭐ Docker <10亿 ⭐⭐⭐⭐ 语义搜索为主

新手指南

  • 个人用户 → ChromaDB(开箱即用,无需额外部署)
  • 有 Docker 基础 → Qdrant(性能更强,支持云端)
  • 企业用户 → MilvusPgvector(依托现有基础设施)
3.2.3 ChromaDB 完整配置(最简单方案)
# config/with-chroma.yaml
memory:
  enabled: true
  provider: "chroma"
  persist_directory: "./data/chroma_db"

  # 关键配置项
  collection:
    name: "hermes_memory"          # 集合名称(可按用途创建多个)
    metadata:
      description: "Hermes Agent 长期记忆"
    
    # 距离度量方式(决定相似度计算方式)
    distance_metric: "cosine"       # cosine=余弦相似度(最常用)
                                   # euclidean=欧氏距离(适合图片/特征向量)
                                   # manhattan=曼哈顿距离(小众场景)

  # Embedding 模型配置
  embedding:
    provider: "ollama"             # 推荐用本地模型,省 API 费用
    model: "nomic-embed-text"      # Ollama 支持最好的 Embedding 模型
    base_url: "http://localhost:11434"
    dimension: 768                 # nomic-embed-text 的维度
    
    # 如果用 OpenAI(需要 API Key)
    # provider: "openai"
    # model: "text-embedding-3-small"  # 1536维,便宜且效果好
    # # 或 text-embedding-3-large(3072维,效果更好但更贵)

  # 检索策略
  retrieval:
    top_k: 5                        # 每次召回 5 条记忆
    min_score: 0.6                  # 相似度低于 0.6 的不返回
    
    # 重排(Rerank)—— 显著提升准确率
    rerank:
      enabled: true
      model: "bge-reranker-base"  # BAAI/bge-reranker-base
      top_n: 3                     # 重排后取 Top 3
      
    # 自动摘要(防止记忆碎片化)
    auto_summary:
      enabled: true
      trigger_after_turns: 5       # 5轮对话后自动生成摘要
      summary_model: "gpt-4o-mini"  # 用小模型做摘要,省钱
      max_summary_length: 500      # 摘要最多 500 字

  # 记忆管理
  auto_archive:
    enabled: true
    max_age_days: 90               # 90天前的记忆自动归档
    max_total_memories: 10000       # 最多保留 10000 条记忆
    summary_before_archive: true    # 归档前生成摘要

  # 分类标签系统
  tags:
    enabled: true
    auto_tag: true                 # 自动从内容中提取标签
    allowed_tags:
      - "project"                  # 项目相关
      - "preference"               # 用户偏好
      - "coding"                   # 代码相关
      - "decision"                # 重要决策
      - "error"                    # 错误记录
# 启动 Ollama 服务(用于本地 Embedding)
ollama serve

# 下载 nomic-embed-text 模型(~274MB)
ollama pull nomic-embed-text

# 如果遇到网络问题,使用镜像
OLLAMA_HOST=https://ollama.cloudmirror.dev ollama pull nomic-embed-text

# 验证 Ollama 运行
curl http://localhost:11434/api/tags
3.2.4 Qdrant 配置(推荐生产环境)

Qdrant 是目前最流行的开源向量数据库,性能优秀,API 友好,支持云端托管。

# config/with-qdrant.yaml
memory:
  enabled: true
  provider: "qdrant"

  qdrant:
    # 本地开发
    host: "localhost"
    port: 6333
    grpc_port: 6334
    
    # 生产环境(云端托管)
    # host: "your-qdrant-cloud..cloud"
    # port: 6333
    # use_ssl: true
    # api_key: "${QDRANT_API_KEY}"
    
    collection:
      name: "hermes_memory_v2"
      vector_size: 1536           # OpenAI text-embedding-3-small = 1536维
      distance: "Cosine"          # Cosine / Euclid / Dot
      
      # HNSW 索引参数(HNSW 是 Qdrant 的核心索引算法)
      hnsw:
        m: 16                      # 连接数,越大精度越高但内存越大
        ef_construct: 128         # 构建时搜索深度
        full_scan_threshold: 10000 # 超过此数量的向量启用 HNSW

  embedding:
    provider: "openai"
    model: "text-embedding-3-small"
    api_key: "${OPENAI_API_KEY}"

  retrieval:
    top_k: 5
    score_threshold: 0.75          # Qdrant 用分数,0.75 ≈ Chroma 的 0.6
    quantization:
      enabled: true
      type: "int8"               # int8 量化,内存减半,精度损失 <2%

  # 多租户支持(企业版功能)
  multi_tenant:
    enabled: false
    tenant_id_field: "user_id"
# 启动 Qdrant(Docker)
docker run -d \
  --name qdrant \
  -p 6333:6333 \
  -p 6334:6334 \
  -v $(pwd)/qdrant_storage:/qdrant/storage \
  qdrant/qdrant

# 验证
curl http://localhost:6333/collections

# 预期输出:
# {"result":{"collections":[...],"... }
3.2.5 记忆系统 API 编程实战
# examples/memory_system.py
# 完整的记忆系统使用示例

from hermes_agent import HermesAgent
from hermes_agent.memory import MemoryStore
from hermes_agent.memory.filters import FilterBuilder
from datetime import datetime

# 初始化 Agent 和记忆存储
agent = HermesAgent(config="config/with-memory.yaml")
memory = MemoryStore(config="config/with-memory.yaml")


async def demo_automatic_memory():
    """
    方式一:自动记忆(最简单)
    Agent 在处理对话时自动将关键信息存入记忆
    """
    print("=== 自动记忆演示 ===")
    
    # 告诉 Agent 一些关键信息
    await agent.chat(
        "我正在开发一个电商推荐系统,使用 FastAPI + PostgreSQL + Redis",
        memory=True,                 # 开启自动记忆
        tags=["project", "fastapi"]   # 添加标签
    )
    
    await agent.chat(
        "我更喜欢使用类型提示(type hints),并且用 pydantic 做数据验证",
        memory=True,
        tags=["preference", "coding"]
    )
    
    await agent.chat(
        "生产环境的数据库连接池大小设为 20",
        memory=True,
        tags=["config", "production"]
    )
    
    print("✅ 记忆已自动存入")


async def demo_manual_memory():
    """
    方式二:手动精确写入记忆
    适合批量导入已有知识库
    """
    print("=== 手动记忆写入 ===")
    
    # 写入项目文档知识
    docs = [
        {
            "text": "本项目使用 FastAPI 构建 REST API,遵循 OpenAPI 3.0 规范",
            "metadata": {"type": "architecture", "source": "readme"},
            "tags": ["project", "fastapi"]
        },
        {
            "text": "数据库表结构:users(用户)、products(商品)、orders(订单)、reviews(评价)",
            "metadata": {"type": "database_schema", "source": "er_diagram"},
            "tags": ["database", "schema"]
        },
        {
            "text": "认证方案:JWT Token,有效期7天,支持 Refresh Token 续期",
            "metadata": {"type": "auth", "source": "design_doc"},
            "tags": ["auth", "security"]
        },
        {
            "text": "推荐算法:协同过滤 + 内容过滤混合方案,A/B测试验证效果",
            "metadata": {"type": "algorithm", "priority": "high"},
            "tags": ["ml", "recommendation"]
        }
    ]
    
    for doc in docs:
        await memory.add(
            text=doc["text"],
            metadata=doc["metadata"],
            tags=doc.get("tags", [])
        )
    
    print(f"✅ 写入 {len(docs)} 条记忆")


async def demo_semantic_search():
    """
    方式三:语义搜索记忆
    用自然语言搜索最相关的记忆
    """
    print("=== 语义搜索演示 ===")
    
    # 搜索与"认证"相关的内容
    results = await memory.search(
        query="JWT 认证 Token 怎么实现的",
        top_k=5,
        filters={
            "tags": {"$contains": "auth"},  # 只搜索 auth 标签
            "metadata.type": {"$in": ["auth", "architecture"]}
        },
        include_scores=True,
        include_metadata=True
    )
    
    print(f"找到 {len(results)} 条相关记忆:")
    for r in results:
        print(f"\n  📌 相似度: {r['score']:.4f}")
        print(f"  内容: {r['text']}")
        print(f"  标签: {r.get('tags', [])}")
        print(f"  来源: {r.get('metadata', {}).get('source', 'unknown')}")


async def demo_contextual_chat():
    """
    方式四:基于记忆的上下文对话
    让 Agent "记得"之前的对话和知识
    """
    print("=== 上下文对话演示 ===")
    
    # 先搜索相关记忆
    relevant_memories = await memory.search(
        query="FastAPI PostgreSQL 电商项目",
        top_k=3,
        filters={"tags": {"$contains": "project"}}
    )
    
    # 构建上下文
    context = "\n".join([
        f"[记忆 {i+1}] {r['text']}" 
        for i, r in enumerate(relevant_memories)
    ])
    
    # 带着记忆回答
    response = await agent.chat(
        f"基于以下背景信息回答:\n{context}\n\n"
        f"问题:我想要给商品添加评论功能,请给我实现方案"
    )
    
    print(f"Agent 回答:\n{response}")


async def demo_memory_statistics():
    """
    查看记忆统计
    """
    print("=== 记忆统计 ===")
    
    stats = await memory.get_statistics()
    print(f"总记忆条数: {stats['total_memories']}")
    print(f"总 Token 数(估算): {stats['total_tokens']:,}")
    print(f"各标签统计: {stats['tags']}")
    print(f"各类型统计: {stats['types']}")
    
    # 最近添加的记忆
    recent = await memory.get_recent(limit=5)
    print("\n最近5条记忆:")
    for r in recent:
        print(f"  - {r['text'][:50]}...")


async def demo_memory_cleanup():
    """
    记忆清理与归档
    """
    print("=== 记忆清理 ===")
    
    # 删除特定记忆
    deleted = await memory.delete(
        filters={"tags": {"$contains": "test"}}
    )
    print(f"删除了 {deleted} 条测试相关记忆")
    
    # 归档旧记忆
    archived = await memory.archive_older_than(days=30)
    print(f"归档了 {archived} 条30天前记忆")
    
    # 导出记忆
    exported = await memory.export(
        format="json",
        path="./data/memory_backup.json",
        filters={"tags": {"$contains": "project"}}
    )
    print(f"导出了 {exported} 条项目相关记忆")


async def main():
    await demo_automatic_memory()
    await demo_manual_memory()
    await demo_semantic_search()
    await demo_contextual_chat()
    await demo_memory_statistics()
    await demo_memory_cleanup()

import asyncio
asyncio.run(main())
# 命令行记忆管理
hermes memory stats              # 查看统计
hermes memory search "FastAPI"  # 搜索
hermes memory list --limit 20   # 列出最近20条
hermes memory export --format json --output ./backup.json
hermes memory import ./backup.json
hermes memory prune --older-than 90d  # 清理90天前记忆
hermes memory clear              # 危险:清空所有记忆

阶段3:全网搜索能力——让 Agent 知道"今天"发生了什么

3.3.1 搜索为什么不可或缺?

大语言模型的训练数据有截止日期(Knowledge Cutoff)。GPT-4o 的知识截止到 2024 年 6 月,DeepSeek V3 是 2024 年 6 月。用昨天的模型回答今天的问题,是 Agent 的硬伤。

搜索集成解决了这个问题——当用户问实时性问题时,Agent 自动调用搜索 API 获取最新信息。

3.3.2 搜索提供商对比与选型
提供商 免费额度 搜索质量 延迟 适合场景
DuckDuckGo 无限 ⭐⭐⭐ 较高 兜底方案,免费首选
Tavily 1000次/月 ⭐⭐⭐⭐⭐ 专业搜索,质量最佳
Brave Search 2000次/月 ⭐⭐⭐⭐ 综合搜索,有图预览
SerpAPI 100次/月 ⭐⭐⭐⭐ Google 搜索结果
Google Serper 500次/月 ⭐⭐⭐⭐ Google 搜索
Exa 100次/月 ⭐⭐⭐⭐⭐ 学术/技术文档

推荐组合:Tavily(主力)+ DuckDuckGo(免费兜底)+ Brave(图片搜索)

3.3.3 搜索配置完整示例
# config/with-search.yaml
search:
  enabled: true
  
  # 默认提供商
  default_provider: "tavily"
  
  # 主提供商:Tavily(精度最高)
  providers:
    tavily:
      api_key: "${TAVILY_API_KEY}"
      max_results: 8              # 最多返回 8 条结果
      search_depth: "advanced"    # basic / advanced(advanced 更慢但更准)
      include_answer: true        # 自动生成答案摘要
      include_images: false       # 图片会占用 Token
      include_raw_content: false  # 原始内容(慎用,占 Token)
      timeout: 15
      
    # 免费兜底:DuckDuckGo
    duckduckgo:
      enabled: true
      max_results: 5
      safe_search: "moderate"     # off / moderate / strict
      
    # 备选:Brave Search
    brave:
      enabled: false
      api_key: "${BRAVE_API_KEY}"
      max_results: 5
      safesearch: "moderate"
      
    # SerpAPI(Google 搜索)
    serpapi:
      enabled: false
      api_key: "${SERPAPI_API_KEY}"
      engine: "google"
      num_results: 10

  # 智能触发规则(Agent 自动判断何时搜索)
  auto_trigger:
    enabled: true
    
    # 关键词触发(出现这些词就搜)
    trigger_keywords:
      - "最新"
      - "今天"
      - "现在"
      - "近期"
      - "新闻"
      - "股价"
      - "天气"
      - "多少"
      - "什么时候"
      - "2024"
      - "2025"
      
    # 正则模式触发(更灵活)
    trigger_patterns:
      - '\d{4}年\d{1,2}月'
      - '.*股价.*'
      - '.*天气.*'
      - '.*最新.*'
      - '.*现在.*'
      - '.*今日.*'
      
    # 排除规则(某些场景不触发搜索)
    exclude_patterns:
      - '.*的历史.*'
      - '.*的概念.*'
      - '.*原理.*'

  # 搜索结果处理
  processing:
    # 自动去重和清洗
    dedup: true
    max_age_hours: 48            # 只用48小时内的结果
    
    # 答案生成
    answer_generation:
      enabled: true
      model: "gpt-4o-mini"        # 用小模型生成答案摘要
      max_sources: 3              # 最多引用 3 个来源
      
    # 内容截断(避免超长网页)
    content_truncation:
      max_chars: 3000             # 每条结果最多 3000 字符
      priority: "head"            # head=开头 / tail=结尾 / middle=中间
      
  # 成本控制
  rate_limiting:
    per_user_per_minute: 10      # 每用户每分钟最多10次搜索
    global_per_hour: 500         # 全局每小时限制
3.3.4 搜索 API 编程实战
# examples/search_demo.py
from hermes_agent import HermesAgent

agent = HermesAgent(config="config/with-search.yaml")


async def demo_auto_search():
    """
    自动搜索:Agent 自动判断何时搜索
    """
    print("=== 自动搜索演示 ===")
    
    # Agent 自动识别需要搜索
    response = await agent.chat(
        "2025年第二季度中国AI市场规模是多少?"
    )
    # Agent 推理链:
    # 1. 检测到"2025年"→需要实时数据
    # 2. 调用 Tavily 搜索
    # 3. 整合搜索结果
    # 4. 生成回答(引用来源)
    
    print(response)


async def demo_manual_search():
    """
    手动搜索:强制触发搜索
    """
    print("=== 手动搜索演示 ===")
    
    response = await agent.chat(
        "帮我搜一下最近一周内关于 LLM 安全漏洞的重要新闻",
        force_search=True,
        search_depth="advanced",
        search_provider="tavily",
        max_results=10
    )
    print(response)


async def demo_search_with_memory():
    """
    搜索 + 记忆结合
    结合用户的项目背景,提供更精准的搜索结果
    """
    print("=== 搜索 + 记忆结合 ===")
    
    # 搜索相关记忆(用户的技术栈)
    from hermes_agent.memory import MemoryStore
    memory = MemoryStore(config="config/with-memory.yaml")
    
    context = await memory.search(
        query="技术栈 FastAPI PostgreSQL",
        top_k=2
    )
    
    context_str = "\n".join([r['text'] for r in context])
    
    # 结合背景搜索
    response = await agent.chat(
        f"背景信息:\n{context_str}\n\n"
        f"问题:帮我找一下 FastAPI + PostgreSQL 部署的最佳实践,需要包含 2025 年的最新方案"
    )
    print(response)


async def demo_search_code():
    """
    搜索代码示例
    """
    print("=== 搜索代码示例 ===")
    
    response = await agent.chat(
        "帮我找一段 FastAPI + SQLAlchemy 异步操作 PostgreSQL 的完整示例代码,"
        "需要包含连接池配置、事务处理和错误重试"
    )
    print(response)


async def demo_compare_search():
    """
    多源搜索对比
    用不同搜索引擎搜同一个问题,看结果差异
    """
    print("=== 多源搜索对比 ===")
    
    question = "2025年最值得学习的AI框架"
    
    # Tavily
    result_tavily = await agent.search(
        query=question,
        provider="tavily",
        max_results=3
    )
    print(f"Tavily 结果: {len(result_tavily)} 条")
    
    # DuckDuckGo
    result_ddg = await agent.search(
        query=question,
        provider="duckduckgo",
        max_results=3
    )
    print(f"DuckDuckGo 结果: {len(result_ddg)} 条")


import asyncio
asyncio.run(demo_auto_search())
# 命令行搜索测试
hermes search "2025年AI Agent发展趋势"
hermes search "FastAPI最佳实践" --provider tavily --max-results 5

阶段4:40+工具链集成——让 Agent 真正能"干活"

3.4.1 工具系统架构

Hermes Agent 的工具系统是整个框架最强大的部分。它基于 LangChain Tools + 自定义 Toolformer 实现:

用户请求
    │
    ▼
┌────────────────────────┐
│   Intent Detection     │  ← 判断是否需要调用工具
└────────────┬───────────┘
             │ 需要工具
             ▼
┌────────────────────────┐
│   Tool Selection        │  ← 从40+工具中选择最合适的
│   (LLM 驱动的选择)      │
└────────────┬───────────┘
             │ 选择工具 N
             ▼
┌────────────────────────┐
│   Parameter Extraction │  ← LLM 提取参数
└────────────┬───────────┘
             │
    ┌────────┴────────┐
    ▼                 ▼
┌─────────┐    ┌─────────┐
│ Tool A  │    │ Tool B  │
│ Execute │    │ Execute │
└────┬────┘    └────┬────┘
     │              │
     └──────┬───────┘
            ▼
┌────────────────────────┐
│   Result Integration   │  ← 整合结果,生成最终回答
└────────────────────────┘
3.4.2 工具分类速查表
类别 工具数量 代表工具 安全性
代码执行 8+ Python REPL, Bash, Git, 代码解释器 ⚠️ 需配置白名单
文件操作 6+ 读写、搜索、比较、压缩 ⚠️ 需配置路径限制
Web 操作 5+ 抓取、下载、提交表单、API 请求 ✅ 安全
数据处理 7+ JSON/YAML/CSV处理、统计分析 ✅ 安全
API 调用 5+ HTTP 请求、REST/GraphQL ⚠️ 需配置域名白名单
开发辅助 6+ 数据库查询、Redis、消息队列 ⚠️ 需配置连接白名单
系统操作 4+ 定时任务、系统命令、通知推送 ⚠️ 高危,需谨慎
信息获取 5+ 搜索、地图、天气、新闻 ✅ 安全
3.4.3 完整工具配置
# config/with-tools.yaml
tools:
  enabled: true
  
  # 执行控制
  execution:
    allow_unsafe: false           # ⚠️ 生产环境务必 false
    timeout_seconds: 30           # 单次工具调用超时
    max_output_chars: 10000       # 输出截断上限
    max_iterations: 10            # Agent 最大迭代次数(防死循环)
    
  # Python 代码执行器(沙箱环境)
  python_executor:
    enabled: true
    sandbox: true                 # 沙箱隔离
    pip_packages:                 # 允许安装的包
      - "numpy"
      - "pandas"
      - "matplotlib"
      - "requests"
      - "beautifulsoup4"
      - "pyyaml"
    blocked_packages:              # 禁止使用的包
      - "os"
      - "sys"
      - "subprocess"
      - "socket"
      - "ctypes"
      - "threading"
      - "multiprocessing"
    max_memory_mb: 512            # 内存限制
    pre_install:                  # 预安装的包
      - "numpy==1.26.0"
      - "pandas==2.1.0"
    execution_timeout: 30

  # Bash 命令执行器
  bash_executor:
    enabled: true
    allowed_commands:              # 白名单命令
      - "git *"                  # git 所有子命令
      - "python *"               # python 相关
      - "node *"                 # node 相关
      - "npm *"                  # npm 相关
      - "pip *"                  # pip 相关
      - "curl *"                 # 网络请求
      - "docker *"               # Docker
      - "ls"
      - "cat"
      - "head"
      - "tail"
      - "grep"
      - "awk"
      - "sed"
    blocked_commands:             # 黑名单命令(优先级高于白名单)
      - "rm -rf /*"
      - "rm -rf /"
      - "sudo *"
      - "mkfs *"
      - ":(){ :|:& };:"          # Fork Bomb
      - "dd if=*"
      - "> /dev/sda"
      - "chmod -R 777"
    execution_timeout: 60

  # 文件操作工具
  file_tools:
    enabled: true
    allowed_paths:                # 只允许操作这些路径
      - "./workspace"
      - "./data"
      - "./projects"
      - "/tmp"
      - "~/Downloads"
    blocked_paths:                 # 禁止操作这些路径
      - "~/.ssh"
      - "~/.aws"
      - "~/.config"
      - "/etc"
      - "/var"
      - "/usr"
    max_file_size_mb: 50          # 单文件大小限制
    allowed_extensions:           # 允许的文件类型
      - ".py"
      - ".md"
      - ".txt"
      - ".json"
      - ".yaml"
      - ".yml"
      - ".csv"
      - ".log"
      - ".sh"
      - ".js"
      - ".ts"
    max_files_per_operation: 10   # 单次操作最多文件数

  # Web 工具
  web_tools:
    enabled: true
    fetch_timeout: 10             # 请求超时
    max_content_length: 1048576   # 1MB
    user_agent: "HermesAgent/1.0"
    allowed_protocols:            # 允许的协议
      - "http"
      - "https"
    max_redirects: 5

  # HTTP 请求工具
  http_tools:
    enabled: true
    allowed_domains:              # 只允许请求这些域名
      - "api.github.com"
      - "api.openweathermap.org"
      - "api.coingecko.com"
      - "api.exchangerate-api.com"
    blocked_domains:              # 禁止请求这些域名
      - "*.internal"
      - "localhost"
      - "127.0.0.1"
    timeout: 15
    max_response_size: 5242880    # 5MB

  # 数据库工具
  database_tools:
    enabled: true
    connections:
      postgres:
        host: "${DB_HOST}"
        port: 5432
        database: "${DB_NAME}"
        user: "${DB_USER}"
        password: "${DB_PASSWORD}"
        read_only: true           # 默认只读模式
        max_connections: 5
        
      mysql:
        host: "${MYSQL_HOST}"
        port: 3306
        database: "${MYSQL_DB}"
        user: "${MYSQL_USER}"
        password: "${MYSQL_PASSWORD}"
        read_only: true
        
      redis:
        enabled: false
        host: "${REDIS_HOST}"
        port: 6379
        password: "${REDIS_PASSWORD}"
        db: 0
        read_only: true
3.4.4 自定义工具开发

自定义工具是 Hermes Agent 最灵活的部分。只需写一个 Python 函数 + 装饰器,就能注册新工具:

# tools/weather_tools.py
from hermes_agent.tools import tool, ToolConfig
import httpx
import os
from typing import Literal

@tool(
    name="get_weather",
    description="查询指定城市的实时天气信息,包括温度、湿度、风速和天气预报。适用于出行规划或日常查询。",
    parameters={
        "type": "object",
        "properties": {
            "city": {
                "type": "string",
                "description": "城市名称(支持中文或英文城市名)",
                "examples": ["上海", "Beijing", "Tokyo"]
            },
            "unit": {
                "type": "string",
                "enum": ["celsius", "fahrenheit"],
                "default": "celsius",
                "description": "温度单位"
            },
            "forecast_days": {
                "type": "integer",
                "minimum": 1,
                "maximum": 7,
                "default": 1,
                "description": "预报天数(1-7天)"
            }
        },
        "required": ["city"]
    },
    tags=["weather", "information"],
    safe=True                     # 标记为安全工具(不涉及文件/系统操作)
)
def get_weather(
    city: str,
    unit: str = "celsius",
    forecast_days: int = 1
) -> dict:
    """
    获取城市天气信息
    
    Args:
        city: 城市名称
        unit: 温度单位(celsius/fahrenheit)
        forecast_days: 预报天数
    
    Returns:
        dict: 包含天气信息的字典
    """
    api_key = os.environ.get("OPENWEATHER_API_KEY")
    
    if not api_key:
        return {
            "error": "请先设置 OPENWEATHER_API_KEY 环境变量",
            "hint": "访问 https://openweathermap.org/api 获取免费 API Key"
        }
    
    # API 调用
    units = "metric" if unit == "celsius" else "imperial"
    url = "https://api.openweathermap.org/data/2.5/weather"
    
    params = {
        "q": city,
        "appid": api_key,
        "units": units
    }
    
    try:
        response = httpx.get(url, params=params, timeout=10)
        data = response.json()
        
        if data.get("cod") != 200:
            return {
                "error": f"查询失败: {data.get('message', '未知错误')}",
                "city": city
            }
        
        result = {
            "城市": data["name"],
            "国家": data["sys"]["country"],
            "天气": data["weather"][0]["main"],
            "描述": data["weather"][0]["description"],
            "温度": f"{data['main']['temp']}°{'C' if unit == 'celsius' else 'F'}",
            "体感温度": f"{data['main']['feels_like']}°",
            "湿度": f"{data['main']['humidity']}%",
            "风速": f"{data['wind']['speed']} m/s",
            "气压": f"{data['main']['pressure']} hPa"
        }
        
        return result
        
    except httpx.TimeoutException:
        return {"error": "请求超时,请稍后重试"}
    except Exception as e:\n        return {"error": f"发生错误: {str(e)}"}


@tool(
    name="get_exchange_rate",
    description="查询两种货币之间的实时汇率",
    parameters={
        "type": "object",
        "properties": {
            "from_currency": {
                "type": "string",
                "description": "源货币代码(如 USD, CNY, EUR)"
            },
            "to_currency": {
                "type": "string",
                "description": "目标货币代码"
            },
            "amount": {
                "type": "number",
                "default": 1,
                "description": "要转换的金额"
            }
        },
        "required": ["from_currency", "to_currency"]
    },
    tags=["finance", "currency"],
    safe=True
)
def get_exchange_rate(
    from_currency: str,
    to_currency: str,
    amount: float = 1
) -> dict:
    """查询汇率(使用 exchangerate-api.com 免费 API)"""
    try:
        url = f"https://open.er-api.com/v6/latest/{from_currency.upper()}"
        response = httpx.get(url, timeout=10)
        data = response.json()
        
        if data.get("result") == "success":
            rate = data["rates"].get(to_currency.upper())
            if rate:
                converted = amount * rate
                return {
                    "from": from_currency.upper(),
                    "to": to_currency.upper(),
                    "amount": amount,
                    "rate": rate,
                    "converted": round(converted, 4)
                }
        
        return {"error": f"无法获取 {from_currency} -> {to_currency} 的汇率"}
        
    except Exception as e:\n        return {"error": f"汇率查询失败: {str(e)}"}


@tool(
    name="safe_code_runner",
    description="在安全的沙箱环境中执行 Python 代码片段,返回执行结果。适合数据分析、计算、文本处理等任务。不支持图形界面和文件操作。",
    parameters={
        "type": "object",
        "properties": {
            "code": {
                "type": "string",
                "description": "要执行的 Python 代码(不含文件操作和系统调用)"
            },
            "show_output": {
                "type": "boolean",
                "default": True,
                "description": "是否显示完整输出"
            }
        },
        "required": ["code"]
    },
    tags=["code", "execution", "python"],
    safe=False                     # ⚠️ 代码执行有风险,需在配置中开启
)
def safe_code_runner(code: str, show_output: bool = True) -> dict:
    """
    安全的 Python 代码执行器
    
    ⚠️ 限制:
    - 禁止的文件操作:open(), file(), os, sys, subprocess
    - 禁止的网络操作:requests, urllib, http.client, socket
    - 禁止的系统调用:import ctypes, threading, multiprocessing
    """
    import subprocess
    import json
    import tempfile
    import os
    
    # 危险操作黑名单检查
    dangerous_patterns = [
        "import os", "import sys", "from os", "from sys",
        "import subprocess", "from subprocess",
        "open(", "file(", "io.open",
        "__import__", "eval", "exec",
        "import requests", "import urllib", "import http",
        "import socket", "import ctypes",
        "import threading", "import multiprocessing",
        "import signal", "import resource",
        "os.system", "os.popen", "os.spawn",
        "subprocess.run", "subprocess.call", "subprocess.Popen",
        "eval(", "exec("
    ]
    
    for pattern in dangerous_patterns:
        if pattern in code:
            return {
                "error": f"禁止使用危险操作: {pattern}",
                "hint": "请移除文件操作、网络请求和系统调用代码"
            }
    
    # 写入临时文件
    with tempfile.NamedTemporaryFile(
        mode='w', suffix='.py', delete=False, encoding='utf-8'
    ) as f:\n        # 添加预导入(常用库)\n        header = """
import sys
import io
sys.stdout = io.TextIOWrapper(sys.stdout.buffer, encoding='utf-8')

# 用户代码开始
"""
        f.write(header + code)
        tmp_path = f.name
    
    try:
        result = subprocess.run(
            ["python", tmp_path],
            capture_output=True,
            text=True,
            timeout=30,
            encoding='utf-8',
            errors='replace'
        )
        
        output = {
            "stdout": result.stdout[:5000] if show_output else "(已截断)",
            "stderr": result.stderr,
            "returncode": result.returncode,
            "success": result.returncode == 0
        }
        
        return output
        
    except subprocess.TimeoutExpired:
        return {"error": "代码执行超时(>30秒),请优化代码"}
    except Exception as e:\n        return {"error": f"执行失败: {str(e)}"}
    finally:
        try:
            os.unlink(tmp_path)
        except:
            pass


# tools/__init__.py
# 注册自定义工具
from .weather_tools import get_weather, get_exchange_rate, safe_code_runner

__all__ = ["get_weather", "get_exchange_rate", "safe_code_runner"]
# 注册工具目录
hermes tools register --path ./tools

# 列出所有可用工具
hermes tools list

# 测试单个工具
hermes tools test get_weather --args '{"city": "北京"}'
hermes tools test get_exchange_rate --args '{"from_currency": "USD", "to_currency": "CNY", "amount": 100}'

# 查看工具使用统计
hermes tools stats

阶段5:自我进化机制——让 Agent 越用越聪明

3.5.1 自我进化的原理

Hermes Agent 内置的自我进化机制是其最独特的能力。核心是 ReAct 范式 + Self-Refine 反思循环

ReAct(Reasoning + Acting)

思考 → 行动 → 观察 → 思考 → 行动 → 观察 → ... → 回答

Self-Refine(自我反思)

初版回答 → 反思(哪里不好?)→ 改进 → 再次反思 → 改进 → 满意为止

这套机制让 Agent 不仅能完成任务,还能在任务中学习,在错误中成长。

3.5.2 自我进化配置
# config/with-evolution.yaml
evolution:
  enabled: true
  
  # ========== ReAct 推理循环 ==========
  react:
    max_iterations: 5              # 最大迭代次数(防止死循环)
    early_stop_on_success: true   # 成功后立即停止
    verbose: true                 # 输出推理过程(调试用)
    
    # 迭代策略
    iteration_strategy:
      backtrack_on_error: true   # 出错时回退
      max_backtrack: 2           # 最多回退2次
      retry_with_different_approach: true  # 失败后换方法重试
      
  # ========== 反思机制 ==========
  reflection:
    enabled: true
    
    # 何时触发反思
    triggers:
      on_error: true              # 执行出错时
      on_repeat: true             # 检测到重复模式时
      on_low_confidence: true     # 模型置信度低时
      after_complex_task: true    # 复杂任务完成后
      on_user_feedback: true      # 用户给出负面反馈时
      
    # 反思内容
    reflection_aspects:
      - "答案是否正确?"
      - "是否完整回答了用户问题?"
      - "有没有遗漏重要信息?"
      - "表达是否清晰易懂?"
      - "有没有可以改进的地方?"
      
    max_reflections: 3            # 最多反思3轮

  # ========== 自我学习 ==========
  learning:
    enabled: true
    
    # 从错误中学习
    error_learning:
      path: "./data/errors"
      auto_learn: true
      similarity_threshold: 0.85  # 相似错误聚合阈值
      min_occurrences: 2          # 出现2次以上才生成通用方案
      
      # 错误分类
      error_categories:
        - name: "tool_execution"
          description: "工具执行错误"
        - name: "reasoning_error"
          description: "推理逻辑错误"
        - name: "knowledge_gap"
          description: "知识盲区"
        - name: "context_miss"
          description: "上下文理解错误"
    
    # 从成功中学习
    success_patterns:
      path: "./data/success_patterns"
      min_uses: 3                 # 使用3次以上才沉淀
      auto_archive: true
      archive_after_uses: 10      # 使用10次后归档
      
    # 知识蒸馏(定期整理)
    distillation:
      enabled: true
      schedule: "daily"           # daily / weekly / manual
      time: "02:00"               # 凌晨2点执行
      model: "gpt-4o-mini"        # 用小模型蒸馏,省钱
      output: "./data/knowledge_base"
      
      # 蒸馏内容
      distill:
        - type: "error_patterns"   # 错误模式
          priority: "high"
        - type: "success_strategies"  # 成功策略
          priority: "medium"
        - type: "user_preferences" # 用户偏好
          priority: "low"

  # ========== 用户反馈学习 ==========
  feedback_learning:
    enabled: true
    
    # 反馈收集
    feedback_types:
      - "thumbs_up"              # 👍
      - "thumbs_down"            # 👎
      - "correction"             # 用户纠正
      - "rating"                 # 1-5 星评分
      - "comment"                # 文字评论
      
    # 自动调整
    auto_adjust:
      enabled: true
      trigger_threshold: 0.2    # 负面反馈占比超过20%时触发调整
      adjustments:
        - "更新系统提示词"
        - "调整回答风格"
        - "修正知识库"
3.5.3 进化系统编程
# examples/evolution_demo.py
from hermes_agent import HermesAgent
from hermes_agent.evolution import EvolutionManager
from hermes_agent.evolution.feedback import FeedbackCollector

agent = HermesAgent(config="config/with-evolution.yaml")
evolver = EvolutionManager(config="config/with-evolution.yaml")
feedback = FeedbackCollector(config="config/with-evolution.yaml")


async def demo_learn_from_task():
    """
    演示:从任务执行中学习
    """
    print("=== 从任务中学习 ===")
    
    # Agent 执行任务时自动记录学习点
    result = await agent.run_task(
        task_description="分析这个销售数据 CSV 文件,找出销量最高的产品类别",
        workspace="./workspace/sales",
        task_id="sales-analysis-001",
        learn=True                 # 开启学习模式
    )
    
    print(f"任务结果: {result['answer'][:200]}...")
    print(f"执行时间: {result['execution_time']:.2f}秒")
    print(f"迭代次数: {result['iterations']}")
    print(f"调用工具: {result['tools_used']}")
    
    # 查看学习成果
    learning = await evolver.get_learning_report(task_id="sales-analysis-001")
    print(f"学到的策略: {learning['learned_strategies']}")
    print(f"改进点: {learning['improvements']}")


async def demo_feedback_learning():
    """
    演示:用户反馈驱动的学习
    """
    print("=== 用户反馈学习 ===")
    
    # 用户对回答进行反馈
    await feedback.submit(
        conversation_id="conv_001",
        response_id="resp_001",
        feedback_type="thumbs_down",
        comment="代码太啰嗦了,我想要更简洁的实现"
    )
    
    # Agent 自动调整
    await agent.adjust_from_feedback(
        conversation_id="conv_001",
        adjustment_type="style"   # style / knowledge / behavior
    )
    
    print("✅ 已根据反馈调整回答风格")


async def demo_view_knowledge_base():
    """
    查看进化知识库
    """
    print("=== 知识库浏览 ===")
    
    # 查看错误模式
    errors = await evolver.get_error_patterns(limit=10)
    print(f"\n错误模式 ({len(errors)} 条):")
    for e in errors:
        print(f"  ❌ {e['pattern']}")
        print(f"     → 解决方案: {e['solution']}")
        print(f"     → 出现次数: {e['occurrences']}")
    
    # 查看成功策略
    strategies = await evolver.get_success_strategies(limit=10)
    print(f"\n成功策略 ({len(strategies)} 条):")
    for s in strategies:
        print(f"  ✅ {s['context']}")
        print(f"     → 方法: {s['approach']}")
        print(f"     → 使用次数: {s['usage_count']}")
    
    # 查看用户偏好
    preferences = await evolver.get_user_preferences()
    print(f"\n用户偏好:")
    for k, v in preferences.items():
        print(f"  {k}: {v}")


async def demo_manual_distillation():
    """
    手动触发知识蒸馏
    """
    print("=== 手动知识蒸馏 ===")
    
    # 蒸馏错误模式
    await evolver.distill(
        source="error_patterns",
        target="knowledge_base",
        model="gpt-4o-mini",
        force=True               # 强制重新蒸馏
    )
    
    # 蒸馏成功模式
    await evolver.distill(
        source="success_patterns",
        target="knowledge_base",
        model="gpt-4o-mini"
    )
    
    print("✅ 知识蒸馏完成")


async def demo_react_verbose():
    """
    演示 ReAct 推理过程(verbose 模式)
    """
    print("=== ReAct 推理过程 ===")
    
    response = await agent.chat(
        "帮我分析这个代码有什么问题:\n"
        "```python\n"
        "def get_user(user_id):\n"
        "    user = db.query(f'SELECT * FROM users WHERE id = {user_id}')\n"
        "    return user\n"
        "```",
        verbose=True              # 显示完整推理过程
    )
    
    # verbose 模式下,Agent 会输出:
    # Thought: 需要先分析这段代码...
    # Action: code_analysis_tool
    # Observation: 发现 SQL 注入漏洞...
    # Thought: 确实有问题...给出修复建议


import asyncio
asyncio.run(demo_learn_from_task())

阶段6:多端接入——让 Agent 出现在每个地方

3.6.1 为什么多端接入很重要?

命令行 Chat 只能覆盖 5% 的使用场景。真正的 Agent 应该在你工作的地方等你——微信、Telegram、Slack、飞书、企业微信……而不是让用户专门打开一个应用来用 Agent。

3.6.2 Telegram 接入(最简单,推荐新手入门)

Telegram Bot 是目前最成熟、最稳定的接入方案。免费、无审查、支持 Bot API、消息必达

# 创建 Bot 步骤:
# 1. 在 Telegram 中搜索 @BotFather
# 2. 发送 /newbot
# 3. 按提示输入 Bot 名称和用户名
# 4. 获取 Bot Token,格式如:123456789:ABCdefGHIjklMNOpqrsTUVwxyz
# 5. 开始对话:https://t.me/YourBotUsername

export TELEGRAM_BOT_TOKEN="123456789:ABCdefGHIjklMNOpqrsTUVwxyz"
# config/channels/telegram.yaml
channels:
  telegram:
    enabled: true
    
    bot:
      token: "${TELEGRAM_BOT_TOKEN}"
      parse_mode: "MarkdownV2"   # 消息格式:Markdown / HTML / MarkdownV2
      disable_web_page_preview: true
      disable_notification: false
      
    # 管理员配置(只有管理员能使用危险功能)
    admin_ids:
      - 123456789                # 替换为你的 Telegram User ID
      # 查看你的 User ID:给 @userinfobot 发消息
      
    # 命令菜单
    commands:
      - command: "start"
        description: "开始使用 Hermes"
        handler: "onboarding"
        
      - command: "search"
        description: "全网搜索"
        handler: "search"
        
      - command: "memory"
        description: "查看我的记忆"
        handler: "memory_list"
        
      - command: "code"
        description: "执行 Python 代码"
        handler: "code_runner"
        
      - command: "stats"
        description: "使用统计"
        handler: "stats"
        
      - command: "weather"
        description: "查天气"
        handler: "weather"
        
      - command: "help"
        description: "帮助信息"
        handler: "help"
        
      - command: "cost"
        description: "查看本月成本"
        handler: "cost_report"
      
    # 群组配置
    group:
      enabled: true
      allowed_groups:             # 允许的群组 ID
        - -1001234567890           # 负数是群组 ID
      require_mention: true        # 必须 @机器人 才响应
      reply_to_message: true       # 回复原始消息
      max_group_members: 100       # 超过此人数的群自动禁用
      
    # 限流保护
    rate_limiting:
      per_user_per_minute: 20     # 每用户每分钟最多消息数
      per_chat_per_minute: 30     # 每群组每分钟最多消息数
      global_per_minute: 500      # 全局每分钟限制
      
    # 响应延迟(模拟人类打字)
    typing_delay:
      enabled: true
      min_ms: 500                 # 最小延迟
      max_ms: 3000                # 最大延迟
      per_char_ms: 30             # 每字符额外延迟

  # Telegram Webhook 部署(Nginx 配置示例)
  # nginx 配置参考:
  # location /telegram {
  #     proxy_pass http://localhost:8001/telegram;
  #     proxy_set_header Host $host;
  #     proxy_set_header X-Real-IP $remote_addr;
  # }
3.6.3 企业微信接入(推荐企业场景)
# config/channels/wecom.yaml
channels:
  wecom:
    enabled: true
    
    # 企业微信应用配置
    # 获取方式:企业微信管理后台 → 应用管理 → 创建应用
    corp:
      corp_id: "${WECOM_CORP_ID}"          # 企业 ID
      agent_id: "${WECOM_AGENT_ID}"         # 应用 Agent ID
      secret: "${WECOM_SECRET}"              # 应用 Secret
      
    # 消息接收(需要公网可访问的回调地址)
    webhook:
      host: "0.0.0.0"
      port: 8001
      path: "/wecom/callback"
      verify_token: "${WECOM_VERIFY_TOKEN}"  # 自定义验证 Token
      aes_key: "${WECOM_AES_KEY}"            # 企业微信提供的 AES Key
      encrypt_mode: "safe"                   # safe(推荐)/ compatible
      
    # 消息处理
    message:
      auto_reply:
        enabled: true
        # 空列表表示对所有人自动回复,或指定关键词
        keywords: []                          # ["help", "帮助"]
        exclude_keywords: ["退订", "取消订阅"]
        
      # 群发限制
      broadcast:
        enabled: false
        max_per_day: 1000
        
    # 限流
    rate_limit:
      per_user: 20
      global: 200
      
    # 媒体文件处理
    media:
      download_enabled: true
      max_file_size_mb: 20      # 企业微信限制 20MB
      
    # 安全设置
    security:
      ip_whitelist:            # IP 白名单
        - "10.0.0.0/8"
        - "172.16.0.0/12"
      require_at: true          # 必须 @机器人 才响应
3.6.4 Slack 接入
# config/channels/slack.yaml
channels:
  slack:
    enabled: true
    
    # Slack App 配置
    # 创建方式:https://api.slack.com/apps → Create New App
    bot:
      token: "${SLACK_BOT_TOKEN}"         # xoxb-... 格式
      signing_secret: "${SLACK_SIGNING_SECRET}"
      app_token: "${SLACK_APP_TOKEN}"     # xapp-... 格式(用于 Socket Mode)
      
    # 事件订阅
    events:
      url: "https://your-domain.com/slack/events"
      bot_id: "${SLACK_BOT_ID}"
      # 推荐使用 Socket Mode(无需公网暴露)
      use_socket_mode: true
      
    # Slash Commands(斜杠命令)
    commands:
      - command: "/hermes"
        description: "与 Hermes AI 对话"
        usage_hint: "[问题]"
        
      - command: "/hermes-search"
        description: "网络搜索"
        usage_hint: "[搜索词]"
        
      - command: "/hermes-code"
        description: "执行代码"
        usage_hint: "[代码]"
        
      - command: "/hermes-weather"
        description: "查天气"
        usage_hint: "[城市]"
        
      - command: "/hermes-stats"
        description: "使用统计"
        
    # Channel 权限
    channels:
      allowed:                   # 允许的频道
        - "C0123456789"          # AI 助手频道
        - "C9876543210"          # 开发频道
      blocked:                   # 禁止的频道
        - "C0000000001"          # 私密频道
      mention_only: false         # true=只有 @ 时才响应
      
    # 线程管理
    threads:
      enabled: true
      reply_in_thread: true      # 在线程中回复
      max_thread_replies: 100    # 线程最大回复数
      
    # 格式化
    formatting:
      use_blocks: true           # 使用 Slack Block Kit
      max_length: 4000            # 单条消息最大长度
3.6.5 多端同时运行
# 方式一:使用 Docker Compose 多服务
# docker-compose.multi-channel.yml
# (综合上述所有渠道配置的完整版)

# 方式二:单进程多渠道
hermes run --config config/multi-channel.yaml

# 方式三:分别启动(方便调试)
hermes run --config config/channels/telegram.yaml --channel telegram &
hermes run --config config/channels/slack.yaml --channel slack &
hermes run --config config/channels/wecom.yaml --channel wecom &

# 方式四:Supervisor 管理进程(生产环境推荐)
# /etc/supervisor/conf.d/hermes.conf
"""
[program:hermes-telegram]
command=hermes run --config /opt/hermes/config/channels/telegram.yaml
directory=/opt/hermes
user=hermes
autostart=true
autorestart=true
stderr_logfile=/var/log/hermes/hermes-telegram.err.log
stdout_logfile=/var/log/hermes/hermes-telegram.out.log

[program:hermes-slack]
command=hermes run --config /opt/hermes/config/channels/slack.yaml
directory=/opt/hermes
user=hermes
autostart=true
autorestart=true
"""

阶段7:可视化面板——看得到才能管得住

3.7.1 为什么监控面板必不可少?

当你把 Agent 跑在生产环境,这些问题会立刻出现:

  • 💸 “Token 怎么用了这么多?” —— 需要实时消耗监控
  • 🐢 “为什么这次响应这么慢?” —— 需要延迟分析
  • 🐛 “Agent 这次答错了,谁来负责?” —— 需要对话历史
  • 📊 “这个月 Agent 帮我省了多少工作量?” —— 需要量化价值
  • 🔧 “哪些工具用得最多?” —— 需要工具使用统计

Hermes Agent 提供了两套监控方案:内置 Dashboard(开箱即用)和 Prometheus + Grafana(专业可扩展)。

3.7.2 内置 Dashboard 使用
# 启动带 Dashboard 的服务
hermes run --config config/full.yaml --dashboard

# 访问
# - Dashboard: http://localhost:3000
# - API Docs:  http://localhost:8000/docs
# - Health:    http://localhost:8000/health

Dashboard 功能一览

模块 功能
对话历史 所有对话记录、评分、反馈
Token 消耗 实时用量、日趋势、月累计
响应延迟 P50/P95/P99 延迟分布
工具调用 Top 10 最常用工具
记忆命中 记忆命中率趋势
错误分布 错误类型与频率
成本分析 按模型/用户/功能的成本分解
3.7.3 Prometheus + Grafana 集成
# config/with-monitoring.yaml
monitoring:
  enabled: true
  
  # Prometheus 指标端点
  prometheus:
    enabled: true
    port: 9090
    path: "/metrics"
    include_metrics:
      - "hermes_conversation_total"
      - "hermes_token_usage_total"
      - "hermes_response_duration_seconds"
      - "hermes_tool_invocations_total"
      - "hermes_memory_retrieval_hits_total"
      - "hermes_cost_usd_total"
      - "hermes_active_users"
      - "hermes_error_total"
      
  # 自定义指标定义
  custom_metrics:
    - name: "hermes_conversation_total"
      type: "Counter"
      description: "总对话数"
      labels: ["channel", "model"]
      
    - name: "hermes_token_usage_total"
      type: "Counter"
      description: "Token 使用总量"
      labels: ["model", "type"]  # type: prompt / completion
      
    - name: "hermes_response_duration_seconds"
      type: "Histogram"
      description: "响应延迟分布(秒)"
      labels: ["model", "channel"]
      buckets: [0.5, 1, 2, 3, 5, 10, 30, 60]
      
    - name: "hermes_tool_invocations_total"
      type: "Counter"
      description: "工具调用统计"
      labels: ["tool_name", "status"]  # status: success / error / timeout
      
    - name: "hermes_memory_retrieval_hits_total"
      type: "Counter"
      description: "记忆命中次数"
      labels: ["collection", "hit"]  # hit: true / false
      
    - name: "hermes_cost_usd_total"
      type: "Counter"
      description: "美元成本累计"
      labels: ["model", "provider"]
      
    - name: "hermes_active_users"
      type: "Gauge"
      description: "当前在线用户数"
      labels: ["channel"]

  # Grafana 配置
  grafana:
    enabled: true
    datasource_url: "http://localhost:3006"
    admin_user: "${GRAFANA_USER}"
    admin_password: "${GRAFANA_PASSWORD}"
    
    # 自动导入 Dashboard
    dashboards:
      - id: "hermes-overview"
        title: "Hermes Agent 总览"
        import_on_start: true
        refresh_interval: "30s"
        
      - id: "hermes-costs"
        title: "成本分析"
        import_on_start: true
        
      - id: "hermes-performance"
        title: "性能分析"
        import_on_start: true
3.7.4 Grafana Dashboard JSON
{
  "annotations": {
    "list": [
      {
        "builtIn": 1,
        "datasource": "-- Grafana --",
        "enable": true,
        "hide": true,
        "iconColor": "rgba(0, 211, 255, 1)",
        "name": "Annotations & Alerts",
        "type": "dashboard"
      }
    ]
  },
  "editable": true,
  "gnetId": null,
  "graphTooltip": 0,
  "id": null,
  "links": [],
  "panels": [
    {
      "datasource": "Prometheus",
      "fieldConfig": {
        "defaults": {
          "color": {"mode": "palette-classic"},
          "mappings": [],
          "thresholds": {
            "mode": "absolute",
            "steps": [
              {"color": "green", "value": null},
              {"color": "yellow", "value": 100},
              {"color": "red", "value": 500}
            ]
          },
          "unit": "short"
        }
      },
      "gridPos": {"h": 4, "w": 6, "x": 0, "y": 0},
      "id": 1,
      "options": {
        "colorMode": "value",
        "graphMode": "area",
        "justifyMode": "auto",
        "orientation": "auto",
        "reduceOptions": {
          "calcs": ["lastNotNull"],
          "fields": "",
          "values": false
        },
        "textMode": "auto"
      },
      "pluginVersion": "10.0.0",
      "targets": [
        {
          "expr": "sum(increase(hermes_conversation_total[24h]))",
          "legendFormat": "今日对话",
          "refId": "A"
        }
      ],
      "title": "今日对话量",
      "type": "stat"
    },
    {
      "datasource": "Prometheus",
      "fieldConfig": {
        "defaults": {
          "unit": "currencyUSD"
        }
      },
      "gridPos": {"h": 4, "w": 6, "x": 6, "y": 0},
      "id": 2,
      "options": {"colorMode": "value", "graphMode": "area"},
      "targets": [
        {
          "expr": "sum(increase(hermes_cost_usd_total[30d]))",
          "legendFormat": "本月成本",
          "refId": "A"
        }
      ],
      "title": "本月成本",
      "type": "stat"
    },
    {
      "datasource": "Prometheus",
      "fieldConfig": {
        "defaults": {
          "unit": "s"
        }
      },
      "gridPos": {"h": 4, "w": 6, "x": 12, "y": 0},
      "id": 3,
      "targets": [
        {
          "expr": "histogram_quantile(0.95, sum(rate(hermes_response_duration_seconds_bucket[5m])) by (le))",
          "legendFormat": "P95 延迟",
          "refId": "A"
        }
      ],
      "title": "响应延迟 P95",
      "type": "gauge"
    },
    {
      "datasource": "Prometheus",
      "fieldConfig": {
        "defaults": {
          "unit": "short"
        }
      },
      "gridPos": {"h": 4, "w": 6, "x": 18, "y": 0},
      "id": 4,
      "targets": [
        {
          "expr": "sum(hermes_active_users)",
          "legendFormat": "在线用户",
          "refId": "A"
        }
      ],
      "title": "当前在线用户",
      "type": "stat"
    },
    {
      "datasource": "Prometheus",
      "gridPos": {"h": 8, "w": 12, "x": 0, "y": 4},
      "id": 5,
      "options": {
        "legend": {"displayMode": "list", "placement": "bottom"},
        "tooltip": {"mode": "single"}
      },
      "targets": [
        {
          "expr": "sum by(type) (rate(hermes_token_usage_total[5m]))",
          "legendFormat": "{{type}}",
          "refId": "A"
        }
      ],
      "title": "Token 消耗趋势(5分钟)",
      "type": "timeseries"
    },
    {
      "datasource": "Prometheus",
      "gridPos": {"h": 8, "w": 12, "x": 12, "y": 4},
      "id": 6,
      "options": {
        "legend": {"displayMode": "list", "placement": "bottom"}
      },
      "targets": [
        {
          "expr": "topk(10, sum by(tool_name) (increase(hermes_tool_invocations_total[24h])))",
          "legendFormat": "{{tool_name}}",
          "refId": "A"
        }
      ],
      "title": "Top 10 工具调用(24小时)",
      "type": "bargauge"
    }
  ],
  "refresh": "30s",
  "schemaVersion": 30,
  "style": "dark",
  "tags": ["hermes", "agent"],
  "templating": {"list": []},
  "time": {"from": "now-6h", "to": "now"},
  "timepicker": {},
  "timezone": "browser",
  "title": "Hermes Agent 生产监控",
  "uid": "hermes-overview",
  "version": 1
}

阶段8:成本管控——让你的 Agent 会"省钱"

3.8.1 AI Agent 的成本陷阱

很多团队发现 Agent 跑一个月后,账单比预期高 5-10 倍。常见的成本陷阱:

  1. 上下文膨胀:每次对话都带上完整历史 → Token 浪费 80%
  2. 模型选型不合理:简单问答用 GPT-4o → 贵 20 倍
  3. 搜索滥用:每句话都触发搜索 → 搜索 API 费用爆炸
  4. 记忆过载:存入太多低价值记忆 → 检索成本高
  5. 无限制迭代:Agent 在复杂任务上无限循环 → Token 燃烧

Hermes Agent 内置了完整的成本管控系统来解决这些问题。

3.8.2 成本控制完整配置
# config/with-cost-control.yaml
cost_control:
  enabled: true
  
  # ========== 全局预算 ==========
  budget:
    daily_limit_usd: 5.0              # 每日预算上限
    monthly_limit_usd: 50.0           # 每月预算上限
    alert_threshold: 0.8              # 80% 时触发警告
    hard_stop: false                  # 达到上限后是否完全停止(false=降级处理)
    
    # 降级策略(达到 90% 预算时)
    degradation:
      enabled: true
      strategy: "switch_to_cheap_model"  # switch_to_cheap_model / reduce_max_tokens / disable_search
      fallback_model: "deepseek-chat"
      
  # ========== 模型路由(智能选型)==========
  model_routing:
    enabled: true
    
    # 路由规则(按任务复杂度自动选择模型)
    rules:
      # 简单问答 → 最小模型
      - name: "simple_qa"
        triggers:
          max_input_tokens: 100
          keywords: ["你好", "谢谢", "再见", "hi", "hello", "thanks"]
        model: "gpt-4o-mini"
        priority: 1
        
      # 代码任务 → 稍大的模型
      - name: "code_tasks"
        triggers:
          keywords: ["代码", "function", "class ", "def ", "import ", "fn ", "func "]
        model: "gpt-4o"
        priority: 3
        
      # 搜索结果整合 → 中等模型
      - name: "search_synthesis"
        triggers:
          context_source: "search"
        model: "gpt-4o-mini"
        priority: 2
        
      # 长文本分析 → 大模型
      - name: "complex_analysis"
        triggers:
          min_input_tokens: 3000
          keywords: ["分析", "总结", "报告", "评估", "review"]
        model: "gpt-4o"
        priority: 5
        
      # 默认 → 经济模型
      - name: "default"
        model: "gpt-4o-mini"
        priority: 0
        
    # 模型价格表($/1M Tokens)
    model_prices:
      gpt-4o:
        input: 2.50
        output: 10.00
      gpt-4o-mini:
        input: 0.15
        output: 0.60
      gpt-4-turbo:
        input: 10.00
        output: 30.00
      claude-3-5-sonnet:
        input: 3.00
        output: 15.00
      claude-3-haiku:
        input: 0.25
        output: 1.25
      deepseek-chat:
        input: 0.10
        output: 0.30
      qwen-plus:
        input: 0.80
        output: 2.00
      qwen-max:
        input: 1.00
        output: 4.00
      gemini-1.5-pro:
        input: 1.25
        output: 5.00
        
  # ========== 上下文压缩 ==========
  context_compression:
    enabled: true
    
    # 对话历史压缩
    conversation:
      max_turns_in_prompt: 15         # 最多保留最近15轮
      summarize_after: 8               # 8轮后自动生成摘要
      
      # 摘要策略
      summary:
        model: "gpt-4o-mini"           # 用小模型做摘要
        trigger_tokens: 3000           # Token 超过 3000 时触发
        max_summary_tokens: 500        # 摘要最多 500 tokens
        include_action_history: true   # 保留工具调用历史
        
    # 记忆检索压缩
    retrieval:
      max_chunk_size: 800              # 召回段落最大 Token
      overlap_tokens: 100              # 重叠 Token 数
      rerank_top_k: 5                  # 重排后取 Top 5
      compress_after_k: 10             # 超过10段时压缩
      
  # ========== Token 精确计数 ==========
  token_counting:
    enabled: true
    estimate_only: false              # false=精确计数(推荐)
    
    # 精确计数需要 LLM Provider 支持
    # OpenAI: 使用 tiktoken 库
    # Anthropic: 使用 cl100k_base
    # 其他: 使用 rough estimation
    
    truncate_at_limit: true           # 超出限制时截断而非拒绝
    max_context_tokens: 128000         # 最大上下文 Token 数
    
  # ========== 搜索成本控制 ==========
  search_cost_control:
    enabled: true
    max_searches_per_conversation: 5   # 单次对话最多搜索 5 次
    use_cache: true                    # 缓存搜索结果
    cache_ttl_minutes: 60              # 缓存 60 分钟
    fallback_to_cheaper_provider: true # 主搜索用完时切换
    
  # ========== 通知 ==========
  alerts:
    on_budget_warning: true            # 80% 警告
    on_budget_exceeded: false          # 超预算通知
    channels:
      - type: "log"
        level: "WARNING"
        
      - type: "email"
        enabled: false
        smtp_host: "${SMTP_HOST}"
        smtp_port: 587
        from_addr: "hermes@example.com"
        to_addrs: ["admin@example.com"]
        
      - type: "telegram"
        enabled: true
        bot_token: "${TELEGRAM_BOT_TOKEN}"
        chat_id: 123456789             # 管理员 Chat ID
# 成本管理命令
hermes cost report --period today          # 今日报告
hermes cost report --period week            # 本周报告
hermes cost report --period month           # 本月报告
hermes cost breakdown --by model            # 按模型分解
hermes cost breakdown --by user             # 按用户分解
hermes cost breakdown --by channel          # 按渠道分解

# 设置预算
hermes cost set-budget --daily 3.0 --monthly 30.0

# 实时监控
hermes cost live                               # 实时刷新

# 导出报告
hermes cost export --format csv --output ./cost_report.csv

预期成本报告输出

========== 月度成本报告 ==========
日期范围: 2026-01-01 ~ 2026-01-31

【模型使用明细】
  gpt-4o-mini:      500,000 tokens  ($0.30)   78.5%
  gpt-4o:           120,000 tokens  ($1.50)   19.7%
  deepseek-chat:     8,000 tokens  ($0.0024)  0.6%
  Embedding:       200,000 tokens  ($0.10)    1.2%
  ─────────────────────────────────────────
  总计:           1,420,000 tokens  $1.91 USD

【按渠道分解】
  Telegram:        $1.20   (62.8%)
  Web:             $0.50   (26.2%)
  Slack:           $0.21   (11.0%)

【按用户分解】
  @zhangsan:       $0.80   (41.9%)
  @lisi:           $0.60   (31.4%)
  @wangwu:         $0.51   (26.7%)

【日均成本】
  日均:      $0.062
  预测月成本: $1.91  (预算: $50.00)

【效率指标】
  总对话数:   892 次
  平均成本:   $0.0021/次
  Token 效率: 1,593 Token/次

四、Windows/Mac/Linux/WSL 全平台安装总结

4.1 安装方式对比矩阵

平台 推荐方式 安装命令 适用场景
Windows 10/11 WSL2 + uv wsl --installuv pip install hermes-agent 日常开发
Windows Docker docker run hermesai/agent 快速尝鲜/生产
macOS Intel Homebrew / uv brew install hermesuv pip install hermes-agent 日常开发
macOS Apple Silicon uv / Docker uv pip install hermes-agentdocker run --platform linux/arm64 日常开发
Linux Ubuntu/Debian apt + uv curl -LsSf https://astral.sh/uv/install.sh | sh && uv pip install hermes-agent 日常开发/生产
Linux Docker docker run -p 8000:8000 hermesai/agent 生产部署
WSL2 uv uv pip install hermes-agent --system Windows 开发者首选
所有平台 Docker Compose docker compose -f docker-compose.prod.yml up -d 生产级部署

4.2 安装检查清单

# 安装后验证清单
hermes --version                    # ✅ 版本号显示
hermes doctor                        # ✅ 环境检查
hermes chat "test"                  # ✅ 基础对话
hermes tools list                   # ✅ 工具加载
hermes memory stats                 # ✅ 记忆系统
hermes run --config config/basic.yaml --dashboard  # ✅ Web UI
curl http://localhost:8000/health   # ✅ 健康检查

五、与商业 Agent 产品横向对比

5.1 功能维度对比

维度 Hermes Agent ChatGPT Plus Microsoft Copilot Google Gemini Advanced Anthropic Claude
月费用 免费(开源) $20 $10-20 $20 $20
部署方式 自托管/私有 SaaS SaaS SaaS SaaS
数据隐私 ✅ 完全可控 ⚠️ 可能用于训练 ⚠️ 企业版可控 ⚠️ 可能用于训练 ✅ 默认不用于训练
工具链 40+ 可扩展 插件商店 Office/VS Code 集成 Google 全家桶 工具调用 + Artifacts
记忆持久化 ✅ 向量数据库 有限会话记忆 项目级记忆 长期记忆(Gemini 1.5) 记忆功能
多端接入 6+ 全支持 仅官方 APP Teams/Office Web/Android Web/API
自我进化 ✅ 开源可定制
搜索能力 多 Provider 免费 Bing 内置 Bing 内置 Google 内置
代码执行 ✅ 沙箱安全 ⚠️ Code Interpreter ⚠️ 部分 ⚠️ ✅ Claude Code
企业定制 ✅ 完全开放 ✅ 企业版部分 ✅ Enterprise
学习曲线 ⭐⭐⭐ 中等 ⭐ 极低 ⭐⭐ 较低 ⭐ 极低 ⭐⭐ 较低
API 开放 ✅ 完全开源 ⚠️ GPTs 部分 ⚠️ 有限 ⚠️

5.2 成本对比分析

假设场景:每天 100 次对话,每次平均 500 input + 500 output tokens

产品 日成本 月成本 年成本 备注
Hermes + DeepSeek ~$0.10 ~$3 ~$36 最省钱方案
Hermes + GPT-4o Mini ~$0.30 ~$9 ~$108 平衡方案
Hermes + GPT-4o ~$2.50 ~$75 ~$900 高质量方案
ChatGPT Plus 固定 $20 $20 $240 不管用多少都 $20
Copilot Pro 固定 $10-20 $10-20 $120-240 同上
Claude Pro 固定 $20 $20 $240 同上

结论:Hermes Agent 在低频使用时不占优势,但中高频使用(>50次/天)时成本优势明显,且具备商业产品没有的灵活性。

5.3 何时选 Hermes?何时选商业产品?

选择 Hermes Agent 的场景:

  • 对数据隐私有严格要求(金融、医疗、法律合规数据)
  • 需要深度定制 Agent 行为(自定义工具、专属工作流)
  • 预算有限但使用频率高
  • 企业内网环境,无法使用外部 SaaS 服务
  • 想学习 Agent 架构与实现原理
  • 需要多端接入(微信等中国平台)
  • 需要完全掌控成本

选择商业产品 的场景:

  • 追求开箱即用的体验,不想投入运维精力
  • 临时性/轻量使用(每天 <10 次)
  • 个人用户,主要用于日常问答
  • 需要最强的模型能力(如 o1 / GPT-5 等最新模型)
  • 没有技术团队支持维护

六、实测效果与局限

6.1 测试环境

我们在以下硬件/软件环境下进行了完整测试:

环境 配置
测试机型 MacBook Pro M3 Max 64GB + Windows Desktop AMD 7950X
操作系统 macOS Sonoma 14 + Ubuntu 22.04 LTS + Windows 11 + WSL2
本地模型 Ollama: DeepSeek V3 7B, Qwen 2.5 7B, Llama 3.1 8B
远程模型 OpenAI GPT-4o Mini, DeepSeek Chat, Claude 3 Haiku
向量数据库 ChromaDB 0.4.x, Qdrant 1.7.x
Embedding nomic-embed-text v1.5, text-embedding-3-small
测试时长 连续 7 天 × 24 小时运行

6.2 测试任务与结果

任务类型 模型 响应时间 Token消耗 成功率 质量评分
简单问答 DeepSeek V3 (本地) 1.2s 280 95% ⭐⭐⭐⭐
带记忆对话 DeepSeek V3 + ChromaDB 2.8s 620 90% ⭐⭐⭐⭐
网络搜索整合 GPT-4o Mini + Tavily 3.5s 890 88% ⭐⭐⭐⭐⭐
Python 代码生成 GPT-4o Mini 2.1s 450 85% ⭐⭐⭐⭐
复杂多步任务(5步+) GPT-4o Mini + ReAct 12s 2100 75% ⭐⭐⭐
中文长文本总结 DeepSeek V3 4.5s 1800 92% ⭐⭐⭐⭐
文件批量处理 GPT-4o Mini 8s 1600 82% ⭐⭐⭐⭐
多端消息同步 全渠道 1s 120 98% ⭐⭐⭐⭐⭐
Telegram Bot 响应 GPT-4o Mini 1.8s 380 94% ⭐⭐⭐⭐

6.3 当前版本的主要局限(诚实评估)

作为一个活跃开发的开源项目,Hermes Agent 仍有以下局限:

6.3.1 技术层面
  1. 推理速度瓶颈:即使 DeepSeek V3 这样的高效模型,复杂任务(多步规划、工具链调用)仍需 5-15 秒。用户心理期望是 ❤️ 秒。这是一个 LLM 推理的物理限制。

  2. 多模态能力较弱:图片理解功能需要额外集成 GPT-4V 或 Claude Vision,当前版本对图片输入的处理能力不如商业产品。

  3. 长程规划稳定性:超过 10 步的复杂任务约有 25% 失败率。ReAct 循环有时会陷入重复推理(Agent Loop),需要在配置中设置合理的 max_iterations

  4. 企业认证缺失:LDAP / Active Directory / SAML SSO 等企业认证尚未完全支持。OAuth2 支持正在开发中。

  5. 运维复杂度:自托管意味着自己要负责:版本升级、监控告警、故障排查、备份恢复。免费不等于零成本。

6.3.2 使用层面
  1. 学习曲线:相比 ChatGPT 的零门槛,Hermes Agent 需要一定的技术背景(至少会配 YAML 和用 Docker)。

  2. 初始配置繁琐:需要手动配置 API Keys、选择向量数据库、设置各渠道参数。

  3. 中文文档:英文文档比中文文档更完整,部分高级功能只有英文说明。

  4. 维护成本:虽然开源免费,但长期维护需要投入时间(尤其是跟进版本更新)。


七、快速上手路径推荐

路径A:30 分钟快速体验(适合尝鲜)

# 1. Docker 一键启动
curl -fsSL https://get.hermes-agent.dev | bash

# 2. 配置 API Key(必须)
export OPENAI_API_KEY="sk-xxxx"   # 或使用 DeepSeek
export DEEPSEEK_API_KEY="sk-xxxx"

# 3. 启动并体验
hermes chat
# 输入:你好,请介绍一下你自己

路径B:2 小时完整搭建(推荐,认真学习)

# 1. 安装 CLI
uv pip install hermes-agent --system

# 2. 初始化项目
hermes init my-agent && cd my-agent
mkdir -p config data/logs

# 3. 配置基础参数
cat > config/basic.yaml << 'EOF'
agent:
  name: "Hermes"
  language: "zh-CN"

llm:
  provider: "deepseek"
  api_key: "${DEEPSEEK_API_KEY}"
  base_url: "https://api.deepseek.com"
  model: "deepseek-chat"
  temperature: 0.7

memory:
  enabled: true
  provider: "chroma"
  persist_directory: "./data/chroma_db"

search:
  enabled: true
  default_provider: "duckduckgo"

tools:
  enabled: true
EOF

# 4. 启动 Web UI
hermes run --config config/basic.yaml --dashboard

# 5. 浏览器打开 http://localhost:3000 体验

路径C:生产级部署(3小时+,企业用户)

# 1. 克隆部署仓库
git clone https://github.com/hermes-agent/hermes.git
cd hermes/deploy/production

# 2. 配置环境变量
cp .env.example .env
# 手动编辑 .env 填入所有 API Keys

# 3. 配置 Nginx 反向代理 + SSL
# (参考 deploy/nginx/nginx.conf.example)

# 4. 启动完整服务栈
docker compose -f docker-compose.prod.yml up -d

# 5. 配置监控
docker compose -f docker-compose.monitoring.yml up -d

# 6. 配置定时备份
# (参考 deploy/scripts/backup.sh)

八、常见问题速查(FAQ)

Q:Windows 下 Docker 运行慢怎么办?
A:确保 WSL2 是后端(wsl --set-default-version 2),Docker Desktop 设置中分配至少 4核 CPU + 8GB RAM 给 WSL2。

Q:内存不够(<8GB)怎么跑?
A:使用 API 调用远程模型(GPT-4o Mini / DeepSeek),本地只跑 ChromaDB 和工具服务。4GB RAM 即可运行。

Q:向量数据库选哪个好?
A:个人/小团队用 ChromaDB(零配置);有 Docker 基础用 Qdrant(性能更强);企业级用 MilvusPgvector(依托现有基础设施)。

Q:如何让 Agent 只用中文回答?
A:在 config/basic.yaml 中设置 agent.language: "zh-CN",并在 agent.system_prompt 中明确要求:“请始终使用中文回答”。

Q:如何阻止 Agent 执行危险操作?
A:确保 tools.execution.allow_unsafe: false,配置 bash_executor.blocked_commands 黑名单,并限制 file_tools.allowed_paths

Q:Tavily API 额度用完了怎么办?
A:降级到 DuckDuckGo(免费无限),或申请 Brave Search(2000次/月免费),或配置多个搜索 Provider 做自动 fallback。

Q:首次运行报 ModuleNotFoundError 怎么办?
A:确保 Python 版本是 3.10-3.12,使用 uv pip install hermes-agent --system 安装,不要用系统自带的 pip。

Q:如何升级 Hermes Agent?
A:pip 升级:uv pip install hermes-agent --upgrade;Docker:docker pull hermesai/agent:latest && docker compose down && docker compose up -d

Q:Agent 回答很慢怎么优化?
A:① 开启模型路由(简单问题用小模型);② 启用上下文压缩;③ 使用本地 Embedding;④ 减少 max_tokens;⑤ 切换到更快的新模型如 GPT-4o Mini。

Q:如何让 Agent 接入自己的知识库?
A:将文档导入向量数据库(见阶段2记忆系统),然后在 system prompt 中告诉 Agent 知识库的位置和用途即可。


结语

Hermes Agent 代表的不仅是一个工具,更是一种思路转变:让 AI Agent 从"大厂的专属玩具"变成每个开发者都能拥有、定制和掌控的生产力系统

从毛坯到满配,本文覆盖了完整的技术路径:

毛坯版(15分钟)  →  CLI 跑起来,能对话
    ↓
基础版(30分钟)  →  加搜索、加记忆
    ↓
专业版(2小时)   →  40+工具、多模型路由、成本控制
    ↓
满配版(3小时+)  →  多端接入、可视化监控、生产级部署

你可以根据自己的需求,从最简单的 CLI 安装开始,逐步叠加功能。每一步都有具体的代码和配置,不需要自己摸索。

开源的力量在于:你不只是使用者,更是塑造者。欢迎 fork 代码、提 issue、写 plugin、参加社区讨论。期待在社区见到你的身影!


📚 相关资源

资源 链接
GitHub 主仓库 https://github.com/hermes-agent/hermes
完整文档 https://docs.hermes-agent.dev
Discord 社区 https://discord.gg/hermes-agent
示例项目集 https://github.com/hermes-agent/examples
Docker Hub https://hub.docker.com/r/hermesai/agent
在线 Demo https://demo.hermes-agent.dev

⚠️ 免责声明:本文所有代码示例基于公开的 Hermes Agent 项目文档整理。具体版本请以官方最新文档为准。API Keys 请勿硬编码,建议使用环境变量管理。向量数据库和 LLM 的成本会因使用量而变化,请务必配置预算上限。


原创不易,转载前请先联系作者并注明出处。

Logo

Agent 垂直技术社区,欢迎活跃、内容共建。

更多推荐