LangChain实战:如何通过Tools与Routing实现智能代理的自动化函数调用

张开发
2026/6/8 20:46:09 15 分钟阅读
LangChain实战:如何通过Tools与Routing实现智能代理的自动化函数调用
1. 理解LangChain中的Tools与Routing在构建智能代理系统时让大语言模型(LLM)能够调用外部函数是提升其能力的关键。LangChain通过Tools和Routing两大组件让这个过程变得简单高效。我刚开始接触这个功能时发现它能解决很多实际场景中的痛点。Tools本质上就是LLM与外部世界交互的接口。想象一下你给LLM装上了一双手和眼睛 - 通过Tools它可以执行网络搜索、查询数据库、调用API等操作。而Routing则是LLM的大脑决策部分决定在什么情况下使用哪个Tool。在实际项目中我经常遇到这样的需求用户问上海现在的天气怎么样LLM需要调用天气API问LangChain是什么又需要查询知识库。传统做法需要写大量判断逻辑而LangChain的Routing机制可以自动完成这个选择过程。2. 定义你的第一个Tool让我们从创建一个简单的Tool开始。安装必要依赖后我们先定义一个查询天气的Toolfrom langchain.agents import tool from pydantic import BaseModel, Field class WeatherInput(BaseModel): city: str Field(description要查询天气的城市名称) tool(args_schemaWeatherInput) def get_weather(city: str) - str: 获取指定城市的当前天气情况 # 这里应该是实际的API调用 return f{city}当前天气晴25℃这个例子中我使用了tool装饰器将一个普通函数转换为LangChain可识别的Tool。几点经验分享务必添加清晰的文档字符串LLM会用它来决定是否调用这个Tool使用Pydantic定义输入参数结构这能确保参数类型安全返回结果尽量简洁明了便于LLM处理测试这个Tool很简单print(get_weather.name) # 输出工具名称 print(get_weather.description) # 查看工具描述 get_weather.run({city: 北京}) # 实际调用3. 构建多Tool系统单一Tool的实用性有限我通常会为代理系统配置多个Tools。比如添加知识库查询和计算器tool def search_knowledge(query: str) - str: 从知识库中检索相关信息 return f找到关于{query}的3条相关信息... tool def calculate(expression: str) - str: 执行数学计算 try: result eval(expression) return f{expression} {result} except: return 无法计算该表达式在实际项目中我发现几个最佳实践每个Tool的功能要单一明确不要设计万能Tool控制Tool数量在5-7个为佳太多会影响LLM的判断为相似功能的Tool添加区分度高的描述4. 实现智能Routing逻辑有了多个Tools后关键是要让LLM能智能选择。以下是Routing的配置方法from langchain.chat_models import ChatOpenAI from langchain.prompts import ChatPromptTemplate from langchain.agents import AgentExecutor # 将Tools转换为LLM能理解的格式 tools [get_weather, search_knowledge, calculate] tool_names [tool.name for tool in tools] tool_descriptions [tool.description for tool in tools] # 设置LLM和提示词模板 llm ChatOpenAI(temperature0) prompt ChatPromptTemplate.from_template( 你是一个智能助手请根据问题选择最合适的工具回答。\n\n问题{input} ) # 创建代理执行器 agent AgentExecutor.from_llm_and_tools( llmllm, toolstools, verboseTrue )测试Routing效果agent.run(北京现在天气如何) # 应调用get_weather agent.run(2的100次方是多少) # 应调用calculate agent.run(LangChain是什么) # 应调用search_knowledge我在实际使用中发现好的Routing依赖三个要素清晰的Tool描述恰当的提示词设计合理的temperature参数设置通常设为05. 处理复杂场景与错误真实项目中的情况往往更复杂。比如用户问北京和上海的天气对比这就需要组合多个Tools。我通常这样处理from typing import List class MultiCityInput(BaseModel): cities: List[str] Field(description需要对比天气的城市列表) tool(args_schemaMultiCityInput) def compare_weather(cities: List[str]) - str: 比较多个城市的天气情况 results [] for city in cities: weather get_weather.run({city: city}) results.append(f{city}: {weather}) return \n.join(results)错误处理也很重要。我的经验是为每个Tool添加try-catch块返回明确的错误信息方便LLM理解设置合理的超时时间tool def safe_calculate(expression: str) - str: 更安全的计算器 try: result eval(expression) return f{expression} {result} except Exception as e: return f计算错误{str(e)}6. 性能优化技巧在大规模应用中我总结了几个优化点缓存机制对频繁查询的结果进行缓存from functools import lru_cache lru_cache(maxsize100) tool def cached_weather(city: str) - str: 带缓存的天气查询 return get_weather.run({city: city})批量处理对相似请求进行批量处理超时控制避免某个Tool卡住整个系统from concurrent.futures import TimeoutError import timeout_decorator timeout_decorator.timeout(5) tool def timed_search(query: str) - str: 带超时的搜索 return search_knowledge.run(query)7. 实际应用案例最近我做了一个客服机器人项目整合了多个Tools产品知识库查询订单状态检查退换货政策查询人工客服转接配置示例tools [ product_knowledge, check_order_status, return_policy, human_agent ] agent initialize_agent( tools, llm, agentconversational-react-description, verboseTrue )关键收获不同场景需要不同的agent类型用户意图识别很重要需要设计平滑的Tool切换体验8. 调试与监控在生产环境中完善的监控必不可少。我通常会记录所有Tool调用日志统计各Tool使用频率监控响应时间设置告警机制def logged_tool(func): 记录Tool调用的装饰器 wraps(func) def wrapper(*args, **kwargs): start time.time() try: result func(*args, **kwargs) duration time.time() - start log_call(func.__name__, success, duration) return result except Exception as e: log_call(func.__name__, failed, 0, str(e)) raise return wrapper通过这些数据可以持续优化Tool和Routing配置。9. 安全注意事项在实现函数调用时安全是重中之重所有API调用都要验证输入敏感操作需要二次确认实现权限控制避免注入攻击tool def safe_query(query: str) - str: 安全的数据库查询 query sanitize_input(query) # 输入消毒 if contains_sensitive_data(query): return 无法执行该查询 return execute_query(query)10. 未来扩展方向随着项目发展你可能需要考虑动态加载Tools用户自定义ToolsTool版本管理分布式Tool执行一个简单的动态加载实现def load_tool_from_config(config): 根据配置动态加载Tool if config[type] api: return create_api_tool(config) elif config[type] database: return create_db_tool(config) else: raise ValueError(未知的Tool类型)在开发过程中我发现LangChain的Tools和Routing机制极大地简化了智能代理系统的开发。刚开始可能需要花些时间理解这些概念但一旦掌握就能构建出真正强大的AI应用。

更多文章