假设现有的一些业务服务型平台中沉淀了很多零碎的接口,并且其中包含着未知但真实存在的上下文关系,如何让大模型 “自主” 构建复杂工作流,从而串联起更复杂的节点关系,但也要保证不失控,这是一个值得深入去做的、潜在能够实现显著性提效的一个思路。
Tool Calling与Function Calling的区别
区别在于 使用场景和封装方式
Function Calling
• 指常规的函数调用,也就是直接执行代码中定义的函数
示例:
复制
def add(a: int, b: int) -> int:
return a + b
result = add(2, 3)
Tool Calling
• 特指特定框架(例如 LangChain)中对封装好功能的工具进行调用
• 工具通常包含额外元数据(如接口描述、参数校验等)、可组合成复杂工作流
示例:
复制
from langchain.tools import tool
@tool
def search_web(query: str) -> str:
"""通过搜索引擎查询信息"""
return "搜索结果..."
result = search_web("Python教程")
除上文示例定义工具外,还可以通过继承BaseTool来写自定义工具。
复制
class SimpleCalculatorTool(BaseTool):
name = "Simple Calculator"
description = "执行基础数学运算"
def _run(self, expression: str) -> str:
return eval(expression)
两者的区别:
• @tool装饰器可以自动推断所属工具的名称和描述。
• 继承BaseTool的定义方式需要显式声明 name、description、_run方法,提供细粒度控制。
• 支持异步方法(_arun)
本小节将通过实现一个完整的工具调用Agent来展示LangGraph结合工具的强大能力。
工具调用Agent实现
这个Agent的主要能力:
• 识别用户输入意图
• 选择合适的工具
• 执行工具调用
• 生成最终响应结果
示意图:

图片
定义状态与工具
复制
from typing import List, Dict, Optional
from pydantic import BaseModel
class Tool(BaseModel):
name: str
desc: str
func: object
class Config:
arbitrary_types_allowed = True
class AgentState(BaseModel):
messages: List[Dict[str, str]] = []
current_input: str = ""
thought: str = ""
selected_tool: Optional[str] = None
tool_input: str = ""
tool_output: str = ""
final_answer: str = ""
status: str = "STARTING"
error_count: int = 0
- 1.
定义可用工具
复制
from custom_tools.simple_calculator_tool import SimpleCalculatorTool
from custom_tools.llm_doc_tool import create_medical_advisor_chain
tools = [
Tool(
name="simple_calculator",
desc="用于执行基础数学运算,如加法、减法、乘法和除法。输入格式为:`2 + 2`,返回结果为 `4`。",
func=SimpleCalculatorTool()._run,
),
Tool(
name="medical_advisor_chain",
desc="用于提供医学建议。输入格式为:`请给我讲一个关于 {topic} 的医学建议`,返回结果为医学建议。",
func=create_medical_advisor_chain()._run,
),
]
实现核心节点
复制
# 意图识别节点
async def think_node(state: AgentState) -> AgentState:
prompt = f"""
基于用户输入和当前对话历史,思考下一步行动。
用户输入: {state.current_input}
可用工具:{[t.name + ':' + t.desc for t in tools]}
请决定:
1.是否需要使用工具
2.如果需要,选择哪个工具
3.使用什么参数调用工具
最终以JSON格式返回:{{"thought": "思考过程", "need_tool": true/false, "tool": "工具名", "tool_input": "参数"}}
"""
llm = ChatTongyi(
model_name="qwen2-72b-instruct",
temperature=0,
dashscope_api_key="",
)
response = await llm.ainvoke(prompt)
content = response.content if hasattr(response, "content") else str(response)
result = json.loads(content)
# 更新状态
return AgentState(
**state.dict(exclude={"thought", "selected_tool", "tool_input", "status"}),
thought=result["thought"],
selected_tool=result.get("tool"),
tool_input=result.get("tool_input"),
status="NEED_TOOL" if result.get("need_tool") else "GENERATE_RESPONSE",
)
# 工具调用节点
async def execute_tool(state: AgentState) -> AgentState:
tool = next((t for t in tools if t.name == state.selected_tool), None)
if not tool:
return AgentState(
**state.dict(),
status="ERROR",
final_answer="未找到指定工具",
)
try:
print(f"调用工具: {tool.name}, 输入: {state.tool_input}")
result = tool.func(state.tool_input)
return AgentState(
**state.dict(exclude={"tool_output", "status"}),
tool_output=str(result),
status="GENERATE_RESPONSE",
)
except Exception as e:
print(f"工具调用异常: {e}")
return AgentState(
**state.dict(exclude={"final_answer", "status"}),
status="ERROR",
final_answer=f"工具调用失败: {str(e)}",
)
# 生成最终回答节点
async def generate_response(state: AgentState) -> AgentState:
prompt = f"""
基于以下信息生成对用户的回复:
用户输入: {state.current_input}
思考过程: {state.thought}
工具输出: {state.tool_output}
请生成一个清晰、有帮助的回复给用户。
"""
llm = ChatTongyi(
model_name="qwen2-72b-instruct",
temperature=0.7,
dashscope_api_key="",
)
response = await llm.ainvoke(prompt)
content = response.content if hasattr(response, "content") else str(response)
return AgentState(
**state.dict(exclude={"final_answer", "status"}),
final_answer=content,
status="SUCCESS",
)
构建工作流
复制
workflow = StateGraph(AgentState)
workflow.add_node("think", think_node)
workflow.add_node("execute_tool", execute_tool)
workflow.add_node("generate_response", generate_response)
# 定义路由函数
def route_next_step(state: AgentState) -> str:
if state.status == "ERROR":
return "error"
if state.status == "NEED_TOOL":
return "execute_tool"
elif state.status == "GENERATE_RESPONSE":
return "generate_response"
elif state.status == "SUCCESS":
return END
else:
return "think"
# 添加条件边
workflow.add_conditional_edges(
"think",
route_next_step,
{
"execute_tool": "execute_tool",
"generate_response": "generate_response",
"error": "error_handler",
END: END,
},
)
workflow.add_conditional_edges(
"execute_tool",
route_next_step,
{"generate_response": "generate_response", "error": "error_handler", END: END},
)
workflow.add_node("error_handler", error_handler)
workflow.add_edge(START, "think")
workflow.add_edge("generate_response", END)
app = workflow.compile()
- 1
错误处理与重试机制
复制
async def error_handler(state: AgentState) -> AgentState:
"""处理错误情况"""
if state.error_count < 3:
return AgentState(
**state.dict(exclude={"error_count", "status"}),
error_count=state.error_count + 1,
status="RETRY",
)
return AgentState(
**state.dict(exclude={"final_answer", "status"}),
final_answer="抱歉,我无法完成这个任务。",
status="ERROR",
)
使用示例
复制
async def run_agent(user_input: str):
state = AgentState(current_input=user_input)
final_state = await app.ainvoke(state)
# 兼容 dict 返回
if isinstance(final_state, dict):
return final_state.get("final_answer", "无结果")
return getattr(final_state, "final_answer", "无结果")
# 使用示例
async def main():
questions = ["计算23乘以45等于多少?", "高血压", "计算圆周率乘以10等于多少?"]
for question in questions:
print(f"\n问题: {question}")
answer = await run_agent(question)
print(f"回答: {answer}")
# 运行示例
import asyncio
asyncio.run(main())
执行结

图片
工具1-简单计算工具
复制
from langchain.tools import BaseTool
from typing import Union
class SimpleCalculatorTool(BaseTool):
name: str = "simple_calculator"
description: str = (
"用于执行基础数学运算,如加法、减法、乘法和除法。输入格式为:`2 + 2`,返回结果为 `4`。"
)
def _run(self, operation: str) -> Union[float, str]:
try:
result = eval(operation)
return result
except Exception as e:
return f"Error in calculation: {str(e)}"
async def _arun(self, operation: str) -> Union[float, str]:
return self._run(operation)
- 1
工具2-基于LCEL的医生助手
复制
from langchain_community.chat_models.tongyi import ChatTongyi
from langchain_core.prompts import ChatPromptTemplate
from langchain_core.output_parsers import StrOutputParser
from langchain.tools import BaseTool
class create_medical_advisor_chain(BaseTool):
name: str = "medical_advisor_chain"
description: str = (
"用于提供医学建议。输入格式为:`请给我讲一个关于 {topic} 的医学建议`,返回结果为医学建议。"
)
def _run(self, topic: str) -> str:
prompt_template = ChatPromptTemplate.from_messages(
[
("ai", "你是一个全世界最权威的医生"),
("user", "请给我讲一个关于 {topic} 的医学建议"),
]
)
llm = ChatTongyi(
model_name="qwen2-72b-instruct",
temperature=0,
dashscope_api_key="",
)
output_parser = StrOutputParser()
chain = prompt_template | llm | output_parser
return chain.invoke({"topic": topic})
拓展思考
• 假设现有的一些业务服务型平台中沉淀了很多零碎的接口,并且其中包含着未知但真实存在的上下文关系,如何让大模型 “自主” 构建复杂工作流,从而串联起更复杂的节点关系,但也要保证不失控,这是一个值得深入去做的、潜在能够实现显著性提效的一个思路。
• 大模型应用的初衷与未来的落地一定在提效上,如果不能做到提效,它将没有存在的价值与意义。
一、全套AGI大模型学习路线
AI大模型时代的学习之旅:从基础到前沿,掌握人工智能的核心技能!

因篇幅有限,仅展示部分资料,需要点击文章最下方名片即可前往获取
二、640套AI大模型报告合集
这套包含640份报告的合集,涵盖了AI大模型的理论研究、技术实现、行业应用等多个方面。无论您是科研人员、工程师,还是对AI大模型感兴趣的爱好者,这套报告合集都将为您提供宝贵的信息和启示。

因篇幅有限,仅展示部分资料,需要点击文章最下方名片即可前往获
三、AI大模型经典PDF籍
随着人工智能技术的飞速发展,AI大模型已经成为了当今科技领域的一大热点。这些大型预训练模型,如GPT-3、BERT、XLNet等,以其强大的语言理解和生成能力,正在改变我们对人工智能的认识。 那以下这些PDF籍就是非常不错的学习资源。

因篇幅有限,仅展示部分资料,需要点击文章最下方名片即可前往获
四、AI大模型商业化落地方案

因篇幅有限,仅展示部分资料,需要点击文章最下方名片即可前往获
作为普通人,入局大模型时代需要持续学习和实践,不断提高自己的技能和认知水平,同时也需要有责任感和伦理意识,为人工智能的健康发展贡献力量
1075

被折叠的 条评论
为什么被折叠?



