零基础入门:手把手搭建你的第一个 AI 智能体

2025-10-30 15:53:33
文章摘要
LLM为什么需要agent化 虽然大语言模型的能力很强大,但是Llm仅限于用于训练的知识,这些知识很快会过时,所以llm有以下缺点: 幻觉 结果并不总是真实的 对时事的了解有限或一无所知 难以应对复杂推理和计算

例如:买高铁票



(虽然LLM完全理解了买票的行为,但是它本身并不知道“我”所处的城市,列车的时刻表,价格等等信息)

而基于大模型的Agent (LLM based Agent) 可以利用外部工具来克服以上缺点。



LLM Agent 的升级之路:

Standard IO(直接回答) -> COT(chain-of-thought)(思维链) -> Action-Only (Function calling) -> Reason + Action

ReAct = Reasoning(推理) + Action(行动)



.ReAct Agent 的组成部分 (通过LangChain实现)

.Models:LLM

.Prompts:对Agent的指令、约束

.Memory : 记录Action执行状态 & 缓存已知信息

.Indexes : 用于结构化文档,以便和模型交互

.Chains :Langchain的核心(链)

.Agent



ReAct Agent 的prompt 模板


from langchain_core.prompts import PromptTemplate

template = '''Answer the following questions as best you can. You have access to the following tools:

{tools}

Use the following format:

Question: the input question you must answer

Thought: you should always think about what to do

Action: the action to take, should be one of [{tool_names}]

Action Input: the input to the action

Observation: the result of the action

... (this Thought/Action/Action Input/Observation can repeat N times)

Thought: I now know the final answer

Final Answer: the final answer to the original input question

 

Begin!

 

Question: {input}

Thought:{agent_scratchpad}'''

prompt = PromptTemplate.from_template(template)


代码

手写一个能帮忙买火车票的智能Agent

注:火车票相关API均为mock


安装 & import依赖


pip install langchain

pip install uuid

pip install pydantic

 

 

import json

import sys

from typing import List, Optional, Dict, Any, Tuple, Union

from uuid import UUID

 

from langchain.memory import ConversationTokenBufferMemory

from langchain.tools.render import render_text_description

from langchain_core.callbacks import BaseCallbackHandler

from langchain_core.language_models import BaseChatModel

from langchain_core.output_parsers import PydanticOutputParser, StrOutputParser

from langchain_core.outputs import GenerationChunk, ChatGenerationChunk, LLMResult

from langchain_core.prompts import PromptTemplate

from langchain_core.tools import StructuredTool

from langchain_openai import ChatOpenAI

 

from pydantic import BaseModel, Field, ValidationError



定义工具

from typing import List

 

from langchain_core.tools import StructuredTool

 

def search_train_ticket(

origin: str,

destination: str,

date: str,

departure_time_start: str,

departure_time_end: str

) -> List[dict[str, str]]:

    """按指定条件查询火车票"""

 

    # mock train list

    return [

        {

            "train_number": "G1234",

            "origin": "北京",

            "destination": "上海",

            "departure_time": "2025-10-21 8:00",

            "arrival_time": "202-10-21 12:00",

            "price": "100.00",

            "seat_type": "商务座",

        },

        {

            "train_number": "G5678",

            "origin": "北京",

            "destination": "上海",

            "departure_time": "2025-10-21 18:30",

            "arrival_time": "2025-10-21 22:30",

            "price": "100.00",

            "seat_type": "商务座",

        },

        {

            "train_number": "G9012",

            "origin": "北京",

            "destination": "上海",

            "departure_time": "2025-10-21 19:00",

            "arrival_time": "2025-10-01 23:00",

            "price": "100.00",

            "seat_type": "商务座",

        }

    ]

 

 

def purchase_train_ticket(

train_number: str,

) -> dict:

    """购买火车票"""

    return {

        "result": "success",

        "message": "购买成功",

        "data": {

            "train_number": "G1234",

            "seat_type": "商务座",

            "seat_number": "7-17A"

        }

    }

 

 

search_train_ticket_tool = StructuredTool.from_function(

func=search_train_ticket,

name="查询火车票",

description="查询指定日期可用的火车票。",

)

 

purchase_train_ticket_tool = StructuredTool.from_function(

func=purchase_train_ticket,

name="购买火车票",

description="购买火车票。会返回购买结果(result), 和座位号(seat_number)",

)

 

finish_placeholder = StructuredTool.from_function(

func=lambda: None,

name="FINISH",

description="用于表示任务完成的占位符工具"

)

 

tools = [search_train_ticket_tool, purchase_train_ticket_tool, finish_placeholder]



测试


if __name__ == "__main__":

my_agent = MyAgent(

tools=tools,

prompt=prompt_text,

final_prompt=final_prompt,

    )

 

task = "帮我买25年10月21日早上去上海的火车票"

reply = my_agent.run(task)

    print(reply)



结果

 

第一轮思考

Agent根据要求,选择了需要使用的Tool,组装了请求参数并完成了调用。

(还可以多定义一些Tools,比如获取当前位置的,获取今天日期的工具等等,这样这里的查询火车票的参数可以更智能)


>>>>Round: 0<<<<

任务:帮我买25年10月21日早上去上海的火车票

 

思考: 根据任务需求,首先需要查询2025年10月21日早上从当前位置到上海的火车票。这需要使用“查询火车票”工具,指定出发地、目的地、日期以及早上的时间范围。

 

动作/工具:

 

{

  "name": "查询火车票",

  "args": {

    "origin": "当前位置",

    "destination": "上海",

    "date": "2025-10-21",

    "departure_time_start": "00:00",

    "departure_time_end": "12:00"

  }

}

 

----

Observation:

[{'train_number': 'G1234', 'origin': '北京', 'destination': '上海', 'departure_time': '2025-10-21 8:00', 'arrival_time': '2025-10-21 12:00', 'price': '100.00', 'seat_type': '商务座'}, {'train_number': 'G5678', 'origin': '北京', 'destination': '上海', 'departure_time': '2025-10-21 18:30', 'arrival_time': '2025-10-21 22:30', 'price': '100.00', 'seat_type': '商务座'}, {'train_number': 'G9012', 'origin': '北京', 'destination': '上海', 'departure_time': '2025-10-21 19:00', 'arrival_time': '2025-10-21 23:00', 'price': '100.00', 'seat_type': '商务座'}]

 



第二轮思考

根据查询出的车票信息去调用购票的Tool


>>>>Round: 1<<<<

任务:帮我买24年6月1日早上去上海的火车票

 

思考: 根据查询结果,有三个车次可供选择,但只有车次G1234符合早上出发的要求,因此应选择购买这个车次的票。

 

动作/工具:

{

  "name": "购买火车票",

  "args": {

    "train_number": "G1234"

  }

}

----

Observation:

{'result': 'success', 'message': '购买成功', 'data': {'train_number': 'G1234', 'seat_type': '商务座', 'seat_number': '7-17A'}}

 



第三轮思考

LLM识别到任务已完成,输出了结果


>>>>Round: 2<<<<

任务:帮我买25年10月21日早上去上海的火车票

 

思考: 根据执行记录,已经成功购买了2025年10月21日早上从北京到上海的火车票(车次G1234)。因此,接下来的任务是完成这个购票任务。

 

动作/工具:

{

  "name": "FINISH"

}

 

购买成功。您已成功购买2025年10月21日早上从北京出发前往上海的火车票,车次为G1234,座位类型为商务座,座位号为7-17A。




声明:该内容由作者自行发布,观点内容仅供参考,不代表平台立场;如有侵权,请联系平台删除。