# 10.5 实战：MiniHarness 生产化加固

本节展示如何将 MiniHarness（第 2 章的简化版 Agent 框架）升级为生产级系统。核心设计决策是“分层配置、插件热加载、结构化可观测性”。

> 完整代码见 `lab/mini_harness/`，本节聚焦生产架构设计与关键实现模式。

## 10.5.1 生产架构演进

从 v1（教学版）到 v2（生产版）的升级关键点：

| 维度   | v1 教学版   | v2 生产版        | 设计决策          |
| ---- | -------- | ------------- | ------------- |
| 配置   | 硬编码      | 分层加载（文件+环境变量） | 支持多环境、热更新     |
| 插件   | 静态注册     | 动态加载 + 清单管理   | 生产中不重启添加工具    |
| 提示词  | 单模板      | 模板库 + 渲染引擎    | 支持不同 Agent 角色 |
| 可观测性 | print 日志 | 结构化日志 + 分布式追踪 | 生产运维必需        |
| 性能   | 同步执行     | 异步 + 并发 + 缓存  | 低延迟、高吞吐       |

## 10.5.2 分层配置系统

配置的核心原则是“环境驱动、分离 secrets、默认值合理”。设计一个三层加载机制：

```python
import json
import os
from dataclasses import dataclass, field
from typing import Dict, List

@dataclass
class MiniHarnessConfig:
    # 第1层：类型定义和默认值
    environment: str  # 'development' | 'production'
    model_name: str = "claude-sonnet-4-6"
    max_tokens: int = 2048
    temperature: float = 0.7
    enable_cache: bool = True
    log_level: str = "INFO"
    plugin_dirs: List[str] = field(default_factory=list)
    feature_flags: Dict[str, bool] = field(default_factory=dict)

    # 第2层：从文件加载（含验证）
    @classmethod
    def from_file(cls, path: str) -> 'MiniHarnessConfig':
        with open(path) as f:
            data = json.load(f)
        # 验证必需字段、类型检查、边界值检查
        return cls(**data)

    # 第3层：从环境变量覆盖（生产优先级最高）
    @classmethod
    def from_env(cls) -> 'MiniHarnessConfig':
        return cls(
            environment=os.getenv('HARNESS_ENV', 'production'),
            model_name=os.getenv('HARNESS_MODEL', 'claude-sonnet-4-6'),
            # 其他变量...
        )
```

完整配置实现参见 `lab/mini_harness/utils/config.py`。设计要点：

1. **层级继承**：环境变量 > 配置文件 > 默认值
2. **类型安全**：Pydantic 验证而非手动检查
3. **Secrets 隔离**：不在配置文件中存储 API Key，仅通过环境变量

## 10.5.3 插件动态加载架构

插件系统支持“不重启添加工具”，关键是清单驱动设计：

```python
class PluginLoader:
    def load_from_directory(self, plugin_dir: str):
        """扫描目录中的所有插件清单"""
        for subdir in Path(plugin_dir).iterdir():
            manifest_path = subdir / 'manifest.json'
            if manifest_path.exists():
                self.load_plugin(subdir, manifest_path)

    def load_plugin(self, plugin_dir: str, manifest_path: str):
        """根据清单加载单个插件"""
        manifest = json.load(manifest_path)
        # 清单格式：
        # {
        #   "name": "search_plugin",
        #   "tools": [
        #     {"name": "web_search", "handler": "handlers.py", "function": "search"}
        #   ]
        # }

        for tool_spec in manifest['tools']:
            # 动态导入处理函数
            handler = self._import_handler(plugin_dir, tool_spec)
            self.register_tool(tool_spec['name'], handler)
```

设计优势：

1. **零重启热加载**：新增 `plugin/new_tool/manifest.json`，应用启动时自动发现
2. **隔离性**：每个插件独立目录，互不污染
3. **版本管理**：清单中可记录 plugin version，支持灰度升级

上述代码为概念示意；MiniHarness 中插件热加载属于进阶能力，当前仓库以 `lab/mini_harness/tools/registry.py` 与 `lab/mini_harness/tools/builtin.py` 为基础，读者可参考示意自行扩展为清单驱动的 Loader。

## 10.5.4 提示词模板库

不同的 Agent 需要不同的角色定义。通过模板库管理：

```python
class PromptTemplateLibrary:
    def _register_default_templates(self):
        # 通用 Agent 模板
        self.register('default_agent', PromptTemplate(
            system="You are a helpful AI assistant...",
            user="User request: {user_input}"
        ))

        # 研究 Agent 模板
        self.register('research_agent', PromptTemplate(
            system="You are a research specialist...",
            user="Research topic: {topic}"
        ))
```

每个模板支持变量插值，让提示词通用化。设计决策：

1. **模板复用**：同一模板可用于不同用户请求
2. **动态注册**：可在运行时添加新模板（在 `before_execute` 钩子中）
3. **版本控制**：模板保存在版本库中，便于 A/B 测试

上述代码为概念示意；MiniHarness 当前未在仓库中提供独立的模板库模块，读者可基于本节示意将模板集成到 `lab/mini_harness/core/agent.py` 的系统提示词构建流程中。

## 10.5.5 核心智能体执行流

Agent 的生产实现重点在“多轮交互、错误恢复、可观测性”：

```python
async def execute(self, user_input: str) -> Dict:
    """多轮 Agent 循环"""
    max_turns = 10
    messages = []

    for turn in range(max_turns):
        # 调用 Claude API
        response = await self.client.messages.create(
            model=self.config.model_name,
            max_tokens=self.config.max_tokens,
            messages=messages,
            system=system_prompt
        )

        content = response.content[0].text

        # 解析是否有工具调用
        tool_calls = self._parse_tool_calls(content)
        if not tool_calls:
            return {'status': 'success', 'result': content}

        # 并发执行工具(最多 N 个)
        results = await self._execute_tools_concurrent(tool_calls)

        # 将结果反馈给 Claude
        messages.append({'role': 'assistant', 'content': content})
        messages.append({'role': 'user', 'content': self._format_results(results)})

    return {'status': 'max_turns_exceeded'}
```

关键设计：

1. **工具并发**：使用 `asyncio.gather()` 加速多工具执行
2. **超时保护**：每个工具调用加超时控制，防止卡住
3. **错误恢复**：工具失败不中断流程，反馈失败信息给 Claude

完整实现参见 `lab/mini_harness/core/agent.py` 与 `lab/mini_harness/runtime/engine.py`。

## 10.5.6 部署清单

生产部署前的关键检查点：

配置与环境 \[ ] .env 文件包含所有必需的 API Key 和端点 \[ ] 生产/开发环境配置文件已分离（config.prod.json/config.dev.json） \[ ] 日志级别在生产中设为 INFO（不是 DEBUG）

插件与工具 \[ ] 所有必需的插件清单已加载 \[ ] 插件目录结构正确（plugin/\*/manifest.json） \[ ] 工具超时设置合理（API 调用通常 30-60s）

可观测性 \[ ] 结构化日志已配置（JSON 格式） \[ ] 分布式追踪链路已接入（trace\_id 在日志中） \[ ] 关键指标已导出（工具调用数、错误率、延迟）

性能与可靠性 \[ ] 异步并发数设置合理（5-10 个并发工具） \[ ] 请求超时设置（通常 60-120s） \[ ] 重试策略已配置（指数退避）

## 10.5.7 总结

MiniHarness 生产版的四大支柱：

1. **分层配置**：环境变量驱动，支持多环境
2. **插件热加载**：不重启添加工具，清单驱动发现
3. **提示词模板库**：支持多种 Agent 角色
4. **异步并发架构**：低延迟、高吞吐、错误恢复


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://yeasy.gitbook.io/harness_engineering_guide/di-san-bu-fen-xi-tong-ji-cheng-yu-gong-cheng-shi-jian/10_production/10.5_miniharness_production.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
