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 回复: 我需要更多信息来帮助您。

✅ 最终答案: 我需要更多信息来帮助您。
--------------------------------------------------
相关推荐
秦歌66624 分钟前
DeepAgents框架详解和文件后端
人工智能·langchain
测试员周周1 小时前
【Appium 系列】第06节-页面对象实现 — LoginPage 实战
开发语言·前端·人工智能·python·功能测试·appium·测试用例
霸道流氓气质1 小时前
基于 Milvus Lite 的 Spring AI RAG 向量库实践方案与示例
人工智能·spring·milvus
ar01231 小时前
AR巡检平台:构筑智能巡检新模式的数字化引擎
人工智能·ar
语音之家1 小时前
【预讲会征集】ACL 2026 论文预讲会
人工智能·论文·acl
碳基硅坊1 小时前
电商场景下的商品自动识别与辅助上架
人工智能
熊猫钓鱼>_>2 小时前
强化学习与决策优化:从理论到工程落地的完整指南
人工智能·llm·强化学习·rl·马尔可夫·mdp·决策过程
-柚子皮-2 小时前
强化学习DPO算法
人工智能
tzc_fly2 小时前
AnisoAlign:各向异性模态对齐
人工智能·深度学习·机器学习