AI Agent 基础概念与开发框架(2026-01-25 贺岁版)


基础介绍

1 什么是 AI Agent

AI Agent 是基于大语言模型(LLM)的智能体,能够自主感知→规划→行动→观察,从而完成复杂任务。
与单纯调用 LLM(输入-思考-输出)不同,Agent 更贴近人类“先拆任务、再动手、边干边改”的解决方式 。

开发框架:AI Agent的应用开发基于LangChain框架。
AI Agent与LM及人类的对比
LM的局限性:LM主要是接收输入,通过内部思考得到输出,缺乏记忆、工具使用和规划能力。
人类解决问题的特点:人类在接收外部环境输入、思考、输出之外,还会运用记忆、工具和规划来解决问题,例如老板下发任务后,人类会拆解任务、规划步骤、寻求帮助。
Agent对人类思维的模拟:Agent正是通过量化人类这种思维习惯来构建的,使其具备更复杂的任务处理能力。


2 AI Agent vs LLM vs 人类

维度 纯 LLM 人类 AI Agent
记忆 无(上下文即记忆) 短期+长期 短期Buffer+长期向量库
工具 不会用 手/计算器/搜索 Function Calling+API
规划 一次性输出 拆解-步骤-反思 ReAct/思维树/状态图
结果 文本 动作+结果 动作+结果+迭代

例子:让纯 LLM 订机票,它只返回文字;Agent 会查天气→比价→下单→发日历邀请 。


3 核心 4 组件(2026 工业界共识)

  1. 感知(Perception)
    接收多模态输入:文本、语音、传感器、API 回调 。

  2. 记忆(Memory)

    • 短期:ConversationBufferWindow,随对话滑动
    • 长期:Chroma/Qdrant + Embedding,支持 Session 找回
  3. 规划(Planning)

    • 单链:ReAct = Thought→Action→Observation
    • 多步:思维树 / CARS,可回溯
    • 状态图:LangGraph 支持循环、条件分支
  4. 工具(Tools)&行动(Action)
    日历、搜索、代码解释器、REST API;通过 Function Calling 由 LLM 自行选择 。

记忆(Memory):
相当于与模型对话的连贯上下文,用于分步解决问题时记住前面的步骤。分为短期记忆和长时记忆。短期记忆在编程练习时通常存于容器,再次调用接口可能清空;长时记忆在用户服务中会持久化存储到内存并给予Session ID,以便用户再次使用时读取之前的对话历史。
规划(Planning):
指执行任务时的步骤安排,如第一步、第二步等,以及在执行过程中根据反馈是否需要重新计划。规划有很多框架,如思维链、思维树、ReAct框架、CARS框架等,后续会挑选Star数高或经测试好用的框架详细讲解。
工具(Tools):
用于让LM连接外部世界,最典型的是Function Calling函数调用。例如,LM本身不具备联网获取天气的能力,但可通过外接API实现。工具还包括日历、计算、代码执行器、搜索等,后续会详细讲解工具的使用。
行动(Action):
当整个任务循环想要执行时,开始当前的活动,是任务执行的具体动作。

4 决策循环流程(ReAct 经典 4 步)

感知输入 → 规划拆解 → 调用工具行动 → 观察反馈 →(循环直至目标)


📖 Part-A 整体知识速记

组件 日常生活例子 技术要点
感知 孩子听到「作业写完了吗?」 接收外部输入(文字/语音/文件)
记忆 记住孩子不吃葱 短期:BufferWindow;长期:向量库 + SessionID
规划 先买菜→再下锅 ReAct / 思维树 / LangGraph 状态图
工具 外卖 App、计算器 Function Calling、搜索、SQL、REST
行动 下单鸡蛋、开火炒菜 代码执行、API 调用、返回结果

Agent 决策循环(ReAct 经典 4 步)
感知 → 思考 → 行动 → 观察 →(循环直到目标完成)


🛠 Part-B 10 行代码跑通「搜索+计算」Agent

# 依赖:首次运行请取消注释
# !pip install langchain==0.3.5 langchain-openai duckduckgo-search
import langchain; print('LangChain版本:', langchain.__version__)
LangChain版本: 1.2.0
#!pip install -U ddgs
# ========== LangChain 1.2.1 极简适配(无任何导入错误) ==========
from langchain_community.chat_models.ollama import ChatOllama
from langchain_community.tools import DuckDuckGoSearchRun
from langchain_core.prompts import ChatPromptTemplate

# ========== 1. 初始化核心组件(保留你的 Ollama 地址) ==========
# 初始化 Ollama 模型(你的远程服务地址)
llm = ChatOllama(
    base_url="http://192.168.52.88:11434", model="qwen2:1.5b", temperature=0.1
)

# 初始化 DuckDuckGo 搜索工具
search_tool = DuckDuckGoSearchRun()


# ========== 2. 核心逻辑:先搜索,再让 LLM 生成 Markdown 表格 ==========
def get_ai_llm_rank_2026():
    # 步骤1:调用搜索工具获取原始信息
    try:
        print("🔍 正在搜索2026年AI大语言模型排名...")
        search_query = "2026年AI大语言模型排名 权威榜单"
        raw_search_result = search_tool.run(search_query)
        if not raw_search_result:
            return "❌ 未搜索到相关信息"
    except Exception as e:
        return f"❌ 搜索失败:{str(e)[:100]}"

    # 步骤2:定义 Prompt,让 LLM 将搜索结果转为 Markdown 表格
    prompt = ChatPromptTemplate.from_messages(
        [
            (
                "system",
                """你是数据格式化助手,严格按以下规则处理:
        1. 基于提供的搜索结果,提取2026年AI大语言模型排名信息;
        2. 仅输出 Markdown 表格格式,包含「框架名称」「排名」「核心特点」三列;
        3. 表格格式规范,无多余文字、无解释、无思考过程;
        4. 若信息不全,按行业常识补充核心特点(仅补充,不编造排名)。""",
            ),
            ("user", "搜索结果:{raw_result}\n请按要求输出Markdown表格"),
        ]
    )

    # 步骤3:调用 LLM 生成格式化结果
    chain = prompt | llm  # 1.2.1 支持的链式调用(核心特性)
    formatted_result = chain.invoke({"raw_result": raw_search_result})

    return formatted_result.content


# ========== 3. 执行并输出结果 ==========
if __name__ == "__main__":
    # 执行查询
    final_result = get_ai_llm_rank_2026()

    # 格式化输出
    print("\n" + "=" * 80)
    print("✅ 2026年AI大模型排名(Markdown表格):")
    print("=" * 80)
    print(final_result)
🔍 正在搜索2026年AI大语言模型排名...

================================================================================
✅ 2026年AI大模型排名(Markdown表格):
================================================================================
| 框架名称 | 排名 | 核心特点 |
| --- | --- | --- |
| Qwen2.5-1.5B-Instruct | 1 | 简单易用,适用于多种场景 |
| Llama3 | 2 | 高效文本生成能力,适合大量数据处理 |
| Gemma | 3 | 强大的语言模型,广泛应用于自然语言处理领域 |
| MaziyarPanahi/calme-3.2-instruct-78b | 4 | 强大的情绪识别和情感分析能力 |
| shuttleai/shuttle-3 | 5 | 高效的文本生成和翻译能力 |
| Hugging Face | 6 | 大量开源 模 型 和工具,支持多种语言 |
| Alibaba's Qwen | 7 | 与Qwen2.5-1.5B-Instruct相似,但具有更广泛的使用场景 |
| OpenAI's Codex | 8 | 强大的文本生成能力,适用于大量数据处理 |
| Google's BERT | 9 | 高效的自然语言处理模型,广泛应用于搜索引擎和问答系统 |
| Microsoft's T5 | 10 | 强大的文本生成和翻译能力,适合多种应用场景 |
| Alibaba's Qwen2.5-1.5B-Instruct | 11 | 具有更广泛的使用场景,适用于多种自然语言处理任务 |

运行后可见 Thought→Action→Observation 全流程日志


🖥 Part-C 本地免费方案:Ollama + LangChain + qdrantDB

# 核心导入
from langchain_community.chat_models import ChatOllama
from langchain_core.prompts import ChatPromptTemplate, MessagesPlaceholder
from langchain_core.runnables.history import RunnableWithMessageHistory
from langchain_community.chat_message_histories import ChatMessageHistory
from langchain_core.runnables import RunnableLambda
from langchain_core.messages import SystemMessage
from langchain_core.documents import Document
import traceback

# Qdrant + LangChain 检索相关导入
from langchain_community.embeddings import OllamaEmbeddings
from langchain_community.vectorstores import Qdrant
from qdrant_client import QdrantClient
from qdrant_client.models import Distance, VectorParams

# ====================== 核心配置 ======================
# Ollama远程配置
OLLAMA_MODEL = "qwen2:1.5b"
OLLAMA_BASE_URL = "http://192.168.52.88:11434"

# Qdrant远程配置
QDRANT_URL = "http://192.168.52.88:6333"
QDRANT_COLLECTION = "qwen2_remote_memory"
QDRANT_VECTOR_SIZE = 1536  # qwen2:1.5b固定维度

# ====================== 初始化组件(关键:创建LangChain Qdrant VectorStore) ======================
try:
    # 1. 初始化Ollama LLM
    llm = ChatOllama(
        model=OLLAMA_MODEL,
        base_url=OLLAMA_BASE_URL,
        temperature=0,
        num_ctx=2048
    )
    print("✅ Ollama LLM初始化成功")

    # 2. 初始化Ollama Embeddings
    embeddings = OllamaEmbeddings(
        model=OLLAMA_MODEL,
        base_url=OLLAMA_BASE_URL,
        embed_instruction="为文本生成用于检索的向量:"
    )
    # 验证向量维度
    test_emb = embeddings.embed_query("测试")
    assert len(test_emb) == QDRANT_VECTOR_SIZE, f"向量维度错误:{len(test_emb)}"
    print("✅ Embeddings初始化成功")

    # 3. 初始化远程Qdrant客户端
    qdrant_client = QdrantClient(
        url=QDRANT_URL,
        timeout=30,
        check_compatibility=False
    )
    qdrant_client.get_collections()
    print("✅ 远程Qdrant连接成功")

    # 4. 创建/确认Qdrant集合
    if not qdrant_client.collection_exists(QDRANT_COLLECTION):
        qdrant_client.create_collection(
            collection_name=QDRANT_COLLECTION,
            vectors_config=VectorParams(size=QDRANT_VECTOR_SIZE, distance=Distance.COSINE)
        )
        print(f"✅ Qdrant集合 {QDRANT_COLLECTION} 创建成功")

    # 5. 关键:创建LangChain Qdrant VectorStore(核心,用于as_retriever)
    vector_store = Qdrant(
        client=qdrant_client,
        collection_name=QDRANT_COLLECTION,
        embeddings=embeddings
    )
    print("✅ LangChain Qdrant VectorStore初始化成功")

    # 6. 创建MMR检索器(按你的参数配置)
    retriever = vector_store.as_retriever(
        search_type="mmr",  # 使用MMR检索策略
        search_kwargs={
            "k": 1,            # 返回前1个结果
            "fetch_k": 1,      # 先获取1个最相似文档
            "lambda_mult": 0.7 # 平衡相关性(值越大越注重相关)
        }
    )
    print("✅ MMR检索器初始化成功")

except Exception as e:
    print(f"❌ 组件初始化失败:{type(e).__name__}: {e}")
    traceback.print_exc()
    exit(1)

# ====================== 长时记忆函数(替换为MMR检索) ======================
def save_to_long_memory(input_text: str, output_text: str):
    """保存到Qdrant(用LangChain封装,避免底层API)"""
    try:
        doc = Document(page_content=f"用户:{input_text}\nAI:{output_text}")
        vector_store.add_documents([doc])  # 用vector_store保存,适配所有版本
        print("✅ 长时记忆保存成功")
    except Exception as e:
        print(f"❌ 长时记忆保存失败:{type(e).__name__}: {e}")
        traceback.print_exc()

def retrieve_long_memory(query: str) -> list:
    """用MMR检索器实现长时记忆检索(彻底规避底层API)"""
    try:
        # 方法1:先尝试用LangChain检索器(推荐)
        docs = retriever.invoke(query)
        
        # 解析检索结果
        retrieved_texts = []
        for doc in docs:
            retrieved_texts.append(doc.page_content)  # 获取文档内容
        
        # 转换为SystemMessage列表(适配MessagesPlaceholder)
        if retrieved_texts:
            long_history_text = "\n".join(retrieved_texts)
            return [SystemMessage(content=f"长时记忆:{long_history_text}")]
        else:
            return [SystemMessage(content="无相关长时记忆")]
    except AttributeError as e:
        # 方法2:如果LangChain调用失败,降级到直接使用Qdrant客户端API
        print(f"⚠️  LangChain检索失败,降级到直接Qdrant查询:{e}")
        try:
            # 生成查询向量
            query_vector = embeddings.embed_query(query)
            # 使用新版API query_points进行搜索
            search_results = qdrant_client.query_points(
                collection_name=QDRANT_COLLECTION,
                query=query_vector,  # 注意参数名从query_vector变为query
                limit=1
            )
            
            retrieved_texts = []
            for point in search_results.points:
                if point.payload and "page_content" in point.payload:
                    retrieved_texts.append(point.payload["page_content"])
            
            if retrieved_texts:
                long_history_text = "\n".join(retrieved_texts)
                return [SystemMessage(content=f"长时记忆:{long_history_text}")]
            else:
                return [SystemMessage(content="无相关长时记忆")]
        except Exception as inner_e:
            print(f"❌ 降级查询也失败:{type(inner_e).__name__}: {inner_e}")
            traceback.print_exc()
            return [SystemMessage(content="长时记忆检索出错")]
    except Exception as e:
        print(f"❌ 长时记忆检索失败:{type(e).__name__}: {e}")
        traceback.print_exc()
        return [SystemMessage(content="长时记忆检索出错")]
        

# ====================== 会话记忆链(保留核心逻辑) ======================
# Prompt模板
prompt = ChatPromptTemplate.from_messages([
    ("system", "你是友好的中文助手,优先参考长时记忆回答。"),
    MessagesPlaceholder(variable_name="long_history"),
    MessagesPlaceholder(variable_name="short_history"),
    ("human", "{input}"),
])

# 整合记忆逻辑
def integrate_memories(inputs):
    try:
        return {
            "long_history": retrieve_long_memory(inputs["input"]),
            "short_history": inputs.get("short_history", []),
            "input": inputs["input"]
        }
    except Exception as e:
        print(f"❌ 记忆整合失败:{type(e).__name__}: {e}")
        traceback.print_exc()
        return {
            "long_history": [SystemMessage(content="记忆整合出错")],
            "short_history": [],
            "input": inputs["input"]
        }

# 完整链
chain = (
    RunnableLambda(integrate_memories)
    | prompt
    | llm
)

# 短期记忆存储
store = {}
def get_session_history(session_id: str):
    if session_id not in store:
        store[session_id] = ChatMessageHistory()
    return store[session_id]

# 包装会话记忆
conversation_with_memory = RunnableWithMessageHistory(
    chain,
    get_session_history,
    input_messages_key="input",
    history_messages_key="short_history",
)

# ====================== 测试调用(验证MMR检索) ======================
# ====================== 测试调用(验证MMR检索) ======================
if __name__ == "__main__":
    input1 = "你好,我叫西米,今年5岁,喜欢贝乐虎识字,家住福州"
    try:
        # 第一轮调用(保存记忆)
        response1 = conversation_with_memory.invoke(
            {"input": input1},
            config={"configurable": {"session_id": "user123"}}
        )
        print(f"✅ 第一轮回复:{response1.content}")
        # 保存到长时记忆
        save_to_long_memory(input1, response1.content)

        # === 新增:显式调用并打印检索到的长时记忆 ===
        print("\n=== 显式验证长时记忆检索 ===")
        test_query = "西米"  # 检索关键词
        retrieved_memory_messages = retrieve_long_memory(test_query)
        # 打印检索结果
        for msg in retrieved_memory_messages:
            print(f"检索返回的消息: {msg.content}")
        print("=== 结束显式验证 ===\n")

        # 清空短期记忆后调用LLM
        store["user123"] = ChatMessageHistory()
        print("⚠️  已清空短期记忆 (ChatMessageHistory)")
        response2 = conversation_with_memory.invoke(
            {"input": "你还记得我叫什么?喜欢什么吗?"},
            config={"configurable": {"session_id": "user123"}}
        )
        print(f"\n✅ 第二轮回复:{response2.content}")

    except Exception as e:
        print(f"❌ 调用失败:{type(e).__name__}: {e}")
        traceback.print_exc()
✅ Ollama LLM初始化成功
✅ Embeddings初始化成功
✅ 远程Qdrant连接成功
✅ LangChain Qdrant VectorStore初始化成功
✅ MMR检索器初始化成功
⚠️  LangChain检索失败,降级到直接Qdrant查询:'QdrantClient' object has no attribute 'search'
✅ 第一轮回复:你好,西米!很高兴见到你。请问有什么可以帮助你的吗?
✅ 长时记忆保存成功

=== 显式验证长时记忆检索 ===
⚠️  LangChain检索失败,降级到直接Qdrant查询:'QdrantClient' object has no attribute 'search'
检索返回的消息: 长时记忆:用户:你好,我叫西米,今年5岁,喜欢贝乐虎识字,家住福州
AI:你好,小明!很高兴见到你。请问有什么可以帮助你的吗?
=== 结束显式验证 ===

⚠️  已清空短期记忆 (ChatMessageHistory)
⚠️  LangChain检索失败,降级到直接Qdrant查询:'QdrantClient' object has no attribute 'search'

✅ 第二轮回复:你好,西米!很高兴见到你。根据我的长时记忆,我记得你叫西米,今年5岁,来自福州,并且你喜欢贝乐虎识字。
#!pip show qdrant-client 
import qdrant_client
print(hasattr(qdrant_client.QdrantClient, "query_points"))  # 应输出True
True

Agent 决策流程应用场景举例

以「用户一句“我有点冷”」为例,完整复盘感知→规划→行动→观察→循环的智能家居温控实战

调节温度需先从外部环境获取输入,例如用户说“我感觉有点冷,能不能把温度调高一些”,这相当于给LM的prompt指令,智能系统会通过语音识别和情感分析技术感知用户需求,如判断房间温度低需提高温度,且情感分析能让AI回复带上人类情绪。
agent决策流程之规划阶段
规划的必要性与多样性:有了感知后需对需求进行规划,如确定温度调高多少,规划有多种可能性,类似数学题有多种解法,思路不同解法不同,若思路错误则需重新制定。
规划的具体步骤与依据:针对调高温度的需求,规划步骤包括:一是获取当前室内温度作为基准;二是根据用户偏好和当前温度决定升高几度,这里利用了memory能力,用户偏好有记录,如可能设置为20°或25°,但规划时还需综合评估其他信息,如用户体重变化(去年120斤怕冷,今年160斤怕热);三是调整温度设置并告知用户。
agent决策流程之行动与反馈观察阶段
系统执行计划的行动:规划后开始行动,系统执行计划,先检查当前温度,如检测到室内温度20°C,根据用户偏好23°,则调到23°并通过语音助手反馈用户“已将温度调高到23摄氏度,请稍等温度将逐渐上升”。
结果的反馈观察与循环调整:调到23°不一定是对的结果,需对结果进行反馈观察,观察房间温度是否到23°及用户反馈是否合理。若用户说温度刚好,系统感知调节OK;若用户仍觉得冷,则replay计划,调整计划进一步调高温度,调高阈值可规划为1°C、2°C调或按用户明确指令调(如调到25°C)。若需调整则反过头重新制定计划,形成循环,直到task任务完成才终止循环。


1 回顾与场景设定

  • 概念痛点:只讲抽象流程,听众对“task 到底长啥样”无感。
  • 具体场景:家庭客厅,任务——把室内温度和灯光调到“家人觉得舒服”

2 需求感知:一句话如何变成结构化输入

  1. 语音捕获 → “我感觉有点冷,能不能把温度调高一些?”
  2. 语音识别 + 情感分析 → 紧急度 8/10,情绪偏“弱请求”。
  3. 参数抽取(Agent 感知输出):
    • intent: raise_temp
    • target_temp: null(未给数值)
    • urgency: 8
    • location: living_room

情感模块让回复带温度:“好的,我这就帮您升温~”。


3 规划阶段:把“冷”翻译成可执行步骤

Agent 在 300 ms 内并行检查 3 条分支,最终合成 Plan-A:

步骤 具体动作 数据来源
① 获取基准 读传感器 current_temp = 20 ℃ 智能瓷砖传感器
② 读记忆 偏好库 preferred = 23 ℃;体重变化 120→160 斤→怕冷↓→修正目标 22 ℃ 长期记忆
③ 能耗评估 户外 5 ℃,阶梯升温 1 ℃→观察→再升,避免热泵满负荷 能耗模型
④ 灯光联动 若客厅灯 < 50 % → 同步调到 70 %,营造“温暖感” 场景联动表

输出 Plan-A JSON:

[{"op":"set_temp","value":22},{"op":"set_light","brightness":70},
 {"op":"notify","text":"已调到 22 ℃,稍等"},{"op":"wait_feedback","timeout":120}]
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

友情链接更多精彩内容