昨天,税务部门合伙人找到我,让帮忙解决一个税务筹划的问题。
我听了半个多小时,一直云里雾里的(可能税务知识太薄弱),
最后稍微理解了,利用 AI + Python 初步解决了这个问题。

AI + Python + 税务你说有没有搞头?
案例背景
下面是我个人理解的,不一定准确。
( 注:涉及数字已进行修改,仅举例 )
某公司有 3.2 亿元 的净利润,准备发放给内部核心成员(合伙人)。
这些利润可以通过两种方式来分配:
👨 方式一:发给“个人”(通过合伙企业)
公司下设一个合伙企业
利润发放到这里后,按“个人所得税累进制”收税
累进制意思是:挣得越多,税率越高(见下表)
公司希望:能尽可能把人安排在税率低的档位,减少整体税。
合伙人分成A 、B 两类:
A类(220人)、B类(180人)
🏢 方式二:发给“公司”(通过多个子公司)
利润发给子公司,公司交完企业所得税后,再以分红形式发给个人,个人再交 20% 税
公司之间税率不同:
个人所得税率:20%
这里“小微企业”和“优惠税率企业”是享受的企业所得税优惠,
因此是先让其每家固定承担了250 万和2000万的利润,
以达到综合税赋减少。
🎯 目标
我们需要在满足以下条件的前提下:
利润总额为 3.2 亿元(必须全部分配完)
A类合伙人(220人)、B类合伙人(180人)都参与分配
使整个分配方案的“个人所得税总额”最低!

🤹问题初探
矛盾点1
虽然领导说是让个人所得税最少,
但仔细想一想,从个人所得税来讲:
合伙企业 5%,10% 就算填满也凑不够多少利润,后面的税率都大于或等于公司的20%分红的税率。
所以,为了保证 3.2 亿利润分配出去,
要个税最小,那就几乎全部凑到公司的去分配了。
但是,再加上 25% 的企业所得税,那么税赋就会非常重,达到45% 的税率。
这显然是不划算的。
个人肯定是满意了,但公司肯定是不满意。
矛盾点2
那如果是考虑:企业所得税 + 个人所得税的综合税赋最小呢?
因为普通公司的综合税率= 25% (企业所得率)+ 20% (个人所得税)= 45%.
大于合伙企业最高 35% 的税率。
所以,肯定又都全部分配到合伙企业上去了。
但是,这样又会造成个人的税很高,
个人肯定不满意,公司肯定满意了。
添加平衡条件
我把这两个矛盾给领导说了,
她又再添加了一个限制条件:
普通企业的利润分配总额不超过小微企业+15%税率公司的利润总额的 30%。
( 注:这个 30% 是拍脑袋,一个平衡的直觉,参数可以修改 )
在此条件下,求个人所得税的最小值。
这样,可以想见,利润会尽量分配给普通企业,但有个上限,
剩下的利润就是在合伙企业中分配,看各税档是多少人。
ChatGpt 规划和代码编写
我将这个问题理解后,扔给 chatgpt ,让它帮我写 Python 代码,
同时把一些关键数字作为参数可以修改,这样就有了复用性。

执行代码:
import pulp
brackets = [
(0, 30000, 0.05),
(30000, 90000, 0.10),
(90000, 300000, 0.20),
(300000, 500000, 0.30),
(500000, 2000000, 0.35)
]
upper_bounds = [high for (_, high, _) in brackets]
rates = [rate for (_, _, rate) in brackets]
quick_deductions = [0, 1500, 10500, 40500, 65500]
avg_tax_per_person = [
upper_bounds[i] * rates[i] - quick_deductions[i]
for i in range(5)
]
total_profit = 3.2e8
num_A = 220
num_B = 180
num_micro = 15
profit_micro = 2_500_000
num_pref = 6
profit_pref = 20_000_000
normal_ratio_limit = 0.3
fixed_micro_total = num_micro * profit_micro
fixed_pref_total = num_pref * profit_pref
prob = pulp.LpProblem("Global_Tax_Minimization", pulp.LpMinimize)
x_A = [pulp.LpVariable(f"A_{i}", lowBound=0, cat='Integer') for i in range(5)]
x_B = [pulp.LpVariable(f"B_{i}", lowBound=0, cat='Integer') for i in range(5)]
normal_profit = pulp.LpVariable("Normal_Profit", lowBound=0, cat='Continuous')
M_expr = pulp.lpSum([(x_A[i] + x_B[i]) * upper_bounds[i] for i in range(5)])
N_expr = fixed_micro_total + fixed_pref_total + normal_profit
prob += M_expr + N_expr == total_profit, "Total_Profit_Constraint"
prob += pulp.lpSum(x_A) == num_A, "Total_A_Count"
prob += pulp.lpSum(x_B) == num_B, "Total_B_Count"
prob += normal_profit <= normal_ratio_limit * (fixed_micro_total + fixed_pref_total), "Normal_Profit_Limit"
tax_expr = (
pulp.lpSum([x_A[i] * avg_tax_per_person[i] for i in range(5)]) +
pulp.lpSum([x_B[i] * avg_tax_per_person[i] for i in range(5)]) +
fixed_micro_total * (1 - 0.05) * 0.2 +
fixed_pref_total * (1 - 0.15) * 0.2 +
normal_profit * (1 - 0.25) * 0.2
)
prob += tax_expr
prob.solve()
print(f"状态: {pulp.LpStatus[prob.status]}")
M_total = pulp.value(M_expr)
N_total = pulp.value(N_expr)
tax_total = pulp.value(tax_expr)
tax_partnership = sum(pulp.value(x_A[i]) * avg_tax_per_person[i] for i in range(5)) + \
sum(pulp.value(x_B[i]) * avg_tax_per_person[i] for i in range(5))
tax_corp_dividend = (
fixed_micro_total * (1 - 0.05) * 0.2 +
fixed_pref_total * (1 - 0.15) * 0.2 +
pulp.value(normal_profit) * (1 - 0.25) * 0.2
)
print(f"\n✅ 合伙企业利润 M: {M_total/1e8:.4f} 亿元")
print(f"✅ 公司企业利润 N: {N_total/1e8:.4f} 亿元")
print("\n📊 公司企业利润结构:")
print(f"小微企业利润({num_micro} 个 × {profit_micro/1e6:.1f} 万): {fixed_micro_total/1e8:.4f} 亿元")
print(f"优惠企业利润({num_pref} 个 × {profit_pref/1e6:.1f} 万): {fixed_pref_total/1e8:.4f} 亿元")
print(f"普通企业利润(限制 ≤ {normal_ratio_limit*100:.1f}%): {normal_profit.varValue/1e8:.4f} 亿元")
print(f"\n💰 总个人所得税额: {tax_total / 1e8:.4f} 亿元")
print(f"├─ 合伙企业个税: {tax_partnership / 1e8:.4f} 亿元")
print(f"└─ 公司股东分红个税: {tax_corp_dividend / 1e8:.4f} 亿元")
corp_tax_micro = fixed_micro_total * 0.05
corp_tax_pref = fixed_pref_total * 0.15
corp_tax_normal = pulp.value(normal_profit) * 0.25
corp_tax_total = corp_tax_micro + corp_tax_pref + corp_tax_normal
total_tax = tax_total + corp_tax_total
print(f"\n🏢 企业所得税总额: {corp_tax_total / 1e8:.4f} 亿元")
print(f"├─ 小微企业: {corp_tax_micro / 1e8:.4
f} 亿元")
print(f"├─ 优惠企业: {corp_tax_pref / 1e8:.4f} 亿元")
print(f"└─ 普通企业: {corp_tax_normal / 1e8:.4f} 亿元")
print(f"\n📊 综合税赋总额(企业税 + 个税): {total_tax / 1e8:.4f} 亿元")
print("\n🧑💼 合伙企业人员分配结构(单位:万元):")
profit_A = 0
profit_B = 0
for i in range(5):
a_num = pulp.value(x_A[i])
b_num = pulp.value(x_B[i])
a_profit = a_num * upper_bounds[i]
b_profit = b_num * upper_bounds[i]
total = a_profit + b_profit
profit_A += a_profit
profit_B += b_profit
total_people = a_num + b_num
avg_per_person = total / total_people if total_people > 0 else 0
print(f"税档{i+1}:A类 {a_num:.0f}人,利润 {a_profit/1e4:.2f} 万元 | "
f"B类 {b_num:.0f}人,利润 {b_profit/1e4:.2f} 万元 | "
f"总计: {total/1e4:.2f} 万元 | 人均: {avg_per_person:,.0f} 元")
print(f"\nA类合伙企业分配总利润: {profit_A/1e8:.4f} 亿元")
print(f"B类合伙企业分配总利润: {profit_B/1e8:.4f} 亿元")
执行完的分配方案:
可以看到,它把合伙企业和公司分别分配多少利润,以及合伙企业中每一档多少人都给我计算出来了。
线性规划原理
本身这个问题有非常多条件,如果人工去凑数会显得非常复杂。
而 chatgpt 给的代码中运用了 pulp
库,它在背后会调用专业的数学优化引擎(比如 CBC),自动穷举、剪枝、线性变换……最后告诉你:
❝“好了!我找到了一个最优方案,你可以按这个分配啦!”
❞
✍️ 举个类比
你可以把 pulp 想象成一个帮你分奖金的AI秘书:
你对它说:
奖金总额 3200 万
A组 220人,B组 180人
每个人按不同档位交税,税率越高越不划算
公司发奖金也得交企业税
普通公司拿到的奖金不能太多
然后你说:
“秘书,你帮我分一下,看怎么分才能总税最少。”
这个秘书说:“好的,交给我。”
几秒钟后它告诉你:
❝✅ “最佳方案已出炉!”
✅ “A类这么分,B类那么分,企业分这样。”
✅ “总税只要 1.87 亿,比你拍脑袋猜的方案省了一大截。”
❞
这就是 pulp 在做的事!
结语
由于本人税务知识欠缺,
这中间在问题简化和描述过程中,可能会有很多不正确的地方。
但通过此案例,可以看出,
一位具备专业知识的税务师 + AI 和少量代码知识,
就可以完成以前很多看似复杂的问题了。
AI + Python + 税务你说有没有搞头?
审计军火库网盘来了!搜罗一切公开审计资料!
打破审计怪圈-创建免费的审计社群
审计军火库迁移至audit dog网站