在这里插入图片描述

从"黑盒魔法"到"透明手术":ReAct第一轮行动完整链路追踪,让你彻底看懂AI Agent是怎么"动脑子"的

本文是《大模型应用开发_动手做AI_Agent》第6章ReAct自动定价实战的核心拆解。很多新手学Agent时,总觉得大模型调用工具是"玄学"——输入一个问题, magically 就返回结果了。但真相是:每一次工具执行背后,都有一条清晰的"思考-行动-观察"链路。本文将带你用"显微镜"视角,完整追踪ReAct第一轮行动中"工具执行搜索"的全流程,从Prompt构造、LLM推理、工具选择、参数填充到结果返回,彻底搞懂Agent的"第一次出手"是怎么完成的。读完这篇,你不仅能调试Agent,更能设计Agent。

ReAct第一轮行动
工具执行搜索
完整链路追踪

核心认知篇

"ReAct不是框架,是思维模式"

"第一轮行动的特殊性"

"工具执行搜索的本质"

链路拆解篇

"Prompt构造:给LLM的'任务说明书'"

"LLM推理:模型怎么'想'的"

"工具选择:从 arsenal 里挑武器"

"参数填充:精确制导的关键"

"结果返回:观察与反思"

实战追踪篇

"代码级链路追踪"

"日志解读技巧"

"常见翻车现场"

调试心法篇

"断点应该打在哪里"

"如何阅读模型的'脑电波'"

"从失败案例反推设计"

进阶思考篇

"第一轮行动的设计模式"

"多工具场景的优先级策略"

"从ReAct到更复杂的Agent架构"

目录

  1. 核心认知篇:ReAct第一轮行动的本质理解
  2. 链路拆解篇:工具执行搜索的五步完整链路
  3. 实战追踪篇:代码级追踪与日志解读
  4. 调试心法篇:Agent开发者的"显微镜"使用手册
  5. 进阶思考篇:从第一轮行动看Agent设计哲学

嗨,大家好呀,我是你的老朋友精通代码大仙。接下来我们一起学习 《大模型应用开发_动手做AI_Agent》,震撼你的学习轨迹!


“万事开头难,然后中间难,最后结尾难。”

这句程序员圈的自嘲,放在学Agent开发上再贴切不过了。你是不是也有这样的经历:照着教程搭了个ReAct Agent,输入问题后看到控制台哗啦啦输出一堆日志,最后神奇地得到了正确答案。但你心里清楚——“我根本不知道刚才发生了什么”

更扎心的是,一旦结果不对,你完全无从下手。改Prompt?加示例?调温度参数?全凭玄学试探。这种"黑盒焦虑"是很多新手卡在Agent开发门口的根本原因。

今天咱们就解决这个痛点。以ReAct自动定价场景为例,我会带你用"手术刀"级别的精度,完整追踪第一轮行动中"工具执行搜索"的每一个步骤。注意,是完整链路,不是概览,不是摘要,是每一环都掰开揉碎给你看。


一、核心认知篇:ReAct第一轮行动的本质理解

1.1 ReAct不是框架,是思维模式

很多新手第一次接触ReAct,以为是某个Python库——pip install react那种。其实不是。ReAct(Reasoning + Acting)是一种让大模型交替进行推理和行动的协作模式

ReAct模式

用户问题

Thought:我需要先查什么

Action:调用搜索工具

Observation:搜索结果

足够回答?

Final Answer

传统模式

用户问题

LLM直接回答

关键区别:传统模式是"闭卷考试",ReAct是"开卷考试+可以翻书"。第一轮行动,就是Agent拿到试卷后,**第一次决定"我要翻哪本书"**的过程。

1.2 第一轮行动的特殊性

为什么专门讲"第一轮"?因为后续轮次都是"观察→思考→行动"的循环,而第一轮是从"零上下文"开始的冷启动

轮次 上下文状态 决策依据
第一轮 只有用户原始问题 完全依赖Prompt设计和工具描述
第二轮及以后 已有Thought+Action+Observation历史 可以基于之前的结果调整策略

这个差异极其关键。第一轮如果选错工具或填错参数,后面可能越跑越偏。就像你导航时第一步就输错目的地,后面再怎么优化路线都是徒劳。

1.3 工具执行搜索的本质

"工具执行搜索"不是简单的函数调用。它是一个多阶段决策过程

用户意图理解 → 工具语义匹配 → 参数槽位填充 → 执行结果观测

很多新手误以为:只要工具描述写清楚,LLM就能自动选对。太天真了。我看过太多案例,工具描述明明写得很详细,模型还是选了错误的工具,或者把参数填得面目全非。

痛点案例:某同学做电商定价Agent,有两个工具:

  • search_competitor_price(product_name):查竞品价格
  • search_cost_price(product_name):查成本价

他输入:“iPhone 15 Pro该定什么价?”

结果模型第一轮调用了search_cost_price,得到成本价后直接开始定价,完全没看竞品价格。为什么?因为Prompt里强调"要控制利润率",模型"误以为"成本价更重要。

这就是典型的第一轮行动偏差——模型基于有限的上下文,做出了局部最优但全局次优的选择。


二、链路拆解篇:工具执行搜索的五步完整链路

现在进入核心部分。我把第一轮行动拆解为五个紧密衔接的步骤,每一步都有明确的输入输出和决策逻辑。

执行器 工具注册表 LLM Prompt构造器 用户 执行器 工具注册表 LLM Prompt构造器 用户 第一轮结束 等待下一轮或输出答案 原始问题 组装系统提示+工具描述+用户问题 完整Prompt 生成Thought 解析Action 工具名称匹配 确认工具存在 参数JSON生成 工具调用请求 实际执行 Observation结果

2.1 第一步:Prompt构造——给LLM的"任务说明书"

这一步发生在LLM收到任何输入之前。系统需要把"原始问题"包装成LLM能理解的格式。

标准ReAct Prompt结构

你是专业的电商定价助手,使用以下工具帮助用户定价。

工具列表:
1. search_market_price(product_name: str) -> 查询商品的市场均价
2. search_competitor_price(product_name: str, platform: str = "all") -> 查询竞品价格
3. calculate_profit(cost: float, price: float) -> 计算利润率

请按以下格式思考:
Thought: 你需要做什么
Action: 工具名称
Action Input: 参数JSON

开始!

用户问题:iPhone 15 Pro该定什么价?

新手常见错误:工具描述写得太简略,或者格式不统一。

# ❌ 错误示例:描述模糊,格式混乱
tools = [
    {"name": "search", "desc": "查价格"},  # 查什么价格?参数是什么?
    {"name": "calc", "desc": "计算"}       # 计算什么?
]

# ✅ 正确示例:结构化描述,明确参数
tools = [
    {
        "name": "search_market_price",
        "description": "查询指定商品在当前市场的平均售价,用于了解价格基准",
        "parameters": {
            "product_name": {"type": "string", "description": "商品完整名称,如'iPhone 15 Pro 256GB'"}
        }
    }
]

关键洞察:Prompt构造的质量,直接决定了第一轮行动的"起跑线"高度。工具描述不是写给人类看的,是写给LLM"理解"的。要用LLM的"语言习惯"来写——清晰、结构化、无歧义。

2.2 第二步:LLM推理——模型怎么"想"的

Prompt送进去后,LLM开始生成内容。在ReAct模式下,模型被训练(或通过Few-shot引导)输出特定格式。

典型生成过程

Thought: 用户询问iPhone 15 Pro的定价建议。我需要先了解这款产品的市场价格水平,才能给出合理建议。我应该先查询市场均价。

Action: search_market_price
Action Input: {"product_name": "iPhone 15 Pro"}

这里有两个关键决策点

决策点 说明 常见错误
Thought生成 模型对任务的内部规划 Thought过于简略或跑题
Action解析 从Thought提取可执行动作 Action名称拼写错误、格式不符

痛点案例:某同学发现模型总是输出"Final Answer"而不调用工具。排查后发现,他的Few-shot示例里最后一个例子是直接回答的,模型"学会"了偷懒。调整示例顺序后解决。

调试技巧:在这一步打断点,打印原始输出。不要依赖封装好的库,要看到模型"裸奔"时的真实输出。

2.3 第三步:工具选择——从arsenal里挑武器

拿到Action: search_market_price后,系统需要:

  1. 确认这个工具是否存在
  2. 获取工具的参数schema
  3. 准备进入参数填充阶段

解析Action名称

工具是否存在?

抛出ToolNotFound错误

获取工具元数据

参数schema校验准备

新手噩梦场景:模型输出了Action: search market price(带空格),或者Action: SearchMarketPrice(驼峰命名),与注册名不匹配。

防御性编程建议

# 工具注册时做名称归一化
def normalize_tool_name(name: str) -> str:
    return name.lower().replace(" ", "_").replace("-", "_")

# 匹配时双向归一化
registered_tools = {normalize_tool_name(t.name): t for t in tools}
requested_name = normalize_tool_name(parsed_action)
tool = registered_tools.get(requested_name)

2.4 第四步:参数填充——精确制导的关键

这是最容易翻车的环节。模型需要把Thought中的意图,转化为符合schema的JSON参数。

理想情况

Action Input: {"product_name": "iPhone 15 Pro"}

现实情况可能是

Action Input: {"product": "iPhone 15 Pro"}           # 参数名错误
Action Input: {"product_name": "iPhone"}              # 参数值不完整
Action Input: {"product_name": "iPhone 15 Pro", "extra": "blah"}  # 多余参数
Action Input: 不是有效的JSON                          # 格式完全错误

参数填充的三层校验

失败

通过

失败

通过

失败

通过

模型生成

JSON语法校验

尝试修复/重试

参数名匹配

模糊匹配/报错

参数类型校验

类型转换/报错

执行调用

实战技巧:在自动定价场景中,product_name的准确性至关重要。建议增加参数后处理

def normalize_product_name(raw_name: str) -> str:
    # 统一大小写
    name = raw_name.strip()
    # 扩展常见缩写
    expansions = {
        "15 pro": "iPhone 15 Pro",
        "15pro": "iPhone 15 Pro",
        "苹果15pro": "iPhone 15 Pro"
    }
    return expansions.get(name.lower(), name)

2.5 第五步:结果返回——观察与反思

工具执行完成后,结果被包装为Observation,送回LLM。第一轮行动到此结束。

Observation的标准格式

Observation: [工具返回的原始结果,或经过精简处理的结果]

关键决策:Observation应该保持原始,还是做预处理?

策略 优点 缺点
原始返回 信息完整,LLM自主筛选 可能超出上下文长度,包含噪声
精简处理 节省token,聚焦关键信息 可能丢失LLM需要的有用细节

自动定价场景的建议:对搜索结果做结构化提取,保留核心数据字段。

# 原始搜索结果可能很长
raw_result = {
    "items": [
        {"platform": "京东", "price": 7999, "seller": "Apple旗舰店"},
        {"platform": "天猫", "price": 7899, "seller": "xx数码"},
        # ... 几十条数据
    ]
}

# 精简为Observation
observation = {
    "market_price_range": [7899, 8299],
    "average_price": 8049,
    "sample_count": 15
}

小结:第一轮行动的完整链路,是从"用户问题"到"首次观察"的转化过程。Prompt构造定基调,LLM推理做决策,工具选择+参数填充保执行,结果返回供反思。每一环都可能是故障点,也都值得精细化打磨。


三、实战追踪篇:代码级追踪与日志解读

理论讲完,咱们上代码。我会展示一个完整的、可运行的追踪示例,并教你读日志的"显微镜"技巧。

3.1 最小可运行示例

import json
import re
from dataclasses import dataclass
from typing import Callable, Dict, Any

@dataclass
class Tool:
    name: str
    description: str
    parameters: Dict[str, Any]
    func: Callable
    
    def execute(self, **kwargs):
        # 参数校验简化版
        return self.func(**kwargs)

class ReActTracer:
    """带完整链路追踪的ReAct执行器"""
    
    def __init__(self, llm_client, tools: list):
        self.llm = llm_client
        self.tools = {t.name: t for t in tools}
        self.history = []  # 追踪日志
        
    def _build_prompt(self, query: str) -> str:
        """第一步:Prompt构造"""
        tool_desc = "\n".join([
            f"{name}: {t.description}\n参数: {json.dumps(t.parameters, ensure_ascii=False)}"
            for name, t in self.tools.items()
        ])
        
        prompt = f"""你是专业定价助手,按ReAct格式思考。

可用工具:
{tool_desc}

格式要求:
Thought: 你的思考过程
Action: 工具名称
Action Input: 参数JSON(严格符合工具参数要求)

用户问题:{query}
Thought:"""
        return prompt
    
    def _parse_llm_output(self, text: str) -> Dict:
        """第二步:解析LLM输出"""
        # Thought提取
        thought_match = re.search(r'Thought:\s*(.*?)(?=Action:|$)', text, re.DOTALL)
        thought = thought_match.group(1).strip() if thought_match else ""
        
        # Action提取
        action_match = re.search(r'Action:\s*(\w+)', text)
        action_name = action_match.group(1) if action_match else None
        
        # Action Input提取
        input_match = re.search(r'Action Input:\s*(\{.*?\})', text, re.DOTALL)
        action_input = {}
        if input_match:
            try:
                action_input = json.loads(input_match.group(1))
            except json.JSONDecodeError as e:
                self._log("PARSE_ERROR", f"JSON解析失败: {e}, 原始文本: {input_match.group(1)}")
        
        return {
            "thought": thought,
            "action_name": action_name,
            "action_input": action_input,
            "raw_output": text
        }
    
    def _select_tool(self, name: str) -> Tool:
        """第三步:工具选择"""
        if name not in self.tools:
            available = list(self.tools.keys())
            raise ValueError(f"工具'{name}'不存在。可用: {available}")
        return self.tools[name]
    
    def _fill_and_validate(self, tool: Tool, raw_params: Dict) -> Dict:
        """第四步:参数填充与校验"""
        schema = tool.parameters
        filled = {}
        
        # 检查必需参数
        for param_name, param_info in schema.items():
            if param_name not in raw_params:
                if param_info.get("required", True):
                    raise ValueError(f"缺少必需参数: {param_name}")
                filled[param_name] = param_info.get("default")
            else:
                # 类型转换简化处理
                filled[param_name] = raw_params[param_name]
        
        # 检查多余参数
        extra = set(raw_params.keys()) - set(schema.keys())
        if extra:
            self._log("PARAM_WARNING", f"忽略多余参数: {extra}")
        
        return filled
    
    def _execute_tool(self, tool: Tool, params: Dict) -> Any:
        """执行并返回Observation"""
        self._log("TOOL_CALL", f"{tool.name}({params})")
        result = tool.execute(**params)
        self._log("TOOL_RESULT", result)
        return result
    
    def _log(self, stage: str, content: Any):
        """记录追踪日志"""
        entry = {
            "stage": stage,
            "content": content,
            "timestamp": len(self.history)  # 简化时间戳
        }
        self.history.append(entry)
        # 实时打印,方便调试
        print(f"\n[{stage}]")
        print(json.dumps(content, ensure_ascii=False, indent=2) if isinstance(content, (dict, list)) else content)
    
    def run_first_round(self, query: str) -> Dict:
        """执行完整的第一轮行动"""
        self._log("START", f"用户查询: {query}")
        
        # Step 1: Prompt构造
        prompt = self._build_prompt(query)
        self._log("PROMPT", prompt)
        
        # Step 2: LLM推理
        llm_output = self.llm.complete(prompt)  # 模拟LLM调用
        self._log("LLM_RAW", llm_output)
        
        parsed = self._parse_llm_output(llm_output)
        self._log("PARSED", parsed)
        
        # Step 3: 工具选择
        tool = self._select_tool(parsed["action_name"])
        self._log("TOOL_SELECTED", {"name": tool.name, "desc": tool.description[:50]})
        
        # Step 4: 参数填充
        validated_params = self._fill_and_validate(tool, parsed["action_input"])
        self._log("PARAMS_VALIDATED", validated_params)
        
        # Step 5: 执行与观察
        observation = self._execute_tool(tool, validated_params)
        
        return {
            "thought": parsed["thought"],
            "action": parsed["action_name"],
            "observation": observation,
            "history": self.history
        }


# ============ 模拟运行 ============

# 模拟LLM(实际项目中替换为真实API)
class MockLLM:
    def complete(self, prompt: str) -> str:
        # 模拟第一轮行动的典型输出
        return """我需要先查询iPhone 15 Pro的市场价格,了解当前市场行情后再给出定价建议。

Action: search_market_price
Action Input: {"product_name": "iPhone 15 Pro"}"""

# 定义工具
def mock_search_price(product_name: str):
    # 模拟价格查询
    prices = {
        "iPhone 15 Pro": {"min": 7899, "max": 8299, "avg": 8049, "count": 23}
    }
    return prices.get(product_name, {"error": "未找到该商品"})

tools = [
    Tool(
        name="search_market_price",
        description="查询商品市场均价,返回价格区间和统计数据",
        parameters={
            "product_name": {"type": "string", "required": True}
        },
        func=mock_search_price
    )
]

# 执行追踪
tracer = ReActTracer(MockLLM(), tools)
result = tracer.run_first_round("iPhone 15 Pro该定什么价?")

3.2 日志解读技巧

运行上面的代码,你会看到结构化的追踪输出。教你怎么"读":

[PROMPT]阶段:检查工具描述是否被正确嵌入,格式是否符合预期。如果LLM输出异常,首先回查这里。

[LLM_RAW]阶段:这是模型的"脑电波"原始信号。重点关注:

  • Thought是否体现了正确的任务分解
  • Action名称是否精确匹配注册名
  • Action Input是否为合法JSON

[PARSED]阶段:验证解析逻辑是否 robust。如果这里出现PARSE_ERROR,说明需要加强正则或增加重试机制。

[TOOL_SELECTED]阶段:确认工具匹配无误。如果经常选错工具,考虑优化工具描述或增加Few-shot示例。

[PARAMS_VALIDATED]阶段:检查参数转换是否符合预期。这是数据质量的关键防线。

[TOOL_CALL] → [TOOL_RESULT]阶段:确认执行链路通畅,结果格式统一。

3.3 常见翻车现场与诊断

现象 根因定位 修复策略
模型不输出Action,直接回答 Prompt缺少格式约束/Few-shot示例不当 增加强制格式说明,调整示例顺序
Action名称匹配失败 模型输出格式不标准(空格、大小写) 名称归一化处理,增加容错匹配
JSON解析失败 模型输出非标准JSON(单引号、注释等) 增加JSON修复逻辑,或使用更宽松的解析器
参数名不匹配 模型对参数理解有误 优化参数描述,增加枚举示例
工具执行报错 参数值非法或工具内部错误 增加参数预处理,完善工具错误处理

真实案例:某次运行中,模型输出了:

Action Input: {'product_name': 'iPhone 15 Pro'}

注意是单引号。标准json.loads直接报错。解决方案:

import ast

def robust_json_parse(text: str) -> Dict:
    """容忍单引号等常见JSON变体"""
    try:
        return json.loads(text)
    except json.JSONDecodeError:
        try:
            # 尝试用ast.literal_eval处理Python字面量
            return ast.literal_eval(text)
        except:
            raise ValueError(f"无法解析: {text[:100]}")

四、调试心法篇:Agent开发者的"显微镜"使用手册

工具链有了,但调试Agent和调试普通程序完全不同。你需要学会"读模型的想法"。

4.1 断点应该打在哪里

传统调试:断点打在变量赋值处,检查状态。

Agent调试:断点打在信息转换的边界处

关键断点位置

Prompt输出前
检查输入上下文

LLM输出后
检查原始生成

解析结果后
检查结构化数据

工具执行前
检查调用参数

Observation生成后
检查反馈质量

最常被忽略的断点:LLM原始输出。太多人直接看解析后的结果,错过了模型"犹豫"、"犯错"的宝贵信号。

4.2 如何阅读模型的"脑电波"

Thought部分不是装饰,是可观测的推理过程

健康的Thought特征

  • 明确提及任务目标
  • 说明选择某工具的理由
  • 体现对参数的思考

危险的Thought信号

  • 过于简略(“我需要查一下”)
  • 跑题(开始讨论无关话题)
  • 自我矛盾(先说查A,实际调B)

调试技巧:收集100条Thought样本,分类标注,找出模型的"惯性错误模式"。

4.3 从失败案例反推设计

当第一轮行动失败时,用逆向分析法

结果错误 ← 观察质量差 ← 工具执行问题 ← 参数错误 ← 解析失败 ← LLM输出异常 ← Prompt引导不足

逐层回溯,找到最早的故障点。不要头痛医头,要在根源处修复。

案例:模型总是把"iPhone 15 Pro"和"iPhone 15 Pro Max"混淆,导致查询错误。

表面修复:在参数处理时做精确匹配。
深层修复:在Prompt中增加区分示例,在工具描述中强调型号精确性。


五、进阶思考篇:从第一轮行动看Agent设计哲学

5.1 第一轮行动的设计模式

基于追踪经验,我总结出三种第一轮启动模式:

模式 适用场景 特点
侦察兵模式 信息不足,需要探索 先调用宽泛搜索,获取概览
狙击手模式 信息明确,目标清晰 直接调用精确工具,一击即中
组合拳模式 多维度信息需求 并行调用多个工具(需架构支持)

自动定价场景通常用侦察兵模式:先查市场均价,再视情况深入。

5.2 多工具场景的优先级策略

当工具数量增加时,第一轮选择的复杂度指数上升。

策略建议

  • 工具分类标签:给工具打"信息类"、“计算类”、"决策类"标签
  • 依赖图构建:明确工具间的数据依赖关系
  • 动态描述:根据上下文,动态调整工具描述的权重

查询类

计算类

比较类

用户问题

意图分类

优先信息工具

优先计算工具

组合调用策略

市场数据

利润分析

竞品对比

5.3 从ReAct到更复杂的Agent架构

ReAct是Agent的"手动挡",适合理解原理。但生产环境往往需要"自动挡":

  • Plan-and-Solve:先规划完整步骤,再执行
  • Tree of Thoughts:多路径探索,择优而行
  • Multi-Agent协作:多个专业Agent分工

但无论多复杂,第一轮行动的决策质量始终是瓶颈。本文追踪的链路,是所有复杂架构的共同基础。


写在最后

学Agent开发,最怕的就是"知其然不知其所以然"。看着Demo能跑,一改就崩;调参能work,换场景就废。这种无力感,我经历过,也知道怎么走出来。

今天的完整链路追踪,就是给你的"显微镜"。当你能看清每一步的数据流动、每一次模型的决策依据,你就从"调参师"变成了"架构师"。

ReAct的第一轮行动,看似简单,实则浓缩了Agent设计的核心挑战:如何让LLM在信息不完全的情况下,做出合理的首次决策。这个问题没有标准答案,但有系统的方法论——Prompt工程、工具设计、错误处理、反馈优化,环环相扣。

编程之路不易,但每一步成长都算数。Agent开发是AI时代的新战场,你现在花的时间,都是在搭建自己的技术护城河。

保持好奇,持续追踪,你也能成为代码高手。


关注私信备注:“资料代找获取”,全网计算机学习资料代找:例如:
《课程:2026 年多模态大模型实战训练营》
《课程:AI 大模型工程师系统课程 (22 章完整版 持续更新)》
《课程:AI 大模型系统实战课第四期 (2026 年开课 持续更新)》
《课程:2026 年 AGI 大模型系统课 23 期》
《课程:2026 年 AGI 大模型系统课 21 期》
《课程:AI 大模型实战课 8 期 (2026 年 2 月最新完结版)》
《课程:AI 大模型系统实战课三期》
《课程:AI 大模型系统课程 (2026 年 2 月开课 持续更新)》
《课程:AI 大模型全阶课程 (2025 年 12 月开课 2026 年 6 月结课)》
《课程:AI 大模型工程师全阶课程 (2025 年 10 月开课 2026 年 4 月结课)》
《课程:2026 年最新大模型 Agent 开发系统课 (持续更新)》
《课程:LLM 多模态视觉大模型系统课》
《课程:大模型 AI 应用开发企业级项目实战课 (2026 年 1 月开课)》
《课程:大模型智能体线上速成班 V2.0》
《课程:Java+AI 大模型智能应用开发全阶课》
《课程:Python+AI 大模型实战视频教程》
《书籍:软件工程 3.0: 大模型驱动的研发新范式.pdf》
《课程:人工智能大模型系统课 (2026 年 1 月底完结版)》
《课程:AI 大模型零基础到商业实战全栈课第五期》
《课程:Vue3.5+Electron + 大模型跨平台 AI 桌面聊天应用实战 (2025)》
《课程:AI 大模型实战训练营 从入门到实战轻松上手》
《课程:2026 年 AI 大模型 RAG 与 Agent 智能体项目实战开发课》
《课程:大模型训练营配套补充资料》

Logo

AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。

更多推荐