OpenRig:将离散 AI Agent 编织为持久化协作系统的多智能体编排实践
掘金
当 AI 编程助手从单一的终端窗口演变为多 Agent 并行工作的复杂系统时,传统的“开一个新终端”式管理方式迅速显露出其局限性。OpenRig 的出现标志着 AI 辅助开发范式的转变:它不再试图替代
Score: 57.17Confidence: 54%
View offerLoading the catalog…
THE AI OPPORTUNITY INDEX
Find your next AI tool. Explore free access, trials, and credits — all in one place.
掘金
当 AI 编程助手从单一的终端窗口演变为多 Agent 并行工作的复杂系统时,传统的“开一个新终端”式管理方式迅速显露出其局限性。OpenRig 的出现标志着 AI 辅助开发范式的转变:它不再试图替代
Score: 57.17Confidence: 54%
View offer掘金
前言 之前写过一篇: Android 架构指南之 Data 层不要再暴露 start/stop 了:用 Flow 接管生命周期 那篇文章讨论的是一个比较常见的问题: 为什么一个 Data 层对象的生命
Score: 57.16Confidence: 54%
View offer掘金
一.DeepAgents是什么? 1.概念 LangChain 家族有三个产品:LangChain 、LangGraph 、还有 DeepAgents 。 LangChain 是给你一堆 AI 开发积
Score: 57.16Confidence: 54%
View offer掘金
项目地址:https://github.com/SFLAQiu/dsh-waker 功能 @机器人 即派活:群聊 @机器人(或单聊直接发),消息自动交给 DSH 执行,结果自动回IM 多角色 Wake
Score: 57.15Confidence: 54%
View offer掘金
AI服务线上响应异常故障排查文档 1. 故障概述 1.1 故障标题 AI服务线上响应异常故障 1.2 故障现象 线上AI推理接口偶发响应超时,部分请求返回504网关超时,业务侧用户提交对话请求长时间无
Score: 57.15Confidence: 54%
View offer掘金
上周四凌晨,我盯着监控面板上 内存泄漏曲线 的陡峭爬升,终于在一个看似无害的工具函数里揪出了凶手——一个潜伏了三年多的闭包引用。你可能觉得闭包的基础知识早就烂熟于心了,但这个案例会让你重新审视那些"理
Score: 57.14Confidence: 54%
View offer掘金
四维对比(消息语义/吞吐/高可用/运维复杂度):微服务用RabbitMQ、数据管道用Kafka、轻量任务用Redis Streams。附完整决策树。
Score: 56.65Confidence: 54%
View offer爱范儿
让 Agent 从个人助手,进化为组织 OS #欢迎关注爱范儿官方微信公众号:爱范儿(微信号:ifanr),更多精彩内容第一时间为您奉上。
Score: 54.96Confidence: 54%
View offervelog
이전 글에서 나는 완성된 결과물뿐 아니라 만드는 과정도 함께 보여주고 싶다는 생각을 했다. 실제로 최근에는 내가 만든 앱의 온보딩 프로세스를 어떻게 개선할 수 있을지 고민하면서, 문제를 발견하고 아이디어를 정리해가는 과정을 하나의 글로 남겨보기도 했다. 예전 같았으면 이런 고민은 프로젝트 안에서만 지나갔을 가능성이 크다. 기능을 수정한 뒤 결과만 보여주고, 그 과정에서 왜 이런 생각을 했는지는 따로 남기지 않았을 것이다. Austin Kleon의 《Show Your Work!》에서 “Become a Documentarian of What You Do” 를 읽으면서 이제는 한 단계 더 나아가 내가 하는 일을 의식적으로 기록해봐야겠다는 생각이 들었다. 무엇인가 대단한 결과물이 생겼을 때만 기록하는 것이 아니라, 내가 무엇을 하고 있는지, 어떤 문제를 고민하고 있는지, 무엇을 발견했고 생각이 어떻게 바뀌었는지를 그때그때 남기는 것이다. Kleon은 이 부분에서 우주비행사 Chris Hadfield의 사례를 소개한다. Hadfield는 국제우주정거장에서 임무를 수행하면서 우주에서 바라본 지구처럼 특별한 모습만 보여준 것이 아니라, 잠을 자고 이를 닦고 운동하고 장비를 관리하는 일상적인 모습까지 사람들과 공유했다. Canadian Space Agency의 당시 기록을 보면 실제로 우주에서 이를 닦거나 잠을 자는 모습부터 장비를 정비하고 과학 실험을 수행하는 과정까지 다양한 콘텐츠가 공개되었다. 사람들은 우주비행이라는 결과보다 그동안 쉽게 볼 수 없었던 우주비행사의 실제 생활과 과정 에도 큰 관심을 보였다. 이 이야기를 보면서 내가 하는 일에도 비슷한 지점이 있을지 생각하게 됐다. 보이지 않는 일을 기록으로 바꾸기 개발을 하다 보면 하루 종일 많은 일을 했는데도 마지막에는 보여줄 것이 없는 것처럼 느껴질 때가 있다. 하지만 다시 생각해보면 그 과정에는 기록할 수 있는 것이 꽤 많다. 최근 온보딩 프로세스를 개선하려고 고민했던 것처럼, 기존 화면에서 어떤 문제를 발견했는지와 왜 그것이 문제라고 생각했는지를 남길 수 있다. 여러 해결 방법을 비교했다면 그 판단 과정도 기록할 수 있고, 실제로 구현하면서 예상과 달랐던 부분이나 개발 과정에서 새롭게 알게 된 내용도 하나의 기록이 된다. 중요한 것은 모든 것을 곧바로 완성된 블로그 글로 만들 필요가 없다는 점이다. 생각이 떠올랐을 때 짧게 메모할 수도 있고, UI가 바뀌는 모습을 스크린샷으로 남길 수도 있다. 구현 과정을 짧은 영상으로 촬영하거나, 글로 정리하기 어려운 생각은 음성으로 기록해둘 수도 있다. 이렇게 남겨둔 자료 중 나중에 공유할 가치가 있는 것을 골라 블로그나 Instagram, YouTube 같은 채널에 맞는 형태로 다시 만들면 된다. Kleon이 이야기하는 documentarian이라는 표현이 그래서 마음에 들었다. 기록하는 목적이 항상 좋은 콘텐츠를 만드는 것은 아니다. 우선 내가 무엇을 하고 있었는지를 사라지지 않게 남기는 것 이다. 실제로 개발 과정에서 했던 고민은 생각보다 빨리 잊힌다. 기능을 완성하고 몇 주만 지나도 왜 처음에 그런 구조를 선택했는지, 어떤 시행착오를 겪었는지 정확하게 기억하지 못할 때가 있다. 반대로 과정이 남아 있으면 나중에 글을 쓸 때 사용할 자료가 생길 뿐 아니라, 내가 무엇을 해왔고 어떻게 생각이 변했는지도 다시 확인할 수 있다. Kleon 역시 이후 자신의 글에서 과정을 기록하면 자신이 어디에서 왔고 현재 어디에 있으며 어디로 가고 있는지를 더 분명하게 볼 수 있다고 설명한다. 내가 하는 일에서 무엇이 흥미로울 수 있을까 Hadfield의 사례를 보면서 또 하나 생각하게 된 것은 내가 너무 쉽게 내 일상을 평범하다고 판단 하고 있었을 수도 있다는 점이다. 우주비행사가 이를 닦는 것은 Hadfield에게는 일상이다. 하지만 우주에서 살아본 적이 없는 사람에게는 전혀 평범하지 않다. 같은 행동이라도 누가 어떤 환경에서 하고 있는지에 따라 완전히 다른 이야기가 된다. 개발 역시 개발자에게는 너무 익숙해서 굳이 공유할 필요가 없다고 생각하는 과정이 다른 사람에게는 흥미로울 수 있다. 하나의 앱 아이디어가 실제 화면으로 바뀌는 과정, 디자인을 수정하는 이유, App Store에 앱을 올리는 과정, 예상하지 못했던 오류, AI를 사용해 문제를 해결하는 방법, 사용자의 피드백으로 기능이 바뀌는 모습은 나에게는 매일 반복되는 개발의 일부일 수 있지만 다른 개발자나 제품을 만드는 데 관심 있는 사람에게는 하나의 이야기가 될 수 있다. 그래서 앞으로는 단순히 “오늘 무엇을 했는가”만 기록하기보다 내가 하는 일에서 다른 사람이 궁금해할 만한 지점이 무엇인지 도 조금씩 찾아보고 싶다. 그렇다고 모든 순간을 콘텐츠로 만들기 위해 억지로 특별하게 포장하고 싶지는 않다. 먼저 꾸준히 기록해두고, 그 안에서 자연스럽게 반복되는 주제나 흥미로운 변화가 무엇인지 살펴보는 편이 더 나에게 맞을 것 같다. 내가 무엇에 계속 시간을 사용하고 있는지, 어떤 문제에서 자주 고민하는지, 어떤 방식으로 문제를 해결하는지를 기록하다 보면 내가 미처 의식하지 못했던 나만의 관점도 발견할 수 있을 것이다. 기록이 쌓이면 공유할 수 있는 것도 많아진다 지금까지는 콘텐츠를 만들려고 하면 매번 무엇을 써야 할지 처음부터 생각하는 경우가 많았다. 하지만 일하는 과정에서 꾸준히 자료를 남기기 시작하면 콘텐츠를 만드는 방식도 달라질 것 같다. 하루 동안 작성한 짧은 메모가 나중에는 블로그 글의 시작이 될 수 있고, 개발 중에 찍은 화면들이 하나의 업데이트 과정을 보여주는 Instagram 콘텐츠가 될 수도 있다. 여러 번 반복해서 고민했던 주제는 YouTube에서 조금 더 길게 이야기할 내용이 될 수 있다. 결과적으로 새로운 콘텐츠를 억지로 만들어내는 것이 아니라 이미 내가 하고 있던 일을 적절한 미디어로 바꾸는 것 에 가까워진다. 이것은 이전에 생각했던 Work → Learn → Document → Share 라는 흐름과도 자연스럽게 연결된다. 다만 이제 Document 를 글을 쓰기 직전에 하는 정리가 아니라, 일을 하는 동안 계속 이루어지는 습관으로 생각해보고 싶다. 그러기 위해서 먼저 내가 하는 일을 보이게 만들어야 한다. 머릿속에서 고민하고 사라지는 생각을 글로 남기고, 눈에 보이지 않는 개발 과정을 이미지나 영상으로 만들고, 하루 동안 배운 작은 내용을 기록한다. 그리고 그 기록 중 다른 사람에게도 의미가 있을 만한 것을 골라 세상에 내놓는다. 그러면서 내가 하는 일 중 어떤 부분이 사람들에게 흥미로운지, 어떤 미디어가 나에게 가장 자연스러운지, 어떻게 공유해야 다른 사람과 좋은 대화를 만들 수 있는지도 계속 찾아가려고 한다. 결국 내가 하고 싶은 것은 모든 순간을 콘텐츠로 만드는 것이 아니라, 내가 하고 있는 일이 흔적 없이 사라지지 않도록 만드는 것 이다. 그 기록들이 쌓이면 나 역시 내가 어디로 가고 있는지 더 분명하게 볼 수 있고, 다른 사람들도 내가 무엇을 만들고 어떤 생각을 하며 성장하고 있는지를 조금 더 가까이서 볼 수 있을 것 같다. References Kleon, Austin. Show Your Work!: 10 Ways to Share Your Creativity and Get Discovered . Workman Publishing Company, 2014. Referenced chapter: Chapter 2, “Think Process, Not Product” Referenced section: “Become a Documentarian of What You Do” ISBN-13: 978-0-7611-7897-2. Chris Hadfield Canadian Space Agency. “Mission Blog — Expedition 34/35.” 2012–2013. Hadfield used social media during his International Space Station mission to share both his work and everyday life in orbit, including photographs, scientific work, maintenance, exercise, sleeping, and other daily activities. 이 글은 Austin Kleon의 《Show Your Work!》 중 “Become a Documentarian of What You Do”를 읽고 얻은 생각을 최근 앱 개발과 온보딩 개선 과정을 기록하고 공유한 경험에 연결해 재구성한 글이다. 원문의 번역이나 재수록을 목적으로 하지 않으며, 내가 하는 일을 어떻게 지속적으로 기록하고 공유 가능한 형태로 남길 것인지에 대한 개인적인 해석과 적용을 중심으로 작성했다.
velog
풀스택
Score: 54.4Confidence: 49%
View offervelog
개요 Linux용 tar.gz 압축 파일을 다운로드하고 ./zap.sh 로 바로 실행하는 비설치형으로 구축하겠습니다. 현재 최신 정식 버전은 2.17.0 이며, GitHub에서 다운로드하여 사용합니다. Java 설치 설치 전 확인 내역 OWASP ZAP은 Java가 필수 설치 되어야 하며, 압축 파일에는 포함되어 있지 않아 별도로 설치해야 합니다. ZAP 2.16.0 부터는 최소 Java 17 이상이 필요합니다. 지원하는 Java 확인 명령어 # 현재 apt 저장소에서 jdk 몇을 제공하는지 전부 확인 apt-cache search openjdk | grep -E 'openjdk-[0-9]+' # jdk-17을 몇 버전을 지원하는지 확인 apt-cache policy openjdk-17-jdk === openjdk-17-jdk: Installed: (none) Candidate: 17.0.20.1+1-1~26.04 Version table: 17.0.20.1+1-1~26.04 500 500 http://archive.ubuntu.com/ubuntu resolute-updates/universe amd64 Packages 500 http://security.ubuntu.com/ubuntu resolute-security/universe amd64 Packages 17.0.18+8-1 500 500 http://archive.ubuntu.com/ubuntu resolute/universe amd64 Packages === apt list openjdk-17-jdk === openjdk-17-jdk/resolute-updates,resolute-security 17.0.20.1+1-1~26.04 amd64 Notice: There is 1 additional version. Please use the '-a' switch to see it === Java 설치 정확하게 Java 17을 설치하려면 아래와 같이 입력합니다. apt install -y openjdk-17-jre # jdk가 필요 시 (zap 실행을 위해서는 jre로만 설치해도 됨) apt install -y openjdk-17-jdk 하지만 17 이상의 버전이라면 최신 버전을 설치해도 무방하므로 최신 버전이 몇인지 확인하고 설치합니다. apt-cache depends default-jre === default-jre Depends: default-jre-headless Depends: openjdk-25-jre === # GUI 지원 서버 apt install -y default-jre xauth # GUI 없는 서버에서 데몬으로만 쓸 때 # apt install -y default-jre-headless # 설치 확인 java -version OWASP ZAP 설치 다운로드 무결성 확인 cd /tmp wget https://github.com/zaproxy/zaproxy/releases/download/v2.17.0/ZAP_2.17.0_Linux.tar.gz # 체크섬 확인 echo "efe799aaa3627db683b43f00c9c210aea0b75c00cc8f0a0f0434d12bb3ddde5a ZAP_2.17.0_Linux.tar.gz" | sha256sum -c 2.17.0 공식 릴리스 페이지에 공개된 Linux tar.gz 의 SHA-256 해시 값과 비교하는 절차를 거쳐 OK 가 출력된다면 실제 설치로 넘어갑니다. 설치 폴더 생성 및 파일 이동 mkdir -p /opt/zap tar -xzf /tmp/ZAP_2.17.0_Linux.tar.gz -C /opt/zap chown -R $USER:$USER /opt/zap # 버전 업그레이드 시 경로가 안 바뀌도록 심볼릭 링크 (선택) ln -sfn /opt/zap/ZAP_2.17.0 /opt/zap/current API KEY 생성 무작위 키를 생성하여 관리자도 모르게 운영된다면 곤란합니다. 따라서 임의로 키를 생성하여 실행 시 선언합니다. cd /opt/zap/ZAP_2.17.0 # 충분히 긴 랜덤 키 생성 후 파일로 보관 openssl rand -hex 32 > ~/.zap_api_key chmod 600 ~/.zap_api_key 실행 # 생성한 API 키로 데몬 실행 cd /opt/zap/current # 로컬 접속만 허용 ./zap.sh -daemon -host 127.0.0.1 -port 8080 \ -config api.key=$(cat ~/.zap_api_key) # 외부 접근 가능한 바인딩 (접근 가능 IP 지정) ./zap.sh -daemon -host 0.0.0.0 -port 8080 \ -config api.key=$(cat ~/.zap_api_key) \ -config api.addrs.addr.name=$AcceptIP -config api.addrs.addr.regex=false 실행 명령어 입력 후에도 모든 작업이 끝나고 listen 중이라는 문구( ZAP is now listening on 0.0.0.0:8080 )가 출력되어야 접근이 가능합니다. 만일 부득이 모든 IP에서 접근 허용하게 하려면 아래 옵션을 사용하면 됩니다. -config api.addrs.addr.name=.* -config api.addrs.addr.regex=true 그러나 보안 상 권장하지 않습니다. 차라리 대역대 자체를 허용하는 방법도 있습니다. -config api.addrs.addr.name=^(127[.]0[.]0[.]1|192[.]168[.]0[.][0-9]+|10[.]172[.]1[.]122)$$ -config api.addrs.addr.regex=true WEB UI를 접근하면 아래와 같이 출력됩니다. 허무하게도 ZAP은 WEB UI가 우리가 생각하는 관리자 기능 제어 화면이 아닙니다. 따라서 스크립트를 만들어 편리하게 사용할 수 있도록 합니다. 편리 설정 시스템 데몬 파일 생성 mkdir -p /etc/zap echo "ZAP_API_KEY=$(cat ~/.zap_api_key)" | sudo tee /etc/zap/zap.env > /dev/null chmod 600 /etc/zap/zap.env vi /etc/systemd/system/zap.service === [Unit] Description=ZAP Daemon After=network-online.target Wants=network-online.target [Service] Type=simple User=$USER WorkingDirectory=/opt/zap/current EnvironmentFile=/etc/zap/zap.env ExecStart=/opt/zap/current/zap.sh -daemon -host 127.0.0.1 -port 8080 -config api.key=\${ZAP_API_KEY} Restart=on-failure RestartSec=10 TimeoutStopSec=60 [Install] WantedBy=multi-user.target === systemctl daemon-reload systemctl enable zap --now
velog
일단 대충 해봤는데 돌아가길래 올립니다... 19번 #include <iostream> #include <vector> #include <cmath> #include <cstring> using namespace std; vector<string> names; vector<int> numbers; int main(int argc, char *argv[]) { string name; int number; int cnt = 0; bool flag = true; cout<<"write down name and number.: "; cin>>name>>number; names.push_back(name); numbers.push_back(number); cnt ++; while(1){ cout<<"write down name and number.: "; cin>>name>>number; for(string a:names){ if(a == name) { cout<<"same name founded"<<endl; flag = false; break; } } if(flag ==false) break; names.push_back(name); numbers.push_back(number); cnt ++; } for(int i=0;i<cnt;i++){ cout<<names[i]<<" "<<numbers[i]<<endl; } } 20번 #include <iostream> #include <vector> #include <cmath> #include <cstring> #include <algorithm> #include <string> using namespace std; vector<string> names; vector<int> numbers; int main(int argc, char *argv[]) { string name; string search_name; int number; bool flag = true; cout<<"write down name and number.: "; cin>>name>>number; names.push_back(name); numbers.push_back(number); while(1){ cout<<"write down name and number.: "; cin>>name>>number; for(string a:names){ if(a == name) { cout<<"same name founded"<<endl; flag = false; break; } } if(flag ==false) break; names.push_back(name); numbers.push_back(number); } cout<<"write down the name you wanna search: "; cin>>search_name; if(find(names.begin(), names.end(), search_name) == names.end()) cout<<"no name"<<endl; else cout<<numbers[find(names.begin(),names.end(),search_name)-names.begin()]<<endl; } 21번 #include <iostream> #include <vector> #include <cmath> #include <cstring> #include <algorithm> #include <string> using namespace std; vector<string> names; vector<int> numbers; int main(int argc, char *argv[]) { string name; int search_num; int number; bool flag = true; bool search_flag = false; cout<<"write down name and number.: "; cin>>name>>number; names.push_back(name); numbers.push_back(number); while(1){ cout<<"write down name and number.: "; cin>>name>>number; for(string a:names){ if(a == name) { cout<<"same name founded"<<endl; flag = false; break; } } if(flag ==false) break; names.push_back(name); numbers.push_back(number); } cout<<"write down the number you wanna search: "; cin>>search_num; for (int i=0; i<numbers.size();i++){ if(numbers[i]==search_num){ cout<<names[i]<<endl; search_bool = true; } } if(search_bool == false)cout<<"no number"<<endl; } 그럼 감사합니다... 이만 총총
Score: 54.4Confidence: 49%
View offerScore: 54.4Confidence: 49%
Score: 54.4Confidence: 49%