
最近这段时间AI Agent 团队的招聘需求明显多了起来。和传统后端团队、前端团队不同的是这类团队在招人时普遍偏好一种岗位画像远程、全栈、能独立交付端到端功能。这种偏好不是偶然而是由 AI Agent 开发本身的工程特点决定的。原因在于 AI Agent 开发与传统软件开发的协作模型完全不同。传统业务系统可以明确分成前端、后端、DBA、运维几条线各层之间有清晰的接口协议。而 AI Agent 的功能通常从第一行提示词开始横跨模型调用、工具编排、数据检索、交互界面、部署运维五个层面。任何一个环节断层Agent 就跑不通。这也解释了为什么企业 AI Agent 团队扩招时远程全栈工程师会成为首选因为这类工程师能同时理解模型行为和系统工程一个人就能把一个 Agent 功能从想法带到生产环境。这篇文章不讨论哪家公司更值得去而是从技术角度拆解一个 AI Agent 团队里的远程全栈工程师到底需要掌握哪些技术栈Agent 开发的核心链路是什么它和传统全栈开发有哪些关键差异如果你正准备加入或组建这样的团队可以从哪里入手我会用一个完整的日志智能分析 Agent 示例把整个技术链路讲清楚同时给出远程协作和工程落地的最佳实践。1. 为什么 AI Agent 团队需要远程全栈工程师1.1 Agent 开发不是调 API而是工程化整合很多对 AI Agent 感兴趣的同学最初的认知是调用大模型接口写一段 System Prompt然后把用户问题丢给模型返回答案。这个流程在小 demo 里完全够用。但真实企业环境里的 Agent 要面对的问题远不止这些需要读取内部系统的数据比如 Elasticsearch 中的日志、MySQL 中的订单、OSS 上的文件需要调用外部工具完成操作比如发送告警、创建工单、修改配置需要把多次工具调用的结果拼起来形成最终答案需要把整个过程通过 Web 界面展示给用户并且支持流式输出需要对模型返回的内容做校验、兜底和权限控制。这些内容叠加起来就是一个典型的全栈工程问题。它不再只是“提示词写得好不好”的问题而是“提示词、代码、数据、交互、运维如何协作”的问题。如果团队里只有模型算法背景的人缺少能写后端服务、能连数据库、能部署容器的全栈工程师Agent 项目很容易停留在演示阶段无法进入生产环境。所以企业 AI Agent 团队在扩招时会优先寻找具备完整工程能力的全栈工程师。1.2 全栈工程师的独立闭环能力在一个 Agent 团队中最高效的人往往是能独立闭环的工程师。以日志分析场景为例需求从“让用户用自然语言查询日志”到上线涉及的链路包括前端聊天界面、后端 Agent 编排服务、LLM 调用、工具注册与执行、Elasticsearch 数据查询、Docker 部署、日志收集与监控。这些工作在传统团队中会拆给三到四个人而在远程协作的 Agent 团队中一个全栈工程师可以承担至少两到三层。这不是说一个人要完成所有事情而是说一个人能把一个功能从开发环境跑到生产环境。大模型应用迭代极快今天调整的 Prompt 可能明天就要上线验证。如果每次改动都要跨多个角色协调一个星期可能只迭代一个版本。全栈工程师在这种快速迭代场景下的价值极高因为他们能缩短反馈回路降低协调成本。1.3 远程协作与 Agent 开发的天然匹配远程办公在 AI Agent 团队中尤其常见这背后有实际的技术原因。Agent 开发的核心工作是“定义工具、写提示词、编排流程、验证效果”这些工作天然适合异步沟通任务边界清晰依赖关系可以用文档和架构图表达代码评审可以异步完成Prompt 的调整也不强依赖实时沟通。需要强调的是远程不等于散漫。成熟的远程 Agent 团队通常有非常强的文档文化、明确的任务拆解粒度以及可复现的开发环境。这也是本文后半部分要重点展开的内容远程全栈工程师不仅要写业务代码还要把环境配置、依赖管理、接口约定这些“隐性知识”显性化否则团队协作很快就会陷入混乱。2. AI Agent 开发的核心技术栈与概念地图2.1 AI Agent 与传统应用的核心区别要理解 AI Agent 团队为什么需要全栈工程师先要理解 Agent 应用本身。一个 AI Agent 可以拆成几个核心部件模型LLM、指令Prompt、工具Tool/Skill、记忆Memory、编排Orchestration。用通俗的话讲模型是大脑Prompt 是任务说明工具是手脚记忆是笔记编排是执行流程。传统后端开发中“业务逻辑”是代码写死的Agent 开发中“业务逻辑”一部分在代码里一部分在 Prompt 里。这个变化带来了新的调试和测试复杂度。传统接口出问题通过日志和断点就能定位Agent 出问题可能是代码写错了可能是 Prompt 歧义可能是模型输出格式不稳定也可能是工具调用返回的数据不符合预期。全栈工程师需要同时具备软件工程能力和对模型行为的理解才能在复杂链路中快速定位问题。2.2 核心术语必须掌握如果你是第一次接触 Agent 开发下面这些术语几乎每天都会遇到术语含义在项目中的典型用途LLM大语言模型理解自然语言、生成回答、做意图判断Prompt提示词定义 Agent 的角色、任务、输出格式Token模型计费与上下文单位影响成本和控制输入长度Function Calling函数调用能力让模型输出结构化参数触发工具执行Tool / Skill工具或技能Agent 可调用的外部能力如 ES 查询、API 请求Memory记忆保存历史对话或长期知识支持多轮交互RAG检索增强生成先从文档库检索相关内容再交给模型生成答案Agent 框架编排工具管理 Prompt、工具、模型调用的执行流程在这些术语中Tool 和 Skill 的概念最容易被误解。Tool 通常指具体的可执行能力比如“查询 Elasticsearch”“发送 HTTP 请求”Skill 更偏向组合能力比如“日志分析技能”可能由索引发现、DSL 生成、结果总结三个 Tool 组合而成。在实际企业项目中团队往往会对 Tool 做统一注册和权限管理而不是让每个 Agent 随意调用。2.3 常用 Agent 框架选型思路目前市面上常见的 Agent 框架有 LangChain、LlamaIndex、AutoGen、CrewAI以及 Hugging Face 推出的 smolagents 等。选型时不要只看热度要看团队场景你已经有一套成熟的接口和数据服务只需要做简单的 LLM 调用编排可以考虑轻量框架或自研项目以文档问答和私有知识库为主LlamaIndex 和 RAG 方案更顺手团队需要多个 Agent 协同完成复杂任务CrewAI、AutoGen 这类多智能体框架更合适对框架掌控力要求高、希望深入理解每一步调用链路的团队可以考虑基于 Function Calling 自研一套轻量编排。框架本身不是银弹。很多团队在项目早期直接上 LangChain后来发现抽象层过重排查问题时要同时理解框架源码和业务逻辑。更稳妥的判断是先跑通最小链路再在有必要时引入框架。全栈工程师的优势在于即使绕过框架自己写几百行代码也能完成编排这比强行套框架更可控。2.4 全栈视角下的技术分层一个 AI Agent 项目从全栈视角看大概可以分为五层层次主要技术全栈工程师的工作内容交互层React / Vue / HTML、SSE、WebSocket聊天界面、流式输出、状态管理服务层Python FastAPI / Java Spring Boot / Node.jsAgent 编排接口、鉴权、限流模型层OpenAI 兼容接口、本地模型、Prompt 管理模型调用、Prompt 版本管理、结果校验工具层Elasticsearch、MySQL、Redis、外部 API工具注册、参数校验、异常兜底运维层Docker、CI/CD、Kubernetes、日志监控环境一致性、部署、可观测性这五层并不是严格分属五个角色。在 AI Agent 团队中全栈工程师通常要横跨交互层、服务层、工具层并在运维层具备基本能力。这篇文章的示例项目就是按照这个分层思路设计的。3. 日志智能分析 Agent场景与架构设计3.1 场景背景为了把前面讲的概念落到实操我设计一个足够真实的企业场景公司有大量应用日志存放在 Elasticsearch 中目前开发排查问题时需要手动写 Kibana 查询语句非技术人员根本不会用。现在要做一个日志智能分析 Agent让用户用自然语言提问Agent 自动把问题翻译成 ES 查询 DSL执行查询后把结果总结成可读的分析结论。这个场景非常典型它同时涉及 AI Agent 的意图理解、工具调用、数据检索、结果生成四大核心能力。而且它并不复杂适合作为入门到进阶的完整示例。3.2 技术选型后端使用 Python FastAPI因为 FastAPI 轻量、适合快速开发 Agent 编排接口。数据查询直接通过 Elasticsearch REST API 完成不引入过重的 ES 客户端库这样能让你更清楚地看到“工具调用”的本质Agent 本质上就是在组织和调用 HTTP API。前端使用一个 HTML 页面通过 JavaScript 调用后端接口。模型层使用 OpenAI 兼容接口这样无论你是使用云模型还是本地部署模型只要提供兼容接口代码逻辑都可以保持统一。为了演示完整流程这个项目会在本地启动一个单节点 Elasticsearch并写入一些模拟日志数据。如果你在真实项目中可以直接把 ES 地址和模型 API 地址替换成内部服务。3.3 项目结构完整项目结构如下log-agent/ ├── backend/ │ ├── Dockerfile │ ├── requirements.txt │ ├── app.py # FastAPI 接口层 │ ├── agent.py # Agent 编排核心逻辑 │ └── es_client.py # Elasticsearch REST 客户端 ├── frontend/ │ └── index.html # 前端聊天页面 ├── docker-compose.yml # 一键启动编排 └── README.md这种结构的好处是前后端分离但又能单独运行后端不依赖任何 Agent 框架核心逻辑可以用肉眼读完整。如果你想深入理解 Agent 的工作原理这个结构会比引入一个大而全的框架更好懂。3.4 环境准备开始之前你需要准备以下环境Docker 和 Docker Compose用于启动 Elasticsearch、后端和前端服务Python 3.10 或更高版本如果不想使用 Docker 运行后端也可以直接用本地 Python 环境一个可用的 LLM API需要提供接口地址、API Key 和模型名称支持 OpenAI Chat Completions 格式本地端口 9200、8000、8080 没有被占用。其中 LLM API 是核心依赖。如果你没有云模型 API可以考虑本地部署一个支持 OpenAI 兼容接口的开源模型或者使用团队内部已接入的模型网关。示例代码默认模型名是gpt-4o-mini实际使用时要改成你自己的模型名称。4. 完整示例与代码实现4.1 ES 查询层实现这个模块负责封装 Elasticsearch REST API 调用。设计上不引入 elasticsearch-py 客户端而是直接用 requests 请求_search接口这样你能直观看到 Agent 的工具层是怎么工作的。# backend/es_client.py import requests class ESClient: 通过 REST API 访问 Elasticsearch避免引入过重的客户端依赖。 def __init__(self, host: str http://localhost:9200, username: str , password: str ): self.host host.rstrip(/) self.auth (username, password) if username else None def search(self, index: str, query_dsl: dict, size: int 20) - dict: 执行一次 ES 查询返回原始响应 JSON。 url f{self.host}/{index}/_search resp requests.post( url, json{**query_dsl, size: size}, authself.auth, timeout30, ) resp.raise_for_status() return resp.json() def list_indices(self) - list: 获取当前 ES 中可用的非系统索引列表。 url f{self.host}/_cat/indices?formatjson resp requests.get(url, authself.auth, timeout15) resp.raise_for_status() return [item[index] for item in resp.json() if not item[index].startswith(.)]这个类看起来很简单但它承担了 Agent 工具层的基础功能。真实项目中工具层往往还要增加超时重试、熔断、权限校验、审计日志。全栈工程师在开发工具层时要特别关注“工具返回的数据是否符合模型预期”因为模型对脏数据的容忍度远低于人。4.2 Agent 编排层实现Agent 编排层是整个示例的核心。它设计了两次模型调用第一次让模型判断是否需要查询 ES并生成查询参数第二次把 ES 返回的日志样本交给模型让模型生成自然语言分析结论。# backend/agent.py import json import requests class LogAgent: 日志分析 Agent意图识别 - ES 查询 - 结果总结。 def __init__(self, es_client, llm_api_url: str, llm_api_key: str, model: str gpt-4o-mini): self.es es_client self.llm_api_url llm_api_url self.llm_api_key llm_api_key self.model model def _call_llm(self, messages, temperature0.2): headers { Authorization: fBearer {self.llm_api_key}, Content-Type: application/json, } payload { model: self.model, messages: messages, temperature: temperature, response_format: {type: json_object}, } resp requests.post(self.llm_api_url, headersheaders, jsonpayload, timeout90) resp.raise_for_status() return resp.json()[choices][0][message][content] def _decide(self, question: str, indices: list) - dict: 第一次模型调用决定是否查询 ES并生成查询 DSL。 index_list , .join(indices) if indices else 暂无可用索引 system_prompt f 你是一个日志分析助手。用户会提出关于应用日志的问题。 当前 Elasticsearch 中可用的索引有{index_list}。 如果问题需要查询 Elasticsearch 数据请返回 JSON {{need_search: true, index: 从可用索引中选择, query_dsl: {{query: {{bool: {{must: [...]}}}}}}, reason: 简短说明}} 如果问题不需要查询数据请直接返回 JSON {{need_search: false, answer: 你的回答}} 注意query_dsl 必须是合法的 Elasticsearch 查询 DSLlevel 字段一般用 term 精确匹配message 字段用 match 或 match_phrase。只返回 JSON。 content self._call_llm([ {role: system, content: system_prompt}, {role: user, content: question}, ]) return json.loads(content) def _summarize(self, question: str, es_result: dict) - str: 第二次模型调用基于 ES 结果生成自然语言分析。 hits es_result.get(hits, {}).get(hits, []) samples [] for hit in hits[:10]: source hit.get(_source, {}) samples.append({ timestamp: source.get(timestamp), level: source.get(level), service: source.get(service), message: source.get(message), }) if not samples: return 没有查询到符合条件的日志。可以尝试调整时间范围或检查索引名称。 context json.dumps(samples, ensure_asciiFalse, indent2) system_prompt 你是一个日志分析助手。用户提出了关于日志的问题下面是 ES 查询得到的日志样本。 请结合样本回答用户问题。要求 1. 指出关键异常、错误原因或趋势。 2. 给出具体的日志时间点和服务名作为证据。 3. 用中文回答条理清晰不要编造样本之外的数据。 content self._call_llm([ {role: system, content: system_prompt}, {role: user, content: f问题{question}\n\n日志样本\n{context}}, ], temperature0.1) return content def analyze(self, question: str) - str: 完整执行一次日志分析。 indices self.es.list_indices() decision self._decide(question, indices) if not decision.get(need_search, False): return decision.get(answer, 我没有理解你的问题请换个说法。) index decision.get(index, ) query_dsl decision.get(query_dsl, {query: {match_all: {}}}) es_result self.es.search(index, query_dsl, size20) return self._summarize(question, es_result)这段代码体现了 Agent 编排的核心思想模型负责判断和生成参数代码负责执行和校验。你可能会问为什么不让模型直接写一段查询代码因为让模型生成可执行代码的安全风险太高而让模型生成结构化的 JSON 查询参数再通过代码执行能更严格地校验参数合法性。这是实际项目中非常关键的设计选择。4.3 FastAPI 接口层实现接口层把 Agent 能力暴露成 HTTP API方便前端或其他系统调用。# backend/app.py import os from fastapi import FastAPI from fastapi.middleware.cors import CORSMiddleware from pydantic import BaseModel from agent import LogAgent from es_client import ESClient app FastAPI() app.add_middleware( CORSMiddleware, allow_origins[*], allow_methods[*], allow_headers[*], ) class ChatRequest(BaseModel): message: str es_client ESClient( hostos.getenv(ES_HOST, http://localhost:9200), usernameos.getenv(ES_USER, ), passwordos.getenv(ES_PASSWORD, ), ) agent LogAgent( es_clientes_client, llm_api_urlos.getenv(LLM_API_URL, https://api.openai.com/v1/chat/completions), llm_api_keyos.getenv(LLM_API_KEY, ), modelos.getenv(LLM_MODEL, gpt-4o-mini), ) app.get(/health) def health(): return {status: ok} app.post(/api/chat) def chat(req: ChatRequest): if not req.message.strip(): return {answer: 请输入问题} answer agent.analyze(req.message) return {answer: answer}接口层需要注意几点一是超时控制Agent 调用 LLM 可能耗时较长需要设置合理的请求超时时间二是错误处理如果 LLM 返回非 JSON 内容导致json.loads失败接口会直接 500实际项目中需要捕获异常并返回友好提示三是认证示例中为了演示方便没有做鉴权生产环境一定要加。4.4 依赖文件与 Dockerfile后端依赖文件如下# backend/requirements.txt fastapi0.110 uvicorn[standard]0.30 requests2.31 pydantic2.6后端 Dockerfile# backend/Dockerfile FROM python:3.11-slim WORKDIR /app COPY requirements.txt . RUN pip install --no-cache-dir -r requirements.txt COPY . . EXPOSE 8000 CMD [uvicorn, app:app, --host, 0.0.0.0, --port, 8000]使用相同的基础镜像和依赖锁定文件可以保证所有远程工程师在本地跑起来的后端行为一致。这也是远程团队协作的第一原则环境必须可复现。4.5 前端页面实现前端使用一个单页 HTML通过 fetch 调用后端接口。Agent 类应用的前端交互通常比传统页面更简单核心是“用户输入问题 - 展示回复”但要注意异步状态的处理。!-- frontend/index.html -- !DOCTYPE html html langzh-CN head meta charsetUTF-8 title日志智能分析 Agent/title style body { font-family: -apple-system, BlinkMacSystemFont, Segoe UI, sans-serif; max-width: 800px; margin: 40px auto; padding: 0 16px; background: #f5f6f8; } h2 { text-align: center; } #messages { background: #fff; border-radius: 12px; padding: 16px; min-height: 400px; max-height: 600px; overflow-y: auto; margin-bottom: 16px; box-shadow: 0 2px 8px rgba(0, 0, 0, 0.06); } .msg { margin-bottom: 12px; line-height: 1.6; } .msg.user { text-align: right; color: #1a73e8; } .msg.assistant { text-align: left; color: #333; } #chatForm { display: flex; gap: 8px; } #messageInput { flex: 1; padding: 12px; font-size: 14px; border: 1px solid #ccc; border-radius: 8px; } button { padding: 12px 20px; background: #1a73e8; color: #fff; border: none; border-radius: 8px; font-size: 14px; cursor: pointer; } button:hover { background: #1558b0; } /style /head body h2日志智能分析 Agent/h2 div idmessages div classmsg assistant你好我是日志分析 Agent。你可以问我最近一小时有哪些 ERROR 日志/div /div form idchatForm input typetext idmessageInput placeholder请输入日志查询问题 autocompleteoff / button typesubmit发送/button /form script const form document.getElementById(chatForm); const input document.getElementById(messageInput); const messages document.getElementById(messages); function addMessage(role, text) { const div document.createElement(div); div.className msg role; div.textContent text; messages.appendChild(div); messages.scrollTop messages.scrollHeight; } form.addEventListener(submit, async (e) { e.preventDefault(); const text input.value.trim(); if (!text) return; addMessage(user, text); input.value ; addMessage(assistant, 正在分析日志请稍候...); try { const resp await fetch(http://localhost:8000/api/chat, { method: POST, headers: { Content-Type: application/json }, body: JSON.stringify({ message: text }) }); if (!resp.ok) { throw new Error(接口返回状态码: resp.status); } const data await resp.json(); messages.lastElementChild.textContent data.answer || 没有返回结果; messages.scrollTop messages.scrollHeight; } catch (err) { messages.lastElementChild.textContent 请求失败请检查后端服务 err.message; } }); /script /body /html前端核心逻辑只有一个 fetch 请求对于 Agent 原型来说足够清晰。实际项目中如果要做流式输出需要把前后端协议从普通 JSON 改成 SSE 或 WebSocket让模型生成的文字一边生成一边显示显著提升用户体验。这是远程全栈工程师接手 Agent 项目后最常见的第一个优化点。4.6 Docker Compose 一键编排在项目根目录创建 docker-compose.yml把 ES、后端、前端三个服务编排起来# docker-compose.yml services: elasticsearch: image: docker.elastic.co/elasticsearch/elasticsearch:8.13.4 container_name: log-agent-es environment: - discovery.typesingle-node - xpack.security.enabledfalse - ES_JAVA_OPTS-Xms512m -Xmx512m ports: - 9200:9200 volumes: - es_data:/usr/share/elasticsearch/data backend: build: ./backend container_name: log-agent-backend environment: - ES_HOSThttp://elasticsearch:9200 - LLM_API_URL${LLM_API_URL} - LLM_API_KEY${LLM_API_KEY} - LLM_MODEL${LLM_MODEL:-gpt-4o-mini} ports: - 8000:8000 depends_on: - elasticsearch frontend: image: nginx:alpine container_name: log-agent-frontend volumes: - ./frontend:/usr/share/nginx/html:ro ports: - 8080:80 depends_on: - backend volumes: es_data:这里有一个需要特别说明的地方为了本地测试方便示例中关闭了 Elasticsearch 的安全认证xpack.security.enabledfalse。真实生产环境中ES 集群必须启用认证并且后端连接 ES 的账号应该遵循最小权限原则只授予所需索引的读取权限。远程团队里密钥和配置信息也绝对不能写进代码仓库。5. 运行结果与效果验证5.1 写入模拟日志数据在启动完整项目之前先启动 Elasticsearch 并写入模拟日志数据。执行 Docker Compose 启动 ESdocker compose up -d elasticsearch等待 ES 健康后写入一条示例日志索引。下面代码创建一个app-logs索引并写入几条不同级别的日志curl -X PUT http://localhost:9200/app-logs -H Content-Type: application/json -d { mappings: { properties: { timestamp: {type: date}, level: {type: keyword}, service: {type: keyword}, message: {type: text} } } } curl -X POST http://localhost:9200/app-logs/_doc -H Content-Type: application/json -d { timestamp: 2026-08-12T10:01:00Z, level: ERROR, service: order-service, message: Failed to deduct stock for order 1001: connection timeout } curl -X POST http://localhost:9200/app-logs/_doc -H Content-Type: application/json -d { timestamp: 2026-08-12T10:03:00Z, level: WARN, service: payment-service, message: Retrying third-party payment callback, attempt 3 } curl -X POST http://localhost:9200/app-logs/_doc -H Content-Type: application/json -d { timestamp: 2026-08-12T10:05:00Z, level: ERROR, service: inventory-service, message: Redis connection pool exhausted }这里的时间戳是示例数据实际情况可以根据你的系统时间调整。5.2 启动后端和前端在项目根目录创建.env文件填入你的模型 API 配置LLM_API_URLhttps://api.openai.com/v1/chat/completions LLM_API_KEYyour-api-key LLM_MODELgpt-4o-mini然后启动全部服务docker compose up --build看到三个容器都进入运行状态后访问http://localhost:8080打开前端页面输入“最近有哪些 ERROR 日志主要集中在哪些服务”5.3 预期输出与成功判断正常情况下Agent 会经历以下内部流程list_indices()拿到app-logs索引第一次 LLM 调用判断需要查询生成包含level: ERROR的 ES 查询 DSL执行 ES 查询返回日志样本第二次 LLM 调用把样本总结成中文分析。最终前端会展示类似这样的回答根据查询结果最近出现了 3 条 ERROR 日志主要集中在以下服务 1. order-service在 2026-08-12T10:01:00Z 出现库存扣减失败原因是连接超时 2. inventory-service在 2026-08-12T10:05:00Z 出现 Redis 连接池耗尽。 初步判断可能是支付回调触发订单状态变更后库存服务在高并发下出现连接资源紧张。建议检查 order-service 和 inventory-service 之间的网络链路以及 Redis 连接池配置。如果前端能够显示这条分析说明整个链路已经跑通。如果失败优先看后端日志后面会给出排查思路。6. 常见问题与排查思路远程开发环境下AI Agent 项目出问题的概率比传统项目更高因为链路更长、参与组件更多。下面列出这个日志 Agent 示例中最常见的几类问题。问题现象可能原因排查方式解决方案后端启动失败Docker 镜像构建失败或端口被占用查看docker compose logs backend检查端口占用删除旧容器后重新 buildES 连接失败ES 还在启动中或认证配置不对在容器内执行curl http://elasticsearch:9200等待 ES 健康检查通过确认 ES_HOST 配置正确LLM 接口返回 401API Key 错误或模型名称不支持查看后端日志中的 HTTP 状态码检查.env文件中的配置确认模型名称可用模型返回内容无法解析模型未输出 JSON 或响应格式不正确打印_call_llm的原始返回内容调整 System Prompt加入“只返回 JSON”的约束或改为用代码正则提取查询结果为空索引名错误或查询 DSL 条件不匹配用 Kibana 或 curl 手动执行 DSL确认索引名称检查 level、message 字段类型前端请求跨域失败后端未开 CORS 或前端地址不对打开浏览器控制台查看报错确认 FastAPI 已配置 CORSMiddleware接口地址为http://localhost:8000没有命中日志但回答却说有模型幻觉生成了不存在的日志内容对比_summarize输入数据在 Prompt 中加入“不要编造样本之外的数据”必要时对生成结果做关键词校验这里最常被忽视的问题是模型幻觉。日志分析场景要求模型必须基于真实数据回答但模型在上下文不足时很容易“脑补”。工程上可以做两件事一是把日志样本完整传给模型二是要求模型在回答中给出具体时间点和服务名这样即使模型在编造用户也能从证据中看出问题。7. 远程全栈工程师的工程最佳实践7.1 环境一致性优先远程团队最先要解决的就是“我本地跑不起来”的问题。最佳实践是所有服务必须能通过 Docker Compose 一键启动所有依赖版本锁定所有配置通过环境变量注入。不要依赖任何一位工程师本地手动安装的软件。示例项目中的 docker-compose.yml 就体现了这个原则。7.2 提示词也是代码需要版本管理