LangGraph 单位换算智能体示例
作者:追风剑情 发布于:2026-5-7 13:05 分类:AI
安装依赖
pip install -U langgraph langchain
import os
os.environ["LANGGRAPH_ALLOWED_OBJECTS"] = "core"
import warnings
warnings.filterwarnings("ignore", message="The default value of `allowed_objects` will change")
import re
from typing import TypedDict, Optional
from langgraph.graph import StateGraph, END
from langchain.tools import tool
# ========== 状态定义 ==========
class GraphState(TypedDict):
input_query: str
raw_result: str
formatted_result: str
# ========== 单位换算数据 ==========
UNITS = {
"米": 1, "公尺": 1, "m": 1, "meter": 1, "meters": 1,
"英尺": 0.3048, "ft": 0.3048, "foot": 0.3048, "feet": 0.3048, "呎": 0.3048,
"公里": 1000, "km": 1000, "kilometer": 1000,
"英里": 1609.34, "mile": 1609.34, "mi": 1609.34,
"厘米": 0.01, "cm": 0.01, "公分": 0.01,
"毫米": 0.001, "mm": 0.001,
"码": 0.9144, "yard": 0.9144, "yd": 0.9144,
}
FROM_METER_FACTOR = {
"米": 1, "公尺": 1, "m": 1, "meter": 1, "meters": 1,
"英尺": 3.28084, "ft": 3.28084, "foot": 3.28084, "feet": 3.28084, "呎": 3.28084,
"公里": 0.001, "km": 0.001,
"英里": 0.000621371, "mile": 0.000621371, "mi": 0.000621371,
"厘米": 100, "cm": 100, "公分": 100,
"毫米": 1000, "mm": 1000,
"码": 1.09361, "yard": 1.09361, "yd": 1.09361,
}
# ========== 解析函数 ==========
def parse_conversion(query: str) -> Optional[tuple[float, str, str]]:
"""解析用户查询,返回 (数值, 源单位, 目标单位)"""
cleaned = re.sub(r'[??!!。,,、\s]', '', query)
num_match = re.search(r'(\d+(?:\.\d+)?)', cleaned)
if not num_match:
return None
value = float(num_match.group(1))
rest = cleaned[num_match.end():]
matches = []
for unit in sorted(UNITS.keys(), key=len, reverse=True):
for m in re.finditer(re.escape(unit), rest):
start, end = m.start(), m.end()
matches.append((start, end, unit))
matches.sort(key=lambda x: x[1]-x[0], reverse=True)
selected = []
occupied = set()
for start, end, unit in matches:
if any(pos in occupied for pos in range(start, end)):
continue
selected.append((start, unit))
occupied.update(range(start, end))
selected.sort(key=lambda x: x[0])
if len(selected) < 2:
return None
keywords = ["等于多少", "等于", "转换为", "转成", "换算成", "转换成", "到", "是多少", "为"]
kw_pos = len(rest)
for kw in keywords:
pos = rest.find(kw)
if pos != -1:
kw_pos = pos
break
src_unit = tgt_unit = None
for pos, unit in selected:
if pos < kw_pos:
src_unit = unit
else:
tgt_unit = unit
if src_unit is None and tgt_unit is None and len(selected) >= 2:
src_unit, tgt_unit = selected[0][1], selected[1][1]
if src_unit is None or tgt_unit is None:
return None
return value, src_unit, tgt_unit
# ========== 工具函数 ==========
@tool(description="长度单位换算,例如「15米等于多少英尺」")
def unit_converter(query: str) -> str:
"""执行单位换算"""
parsed = parse_conversion(query)
if parsed is None:
return "无法解析单位换算请求,请使用如:'15米等于多少英尺' 或 '10公里转换为英里'"
value, src_unit, tgt_unit = parsed
if src_unit not in UNITS:
return f"不支持的单位:{src_unit}"
if tgt_unit not in FROM_METER_FACTOR:
return f"不支持的单位:{tgt_unit}"
value_in_meters = value * UNITS[src_unit]
result = value_in_meters * FROM_METER_FACTOR[tgt_unit]
return f"{value:.2f} {src_unit} = {result:.2f} {tgt_unit}"
# ========== LangGraph 节点 ==========
def process_query(state: GraphState) -> GraphState:
raw = unit_converter.invoke({"query": state["input_query"]})
state["raw_result"] = raw
return state
def format_result(state: GraphState) -> GraphState:
raw = state["raw_result"]
if "=" in raw:
a, b = raw.split("=")
state["formatted_result"] = f"换算结果:{a.strip()} = {b.strip()}"
else:
state["formatted_result"] = f"信息:{raw}"
return state
def build_conversion_graph():
workflow = StateGraph(GraphState)
workflow.add_node("process", process_query)
workflow.add_node("format", format_result)
workflow.set_entry_point("process")
workflow.add_edge("process", "format")
workflow.add_edge("format", END)
return workflow.compile()
# ========== 测试入口 ==========
if __name__ == "__main__":
app = build_conversion_graph()
test_queries = [
"15米等于多少英尺",
"10公里转换为英里",
"100厘米等于多少米",
"3英尺到米",
"5000毫米转换成米",
]
print("=" * 50)
print("单位换算智能体测试")
print("=" * 50)
for q in test_queries:
print(f"\n输入:{q}")
initial = {"input_query": q, "raw_result": "", "formatted_result": ""}
result = app.invoke(initial)
print(result["formatted_result"])
print("\n" + "=" * 50)
print("交互模式(输入 '退出' 结束)")
while True:
user = input("\n请输入换算需求:")
if user in ["退出", "quit", "exit"]:
print("已退出")
break
initial = {"input_query": user, "raw_result": "", "formatted_result": ""}
res = app.invoke(initial)
print(res["formatted_result"])
标签: AI
日历
最新文章
随机文章
热门文章
分类
存档
- 2026年5月(1)
- 2026年4月(7)
- 2026年3月(15)
- 2026年2月(3)
- 2026年1月(6)
- 2025年12月(1)
- 2025年11月(1)
- 2025年9月(3)
- 2025年7月(4)
- 2025年6月(5)
- 2025年5月(1)
- 2025年4月(5)
- 2025年3月(4)
- 2025年2月(3)
- 2025年1月(1)
- 2024年12月(5)
- 2024年11月(5)
- 2024年10月(5)
- 2024年9月(3)
- 2024年8月(3)
- 2024年7月(11)
- 2024年6月(3)
- 2024年5月(9)
- 2024年4月(10)
- 2024年3月(11)
- 2024年2月(24)
- 2024年1月(12)
- 2023年12月(3)
- 2023年11月(9)
- 2023年10月(7)
- 2023年9月(2)
- 2023年8月(7)
- 2023年7月(9)
- 2023年6月(6)
- 2023年5月(7)
- 2023年4月(11)
- 2023年3月(6)
- 2023年2月(11)
- 2023年1月(8)
- 2022年12月(2)
- 2022年11月(4)
- 2022年10月(10)
- 2022年9月(2)
- 2022年8月(13)
- 2022年7月(7)
- 2022年6月(11)
- 2022年5月(18)
- 2022年4月(29)
- 2022年3月(5)
- 2022年2月(6)
- 2022年1月(8)
- 2021年12月(5)
- 2021年11月(3)
- 2021年10月(4)
- 2021年9月(9)
- 2021年8月(14)
- 2021年7月(8)
- 2021年6月(5)
- 2021年5月(2)
- 2021年4月(3)
- 2021年3月(7)
- 2021年2月(2)
- 2021年1月(8)
- 2020年12月(7)
- 2020年11月(2)
- 2020年10月(6)
- 2020年9月(9)
- 2020年8月(10)
- 2020年7月(9)
- 2020年6月(18)
- 2020年5月(4)
- 2020年4月(25)
- 2020年3月(38)
- 2020年1月(21)
- 2019年12月(13)
- 2019年11月(29)
- 2019年10月(44)
- 2019年9月(17)
- 2019年8月(18)
- 2019年7月(25)
- 2019年6月(25)
- 2019年5月(17)
- 2019年4月(10)
- 2019年3月(36)
- 2019年2月(35)
- 2019年1月(28)
- 2018年12月(30)
- 2018年11月(22)
- 2018年10月(4)
- 2018年9月(7)
- 2018年8月(13)
- 2018年7月(13)
- 2018年6月(6)
- 2018年5月(5)
- 2018年4月(13)
- 2018年3月(5)
- 2018年2月(3)
- 2018年1月(8)
- 2017年12月(35)
- 2017年11月(17)
- 2017年10月(16)
- 2017年9月(17)
- 2017年8月(20)
- 2017年7月(34)
- 2017年6月(17)
- 2017年5月(15)
- 2017年4月(32)
- 2017年3月(8)
- 2017年2月(2)
- 2017年1月(5)
- 2016年12月(14)
- 2016年11月(26)
- 2016年10月(12)
- 2016年9月(25)
- 2016年8月(32)
- 2016年7月(14)
- 2016年6月(21)
- 2016年5月(17)
- 2016年4月(13)
- 2016年3月(8)
- 2016年2月(8)
- 2016年1月(18)
- 2015年12月(13)
- 2015年11月(15)
- 2015年10月(12)
- 2015年9月(18)
- 2015年8月(21)
- 2015年7月(35)
- 2015年6月(13)
- 2015年5月(9)
- 2015年4月(4)
- 2015年3月(5)
- 2015年2月(4)
- 2015年1月(13)
- 2014年12月(7)
- 2014年11月(5)
- 2014年10月(4)
- 2014年9月(8)
- 2014年8月(16)
- 2014年7月(26)
- 2014年6月(22)
- 2014年5月(28)
- 2014年4月(15)
友情链接
- Unity官网
- Unity圣典
- Unity在线手册
- Unity中文手册(圣典)
- Unity官方中文论坛
- Unity游戏蛮牛用户文档
- Unity下载存档
- Unity引擎源码下载
- Unity服务
- Unity Ads
- wiki.unity3d
- Visual Studio Code官网
- SenseAR开发文档
- MSDN
- C# 参考
- C# 编程指南
- .NET Framework类库
- .NET 文档
- .NET 开发
- WPF官方文档
- uLua
- xLua
- SharpZipLib
- Protobuf-net
- Protobuf.js
- OpenSSL
- OPEN CASCADE
- JSON
- MessagePack
- C在线工具
- 游戏蛮牛
- GreenVPN
- 聚合数据
- 热云
- 融云
- 腾讯云
- 腾讯开放平台
- 腾讯游戏服务
- 腾讯游戏开发者平台
- 腾讯课堂
- 微信开放平台
- 腾讯实时音视频
- 腾讯即时通信IM
- 微信公众平台技术文档
- 白鹭引擎官网
- 白鹭引擎开放平台
- 白鹭引擎开发文档
- FairyGUI编辑器
- PureMVC-TypeScript
- 讯飞开放平台
- 亲加通讯云
- Cygwin
- Mono开发者联盟
- Scut游戏服务器引擎
- KBEngine游戏服务器引擎
- Photon游戏服务器引擎
- 码云
- SharpSvn
- 腾讯bugly
- 4399原创平台
- 开源中国
- Firebase
- Firebase-Admob-Unity
- google-services-unity
- Firebase SDK for Unity
- Google-Firebase-SDK
- AppsFlyer SDK
- android-repository
- CQASO
- Facebook开发者平台
- gradle下载
- GradleBuildTool下载
- Android Developers
- Google中国开发者
- AndroidDevTools
- Android社区
- Android开发工具
- Google Play Games Services
- Google商店
- Google APIs for Android
- 金钱豹VPN
- TouchSense SDK
- MakeHuman
- Online RSA Key Converter
- Windows UWP应用
- Visual Studio For Unity
- Open CASCADE Technology
- 慕课网
- 阿里云服务器ECS
- 在线免费文字转语音系统
- AI Studio
- 网云穿
- 百度网盘开放平台
- 迅捷画图
- 菜鸟工具
- [CSDN] 程序员研修院
- 华为人脸识别
- 百度AR导航导览SDK
- 海康威视官网
- 海康开放平台
- 海康SDK下载
- git download
- Open CASCADE
- CascadeStudio
- OpenClaw中文社区
- three.js manual
- SVG官方文档
交流QQ群
-
Flash游戏设计: 86184192
Unity游戏设计: 171855449
游戏设计订阅号







