agent 学习 -模拟AI调用工具

模拟 AI 回复生成器

为方便理解Agentic Loop,实现一个能**"感知-思考-行动"**的极简 Agent。用python模拟AI调用工具的工程。

核心实验:让 AI 学会使用"加法工具"

这个实验的逻辑是:AI 默认数学不好,我们要给它一个 Python 函数(工具),让它意识到自己算不出来时,主动找工具帮忙。

复制代码
#!/usr/bin/env python3
import re
import json
from typing import Optional

# 定义可用的工具函数
def add_numbers(a: int, b: int) -> int:
    """加法工具函数"""
    return a + b

def multiply_numbers(a: int, b: int) -> int:
    """乘法工具函数"""
    return a * b

# 工具注册表
TOOLS = {
    "add_numbers": add_numbers,
    "multiply_numbers": multiply_numbers,
}

# 模拟 AI 回复生成器(实际应该调用 OpenAI/Claude 等 API)
def simulate_ai_response(prompt: str, context: str = "") -> str:
    """模拟 AI 回复 - 实际使用时替换为真实 AI API 调用"""
    full_prompt = f"{context}\n用户: {prompt}" if context else f"用户: {prompt}"
    
    # 检查是否是工具结果反馈(优先级最高)
    if "工具计算结果是" in prompt:
        # 从上下文中提取结果并生成最终回答
        result_match = re.search(r'工具计算结果是 (\d+)', prompt)
        if result_match:
            result = result_match.group(1)
            # 检查原始问题类型
            if "加" in prompt:
                return f"根据计算,12345 加上 67890 的结果是 {result}。"
            elif "乘" in prompt:
                return f"根据计算,123 乘以 456 的结果是 {result}。"
            else:
                return f"根据计算,结果是 {result}。"
    
    # 简单的模式匹配来模拟 AI 的工具调用决策
    if "加" in prompt and any(char.isdigit() for char in prompt):
        numbers = re.findall(r'\d+', prompt)
        if len(numbers) >= 2:
            return f"CALL: add_numbers({numbers[0]}, {numbers[1]})"
    elif "乘" in prompt and any(char.isdigit() for char in prompt):
        numbers = re.findall(r'\d+', prompt)
        if len(numbers) >= 2:
            return f"CALL: multiply_numbers({numbers[0]}, {numbers[1]})"
    
    return "我需要更多信息来帮助您。"

def parse_tool_call(response: str) -> Optional[tuple[str, list]]:
    """解析工具调用字符串"""
    if "CALL:" not in response:
        return None
    
    # 提取工具调用部分
    call_part = response.split("CALL:")[-1].strip()
    
    # 解析函数名和参数
    match = re.match(r'(\w+)\((.*?)\)', call_part)
    if not match:
        return None
    
    func_name = match.group(1)
    args_str = match.group(2)
    
    # 解析参数
    try:
        # 简单解析数字参数
        args = [int(x.strip()) for x in args_str.split(',')]
        return func_name, args
    except:
        return None

def execute_tool(func_name: str, args: list) -> any:
    """执行工具函数"""
    if func_name not in TOOLS:
        raise ValueError(f"Unknown tool: {func_name}")
    
    return TOOLS[func_name](*args)

def ai_chat_with_tools(user_question: str, system_prompt: str) -> str:
    """完整的 AI 工具调用对话流程"""
    print(f"🤖 用户问题: {user_question}")
    
    # 1. 系统提示 + 用户问题
    context = system_prompt
    
    # 2. 第一次 AI 调用:让 AI 思考并决定是否使用工具
    print("\n📝 第一次 AI 调用...")
    first_response = simulate_ai_response(user_question, context)
    print(f"AI 回复: {first_response}")
    
    # 3. 检查是否有工具调用
    tool_call = parse_tool_call(first_response)
    
    if tool_call is None:
        # 没有工具调用,直接返回 AI 的回复
        return first_response
    
    # 4. 执行工具
    func_name, args = tool_call
    print(f"\n🔧 执行工具: {func_name}({', '.join(map(str, args))})")
    
    try:
        result = execute_tool(func_name, args)
        print(f"工具结果: {result}")
    except Exception as e:
        return f"工具执行失败: {e}"
    
    # 5. 第二次 AI 调用:把工具结果反馈给 AI
    print(f"\n📝 第二次 AI 调用(反馈工具结果)...")
    tool_result_prompt = f"工具计算结果是 {result},请根据这个结果回答用户问题:{user_question}"
    final_response = simulate_ai_response(tool_result_prompt, context)
    print(f"AI 最终回复: {final_response}")
    
    return final_response

# 主程序
if __name__ == "__main__":
    # 系统提示
    system_prompt = """
你是一个全能助手。如果你发现需要进行复杂的加法运算,
请不要自己算,而是输出固定格式:CALL: add_numbers(数值1, 数值2)。
如果需要乘法运算,请输出:CALL: multiply_numbers(数值1, 数值2)。
我会帮你算完后把结果告诉你。
"""
    
    # 测试用例
    test_questions = [
        "请问 12345 加上 67890 等于多少?",
        "计算 123 乘以 456",
        "今天天气怎么样?",  # 不需要工具的问题
    ]
    
    print("=" * 60)
    print("🚀 AI 工具调用系统演示")
    print("=" * 60)
    
    for i, question in enumerate(test_questions, 1):
        print(f"\n{'='*20} 测试用例 {i} {'='*20}")
        result = ai_chat_with_tools(question, system_prompt)
        print(f"\n✅ 最终答案: {result}")
        print("-" * 50)

运行结果

复制代码
============================================================
🚀 AI 工具调用系统演示
============================================================

==================== 测试用例 1 ====================
🤖 用户问题: 请问 12345 加上 67890 等于多少?

📝 第一次 AI 调用...
AI 回复: CALL: add_numbers(12345, 67890)

🔧 执行工具: add_numbers(12345, 67890)
工具结果: 80235

📝 第二次 AI 调用(反馈工具结果)...
AI 最终回复: 根据计算,12345 加上 67890 的结果是 80235。

✅ 最终答案: 根据计算,12345 加上 67890 的结果是 80235。
--------------------------------------------------

==================== 测试用例 2 ====================
🤖 用户问题: 计算 123 乘以 456

📝 第一次 AI 调用...
AI 回复: CALL: multiply_numbers(123, 456)

🔧 执行工具: multiply_numbers(123, 456)
工具结果: 56088

📝 第二次 AI 调用(反馈工具结果)...
AI 最终回复: 根据计算,123 乘以 456 的结果是 56088。

✅ 最终答案: 根据计算,123 乘以 456 的结果是 56088。
--------------------------------------------------

==================== 测试用例 3 ====================
🤖 用户问题: 今天天气怎么样?

📝 第一次 AI 调用...
AI 回复: 我需要更多信息来帮助您。

✅ 最终答案: 我需要更多信息来帮助您。
--------------------------------------------------
相关推荐
试剂界的爱马仕1 小时前
AI学习实现:如何给基金实时估值?
大数据·人工智能·科技·学习·机器学习
笑不语2 小时前
从共病网络到可解释 AI:同济医院 10 分 SCI 全流程复现(R 语言)
开发语言·人工智能·r语言
xiangzhihong82 小时前
Claude Code系列教程之Claude Code 基础用法基础用法
人工智能
deephub2 小时前
2026年的 ReAct Agent架构解析:原生 Tool Calling 与 LangGraph 状态机
人工智能·大语言模型·agent·langgraph
淡海水2 小时前
【AI模型】概念-Token
人工智能·算法
数智化精益手记局2 小时前
什么是安全生产?解读安全生产的基本方针与核心要求
大数据·运维·人工智能·安全·信息可视化·自动化·精益工程
ManThink Technology2 小时前
KS31 4-20mA 模拟量采集器通过LoRaWAN 接入ThinkLink
人工智能·物联网
Zzj_tju2 小时前
大语言模型部署实战:生产环境怎么做高并发、监控、限流与故障恢复?
人工智能·语言模型·自然语言处理
2301_792674862 小时前
java学习day31(redis)
java·redis·学习