解决 AI 算不准,其实很简单,加部计算器

查看 85|回复 11
作者:pyjiujiu   
前言:
[color=]这篇是个demo,目的是,让各位朋友 ,稍微感受下当前 AI 真正的发展
,现在25年1月,网上争论的都是不了解的小伙伴居多
比如,纠结 AI 算不准,真没必要,人脑也是算不准,古人云,君子性非异,善假于物也。
---分割线---
装计算器,其实很简单,也就是 加个 function call,
下面是个人  基于gemini 写的,,其他模型可能要自己查询相应的API文档
为什么用 gemini?
因为这家代码,还是能有点前瞻性的,甚至有种黑科技的感觉
[color=]---分割线---
要安装的库:pip install google-genai
[Python] 纯文本查看 复制代码
from typing import Callable, Dict, List, Union, Any
import math
import dataclasses
from functools import wraps
from google import genai
from google.genai import types
API_KEY = 'xxxxxxxxxx' #需要自己的 API key,也可以写入系统的环境变量
client = genai.Client(api_key=API_KEY)
MAX_COUNT = 4
   
@dataclasses.dataclass
class Count_f_call:
    """in case of looping forever"""
    count:int = 0
    need_terminate:bool = False
func_count = Count_f_call()
def add_count(func):
    @wraps(func)
    def wrapper(*args,**kwargs):
        func_count.count += 1
        if func_count.count > MAX_COUNT: func_count.need_terminate = True
        return func(*args,**kwargs)
    return wrapper
def zero_count(func):
    def wrapper(*args,**kwargs):
        func_count.count = 0
        func_count.need_terminate = False
        func(*args,**kwargs)
    return wrapper
def tokenize(s: str) -> list[str]:
    """Convert a string into a list of tokens.
    e.g.tokenize('(+ 18 45)') --> ['(', '+', '18', '45', ')']
    """
    return s.replace('(', ' ( ').replace(')', ' ) ').split()
def parse(expression: str) -> list[str]:
    "Read a expression from a string."
    return tokenize(expression)
@add_count
def calculator(expression: str) -> Union[str, int, float]:
    """
    A calculator for performing basic arithmetic calculations.
    Args:
        expression: A string representing the expression to evaluate using prefix notation, with outermost '()'.
            Supported operations: "+", "-", "*", "/", "^", "sqrt", "abs","sin","cos", "tan", "log", "exp", "round"
            The delimiter: "(",")"
            e.g. '(+ 1 2)' or '(* (+ 1 2) 3)' or '(sqrt (+ 1 2))'
    Returns:
        The result of the calculation, or an error message string.
    """
    if func_count.need_terminate:
        return "Warning: exceed the max function call times in a single LLM call"
    available_operations: List[str] = ["+", "-", "*", "/", "^", "sqrt", "abs", "sin", "cos", "tan", "log", "exp", "round"]
    print(f"\r函数调用:{func_count.count}  算式: {expression}",end='',flush=True)
    try:
        tokens = parse(expression)
        return _evaluate_expression(tokens, available_operations)
    except Exception as e:
         return f"Error: An unexpected error occurred: {str(e)}"
def _evaluate_expression(tokens: list[str], available_operations: List[str]) -> Union[str, int, float]:
    """
    Recursively evaluates a list of tokens representing an expression.
    Args:
        tokens: A list of tokens representing the expression.
        available_operations: List of supported operations.
    Returns:
        The result of the calculation, or an error message string.
    """
    if not tokens:
        return "Error: Empty expression."
    if tokens[0] == '(':
        tokens.pop(0)  
        if not tokens:
            return "Error: Unbalanced parenthesis."
        operation = tokens.pop(0)  
        if operation not in available_operations:
             return f"Error: Unsupported operation: {operation}. Available operations are: {', '.join(available_operations)}"
        arguments = []
        while tokens and tokens[0] != ')':
            arg = _evaluate_expression(tokens, available_operations)  
            if isinstance(arg, str) and arg.startswith("Error:"):
                return arg
            arguments.append(arg)
        if not tokens:
            return "Error: Unbalanced parenthesis."
        tokens.pop(0)
        return _apply_operation(operation, arguments)
    try:
        return float(tokens.pop(0))
    except (ValueError, IndexError):
        return "Error: Invalid number or unexpected token."
def _apply_operation(operation: str, arguments: List[Union[int, float]]) -> Union[str, int, float]:
    """Applies the specified operation to the arguments."""
    match operation:
        case "+":
            return sum(arguments)
        case "-":
            if len(arguments) != 2:
                return "Error: Subtraction requires exactly 2 arguments."
            return arguments[0] - arguments[1]
        case "*":
            result = 1
            for arg in arguments:
                result *= arg
            return result
        case "/":
            if len(arguments) != 2:
                return "Error: Division requires exactly 2 arguments."
            if arguments[1] == 0:
                return "Error: Division by zero."
            return arguments[0] / arguments[1]
        case "^":
            if len(arguments) != 2:
                return "Error: Power operation requires exactly 2 arguments."
            return arguments[0] ** arguments[1]
        case "sqrt":
            if len(arguments) != 1:
                return "Error: Square root requires exactly 1 argument."
            if arguments[0]
---分割线---
稍微展示下 测试


test_interface.png (11.58 KB, 下载次数: 0)
下载附件
2025-1-8 20:38 上传

[color=]--说明
其实个人用的场景也不多,所以也没怎么测试,大概记录几点
#首先如果调用 gemini ,网络问题要自己解决(可以转成 本土大模型的 function call 版本)
1  小模型对算式输出会有问题,gemini-2.0-flash-exp 就没遇到错误 (但存在 分解成小计算,调用过多的问题)
2  如果不设置 system prompt ,让LLM 必须执行计算器,对于简单的(如根号2 +1),是不会调用的 (这个 deepseek 是有必须选项,gemini 没找到)
3 代码的问题,要求Python 3.10+ ,因为 match case 的写法 (个人很喜欢 match 的写法)(大家可以自行修改 去兼容老版本)。
4 受人鱼 不如授人以渔,这篇代码,主要参考了书籍 fluent python》的解析 lisp 的部分,还有 Antropic (Claude的公司) 的官方仓库,这两个都是好东西,推荐大家多关注。
代码完全原创,本人不介意版权可以随便修改,以及分享给自己的好朋友,(不要纠结 copyright )
#最后,最近更多是在研究 AI prompt,本篇是之前做的,希望对大家有所启示,其实 AI 真的很强的 也很好用的工具,不用太在意一般的观点,很多功能本身还在探索当中,要说的话,历史上是没有任何参考的,我们才是第一代。

计算器, 代码

waningmoon   

对的,其他方面都还挺好,但数学问题真的一算一个不吱声,给人的感觉就是别管我算得对不对,我就问你快不快
HG2022   

有价值,有思想的好贴!“要说的话,历史上是没有任何参考的,我们才是第一代。”,非常赞同!
crystalZ   

还有在研究function call的坛友,幸会
yunyanyishi   

君子性非异,善假于物也。善于利用工具,提高效率,这才是人的最大优势
一场荒唐半生梦   

要是打包个成品就更好了
MCQSJ   

很强,正好在学习function call
bbk74   

现在问题是算的太准了。到处都是大树去杀熟啊。
kenkenss   

不敢相信AI竟然算不准
yxf515321   

AI的数学推理能力目前公认还是欠缺的,谢谢楼主分享
您需要登录后才可以回帖 登录 | 立即注册

返回顶部