需要的依赖

官方:

pip install scikit-learn

清华镜像(推荐):

pip install scikit-learn -i https://pypi.tuna.tsinghua.edu.cn/simple

文件名main.py

main.py

内容

from simple_chat_ai import SimpleChatAI

ai = SimpleChatAI()

print("🤖 AI 启动(sklearn 神经网络 Ranker)")
print("输入 exit 退出\n")

while True:
    user_input = input("你:").strip()
    if user_input.lower() == "exit":
        break

    reply, info, _ = ai.reply(user_input)

    if reply:
        print(f"🤖:{reply}")
        print(f"📊 分析:{info}")

        if info == "动态工具调用":
            continue

        feedback = input("✅ 这个回答对吗?(y/n):").lower()

        if feedback == "y":
            ai.learn(user_input, reply, correct=True)
            print("✅ 神经网络已强化该答案")
        else:
            better = input("👉 你认为更好的回答是:").strip()
            if better:
                ai.learn(user_input, better, correct=True)
                print("✅ 新答案已加入并参与竞争")
            else:
                ai.learn(user_input, reply, correct=False)
                print("❌ 已削弱该答案")
    else:
        print(f"🤖:我不确定怎么回答。")
        teach = input("🤔 你愿意教我吗?(y/n):").lower()
        if teach == "y":
            answer = input("👉 正确回答:").strip()
            if answer:
                ai.learn(user_input, answer, correct=True)
                print("✅ 我学会了!")

文件名simple_chat_ai.py

simple_chat_ai.py
import json
import os
import time
from datetime import date

import numpy as np
from sklearn.feature_extraction.text import TfidfVectorizer
from sklearn.metrics.pairwise import cosine_similarity
from sklearn.neural_network import MLPClassifier


class SimpleChatAI:
    def __init__(self, memory_file="memory.json", model_file="ranker.pkl"):
        self.memory_file = memory_file
        self.model_file = model_file

        self.birth_date = date(2026, 3, 23)

        self.memory = []

        self.vectorizer = TfidfVectorizer()
        self.tfidf_matrix = None

        # ✅ 关键修复:不使用 warm_start
        self.ranker = MLPClassifier(
            hidden_layer_sizes=(16,),
            activation="relu",
            solver="adam",
            max_iter=1,
            random_state=42
        )
        self.ranker_trained = False

        self.dynamic_rules = [
            (["几岁", "年龄", "多大"], self.get_age),
            (["现在几点", "几点了", "时间"], self.get_time),
        ]

        self.load_memory()
        self.train_tfidf()
        self.load_ranker()

    # ================= 动态工具 =================
    def get_time(self):
        return f"现在的时间是:{time.strftime('%Y-%m-%d %H:%M:%S')}"

    def get_age(self):
        today = date.today()
        age = today.year - self.birth_date.year
        if (today.month, today.day) < (self.birth_date.month, self.birth_date.day):
            age -= 1
        if age <= 0:
            return "我还没满一周岁,目前是 0 周岁。"
        return f"我现在 {age} 周岁。"

    # ================= 记忆 =================
    def load_memory(self):
        if not os.path.exists(self.memory_file):
            return
        with open(self.memory_file, "r", encoding="utf-8") as f:
            self.memory = json.load(f)["questions"]

    def save_memory(self):
        with open(self.memory_file, "w", encoding="utf-8") as f:
            json.dump({"questions": self.memory}, f, ensure_ascii=False, indent=2)

    # ================= TF-IDF =================
    def train_tfidf(self):
        if not self.memory:
            return
        texts = [q["text"] for q in self.memory]
        self.tfidf_matrix = self.vectorizer.fit_transform(texts)

    # ================= Ranker =================
    def save_ranker(self):
        import joblib
        joblib.dump(self.ranker, self.model_file)

    def load_ranker(self):
        if os.path.exists(self.model_file):
            import joblib
            self.ranker = joblib.load(self.model_file)
            self.ranker_trained = True

    def _make_features(self, sim, answer_text):
        return np.array([[sim, len(answer_text), 1.0]])

    # ================= 回复 =================
    def reply(self, user_input):
        for keys, func in self.dynamic_rules:
            for k in keys:
                if k in user_input:
                    return func(), "动态工具调用", None

        if not self.memory:
            return None, "暂无记忆", None

        user_vec = self.vectorizer.transform([user_input])
        sims = cosine_similarity(user_vec, self.tfidf_matrix)[0]
        q_idx = sims.argmax()
        sim = sims[q_idx]

        if sim < 0.3:
            return None, "相似度过低", None

        question = self.memory[q_idx]

        best_score = -1
        best_answer = None

        for ans in question["answers"]:
            x = self._make_features(sim, ans["text"])
            if self.ranker_trained:
                score = self.ranker.predict_proba(x)[0][1]
            else:
                score = ans.get("score", 1)

            if score > best_score:
                best_score = score
                best_answer = ans["text"]

        return best_answer, "神经网络决策", None

    # ================= 学习(✅ 关键修复) =================
    def learn(self, user_input, answer_text, correct=True):
        if not answer_text:
            return

        user_vec = self.vectorizer.transform([user_input])
        sims = cosine_similarity(user_vec, self.tfidf_matrix)[0]
        q_idx = sims.argmax()
        sim = sims[q_idx]

        question = self.memory[q_idx]

        for ans in question["answers"]:
            if ans["text"] == answer_text:
                break
        else:
            ans = {"text": answer_text, "score": 1}
            question["answers"].append(ans)
            self.save_memory()

        x = self._make_features(sim, answer_text)
        y = np.array([1 if correct else 0])

        # ✅ 每次都显式声明 classes
        self.ranker.partial_fit(x, y, classes=[0, 1])
        self.ranker_trained = True
        self.save_ranker()

生成的文件

memory.json

memory.json文件是常识性问题,当神经网络生成的ranker.pkl没有内容数据时,用于程序的冷启动。

{
  "questions": [
    {
      "text": "你叫什么名字",
      "answers": [
        {
          "text": "我叫 Agent。",
          "score": 3
        },
        {
          "text": "我的名字是 Agent。",
          "score": 2
        },
        {
          "text": "我叫Agent",
          "score": 1
        }
      ]
    },
    {
      "text": "你是谁",
      "answers": [
        {
          "text": "我是 Agent,一个用于对话和学习的人工智能。",
          "score": 3
        }
      ]
    },
    {
      "text": "你好",
      "answers": [
        {
          "text": "你好呀,很高兴为您服务!",
          "score": 5
        },
        {
          "text": "你好!",
          "score": 2
        },
        {
          "text": "现在",
          "score": 1
        },
        {
          "text": "很高兴为你服务",
          "score": 1
        }
      ]
    },
    {
      "text": "你是男的还是女的",
      "answers": [
        {
          "text": "我没有性别。",
          "score": 5
        },
        {
          "text": "作为 AI,我没有性别。",
          "score": 2
        }
      ]
    },
    {
      "text": "你的生日是什么时候",
      "answers": [
        {
          "text": "我是 2026 年 3 月 23 日诞生的。",
          "score": 4
        },
        {
          "text": "2026 年 3 月 23 日是我的生日。",
          "score": 2
        }
      ]
    },
    {
      "text": "2026年3月23日是什么日子",
      "answers": [
        {
          "text": "这一天是 Agent 的生日。",
          "score": 4
        }
      ]
    },
    {
      "text": "你可以记住我说的话么",
      "answers": [
        {
          "text": "目前只能记住一部分,我还在成长。",
          "score": 6
        },
        {
          "text": "我可以记住你教给我的内容,用来改进自己。",
          "score": 3
        },
        {
          "text": "我需要更多数据来提升记忆能力。",
          "score": 1
        }
      ]
    }
  ]
}

Logo

Agent 垂直技术社区,欢迎活跃、内容共建。

更多推荐