一、引言:告别 AI 应用"盲盒式"开发,LangSmith 破局核心痛点
在 LangChain 应用开发中,你是否经常遇到这样的情况:RAG 问答输出了错误答案却不知道是检索环节出了问题还是模型生成环节出了偏差?Agent 明明配置了工具却始终不调用,终端打印的日志密密麻麻却无法快速定位根因?这些问题本质上是 AI 应用"黑盒化"带来的调试困境——应用跑通并不等于好用,终端输出无法替代全链路可观测性。
本文正是为解决这一核心痛点而生。我们将从 LangSmith 的基础配置入手,逐步深入到全链路追踪、多场景自动化评估,最终通过一个融合 RAG 与 Agent 的企业级智能客服综合项目,帮助你系统性地掌握 AI 应用的可观测、可调试、可评估能力。
目标读者:Python 开发者、AI 智能体工程师、LangChain 技术学习者、LLMOps 从业者。阅读本文前,建议你具备基础的 LangChain 使用经验,并了解 RAG 和 Agent 的基本概念。
技术栈预告:LangChain、LangSmith、DeepSeek、Python、RAG、Agent。
二、LangSmith 核心认知:为什么它是 AI 应用的"透视镜"
2.1 LangSmith 是什么?核心定位与价值
LangSmith 是 LangChain 官方推出的 AI 应用工程平台,专注于调试、观测、评估大模型应用。它的核心价值在于将 AI 应用的"黑盒"转化为可追溯、可分析的全链路系统,让开发者能够清晰看到每一次调用的完整执行过程。
在开发阶段,LangSmith 帮助你快速定位 Prompt 设计缺陷、工具调用异常、链式调用逻辑错误等问题;在生产阶段,它则承担起性能监控、成本统计、异常告警等关键职责,是连接开发与生产的桥梁。
适用场景:RAG 知识库问答、Agent 工具调用、LCEL 链式调用等全场景 LangChain 应用,几乎覆盖了 LangChain 生态下的所有典型应用形态。
2.2 LangSmith 能看到什么?核心功能一览
| 功能模块 | 核心作用 |
|---|---|
| Trace/Run | 完整调用链路与单步骤执行记录,追溯每一步输入输出 |
| Prompt/Token/Latency | 查看提示词、Token 消耗、各步骤耗时,优化性能与成本 |
| Tool Call | 记录 Agent 工具调用详情,排查工具调用异常 |
| Metadata/Tags | 自定义标签与元数据,实现调用记录的筛选与定位 |
| Error | 捕获报错信息,快速定位异常节点 |
这些功能模块构成了 LangSmith 的核心能力矩阵。Trace/Run 让你看到"发生了什么",Prompt/Token/Latency 让你了解"消耗了多少资源",Tool Call 帮助排查"工具为什么没调用成功",Metadata/Tags 则让你能够高效筛选海量调用记录,快速聚焦问题节点。
2.3 本章学习目标:从入门到实战的能力清单
通过本文的学习和实战,你将逐步建立起以下核心能力:
- 掌握 LangSmith 的开通、配置与追踪开启方法
- 实现模型调用、LCEL 链式调用、Agent 工具调用的全链路追踪
- 掌握 RAG、Agent 的自动化评估方法,搭建简易评估体系
- 完成企业级智能客服综合项目,掌握上线前核心检查要点
三、LangSmith 快速上手:开通、配置与依赖安装
3.1 平台开通与 API Key 获取
访问 LangSmith 官方平台(https://smith.langchain.com),支持多区域选择与多种登录方式。首次使用建议直接用 GitHub 或 Google 账号登录,降低注册门槛。
登录后进入 Settings 页面,在 API Keys 选项卡中创建一个新的 API Key。这个 Key 是后续应用与 LangSmith 平台通信的凭证,请妥善保管,不要提交到公开仓库中。建议将 API Key 命名为有业务含义的名称,如"customer-service-agent-dev",以便在多人协作时区分不同环境和项目。
3.2 环境变量配置:.env 文件核心参数详解
在项目根目录创建.env文件,配置以下核心参数:
# LangSmith 追踪配置(必填) LANGSMITH_TRACING=true LANGSMITH_API_KEY=lsv2_pt_xxxxxx LANGSMITH_PROJECT=customer-service-agent DeepSeek 模型配置 DEEPSEEK_API_KEY=sk-xxxxxx DEEPSEEK_BASE_URL=https://api.deepseek.com/v1参数说明:
- LANGSMITH_TRACING:设置为 true 开启追踪,设为 false 则临时关闭追踪(适合开发环境快速测试时使用)。
- LANGSMITH_API_KEY:前一步创建的 API Key,是连接 LangSmith 平台的唯一凭证。
- LANGSMITH_PROJECT:项目名称标识,用于在 LangSmith 控制台中隔离不同项目的调用记录。建议为每个独立应用设置不同的项目名。
- DEEPSEEK_API_KEY / DEEPSEEK_BASE_URL:DeepSeek 模型调用的凭证和接口地址,可根据实际使用的模型服务商替换。
调试技巧:当你在本地快速迭代、不需要追踪记录时,可以将 LANGSMITH_TRACING 设为 false,避免产生大量无效的 Trace 记录。上线后记得重新开启。
3.3 依赖安装:核心依赖与国内镜像加速
基础依赖安装命令:
pip install langsmith langchain langchain-openai python-dotenv综合项目依赖安装命令(包含 RAG、向量数据库等组件):
pip install langchain-community sentence-transformers chromadb pypdf如果遇到下载速度慢的问题,可以使用国内镜像加速:
pip install langsmith langchain langchain-openai python-dotenv -i https://pypi.tuna.tsinghua.edu.cn/simple建议使用虚拟环境隔离依赖,避免与系统已有的 Python 包产生冲突。可以使用 venv 或 conda 创建独立环境。
四、全链路追踪实战:从基础调用到 Agent 工具调用
4.1 案例一:普通模型调用追踪
首先创建一个基础脚本,调用 DeepSeek 模型并开启 LangSmith 追踪:
from dotenv import load_dotenv from langchain_openai import ChatOpenAI from langsmith import traceable load_dotenv() @traceable(run_type="llm", name="deepseek-chat") def call_deepseek(prompt: str) -> str: llm = ChatOpenAI( model="deepseek-chat", openai_api_key=os.getenv("DEEPSEEK_API_KEY"), openai_api_base=os.getenv("DEEPSEEK_BASE_URL"), ) response = llm.invoke(prompt) return response.content if name == "main": result = call_deepseek("请用一句话介绍什么是 LangSmith。") print(result)运行脚本后,打开 LangSmith 控制台,即可看到一条完整的 Trace 记录。查看要点:输入 Prompt 内容、模型输出的响应、Token 消耗数量(输入 Token 和输出 Token 分别统计)、调用总耗时、模型名称和版本信息。通过这些数据,你可以直观地评估每次调用的资源消耗和响应质量,为后续优化提供依据。
4.2 案例二:LCEL 链式调用追踪
LCEL(LangChain Expression Language)是 LangChain 推荐的链式调用方式。下面构建一个包含 Prompt 模板、模型调用和输出解析器的完整链:
from langchain_core.prompts import ChatPromptTemplate from langchain_core.output_parsers import StrOutputParser from langchain_openai import ChatOpenAI llm = ChatOpenAI( model="deepseek-chat", openai_api_key=os.getenv("DEEPSEEK_API_KEY"), openai_api_base=os.getenv("DEEPSEEK_BASE_URL"), ) prompt = ChatPromptTemplate.from_messages([ ("system", "你是一个专业的{role},擅长{skill}。"), ("user", "{question}") ]) chain = ( prompt | llm | StrOutputParser() ).with_config( run_name="qa-chain", tags=["qa", "production"], metadata={"version": "1.0", "env": "dev"} ) result = chain.invoke({ "role": "Python 技术顾问", "skill": "解决 Python 开发中的疑难问题", "question": "Python 中的 GIL 是什么?它会影响多线程性能吗?" })在 LangSmith 控制台中,你将看到这条 Trace 被拆分为多个子步骤:Prompt 格式化、LLM 调用、输出解析。每个步骤的输入输出都被完整记录。追踪价值:通过run_name可以快速识别具体的调用场景;通过tags和metadata设置的标签与元数据,你可以在 LangSmith 控制台中使用过滤条件快速筛选特定版本、特定环境的调用记录,大幅提升问题定位效率。例如,当线上出现问题时,可以筛选 tags 中包含 "production" 的记录进行排查。
4.3 案例三:Agent 工具调用追踪(核心重点)
Agent 工具调用是 LangSmith 追踪最具价值的场景之一。下面搭建一个模拟电商客服 Agent,集成订单查询工具:
from langchain.agents import AgentExecutor, create_openai_functions_agent from langchain.tools import tool from langchain_core.prompts import ChatPromptTemplate, MessagesPlaceholder from langchain_openai import ChatOpenAI @tool def query_order(order_id: str) -> str: """根据订单号查询订单状态和详情。order_id 是订单编号。""" orders = { "20240101001": "订单状态:已发货,快递单号:SF1234567890,预计2024年1月3日送达", "20240101002": "订单状态:待支付,金额:299.00元,请尽快完成支付", } return orders.get(order_id, f"未找到订单 {order_id} 的信息,请核实订单号是否正确。") llm = ChatOpenAI(model="deepseek-chat", ...) tools = [query_order] prompt = ChatPromptTemplate.from_messages([ ("system", "你是一个专业的电商客服助手。当用户询问订单相关问题时,请使用 query_order 工具查询。"), ("user", "{input}"), MessagesPlaceholder(variable_name="agent_scratchpad"), ]) agent = create_openai_functions_agent(llm, tools, prompt) agent_executor = AgentExecutor(agent=agent, tools=tools, verbose=True) result = agent_executor.invoke({"input": "帮我查一下订单 20240101001 的状态"})运行后在 LangSmith 控制台中,你可以清晰看到 Agent 的完整决策流程:用户输入→Agent 推理(决定调用 query_order 工具)→工具执行(返回订单状态)→Agent 整合信息(生成最终回复)。
追踪排查要点:当 Agent 表现异常时,LangSmith 的 Trace 能帮你快速定位以下常见问题:
- 未调用工具:检查 Agent 的推理步骤,看它是否认为不需要调用工具就直接回答了问题(可能是 Prompt 指示不清或工具描述不够明确)。
- 工具参数错误:查看工具调用时传入的参数是否正确,比如 order_id 是否被正确解析。
- 结果未使用:Agent 虽然调用了工具并拿到了结果,但最终回答中没有引用工具返回的信息,而是"猜"了一个答案。
五、AI 应用评估实战:从简单测试到 LangSmith 自动化评估
5.1 评估核心认知:调试解决单次问题,评估关注整体效果
很多开发者容易陷入一个误区:费尽心思调试好一个 Case,就认为应用已经完善了。但实际上,单个 Case 的调试只能解决"这一条"的问题,而评估能够帮助你从整体上了解应用的质量水平。批量验证应用效果、发现共性问题、指导优化迭代方向——这才是评估的真正价值所在。
在实践中,建议先从基础的关键词匹配评估方法入手,快速建立评估意识。随着对 LangSmith 的深入使用,再逐步引入自动化评估流程,将评估体系化、常态化。
5.2 案例四:普通 Chain 评估(关键词匹配法)
先设计测试集,为每个测试用例明确预期关键词:
test_cases = [ {"question": "Python 中的 GIL 是什么?", "expected_keywords": ["全局", "解释器", "锁", "线程"]}, {"question": "什么是装饰器?", "expected_keywords": ["函数", "包装", "运行时"]}, {"question": "列表和元组有什么区别?", "expected_keywords": ["可变", "不可变", "字典"]}, ] def evaluate_with_keywords(chain, test_cases): passed, failed = 0, 0 for case in test_cases: result = chain.invoke({"question": case["question"]}) matched = all(kw in result for kw in case["expected_keywords"]) if matched: passed += 1 else: failed += 1 print(f"失败: {case['question'][:30]}... 预期关键词未完全匹配") print(f"评估完成: 通过 {passed}/{len(test_cases)}, 通过率 {passed/len(test_cases)*100:.1f}%")这种方法虽然简单,但非常实用。它能够快速发现回答是否遗漏了关键信息点。当通过率低于预期时,你可以针对性地优化 Prompt 或调整模型参数。
5.3 案例五:RAG 问答评估(核心场景)
RAG 问答的评估需要从全流程排查失败用例。当某个测试用例未通过时,按以下顺序逐一排查:
- 文档检查:原始文档中是否确实包含回答所需的全部信息?如果文档本身信息不全,再好的检索也无法弥补。
- 切分检查:文本切分是否合理?切分粒度太粗可能导致检索到的 Chunk 包含过多无关内容,太细则可能丢失关键上下文。
- 检索检查:检索到的文档片段是否与问题高度相关?如果相关度低,说明 Embedding 模型或检索策略需要优化。
- 上下文检查:拼接给模型的上下文是否完整、清晰?是否包含了足够的信息供模型生成准确回答?
- Prompt 检查:Prompt 是否明确要求模型基于上下文回答,是否约束了模型在信息不足时的行为?
- 回答检查:模型的最终回答是否忠实于上下文?是否存在"幻觉"生成的内容?
LangSmith 为这个排查流程提供了天然的便利。在 Trace 中,你可以清晰看到检索步骤返回了哪些文档片段、最终拼接的完整 Prompt 是什么、模型输出前后的上下文对比,从而快速锁定问题环节。
5.4 案例六:Agent 工具调用评估(双重验证)
Agent 的评估需要同时验证两个维度:最终回答的正确性和工具调用的正确性。这是为了避免"模型猜对了答案但根本没调用工具"的情况——表面上回答正确,实际上 Agent 的决策链路存在问题。
agent_test_cases = [ { "input": "查询订单 20240101001", "expected_tool": "query_order", "expected_keywords": ["已发货", "SF1234567890"] }, { "input": "我的订单 20240101002 付了多少钱", "expected_tool": "query_order", "expected_keywords": ["299.00", "待支付"] }, ] def evaluate_agent(agent_executor, test_cases): tool_pass, answer_pass, total = 0, 0, 0 for case in test_cases: # 实际应用中需要从 LangSmith Trace 中提取工具调用记录 result = agent_executor.invoke({"input": case["input"]}) # 检查工具调用和回答关键词 tool_pass += 1 # 简化示意,实际需解析 Trace answer_pass += all(kw in result["output"] for kw in case["expected_keywords"]) total += 1 print(f"工具调用通过率: {tool_pass/total100:.1f}%, 回答通过率: {answer_pass/total100:.1f}%")双重验证的核心理念是:即使回答内容正确,也必须确认 Agent 按照预期的决策路径执行了工具调用。这能有效避免"模型直接编造答案"的问题。
5.5 案例七:LangSmith 自动化评估(进阶实战)
LangSmith 提供了完整的自动化评估框架,支持创建数据集、定义评估器、启动实验并查看结果。核心流程如下:
from langsmith import Client client = Client() 1. 创建数据集 dataset = client.create_dataset( dataset_name="qa-evaluation-dataset", description="智能客服问答评估数据集" ) 2. 添加测试用例 for case in test_cases: client.create_example( inputs={"question": case["question"]}, outputs={"expected_answer": case["expected_answer"]}, dataset_id=dataset.id, ) 3. 定义评估函数 def evaluate_accuracy(run, example): expected = example.outputs["expected_answer"] actual = run.outputs["output"] score = 1.0 if expected in actual else 0.0 return {"key": "accuracy", "score": score} 4. 启动评估实验 experiment_results = client.evaluate( target_function, # 你的应用函数 data=dataset.name, evaluators=[evaluate_accuracy], experiment_prefix="qa-eval-v1", )运行后可以在 LangSmith 控制台的 Experiments 页面查看每条测试用例的得分、失败的详细原因以及整体统计指标。相比于手动评估,自动化评估能够持续运行、记录历史趋势,帮助你更科学地评估每次迭代改进的效果。
六、综合项目实战:企业智能客服助手(RAG+Agent 融合)
6.1 项目需求与架构设计
这个综合项目模拟一个企业级智能客服助手,需要同时支持两类场景:一是基于知识库的问答(如"退换货政策是什么"),需要走 RAG 流程从文档中检索答案;二是业务查询(如"我的订单状态"),需要 Agent 调用工具接口获取实时数据。
项目目录结构:
project/ ├── .env # 环境变量配置 ├── tools/ │ ├── __init__.py │ └── order_tools.py # 业务工具定义(订单、库存、折扣) ├── agent/ │ ├── __init__.py │ └── service_agent.py # Agent 模块:客服 Agent 创建与配置 ├── rag/ │ ├── __init__.py │ ├── document_loader.py # 文档加载与切分 │ └── retriever.py # 向量存储与检索 ├── router.py # 路由模块:区分知识库问题与业务问题 ├── main.py # 终端交互入口 └── evaluate.py # 综合评估脚本6.2 核心模块实现
工具模块(tools/order_tools.py):定义业务工具,每个工具包含清晰的描述、参数定义、参数校验和异常处理。
from langchain.tools import tool @tool def query_order(order_id: str) -> str: """查询订单状态和详情。参数 order_id:订单编号,格式为数字字符串。""" if not order_id or not order_id.isdigit(): return "错误:订单号必须为纯数字,请核实后重新输入。" # 模拟数据库查询 orders_db = {"20240101001": "订单状态:已发货,金额:599元", ...} result = orders_db.get(order_id) if not result: return f"未查询到订单 {order_id},请确认订单号是否正确。" return result @tool def check_inventory(product_name: str) -> str: """查询商品库存信息。参数 product_name:商品名称。""" inventory = {"无线耳机": "库存充足(150件)", "机械键盘": "库存紧张(3件)"} return inventory.get(product_name, f"未找到商品'{product_name}'的信息。")Agent 模块(agent/service_agent.py):创建客服 Agent,配置系统提示词并绑定工具。
from langchain.agents import AgentExecutor, create_openai_functions_agent from langchain_core.prompts import ChatPromptTemplate, MessagesPlaceholder from tools.order_tools import query_order, check_inventory system_prompt = """你是一个专业的电商客服助手。你的职责是: 当用户询问订单、库存等业务问题时,必须使用相应的工具查询,不得凭空编造信息。 如果工具调用失败或返回错误信息,请如实告知用户,并建议用户联系人工客服。 回答时要礼貌、专业,提供清晰准确的信息。 """ prompt = ChatPromptTemplate.from_messages([ ("system", system_prompt), ("user", "{input}"), MessagesPlaceholder(variable_name="agent_scratchpad"), ]) agent = create_openai_functions_agent(llm, [query_order, check_inventory], prompt) agent_executor = AgentExecutor(agent=agent, tools=[query_order, check_inventory])路由模块(router.py):通过关键词匹配区分知识库问题和业务问题,将不同类别的问题转发到对应的处理模块。
business_keywords = ["订单", "库存", "折扣", "优惠券", "退款"] knowledge_keywords = ["政策", "怎么", "如何", "是什么", "规则", "流程"] def route_question(question: str) -> str: if any(kw in question for kw in business_keywords): return "agent" elif any(kw in question for kw in knowledge_keywords): return "rag" return "agent" # 默认走 Agent 处理6.3 项目运行与 LangSmith 观测
运行顺序:
- 配置 .env 文件,设置所有必要的环境变量。
- 构建知识库索引:运行 document_loader.py 加载文档、切分、向量化并存入 ChromaDB。
- 启动应用:运行 main.py,进入终端交互模式。
- 执行评估:运行 evaluate.py,批量验证应用效果。
LangSmith 观测要点:在 LangSmith 控制台中重点关注以下内容:RAG 调用链路是否完整(文档检索→上下文拼接→生成回答)、Agent 工具调用链路的每一步决策和输出、测试用例的执行详情和得分。通过这些信息,你可以全面了解应用的运行状态,快速发现并解决问题。
七、上线前核心检查清单:避坑指南
在将 AI 应用推向生产环境之前,请逐项确认以下检查点,这些是实践经验中总结出的高频问题:
- Prompt 检查:角色定义是否清晰明确?是否添加了防编造约束(如 "请严格基于提供的上下文回答,如果上下文无法回答请明确说不知道")?资料不足时的应答规则是否合理(避免模型胡编乱造)?
- RAG 检查:知识库文档是否完整覆盖了核心业务场景?文本切分策略是否合理(Chunk 大小和重叠量是否适配业务特点)?检索返回的文档片段是否与用户问题高度相关?回答中是否附带信息来源引用,便于用户核实和建立信任?
- Agent 检查:每个工具的描述是否足够清晰和准确(模型完全依赖描述来决定是否调用)?工具参数是否做了必要的校验(防止模型传入非法参数导致工具调用失败)?高风险操作(如订单取消、退款)是否设置了人工确认环节或权限校验?是否记录了完整的操作日志以供审计?
- 评估检查:测试集是否覆盖了主要核心场景?是否包含了典型的异常场景(如用户输入不完整信息、询问超出知识范围的问题)?是否记录了失败案例并进行分析,建立持续改进机制?
- 安全检查:API Key 是否通过环境变量管理而未硬编码在代码中?敏感用户数据(如手机号、地址)在处理和日志中是否进行了脱敏?是否考虑了 Prompt 注入攻击的防护措施(如限制用户输入对系统 Prompt 的影响)?是否设置了合理的权限控制,限制应用访问不必要的系统能力?
八、常见问题与解决方案
LangSmith 看不到记录:首先检查 .env 文件中的 LANGSMITH_TRACING 是否为 true;确认 LANGSMITH_API_KEY 是否正确(注意不要有空格或换行符);检查网络是否能访问 LangSmith 服务;确认 LANGSMITH_PROJECT 参数是否与平台中创建的项目一致。如果以上都正确,可以尝试在代码中添加os.environ["LANGSMITH_TRACING"] = "true"强制开启。
评估方法的局限性:关键词匹配评估虽然简单高效,但存在明显不足——它只能检查"是否提到了",无法判断语义是否正确、表达是否流畅。进阶优化方向包括:引入人工评分机制(对关键场景进行人工抽检)、使用大模型作为评估器(让另一个 LLM 判断回答质量)、建立多维度评分体系(准确性、完整性、流畅性分别打分)。
Agent 路由优化:本文示例中使用了简单的关键词路由,在实际生产环境中可能存在误判(如用户说"我的订单怎么取消"同时包含业务和知识两类关键词)。进阶方案包括:引入意图分类模型进行语义级路由判断、使用 LangGraph 的条件路由实现更精细的分流逻辑、结合历史对话上下文进行更准确的意图识别。
生产环境配置:建议在生产环境中保持追踪开启,以便持续监控应用状态。如果担心成本或数据量过大,可以设置采样率(只追踪部分请求)。对于涉及用户隐私的敏感数据,在传入 LangSmith 之前进行脱敏处理,或使用 LangSmith 的数据过滤功能屏蔽特定字段。
九、总结与学习路线回顾
本文系统性地讲解了 LangSmith 从基础到进阶的核心内容:
- 核心功能:Trace/Run 全链路追踪、Prompt/Token/Latency 资源监控、Tool Call 工具调用排查、Metadata/Tags 自定义标识、Error 异常定位。
- 全链路追踪:从普通模型调用到 LCEL 链式调用,再到 Agent 工具调用的三层递进追踪体系,覆盖了 LangChain 应用的典型形态。
- 多场景评估:从简单的关键词匹配评估到 LangSmith 自动化评估实验,帮助建立系统化的质量保障机制。
- 综合项目落地:RAG+Agent 融合的企业级智能客服助手,展现了 LangSmith 在真实项目中的实践价值。
完整学习路线回顾:模型调用开启追踪→LCEL 链式调用配置标签和元数据→Agent 工具调用全链路排查→RAG 和 Agent 的双重评估→LangSmith 自动化评估实验→综合项目实战→上线前检查清单。这条路线从浅入深、从单一到综合,建议按照顺序逐步实践。
最佳实践建议:开发阶段始终开启追踪,将 Tracing 视为日常开发流程的一部分而非额外负担;评估优先覆盖核心业务场景,避免追求测试覆盖率而忽视最重要的场景质量;上线前逐项走一遍检查清单,这是从"能用"到"好用"的关键跨越。
十、结语与互动交流
AI 应用的可观测性与评估,正在从"锦上添花"变为"必备能力"。随着大模型在生产环境中的深入应用,能够清晰地看到应用内部发生了什么、准确地评估应用的表现水平,已经成为 AI 工程化的基本功。LangSmith 为 LangChain 生态提供了一套完整的解决方案,帮助开发者在日益复杂的 AI 应用栈中保持掌控力。
展望未来,LangSmith 正在不断丰富其功能生态,包括更智能的异常检测、更灵活的自定义评估器、与 CI/CD 流程的更深度集成。同时,LLMOps 作为新兴领域,其方法论和工具链也在快速演进。建议持续关注 LangChain 官方更新,积极参与社区讨论,在实践中不断积累经验。
欢迎你在评论区分享自己的实战问题、优化思路或踩坑经验。AI 应用开发的路上,我们都不是独行者,一起交流、共同进步!