第 08 期 | Context Files 与工作区感知

更新于 2026/4/15

好的,作为技术教育专家,我将为你撰写 Hermes Agent 教程的第 8 期文章。


副标题:掌握 .hermes/context 目录的使用,让 Agent 自动理解你的项目结构和团队约定。

在之前的课程中,我们学习了如何通过 Skills 让 Agent 掌握新能力,通过 Memory 让 Agent 拥有跨会话记忆。这些机制极大地增强了 Agent 的动态交互能力。然而,在真实的开发场景中,我们常常需要 Agent 理解并遵守一些静态的、项目级别的规则,例如项目的目录结构、团队的编码规范、API 设计准则等。如果每次交互都要重复告知 Agent 这些信息,效率将极其低下。

本期,我们将深入探讨 Hermes Agent 的一个核心特性——工作区感知 (Workspace Awareness),以及实现这一特性的关键:.hermes/context 目录。通过它,我们可以为 Agent "一次性" 注入项目背景知识,使其在后续的所有交互中都能像一位经验丰富的团队成员一样,遵循既定规则行事。


学习目标

完成本期课程后,你将能够:

  1. 理解工作区感知 (Workspace Awareness) 的核心价值:明白为什么让 Agent 理解当前工作环境至关重要。
  2. 掌握 .hermes/context 目录的机制:了解其工作原理,以及 Agent 是如何利用其中的文件来构建上下文的。
  3. 学会构建高效的上下文文件:学习如何组织和编写不同类型的上下文信息,如项目结构、编码规范、API 约定等。
  4. 实战应用:通过一个完整的示例,引导 Agent 在遵循项目规范的前提下,完成一个真实的编码任务。

核心概念讲解

2.1 什么是工作区感知 (Workspace Awareness)?

工作区感知,指的是 AI Agent 能够理解其当前所处的文件系统环境、项目配置、团队约定和领域知识的能力。它与我们在第四期讲到的 Memory 有本质区别:

  • Memory动态的、对话驱动的。它记录的是你与 Agent 的交互历史,是 Agent 在与你“聊天”过程中逐渐学习到的关于你的偏好和过往任务的信息。
  • Workspace Awareness静态的、环境驱动的。它源于你预先在项目中定义好的规则和文档,是 Agent 在开始任何对话前就应该了解的“项目入职手册”。

一个具备工作区感知的 Agent,不会在你要求它创建一个新的 API 路由时,随意地将代码添加到主文件 app.py 中;相反,它会检查项目规范,发现所有路由都应在 routes/ 目录下创建独立的蓝图 (Blueprint) 文件,并遵循特定的 JSON 返回格式。这种能力,是 Agent 从一个“通用聊天机器人”转变为“专业领域助手”的关键一步。

2.2 .hermes/context 目录:静态知识的注入点

Hermes Agent 实现工作区感知的核心机制,就是通过一个特殊的目录:.hermes/context

当你从某个项目目录启动 Hermes Agent 时(例如,在 /path/to/my_project/ 下执行 hermes run),Agent 会自动检查该目录下是否存在 .hermes/context 子目录。如果存在,它会递归地读取该目录下的所有文件内容,并将其作为高级别的上下文(通常是注入到 System Prompt 或类似的高优先级区域)提供给大语言模型 (LLM)。

这意味着,.hermes/context 目录下的所有内容,都会成为模型在处理该项目中每一次请求时的背景知识。

2.3 上下文注入机制 (Context Injection Mechanism)

理解其工作原理至关重要:

  1. 启动时加载:Agent 在启动时扫描 .hermes/context 目录。
  2. 内容聚合:它会读取所有文件的内容(通常按文件名排序以保证顺序),并将这些内容整合成一个大的文本块。
  3. 前置注入:这个聚合后的文本块会被放置在发送给 LLM 的请求的最前端,作为基础指令的一部分。这使得模型在分析你的具体问题之前,总会先“阅读”一遍项目规范。
  4. 持久生效:只要 Agent 在该工作区运行,这个上下文就会在每一次交互中持续生效,无需重复提供。

重要提示:上下文内容会消耗宝贵的 Token 空间。因此,.hermes/context 中的文件应遵循 简洁、清晰、准确 的原则。避免放入大型库文件、二进制文件或无关的文档。只包含指导 Agent 行为所必需的核心规则和信息。

2.4 典型用例 (Typical Use Cases)

.hermes/context 目录的威力体现在其灵活性上。以下是一些高效的用例:

  • 项目结构说明 (Project Structure)
    • 用 Markdown 或文本文件描述项目的目录树和每个目录的用途。
    • 例如:src/api/ 存放所有 API 蓝图,src/models/ 存放数据库模型。
  • 编码规范与风格指南 (Coding Standards & Style Guides)
    • 指定代码风格(如 PEP 8)、命名约定(如变量使用 snake_case,类使用 CamelCase)。
    • 规定日志格式、错误处理方式等。
  • API 文档与数据模型 (API Docs & Data Models)
    • 定义标准的 API 响应结构,如 { "status": "success", "data": {...} }{ "status": "error", "message": "..." }
    • 提供核心数据模型的字段定义和类型。
  • 部署流程与环境配置 (Deployment & Environment)
    • 说明项目如何构建、测试和部署。
    • Dockerfile 的关键指令解释,或 CI/CD 流程的简要说明。
  • 领域知识与业务术语 (Domain Knowledge & Business Terminology)
    • 解释项目特有的业务术语,例如“什么是'活跃用户'的定义?”、“'结算周期'是如何计算的?”。

通过将这些“隐性知识”显式化,你极大地降低了 Agent 产生不符合项目要求代码的概率。

💻 实战演示

现在,让我们通过一个完整的场景,体验 .hermes/context 的强大之处。

场景:我们有一个基于 Python Flask 的 Web 应用项目。我们需要让 Hermes Agent 帮助我们添加一个新的 API endpoint,用于获取用户信息。我们要求 Agent 必须遵循团队制定的项目结构和 API 规范。

第 1 步:准备项目环境

首先,创建一个简单的 Flask 项目结构。

# 创建项目根目录
mkdir my_flask_project && cd my_flask_project

# 创建应用目录结构
mkdir -p src/routes src/models

# 创建主应用文件
touch src/__init__.py
touch src/app.py

# 创建一个空的模型文件
touch src/models/user.py

# 创建一个空的路由文件
touch src/routes/health.py

# 创建依赖文件
touch requirements.txt

# 创建我们的核心目录
mkdir -p .hermes/context

使用 tree 命令查看我们的项目结构(如果未安装,请使用 sudo apt-get install treebrew install tree):

tree .

输出应如下所示:

.
├── .hermes
│   └── context
├── requirements.txt
└── src
    ├── __init__.py
    ├── app.py
    ├── models
    │   └── user.py
    └── routes
        └── health.py

现在,填充一些基础代码。

src/app.py:

# src/app.py
from flask import Flask

def create_app():
    app = Flask(__name__)

    # 导入并注册蓝图
    from .routes.health import health_bp
    app.register_blueprint(health_bp, url_prefix='/api/v1')

    # 在这里我们将动态注册其他蓝图
    
    return app

if __name__ == '__main__':
    app = create_app()
    app.run(debug=True)

src/routes/health.py:

# src/routes/health.py
from flask import Blueprint, jsonify

health_bp = Blueprint('health', __name__)

@health_bp.route('/health', methods=['GET'])
def health_check():
    """Health check endpoint."""
    return jsonify({
        "status": "success",
        "data": {
            "service": "my_flask_project",
            "status": "ok"
        }
    })

第 2 步:定义我们的“团队约定”

这是最关键的一步。我们在 .hermes/context 目录下创建几个文件,用来定义我们的规则。

.hermes/context/01-project-architecture.md

# Project Architecture Guide

1.  **Directory Structure**:
    -   `src/app.py`: Main Flask application factory.
    -   `src/routes/`: Contains all API Blueprints. Each feature set should have its own file (e.g., `users.py`, `products.py`).
    -   `src/models/`: Contains all SQLAlchemy or data-related models.

2.  **Blueprints**:
    -   All new API endpoints MUST be implemented within a Flask Blueprint.
    -   Blueprints must be defined in the `src/routes/` directory.
    -   The main `create_app` function in `src/app.py` is responsible for registering blueprints.

.hermes/context/02-api-conventions.md

# API Conventions

1.  **Versioning**: All API endpoints must be versioned under the `/api/v1/` prefix.

2.  **Response Structure**: All JSON responses MUST follow this structure:
    -   **Success**: `{"status": "success", "data": <payload>}`
    -   **Error**: `{"status": "error", "message": "<error_description>"}`

3.  **Naming**:
    -   Endpoint URLs should be plural and use kebab-case (e.g., `/users`, `/product-orders`).
    -   Blueprint variables should end with `_bp` (e.g., `users_bp`).

.hermes/context/03-coding-style.md

# Coding Style Guide

1.  **Imports**: Use absolute imports from the `src` root (e.g., `from src.models.user import User`).
2.  **Docstrings**: All public functions and API endpoints must have a clear docstring explaining their purpose.
3.  **Logging**: Use the standard Python `logging` module. Do not use `print()` statements for debugging in production code.

现在,我们的 .hermes/context 目录包含了项目架构、API 约定和编码风格三个方面的清晰指令。

第 3 步:启动 Agent 并下达任务

在项目根目录 (my_flask_project) 启动 Hermes Agent。

hermes run

Agent 启动后,它会静默地加载 .hermes/context 里的所有内容。现在,我们向它提出我们的需求。

用户 Prompt: 你好,请帮我在项目中添加一个新的 API 功能。我需要一个 endpoint,路径是 /users/<user_id>,通过 GET 请求可以获取指定用户的信息。暂时先返回一个模拟的用户数据即可。

第 4 步:分析 Agent 的响应

一个没有工作区感知的 Agent 可能会这样做:

  1. 直接修改 src/app.py
  2. 使用 @app.route('/users/<user_id>') 装饰器。
  3. 返回一个简单的字典 {"id": user_id, "name": "Test User"}

但是,一个已经学习了我们上下文的 Hermes Agent,会给出截然不同的、更专业的响应。

预期的 Agent 响应 (分析与代码):

好的,收到。根据您项目中的架构指南和 API 约定,我将为您创建这个新的用户 Endpoint。

为了遵循规范,我将执行以下操作:

  1. src/routes/ 目录下创建一个新文件 users.py 来存放用户相关的路由。
  2. 在该文件中定义一个名为 users_bp 的新 Flask Blueprint。
  3. 实现 /users/<user_id> endpoint,并确保其 JSON 响应格式符合 { "status": "success", "data": ... } 的约定。
  4. 最后,我将提供需要在 src/app.py 中添加的代码,以便注册这个新的 Blueprint。

步骤 1: 创建新文件 src/routes/users.py

# src/routes/users.py
from flask import Blueprint, jsonify

# 遵循 `_bp` 命名约定
users_bp = Blueprint('users', __name__)

@users_bp.route('/users/<user_id>', methods=['GET'])
def get_user(user_id):
    """Fetches information for a specific user."""
    # 模拟用户数据
    mock_user = {
        "id": user_id,
        "name": "John Doe",
        "email": "[email protected]"
    }
    
    # 遵循标准的成功响应结构
    return jsonify({
        "status": "success",
        "data": mock_user
    })

步骤 2: 在 src/app.py 中注册新的 Blueprint

请打开 src/app.py 文件,并添加以下两行代码:

# src/app.py
from flask import Flask

def create_app():
    app = Flask(__name__)

    # 导入并注册蓝图
    from .routes.health import health_bp
    # 新增导入
    from .routes.users import users_bp

    app.register_blueprint(health_bp, url_prefix='/api/v1')
    # 新增注册,并应用 /api/v1 前缀
    app.register_blueprint(users_bp, url_prefix='/api/v1')

    return app

# ... (文件其余部分保持不变)

请检查以上代码。如果您确认无误,我可以为您应用这些更改。

分析

  • 遵循了项目结构:Agent 正确地建议在 src/routes/ 下创建新文件,而不是污染 app.py。这是因为它学习了 01-project-architecture.md
  • 使用了 Blueprint:Agent 知道要使用 Blueprint,并正确地命名为 users_bp。这同样来自 01-project-architecture.md02-api-conventions.md
  • 遵守了 API 约定:返回的 JSON 结构完全符合 02-api-conventions.md 中定义的规范。URL 前缀 /api/v1/ 也在注册蓝图时被正确应用。
  • 代码风格良好:代码包含了清晰的文档字符串,符合 03-coding-style.md 的要求。

这个例子清晰地展示了,通过预置上下文,Agent 的行为从“猜测”变为了“遵循”,其输出质量和项目契合度得到了质的飞跃。

涉及命令

本次课程中我们使用到的终端命令:

  • mkdir -p <path>: 创建多级目录。
  • touch <file>: 创建空文件。
  • tree .: 以树状图展示当前目录结构。
  • hermes run: 在当前工作区启动 Hermes Agent。

要点回顾

  1. 工作区感知是关键:它让 Agent 从通用工具转变为能够深度融入特定项目流程的专业助手。
  2. .hermes/context 是核心:这是向 Agent 注入静态、项目级知识的标准方式。
  3. 上下文在每次交互中都生效:Agent 在当前工作区的所有对话都会受到 .hermes/context 内容的影响。
  4. 结构化你的上下文:将不同类型的规范(架构、API、代码风格)拆分到不同的文件中,可以使上下文更清晰、更易于维护。
  5. 简洁至上:上下文会占用 Token,因此内容必须精炼、准确,只包含必要的指导性信息。
  6. 自动化团队规范.hermes/context 是一个绝佳的工具,可以用来自动化地向新成员(无论是人类还是 AI)传授团队的最佳实践和技术约定。

通过熟练运用 Context Files,你将能把 Hermes Agent 调教成真正懂你项目、懂你团队的得力助手,从而在开发工作中实现更高层次的人机协作。

参考资料