模拟 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 回复: 我需要更多信息来帮助您。
✅ 最终答案: 我需要更多信息来帮助您。
--------------------------------------------------