[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 真的很强的 也很好用的工具,不用太在意一般的观点,很多功能本身还在探索当中,要说的话,历史上是没有任何参考的,我们才是第一代。