langchain实现agent智能体笔记

文章目录

环境

python #3.11

沿用之前的项目和环境。

langchain示例

步骤

不用换项目,在项目下新建文件夹agent_demo
agent_demo文件夹下,再新建data.txtmain.py

新建data.txt,输入内容
python 复制代码
公司名称:未来科技 (FutureTech)
CEO: 艾琳·陈 (Erin Chen)
核心产品:量子助手 (QuantumAssistant)
成立时间:2024年
总部地点:上海张江
新建python文件

代码:

python 复制代码
import os
import re
from typing import List, Dict, Any

# ================= 0. 网络环境修复 (关键) =================
# 强制清空代理环境变量,防止因为开启了全局代理导致无法连接阿里云国内节点
os.environ['HTTP_PROXY'] = ''
os.environ['HTTPS_PROXY'] = ''
os.environ['ALL_PROXY'] = ''
print("🚀 已清除环境变量代理,确保直连...")

# 基础导入
from langchain_core.tools import Tool
from langchain_core.runnables import RunnableLambda
from langchain_huggingface import HuggingFaceEmbeddings
from langchain_community.vectorstores import Chroma
from langchain_community.document_loaders import TextLoader
from langchain_text_splitters import CharacterTextSplitter

# OpenAI 库导入
from openai import OpenAI

# ================= 1. 配置 API KEY 和 客户端 =================

# 按照你的要求获取 Key
API_KEY = os.getenv("DASHSCOPE_API_KEY", "YOUR API KEY")
print(f"🔍 代码读取到的API_KEY:{API_KEY}")

# 打印 Key 的前8位进行调试确认(保护隐私)
key_preview = API_KEY[:8] + "..." if len(API_KEY) > 8 else "Key太短或无效"
print(f"🔍 代码读取到的API_KEY:{key_preview}")

# 初始化 OpenAI 客户端,指向阿里云百炼的兼容接口
client = OpenAI(
    api_key=API_KEY,  # 替换为你的实际 Key (sk-...)
    base_url="https://dashscope.aliyuncs.com/compatible-mode/v1"
)

# 指定模型 ID
# 注意:在百炼兼容模式下,建议使用短名称,去掉 "Qwen/" 前缀
MODEL_ID = "qwen2.5-72b-instruct"

print(f"🔄 正在连接模型: {MODEL_ID} ...")


# ================= 2. 定义工具函数 =================

def simple_calculator(expression: str) -> str:
    """计算数学表达式。"""
    try:
        if re.match(r'^[0-9\.\s\+\-\*\/\(\)\*\*]+$', expression):
            result = eval(expression)
            return str(result)
        else:
            return "无效的数学表达式"
    except Exception as e:
        return f"计算错误: {str(e)}"


def setup_rag_tool():
    if not os.path.exists("data.txt"):
        return None
    try:
        loader = TextLoader("data.txt", encoding="utf-8")
        docs = CharacterTextSplitter(chunk_size=500, chunk_overlap=50).split_documents(loader.load())
        embeddings = HuggingFaceEmbeddings(model_name="sentence-transformers/all-MiniLM-L6-v2")
        vectorstore = Chroma.from_documents(documents=docs, embedding=embeddings, persist_directory="./chroma_db")

        def search_func(query: str) -> str:
            results = vectorstore.similarity_search(query, k=2)
            return "\n".join([d.page_content for d in results])

        return Tool(
            name="CompanySearch",
            func=search_func,
            description="用于查询公司内部信息,如CEO、产品、成立时间等。"
        )
    except Exception as e:
        print(f"⚠️ 知识库工具创建失败: {e}")
        return None


# 创建工具列表
tools: List[Tool] = []
tools.append(Tool(name="Calculator", func=simple_calculator, description="用于计算数学表达式。"))
rag_tool = setup_rag_tool()
if rag_tool:
    tools.append(rag_tool)


# ================= 3. 手动实现 ReAct 逻辑 (OpenAI 格式) =================

def create_simple_agent(client, model_id, tools: List[Tool]):
    tool_map = {tool.name: tool.func for tool in tools}
    tool_names = "[" + ", ".join([tool.name for tool in tools]) + "]"

    # 系统提示词
    system_prompt = f"""你是一个智能助手。请使用以下工具来回答问题:

可用工具:{tool_names}

请严格按照以下格式回答:
问题:你需要回答的问题
思考:你应该总是思考该做什么
行动:要采取的行动,必须是以下之一:{tool_names}
行动输入:行动的输入
观察:行动的结果
...(这个思考/行动/行动输入/观察可以重复N次)
思考:我现在知道最终答案了
最终答案:对原始问题的最终答案

开始!"""

    def agent_logic(inputs: Dict[str, Any]) -> str:
        question = inputs["input"]
        # 初始化消息历史
        messages = [
            {"role": "system", "content": system_prompt},
            {"role": "user", "content": f"问题:{question}\n思考:"}
        ]

        thought_history = ""

        max_iterations = 5
        for _ in range(max_iterations):
            try:
                # 调用 OpenAI 接口
                response = client.chat.completions.create(
                    model=model_id,
                    messages=messages + [{"role": "assistant", "content": thought_history}],
                    temperature=0.7,
                    max_tokens=512
                )

                new_text = response.choices[0].message.content
                thought_history += new_text

                # 检查是否需要调用工具
                if "行动:" in new_text:
                    action_match = re.search(r"行动:\s*(\w+)", new_text)
                    action_input_match = re.search(r"行动输入:\s*(.+?)(?:\n|$)", new_text)

                    if action_match and action_input_match:
                        action_name = action_match.group(1)
                        action_input = action_input_match.group(1).strip()

                        if action_name in tool_map:
                            try:
                                observation = tool_map[action_name](action_input)
                                thought_history += f"\n观察:{observation}\n思考:"
                            except Exception as e:
                                thought_history += f"\n观察:工具执行错误: {str(e)}\n思考:"
                        else:
                            thought_history += f"\n观察:未知工具 '{action_name}'\n思考:"
                    else:
                        thought_history += "\n思考:"
                elif "最终答案:" in new_text:
                    final_answer = new_text.split("最终答案:")[-1].strip()
                    return final_answer
                else:
                    thought_history += "\n思考:"

            except Exception as e:
                print(f"❌ API 调用错误: {e}")
                return f"调用模型失败: {e}"

        return thought_history

    return RunnableLambda(agent_logic)


# 创建智能体
agent = create_simple_agent(client, MODEL_ID, tools)

# ================= 4. 运行智能体 =================
print("\n🤖 云端智能体已启动! (输入 'quit' 退出)")

while True:
    try:
        user_input = input("\n👤 你: ").strip()
        if not user_input or user_input.lower() in ["quit", "exit"]:
            print("👋 再见!")
            break

        response = agent.invoke({"input": user_input})
        print(f"🤖 AI: {response}")

    except KeyboardInterrupt:
        print("\n👋 强制退出")
        break
    except Exception as e:
        print(f"❌ 发生错误: {e}")

不使用langchain,原代码实现agent

使用方法:

1、直接运行该代码,跑的是第一个问题,应该会

2、然后注释掉最后的第一个问题,换第二个问题运行下有正确答案。

python 复制代码
import re
from openai import OpenAI
import os

# =================配置区=================
# API_KEY = "ms-你的Key"
# BASE_URL = "https://api.modelscope.cn/v1"
MODEL_NAME = "qwen2.5-72b-instruct"
# client = OpenAI(api_key=API_KEY, base_url=BASE_URL)

API_KEY = os.getenv("DASHSCOPE_API_KEY", "YOUR API KEY")
print(f"🔍 代码读取到的API_KEY:{API_KEY}")
client = OpenAI(
    api_key=API_KEY,  # 替换为你的实际 Key (sk-...)
    base_url="https://dashscope.aliyuncs.com/compatible-mode/v1"
)




# =================1. 定义工具(这是手脚)=================
# 我们手动定义两个简单的工具,方便演示
def search_tool(query):
    """搜索工具:用于查询实时信息"""
    print(f"   🔍 [执行日志] 正在调用搜索引擎,查询关键词:'{query}'...")
    # 模拟网络延迟和返回结果
    return f"搜索结果:{query} 是未来科技的核心产品,发布于2024年。"


def calculator_tool(expression):
    """计算工具:用于数学计算"""
    print(f"   🧮 [执行日志] 正在调用计算器,计算公式:'{expression}'...")
    try:
        result = eval(expression)  # 注意:实际生产中 eval 有风险,这里仅做演示
        return f"计算结果:{result}"
    except:
        return "计算错误"


# 将工具注册到一个字典里,方便通过名字查找
tools_map = {
    "Search": search_tool,
    "Calculator": calculator_tool
}

# =================2. 定义提示词(这是大脑)=================
system_prompt = """
你是一个智能助手。你可以使用以下工具来回答用户的问题:

1. Search(query): 当你需要查询公司信息或实时新闻时使用。
2. Calculator(expression): 当你需要进行数学计算时使用。

请严格按照以下格式回答:

思考:你需要先思考该怎么做。
行动:只能从 [Search, Calculator] 中选择一个工具名称。
行动输入:工具所需的输入参数。
观察:等待系统返回结果(这一步由系统自动完成,你不需要写)。

如果不需要使用工具,直接回答:
思考:我可以直接回答。
最终答案:你的回答。
"""


# =================3. 核心执行循环(这是神经系统)=================
def run_agent_loop(user_question):
    messages = [
        {"role": "system", "content": system_prompt},
        {"role": "user", "content": user_question}
    ]

    print(f"\n👤 用户提问: {user_question}")
    print("-" * 30)

    # 最多循环 5 次,防止死循环
    for step in range(5):
        print(f"\n--- 第 {step + 1} 轮思考 ---")

        # A. 调用大模型获取思考结果
        response = client.chat.completions.create(
            model=MODEL_NAME,
            messages=messages
        )
        ai_content = response.choices[0].message.content
        print(f"🧠 AI思考内容:\n{ai_content}")

        # B. 解析 AI 的回复,看它想干什么
        # 使用正则表达式提取 "行动:" 和 "行动输入:"
        action_match = re.search(r"行动:(.*?)\n行动输入:(.*?)\n", ai_content)

        # 如果没有找到行动指令,说明它想直接回答(或者出错了)
        if not action_match:
            final_answer_match = re.search(r"最终答案:(.*)", ai_content, re.DOTALL)
            if final_answer_match:
                print(f"\n✅ 最终回答: {final_answer_match.group(1)}")
            else:
                print("\n❌ 无法理解 AI 的回复")
            break

        # C. 提取工具名称和参数
        tool_name = action_match.group(1).strip()
        tool_args = action_match.group(2).strip()

        print(f"🛠️ 识别到工具调用: {tool_name}({tool_args})")

        # D. 真正执行 Python 函数
        if tool_name in tools_map:
            tool_func = tools_map[tool_name]
            observation = tool_func(tool_args)  # <--- 这里就是真正的"执行"

            print(f"👁️ 观察结果: {observation}")

            # E. 将观察结果塞回给 AI,让它进行下一轮思考
            messages.append({"role": "assistant", "content": ai_content})
            messages.append({"role": "system", "content": f"观察:{observation}"})
        else:
            print(f"❌ 错误:AI 试图使用不存在的工具 {tool_name}")
            break


# =================运行=================
# 试着问一个需要查资料的问题
run_agent_loop("未来科技的核心产品是什么?")

# 试着问一个需要计算的问题
# run_agent_loop("帮我算一下 123 * 456 等于多少")
如何理解智能体
逻辑模块 代码中的位置 核心作用
工具库 tools: List[Tool] 提供外部能力(计算、查文档),打破模型知识限制。
大脑指令 system_prompt 强制模型遵循"先想后做"的逻辑,而不是直接瞎编答案。
感知-行动环 while 循环 + re.search 这是智能体的灵魂。它不断: 1. 听 (API Response) 2. 做 (Run Tool) 3. 回传 (Update History) 直到得出最终结论。

总结:

这段代码没有直接调用模型问"1+1等于几"然后直接返回,而是通过"思考 -> 计算 -> 观察 -> 回答"的闭环,证明了它是一个能调用工具解决问题的智能体,而不仅仅是一个聊天机器人。

相关推荐
诗酒当趁年华2 小时前
langchain核心组件1-智能体
数据库·langchain
jyan_敬言2 小时前
【算法】高精度算法(加减乘除)
c语言·开发语言·c++·笔记·算法
¥-oriented2 小时前
数据集资源
笔记
biuyyyxxx2 小时前
Power Query功能区 - 主页
笔记·学习·excel
今儿敲了吗2 小时前
DS-3 循环队列判断队满
数据结构·笔记·学习
m0_651562523 小时前
2026.3.23搭建AI算法可视化部署演示学习笔记
笔记·学习
CODE_RabbitV3 小时前
STM32F103C8T6 理论部分学习笔记
笔记·stm32·学习
小陈phd4 小时前
系统架构师学习笔记(四)——计算机体系结构之校验码
笔记·学习
飞Link4 小时前
LangChain 核心链式架构演进史:从顺序链到企业级路由兜底实战
python·架构·langchain