Energy-system-agent 工具函数详尽指南
本文档提供了 tools.py 中所有工具函数的详尽技术参考,包括其内部实现代码、参数逻辑以及与后台 IPython 会话的交互方式。
1. 核心辅助与架构设计
在深入具体工具前,了解两个核心的内部辅助函数至关重要,它们确保了所有工具的输出格式一致且能够正确访问会话。
统一返回格式
_format_tool_result 用于将工具的执行结果封装为标准的 JSON 字符串,确保 Agent 能够稳定解析。
python
def _format_tool_result(success: bool, message: str, data: Any = None) -> str:
"""统一工具返回格式为 JSON 字符串"""
return json.dumps({
"success": success,
"message": message,
"data": data
}, ensure_ascii=False)
会话访问
_get_session 负责从全局管理器中提取当前活跃的 IPython 会话。
python
def _get_session():
if _active_session_id is None:
return None
return manager.get_session(_active_session_id)
2. 会话管理工具
启动建模会话 (start_modeling_session)
该工具是所有建模任务的起点。它不仅启动后台进程,还预先导入了必要的库并定义了 SessionState 类来跟踪建模进度。
python
@tool
def start_modeling_session(force_new: bool = False) -> str:
global _active_session_id, _code_history
# 复用现有活跃会话
if not force_new and _active_session_id:
session = manager.get_session(_active_session_id)
if session and session.is_active:
return _format_tool_result(True, f"正在使用现有活跃会话...", {"session_id": _active_session_id})
# 创建新会话并注入基础环境代码
_active_session_id = manager.create_session()
_code_history = [
"import pandas as pd",
"import os",
"from oemof.solph import EnergySystem, Bus, Flow, Model, views",
"from oemof.solph.components import Source, Sink, Converter, GenericStorage",
"import matplotlib.pyplot as plt",
"class SessionState:",
" def __init__(self):",
" self.es = None",
" self.buses = {}",
" self.results = None",
"session = SessionState()"
]
return _format_tool_result(True, f"会话已启动...", {"session_id": _active_session_id})
3. 建模基础工具
执行自定义代码 (run_custom_code)
这是最底层的核心工具,允许 Agent 在 IPython 环境中执行任何复杂的 Python 逻辑。
python
@tool
def run_custom_code(code: str) -> str:
session = _get_session()
if not session:
return _format_tool_result(False, "没有活跃的会话...")
result = session.run_code(code)
if result["status"] == "success":
_code_history.append(code) # 记录代码历史,用于后续生成脚本
return _format_tool_result(True, result["output"], {"result": result["result"]})
else:
return _format_tool_result(False, f"代码运行失败: {result['error']}", {"output": result['output']})
初始化能源系统 (init_energy_system)
通过执行一段特定的代码来实例化 oemof.solph.EnergySystem。
python
@tool
def init_energy_system(time_steps: int = 24) -> str:
code = f"""
date_time_index = pd.date_range('2024-01-01', periods={time_steps}, freq='H')
session.es = EnergySystem(timeindex=date_time_index, infer_last_interval=True)
session.buses = {{}}
print(f"EnergySystem initialized with {time_steps} time steps.")
"""
res_str = run_custom_code.invoke(code)
return res_str
4. 组件添加工具
添加总线 (add_bus)
python
@tool
def add_bus(label: str) -> str:
code = f"""
if session.es is None: raise ValueError("EnergySystem not initialized.")
if '{label}' in session.buses:
print("Bus '{label}' already exists.")
else:
bus = Bus(label='{label}')
session.buses['{label}'] = bus
session.es.add(bus)
print("Bus '{label}' added successfully.")
"""
return run_custom_code.invoke(code)
添加源与汇 (add_source, add_sink)
这两者逻辑相似,通过构造 Flow 对象来实现。以下以 add_source 为例:
python
@tool
def add_source(label: str, bus_label: str, variable_costs: float = 0, nominal_value: Optional[float] = None, fix: Optional[List[float]] = None) -> str:
# 动态构造 Flow 参数字符串
nom_val_str = f"nominal_value={nominal_value}" if nominal_value is not None else ""
fix_str = f"fix={fix}" if fix is not None else ""
params_str = ", ".join([p for p in [f"variable_costs={variable_costs}", nom_val_str, fix_str] if p])
code = f"""
source = Source(label='{label}', outputs={{session.buses['{bus_label}']: Flow({params_str})}})
session.es.add(source)
"""
return run_custom_code.invoke(code)
5. 求解与结果处理工具
模型求解 (solve_model)
这是最复杂的工具之一。它不仅调用求解器,还会:
- 检查
EnergySystem是否为空。 - 提取优化结果并将其展开(flatten)为 CSV。
- 自动持久化 :将所有历史执行的代码合并为一个完整的
.py脚本保存,以便用户离线运行。
python
@tool
def solve_model(solver: str = 'cbc') -> str:
code = f"""
model = Model(session.es)
solve_res = model.solve(solver_name='{solver}')
# ... 结果处理逻辑:提取 sequences 并保存为 results.csv ...
"""
res_str = run_custom_code.invoke(code)
res_json = json.loads(res_str)
if res_json["success"]:
# 核心功能:保存完整的建模脚本
script_path = session.save_model_script(_code_history)
return _format_tool_result(True, f"{res_json['message']}\n脚本已保存: {script_path}", {"script_path": script_path})
return res_str
图表保存 (save_modeling_plot)
通过正则表达式从后台输出中提取文件路径并返回。
python
@tool
def save_modeling_plot(filename: str) -> str:
code = f"""
results_path = os.path.join(RESULTS_DIR, "{filename}")
plt.savefig(results_path)
plt.close()
"""
res_str = run_custom_code.invoke(code)
# ... 正则提取逻辑 ...
总结
Energy-system-agent 的工具设计哲学是 "代码即协议"。Agent 通过自然语言生成的意图,最终都被转化为这一系列严谨的工具调用,在隔离的 IPython 沙箱中精准地构建出能源系统的数学模型。