🤖 第8期:Agents智能体 — 给高炉装上"自主决策大脑"
专栏:《LangChain框架在高炉炼铁智能化领域的应用》
前情回顾:上期我们用 RAG 给 AI 配了"知识库"
本期重点:Agent —— 让 AI 从"被动回答"升级为"主动思考和行动"
🎯 引言:从"问答机器"到"智能体"
回顾一下我们已经走过的路:
第2期 Prompt → AI会听懂高炉术语了
第5期 Memory → AI能记住对话上下文了
第6期 Chain → AI能按步骤执行任务了
第7期 RAG → AI会查资料了
等等……这些好像都是被动的?🤔
你问一句,AI答一句。就像一个"有问必答机",不推不走,不打不动。
但真实的工业场景需要的是——主动思考、自主决策、自动执行的智能体!
❌ 普通AI(被动):
用户提问 → AI回答 → 等待下一个问题
✅ Agent(主动):
用户提问 → AI思考需要什么工具 → 调用工具获取数据
→ 分析数据 → 再思考需要什么工具 → 再调用工具
→ 综合所有信息 → 给出最终答案
Agent 的本质 = LLM + 推理 + 工具调用 🧠🔧
🧩 Agent 是如何"思考"的?
Agent 的工作方式叫做 ReAct(Reasoning + Acting)——边思考边行动!
Round 1:
思考(Thought): "用户问炉况是否正常,我需要查当前参数"
行动(Action): 调用 query_furnace_param 工具
观察(Observe): 收到参数数据
Round 2:
思考(Thought): "风温正常,但铁温偏低,需要查历史趋势"
行动(Action): 调用 query_history_trend 工具
观察(Observe): 收到趋势数据
Round 3:
思考(Thought): "综合来看,炉温有下行趋势,建议加焦"
行动(Action): 给出最终答案
这个过程就像人类专家的思考方式:查数据 → 分析 → 再查数据 → 综合分析 → 下结论 🔄
💻 实战:打造高炉智能体 Agent
Step 1: 定义工具集
# 📁 bf_agent_tools.py
# 高炉智能体的工具集
from langchain.tools import tool
from typing import Optional
@tool
def get_furnace_params(furnace_name: str) –> str:
"""
获取高炉当前运行参数
furnace_name: 高炉名称,如"5号高炉"
"""
# 模拟数据,真实场景连接SCADA系统
params_db = {
"5号高炉": {
"风温": "1205°C", "风压": "0.392MPa",
"风量": "4920m³/min", "铁水温度": "1490°C",
"硅含量": "0.42%", "焦比": "362kg/t",
"利用系数": "2.38", "透气性指数": "33.8",
"料速": "6.3批/h", "炉渣碱度": "1.18"
},
"6号高炉": {
"风温": "1210°C", "风压": "0.385MPa",
"风量": "4850m³/min", "铁水温度": "1505°C",
"硅含量": "0.48%", "焦比": "355kg/t",
"利用系数": "2.42", "透气性指数": "34.5",
"料速": "6.5批/h", "炉渣碱度": "1.20"
}
}
params = params_db.get(furnace_name, {})
if not params:
return f"未找到{furnace_name}的数据"
result = f"\\n【{furnace_name} 当前参数】\\n"
for key, value in params.items():
result += f" {key}: {value}\\n"
return result
@tool
def get_param_history(furnace_name: str, param_name: str, hours: int = 8) –> str:
"""
查询参数的历史变化趋势
furnace_name: 高炉名称
param_name: 参数名称
hours: 回溯小时数
"""
# 模拟趋势数据
trends = {
"铁水温度": "先降后稳",
"硅含量": "缓慢下降",
"风温": "稳定",
"风压": "略有上升"
}
trend = trends.get(param_name, "无明显趋势")
return f"{furnace_name}的{param_name}在过去{hours}小时内趋势:{trend}"
@tool
def calculate_furnace_params(param_a: float, param_b: float, operation: str) –> str:
"""
计算高炉参数(如透气性指数、焦比等)
param_a: 参数A
param_b: 参数B
operation: 计算类型 (permeability/coke_ratio/others)
"""
if operation == "permeability":
result = param_a / param_b # 透气性 = 风量/风压
return f"透气性指数 = {param_a}/{param_b} = {result:.1f}"
elif operation == "coke_ratio":
result = param_a / param_b * 1000
return f"焦比 = {param_a}/{param_b}*1000 = {result:.1f} kg/t"
else:
return f"计算完成: {param_a} 和 {param_b} 的 {operation} 结果为: {param_a + param_b}"
Step 2: 构建Agent
# 📁 bf_agent.py
# 高炉智能体主程序
from langchain.agents import create_agent
from langchain_openai import ChatOpenAI
from langgraph.graph import MessagesState
from langgraph.graph.message import add_messages
from langchain_core.messages import AnyMessage
from langchain.agents.middleware import wrap_tool_call
from langchain.messages import ToolMessage
from typing import Annotated
# ─────────── 状态管理(带滑动窗口记忆) ───────────
MAX_MESSAGES = 40
def windowed_messages(old, new):
return add_messages(old, new)[–MAX_MESSAGES:]
class BFAgentState(MessagesState):
messages: Annotated[list[AnyMessage], windowed_messages]
# ─────────── 工具错误处理中间件 ───────────
@wrap_tool_call
def handle_tool_errors(request, handler):
"""工具执行错误处理"""
try:
return handler(request)
except Exception as e:
return ToolMessage(
content=f"工具执行出错: {str(e)},请检查参数后重试",
tool_call_id=request.tool_call["id"]
)
# ─────────── 构建Agent ───────────
def build_blast_furnace_agent():
"""构建高炉智能体"""
llm = ChatOpenAI(
model="doubao-seed-2-0-lite-260215",
temperature=0.2,
timeout=600
)
agent = create_agent(
model=llm,
system_prompt="""🏭 你是高炉炼铁智能体助手,具备以下能力:
【角色定位】
你是一位拥有30年经验的高炉炼铁首席专家,精通高炉工艺、数据分析与故障诊断。
【可用工具】
1. get_furnace_params – 查询高炉实时参数
2. get_param_history – 查询参数历史趋势
3. calculate_furnace_params – 计算复合参数
【行为准则】
1. 自主思考:根据用户问题,自主决定需要调用哪些工具
2. 数据驱动:每次分析必须引用实际数据,不能凭空判断
3. 多步推理:复杂问题要分步处理,逐步深入
4. 专业输出:给出明确的结论和可操作的建议
5. 安全优先:发现异常情况要优先提示安全风险
【输出规范】
– 每次回答先给出数据依据
– 再给出分析结论
– 最后给出操作建议
""",
tools=[
get_furnace_params,
get_param_history,
calculate_furnace_params
],
middleware=[handle_tool_errors],
state_schema=BFAgentState
)
return agent
# ─────────── 运行Agent ───────────
def chat_with_agent(agent, user_input: str, thread_id: str = "bf-furnace-5"):
"""与Agent对话"""
config = {"configurable": {"thread_id": thread_id}}
result = agent.invoke(
{"messages": [{"role": "user", "content": user_input}]},
config
)
# 显示完整对话过程
print(f"\\n👨🏭 你: {user_input}")
for msg in result["messages"]:
if msg.type == "ai" and msg.content:
print(f"\\n🤖 Agent: {msg.content}")
elif msg.type == "tool":
print(f" 🔧 [工具调用] {msg.name}: {msg.content[:80]}…")
return result
# ─────────── 主程序 ───────────
if __name__ == "__main__":
agent = build_blast_furnace_agent()
# 测试1:简单的参数查询
chat_with_agent(agent, "帮我查一下5号高炉当前的铁水温度和硅含量")
# 测试2:复杂分析(需要多步推理)
chat_with_agent(agent,
"5号高炉最近铁水温度有点低,帮我查一下当前参数,"
"再看看8小时内的趋势变化,综合分析一下炉况"
)
# 测试3:计算类任务
chat_with_agent(agent,
"帮我算一下透气性指数,风量是4920,风压是0.392"
)
🔥 Agent 的"思考过程"全解析
当 Agent 执行复杂任务时,背后发生了什么?让我们揭开黑盒 👇
案例:查参数 + 查趋势 + 综合分析
用户输入:“5号高炉铁水温度有点低,帮我查查当前参数和趋势”
Agent 的"内心戏" 🔍:
=== ReAct 思考循环开始 ===
🤔 Thought 1:
"用户说铁温低,我需要先查一下当前所有参数"
⚡ Action 1: get_furnace_params(furnace_name="5号高炉")
👀 Observation 1: 风温1205°C, 铁水温度1490°C, 硅含量0.42%…
🤔 Thought 2:
"铁温1490°C在正常区间但偏低,硅含量0.42%正常。
用户说'有点低',我需要查查历史趋势确认是否在下降"
⚡ Action 2: get_param_history(furnace_name="5号高炉", param_name="铁水温度", hours=8)
👀 Observation 2: 铁水温度在过去8小时内趋势:先降后稳
🤔 Thought 3:
"现在我有当前参数和历史趋势了。
当前铁温1490°C处于正常区间(1480-1520°C),
但处于区间偏低位置,趋势是'先降后稳'——说明之前下降但现在稳住了。
硅含量0.42%正常,整体来看炉况稳定但偏保守。"
✅ Final Answer: 给出综合分析结果
Agent 最终输出:
📊 【数据分析】
• 铁水温度:1490°C(正常区间1480-1520°C,处于偏低位置)
• 硅含量:0.42%(正常范围0.35-0.55%,处于合理区间)
• 8小时趋势:铁温先降后稳,目前已趋于稳定
🔍 【综合分析】
铁水温度1490°C虽然偏低,但结合硅含量0.42%来看,
炉热水平尚可,且趋势已企稳,无需过度担忧。
💡 【操作建议】
1. 建议保持当前操作,继续观察2-3炉
2. 如铁温继续降至1485°C以下,可小幅度加焦
3. 密切注意硅含量变化,若持续下降也需干预
🆚 Agent vs Chain:什么时候该用谁?
| 执行方式 | 固定流程 | 动态决策 |
| 步骤数量 | 预先确定 | 不确定,根据情况动态决定 |
| 工具调用 | 需手动编排 | 自主决定调用哪些工具 |
| 适用场景 | 流程固定的任务(如日报生成) | 需要判断和决策的复杂任务 |
| 灵活度 | 低 | 高 |
| 可控性 | 高 | 低(LLM可能"跑偏") |
| 高炉应用 | 自动报表、数据清洗 | 炉况诊断、异常处理 |
选择建议:流程固定的用 Chain,需要判断决策的用 Agent 👌
⚡ Agent 高阶技巧
1️⃣ 限制 Agent “脑补”
# 在 System Prompt 中加入约束
system_prompt = """
…
【使用边界】
– 仅在工具有效范围内回答
– 不确定时,请说"需要进一步确认"
– 禁止编造数据或猜测结论
– 涉及安全问题时必须优先提醒
"""
2️⃣ 设置最大迭代次数
# Agent 默认有最大调用次数限制,防止无限循环
agent = create_agent(
model=llm,
tools=tools,
system_prompt="…",
# 设置递归调用限制
recursion_limit=15 # 最多思考-行动15轮
)
3️⃣ 结合 RAG 的 Agent
# 把 RAG 检索也作为 Agent 的一个工具
@tool
def search_knowledge_base(query: str) –> str:
"""搜索高炉知识库,获取相关技术资料"""
# 这里是上一期的 RAG 检索代码
# …
return relevant_docs
# 这样 Agent 就能综合使用"查询数据"+"查资料"两种能力!
📊 本期小结
| Agent是什么 | 有"大脑"能自主思考和行动的AI |
| ReAct模式 | 思考→行动→观察→再思考→再行动 |
| 工具集 | 给Agent配备的"工具箱" |
| 错误处理 | 工具执行失败时优雅降级 |
| 应用场景 | 复杂炉况诊断、多步推理分析 |
核心心法:
Agent 就像一个有"自主意识"的AI员工——你告诉它目标,它能自己决定怎么干。但越强大的能力越需要约束,给 Agent 设定清晰的行为边界和安全规则是工业落地的关键!
📌 下期预告
第9期:《工具调用Tool:让AI学会操作高炉仪表盘》 🔧
Agent 的"大脑"再好使,也得有"手"去干活!这些"手"就是 Tool(工具)。
在实际的高炉场景中,工具不仅仅是查数据——还可以是发送控制指令、读写数据库、调用API、发送飞书通知……
下期我们来深度探索 Tool 的进阶用法,包括带参数校验的工具、组合工具、以及自定义中间件!让你的 Agent 真正"动手干活"!🔨👷
🌟 点赞收藏关注,16期硬核内容持续输出!
作者:高炉炼铁智能化技术研究者,专注钢铁冶金与人工智能 交叉领域。
👍 如果觉得有帮助,请点赞、收藏、转发!
版权归作者所有,未经许可请勿抄袭,套用,商用(或其它具有利益性行为)。
🔔 关注专栏,不错过后续精彩内容!





